Merge branch 'topic/pcm-internal' into for-next
This commit is contained in:
commit
0eee62e08c
|
@ -49,8 +49,6 @@ static struct snd_pcm *snd_pcm_get(struct snd_card *card, int device)
|
|||
struct snd_pcm *pcm;
|
||||
|
||||
list_for_each_entry(pcm, &snd_pcm_devices, list) {
|
||||
if (pcm->internal)
|
||||
continue;
|
||||
if (pcm->card == card && pcm->device == device)
|
||||
return pcm;
|
||||
}
|
||||
|
@ -62,8 +60,6 @@ static int snd_pcm_next(struct snd_card *card, int device)
|
|||
struct snd_pcm *pcm;
|
||||
|
||||
list_for_each_entry(pcm, &snd_pcm_devices, list) {
|
||||
if (pcm->internal)
|
||||
continue;
|
||||
if (pcm->card == card && pcm->device > device)
|
||||
return pcm->device;
|
||||
else if (pcm->card->number > card->number)
|
||||
|
@ -76,6 +72,9 @@ static int snd_pcm_add(struct snd_pcm *newpcm)
|
|||
{
|
||||
struct snd_pcm *pcm;
|
||||
|
||||
if (newpcm->internal)
|
||||
return 0;
|
||||
|
||||
list_for_each_entry(pcm, &snd_pcm_devices, list) {
|
||||
if (pcm->card == newpcm->card && pcm->device == newpcm->device)
|
||||
return -EBUSY;
|
||||
|
@ -782,6 +781,9 @@ static int _snd_pcm_new(struct snd_card *card, const char *id, int device,
|
|||
pcm->card = card;
|
||||
pcm->device = device;
|
||||
pcm->internal = internal;
|
||||
mutex_init(&pcm->open_mutex);
|
||||
init_waitqueue_head(&pcm->open_wait);
|
||||
INIT_LIST_HEAD(&pcm->list);
|
||||
if (id)
|
||||
strlcpy(pcm->id, id, sizeof(pcm->id));
|
||||
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,
|
|||
snd_pcm_free(pcm);
|
||||
return err;
|
||||
}
|
||||
mutex_init(&pcm->open_mutex);
|
||||
init_waitqueue_head(&pcm->open_wait);
|
||||
if ((err = snd_device_new(card, SNDRV_DEV_PCM, pcm, &ops)) < 0) {
|
||||
snd_pcm_free(pcm);
|
||||
return err;
|
||||
|
@ -888,8 +888,9 @@ static int snd_pcm_free(struct snd_pcm *pcm)
|
|||
|
||||
if (!pcm)
|
||||
return 0;
|
||||
list_for_each_entry(notify, &snd_pcm_notify_list, list) {
|
||||
notify->n_unregister(pcm);
|
||||
if (!pcm->internal) {
|
||||
list_for_each_entry(notify, &snd_pcm_notify_list, list)
|
||||
notify->n_unregister(pcm);
|
||||
}
|
||||
if (pcm->private_free)
|
||||
pcm->private_free(pcm);
|
||||
|
@ -919,6 +920,9 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
|
|||
|
||||
if (snd_BUG_ON(!pcm || !rsubstream))
|
||||
return -ENXIO;
|
||||
if (snd_BUG_ON(stream != SNDRV_PCM_STREAM_PLAYBACK &&
|
||||
stream != SNDRV_PCM_STREAM_CAPTURE))
|
||||
return -EINVAL;
|
||||
*rsubstream = NULL;
|
||||
pstr = &pcm->streams[stream];
|
||||
if (pstr->substream == NULL || pstr->substream_count == 0)
|
||||
|
@ -927,25 +931,14 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
|
|||
card = pcm->card;
|
||||
prefer_subdevice = snd_ctl_get_preferred_subdevice(card, SND_CTL_SUBDEV_PCM);
|
||||
|
||||
switch (stream) {
|
||||
case SNDRV_PCM_STREAM_PLAYBACK:
|
||||
if (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX) {
|
||||
for (substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; substream; substream = substream->next) {
|
||||
if (SUBSTREAM_BUSY(substream))
|
||||
return -EAGAIN;
|
||||
}
|
||||
if (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX) {
|
||||
int opposite = !stream;
|
||||
|
||||
for (substream = pcm->streams[opposite].substream; substream;
|
||||
substream = substream->next) {
|
||||
if (SUBSTREAM_BUSY(substream))
|
||||
return -EAGAIN;
|
||||
}
|
||||
break;
|
||||
case SNDRV_PCM_STREAM_CAPTURE:
|
||||
if (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX) {
|
||||
for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next) {
|
||||
if (SUBSTREAM_BUSY(substream))
|
||||
return -EAGAIN;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (file->f_flags & O_APPEND) {
|
||||
|
@ -968,15 +961,12 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (prefer_subdevice >= 0) {
|
||||
for (substream = pstr->substream; substream; substream = substream->next)
|
||||
if (!SUBSTREAM_BUSY(substream) && substream->number == prefer_subdevice)
|
||||
goto __ok;
|
||||
}
|
||||
for (substream = pstr->substream; substream; substream = substream->next)
|
||||
if (!SUBSTREAM_BUSY(substream))
|
||||
for (substream = pstr->substream; substream; substream = substream->next) {
|
||||
if (!SUBSTREAM_BUSY(substream) &&
|
||||
(prefer_subdevice == -1 ||
|
||||
substream->number == prefer_subdevice))
|
||||
break;
|
||||
__ok:
|
||||
}
|
||||
if (substream == NULL)
|
||||
return -EAGAIN;
|
||||
|
||||
|
@ -1086,15 +1076,16 @@ static int snd_pcm_dev_register(struct snd_device *device)
|
|||
if (snd_BUG_ON(!device || !device->device_data))
|
||||
return -ENXIO;
|
||||
pcm = device->device_data;
|
||||
if (pcm->internal)
|
||||
return 0;
|
||||
|
||||
mutex_lock(®ister_mutex);
|
||||
err = snd_pcm_add(pcm);
|
||||
if (err) {
|
||||
mutex_unlock(®ister_mutex);
|
||||
return err;
|
||||
}
|
||||
if (err)
|
||||
goto unlock;
|
||||
for (cidx = 0; cidx < 2; cidx++) {
|
||||
int devtype = -1;
|
||||
if (pcm->streams[cidx].substream == NULL || pcm->internal)
|
||||
if (pcm->streams[cidx].substream == NULL)
|
||||
continue;
|
||||
switch (cidx) {
|
||||
case SNDRV_PCM_STREAM_PLAYBACK:
|
||||
|
@ -1109,9 +1100,8 @@ static int snd_pcm_dev_register(struct snd_device *device)
|
|||
&snd_pcm_f_ops[cidx], pcm,
|
||||
&pcm->streams[cidx].dev);
|
||||
if (err < 0) {
|
||||
list_del(&pcm->list);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return err;
|
||||
list_del_init(&pcm->list);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
for (substream = pcm->streams[cidx].substream; substream; substream = substream->next)
|
||||
|
@ -1121,8 +1111,9 @@ static int snd_pcm_dev_register(struct snd_device *device)
|
|||
list_for_each_entry(notify, &snd_pcm_notify_list, list)
|
||||
notify->n_register(pcm);
|
||||
|
||||
unlock:
|
||||
mutex_unlock(®ister_mutex);
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int snd_pcm_dev_disconnect(struct snd_device *device)
|
||||
|
@ -1133,13 +1124,10 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)
|
|||
int cidx;
|
||||
|
||||
mutex_lock(®ister_mutex);
|
||||
if (list_empty(&pcm->list))
|
||||
goto unlock;
|
||||
|
||||
mutex_lock(&pcm->open_mutex);
|
||||
wake_up(&pcm->open_wait);
|
||||
list_del_init(&pcm->list);
|
||||
for (cidx = 0; cidx < 2; cidx++)
|
||||
for (cidx = 0; cidx < 2; cidx++) {
|
||||
for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) {
|
||||
snd_pcm_stream_lock_irq(substream);
|
||||
if (substream->runtime) {
|
||||
|
@ -1149,18 +1137,20 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)
|
|||
}
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
}
|
||||
list_for_each_entry(notify, &snd_pcm_notify_list, list) {
|
||||
notify->n_disconnect(pcm);
|
||||
}
|
||||
if (!pcm->internal) {
|
||||
list_for_each_entry(notify, &snd_pcm_notify_list, list)
|
||||
notify->n_disconnect(pcm);
|
||||
}
|
||||
for (cidx = 0; cidx < 2; cidx++) {
|
||||
snd_unregister_device(&pcm->streams[cidx].dev);
|
||||
if (!pcm->internal)
|
||||
snd_unregister_device(&pcm->streams[cidx].dev);
|
||||
if (pcm->streams[cidx].chmap_kctl) {
|
||||
snd_ctl_remove(pcm->card, pcm->streams[cidx].chmap_kctl);
|
||||
pcm->streams[cidx].chmap_kctl = NULL;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&pcm->open_mutex);
|
||||
unlock:
|
||||
mutex_unlock(®ister_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue