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