Skip to content

Commit 0eee62e

Browse files
committed
Merge branch 'topic/pcm-internal' into for-next
2 parents 8d085d3 + b202213 commit 0eee62e

File tree

1 file changed

+41
-51
lines changed

1 file changed

+41
-51
lines changed

sound/core/pcm.c

Lines changed: 41 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ static struct snd_pcm *snd_pcm_get(struct snd_card *card, int device)
4949
struct snd_pcm *pcm;
5050

5151
list_for_each_entry(pcm, &snd_pcm_devices, list) {
52-
if (pcm->internal)
53-
continue;
5452
if (pcm->card == card && pcm->device == device)
5553
return pcm;
5654
}
@@ -62,8 +60,6 @@ static int snd_pcm_next(struct snd_card *card, int device)
6260
struct snd_pcm *pcm;
6361

6462
list_for_each_entry(pcm, &snd_pcm_devices, list) {
65-
if (pcm->internal)
66-
continue;
6763
if (pcm->card == card && pcm->device > device)
6864
return pcm->device;
6965
else if (pcm->card->number > card->number)
@@ -76,6 +72,9 @@ static int snd_pcm_add(struct snd_pcm *newpcm)
7672
{
7773
struct snd_pcm *pcm;
7874

75+
if (newpcm->internal)
76+
return 0;
77+
7978
list_for_each_entry(pcm, &snd_pcm_devices, list) {
8079
if (pcm->card == newpcm->card && pcm->device == newpcm->device)
8180
return -EBUSY;
@@ -782,6 +781,9 @@ static int _snd_pcm_new(struct snd_card *card, const char *id, int device,
782781
pcm->card = card;
783782
pcm->device = device;
784783
pcm->internal = internal;
784+
mutex_init(&pcm->open_mutex);
785+
init_waitqueue_head(&pcm->open_wait);
786+
INIT_LIST_HEAD(&pcm->list);
785787
if (id)
786788
strlcpy(pcm->id, id, sizeof(pcm->id));
787789
if ((err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK, playback_count)) < 0) {
@@ -792,8 +794,6 @@ static int _snd_pcm_new(struct snd_card *card, const char *id, int device,
792794
snd_pcm_free(pcm);
793795
return err;
794796
}
795-
mutex_init(&pcm->open_mutex);
796-
init_waitqueue_head(&pcm->open_wait);
797797
if ((err = snd_device_new(card, SNDRV_DEV_PCM, pcm, &ops)) < 0) {
798798
snd_pcm_free(pcm);
799799
return err;
@@ -888,8 +888,9 @@ static int snd_pcm_free(struct snd_pcm *pcm)
888888

889889
if (!pcm)
890890
return 0;
891-
list_for_each_entry(notify, &snd_pcm_notify_list, list) {
892-
notify->n_unregister(pcm);
891+
if (!pcm->internal) {
892+
list_for_each_entry(notify, &snd_pcm_notify_list, list)
893+
notify->n_unregister(pcm);
893894
}
894895
if (pcm->private_free)
895896
pcm->private_free(pcm);
@@ -919,6 +920,9 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
919920

920921
if (snd_BUG_ON(!pcm || !rsubstream))
921922
return -ENXIO;
923+
if (snd_BUG_ON(stream != SNDRV_PCM_STREAM_PLAYBACK &&
924+
stream != SNDRV_PCM_STREAM_CAPTURE))
925+
return -EINVAL;
922926
*rsubstream = NULL;
923927
pstr = &pcm->streams[stream];
924928
if (pstr->substream == NULL || pstr->substream_count == 0)
@@ -927,25 +931,14 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
927931
card = pcm->card;
928932
prefer_subdevice = snd_ctl_get_preferred_subdevice(card, SND_CTL_SUBDEV_PCM);
929933

930-
switch (stream) {
931-
case SNDRV_PCM_STREAM_PLAYBACK:
932-
if (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX) {
933-
for (substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; substream; substream = substream->next) {
934-
if (SUBSTREAM_BUSY(substream))
935-
return -EAGAIN;
936-
}
937-
}
938-
break;
939-
case SNDRV_PCM_STREAM_CAPTURE:
940-
if (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX) {
941-
for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next) {
942-
if (SUBSTREAM_BUSY(substream))
943-
return -EAGAIN;
944-
}
934+
if (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX) {
935+
int opposite = !stream;
936+
937+
for (substream = pcm->streams[opposite].substream; substream;
938+
substream = substream->next) {
939+
if (SUBSTREAM_BUSY(substream))
940+
return -EAGAIN;
945941
}
946-
break;
947-
default:
948-
return -EINVAL;
949942
}
950943

951944
if (file->f_flags & O_APPEND) {
@@ -968,15 +961,12 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
968961
return 0;
969962
}
970963

971-
if (prefer_subdevice >= 0) {
972-
for (substream = pstr->substream; substream; substream = substream->next)
973-
if (!SUBSTREAM_BUSY(substream) && substream->number == prefer_subdevice)
974-
goto __ok;
975-
}
976-
for (substream = pstr->substream; substream; substream = substream->next)
977-
if (!SUBSTREAM_BUSY(substream))
964+
for (substream = pstr->substream; substream; substream = substream->next) {
965+
if (!SUBSTREAM_BUSY(substream) &&
966+
(prefer_subdevice == -1 ||
967+
substream->number == prefer_subdevice))
978968
break;
979-
__ok:
969+
}
980970
if (substream == NULL)
981971
return -EAGAIN;
982972

@@ -1086,15 +1076,16 @@ static int snd_pcm_dev_register(struct snd_device *device)
10861076
if (snd_BUG_ON(!device || !device->device_data))
10871077
return -ENXIO;
10881078
pcm = device->device_data;
1079+
if (pcm->internal)
1080+
return 0;
1081+
10891082
mutex_lock(&register_mutex);
10901083
err = snd_pcm_add(pcm);
1091-
if (err) {
1092-
mutex_unlock(&register_mutex);
1093-
return err;
1094-
}
1084+
if (err)
1085+
goto unlock;
10951086
for (cidx = 0; cidx < 2; cidx++) {
10961087
int devtype = -1;
1097-
if (pcm->streams[cidx].substream == NULL || pcm->internal)
1088+
if (pcm->streams[cidx].substream == NULL)
10981089
continue;
10991090
switch (cidx) {
11001091
case SNDRV_PCM_STREAM_PLAYBACK:
@@ -1109,9 +1100,8 @@ static int snd_pcm_dev_register(struct snd_device *device)
11091100
&snd_pcm_f_ops[cidx], pcm,
11101101
&pcm->streams[cidx].dev);
11111102
if (err < 0) {
1112-
list_del(&pcm->list);
1113-
mutex_unlock(&register_mutex);
1114-
return err;
1103+
list_del_init(&pcm->list);
1104+
goto unlock;
11151105
}
11161106

11171107
for (substream = pcm->streams[cidx].substream; substream; substream = substream->next)
@@ -1121,8 +1111,9 @@ static int snd_pcm_dev_register(struct snd_device *device)
11211111
list_for_each_entry(notify, &snd_pcm_notify_list, list)
11221112
notify->n_register(pcm);
11231113

1114+
unlock:
11241115
mutex_unlock(&register_mutex);
1125-
return 0;
1116+
return err;
11261117
}
11271118

11281119
static int snd_pcm_dev_disconnect(struct snd_device *device)
@@ -1133,13 +1124,10 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)
11331124
int cidx;
11341125

11351126
mutex_lock(&register_mutex);
1136-
if (list_empty(&pcm->list))
1137-
goto unlock;
1138-
11391127
mutex_lock(&pcm->open_mutex);
11401128
wake_up(&pcm->open_wait);
11411129
list_del_init(&pcm->list);
1142-
for (cidx = 0; cidx < 2; cidx++)
1130+
for (cidx = 0; cidx < 2; cidx++) {
11431131
for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) {
11441132
snd_pcm_stream_lock_irq(substream);
11451133
if (substream->runtime) {
@@ -1149,18 +1137,20 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)
11491137
}
11501138
snd_pcm_stream_unlock_irq(substream);
11511139
}
1152-
list_for_each_entry(notify, &snd_pcm_notify_list, list) {
1153-
notify->n_disconnect(pcm);
1140+
}
1141+
if (!pcm->internal) {
1142+
list_for_each_entry(notify, &snd_pcm_notify_list, list)
1143+
notify->n_disconnect(pcm);
11541144
}
11551145
for (cidx = 0; cidx < 2; cidx++) {
1156-
snd_unregister_device(&pcm->streams[cidx].dev);
1146+
if (!pcm->internal)
1147+
snd_unregister_device(&pcm->streams[cidx].dev);
11571148
if (pcm->streams[cidx].chmap_kctl) {
11581149
snd_ctl_remove(pcm->card, pcm->streams[cidx].chmap_kctl);
11591150
pcm->streams[cidx].chmap_kctl = NULL;
11601151
}
11611152
}
11621153
mutex_unlock(&pcm->open_mutex);
1163-
unlock:
11641154
mutex_unlock(&register_mutex);
11651155
return 0;
11661156
}

0 commit comments

Comments
 (0)