1235 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Digital Audio (PCM) abstract layer4 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>5 */6 7#include <linux/init.h>8#include <linux/slab.h>9#include <linux/module.h>10#include <linux/time.h>11#include <linux/mutex.h>12#include <linux/device.h>13#include <linux/nospec.h>14#include <sound/core.h>15#include <sound/minors.h>16#include <sound/pcm.h>17#include <sound/timer.h>18#include <sound/control.h>19#include <sound/info.h>20 21#include "pcm_local.h"22 23MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Abramo Bagnara <abramo@alsa-project.org>");24MODULE_DESCRIPTION("Midlevel PCM code for ALSA.");25MODULE_LICENSE("GPL");26 27static LIST_HEAD(snd_pcm_devices);28static DEFINE_MUTEX(register_mutex);29#if IS_ENABLED(CONFIG_SND_PCM_OSS)30static LIST_HEAD(snd_pcm_notify_list);31#endif32 33static int snd_pcm_free(struct snd_pcm *pcm);34static int snd_pcm_dev_free(struct snd_device *device);35static int snd_pcm_dev_register(struct snd_device *device);36static int snd_pcm_dev_disconnect(struct snd_device *device);37 38static struct snd_pcm *snd_pcm_get(struct snd_card *card, int device)39{40 struct snd_pcm *pcm;41 42 list_for_each_entry(pcm, &snd_pcm_devices, list) {43 if (pcm->card == card && pcm->device == device)44 return pcm;45 }46 return NULL;47}48 49static int snd_pcm_next(struct snd_card *card, int device)50{51 struct snd_pcm *pcm;52 53 list_for_each_entry(pcm, &snd_pcm_devices, list) {54 if (pcm->card == card && pcm->device > device)55 return pcm->device;56 else if (pcm->card->number > card->number)57 return -1;58 }59 return -1;60}61 62static int snd_pcm_add(struct snd_pcm *newpcm)63{64 struct snd_pcm *pcm;65 66 if (newpcm->internal)67 return 0;68 69 list_for_each_entry(pcm, &snd_pcm_devices, list) {70 if (pcm->card == newpcm->card && pcm->device == newpcm->device)71 return -EBUSY;72 if (pcm->card->number > newpcm->card->number ||73 (pcm->card == newpcm->card &&74 pcm->device > newpcm->device)) {75 list_add(&newpcm->list, pcm->list.prev);76 return 0;77 }78 }79 list_add_tail(&newpcm->list, &snd_pcm_devices);80 return 0;81}82 83static int snd_pcm_control_ioctl(struct snd_card *card,84 struct snd_ctl_file *control,85 unsigned int cmd, unsigned long arg)86{87 switch (cmd) {88 case SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE:89 {90 int device;91 92 if (get_user(device, (int __user *)arg))93 return -EFAULT;94 scoped_guard(mutex, ®ister_mutex)95 device = snd_pcm_next(card, device);96 if (put_user(device, (int __user *)arg))97 return -EFAULT;98 return 0;99 }100 case SNDRV_CTL_IOCTL_PCM_INFO:101 {102 struct snd_pcm_info __user *info;103 unsigned int device, subdevice;104 int stream;105 struct snd_pcm *pcm;106 struct snd_pcm_str *pstr;107 struct snd_pcm_substream *substream;108 109 info = (struct snd_pcm_info __user *)arg;110 if (get_user(device, &info->device))111 return -EFAULT;112 if (get_user(stream, &info->stream))113 return -EFAULT;114 if (stream < 0 || stream > 1)115 return -EINVAL;116 stream = array_index_nospec(stream, 2);117 if (get_user(subdevice, &info->subdevice))118 return -EFAULT;119 guard(mutex)(®ister_mutex);120 pcm = snd_pcm_get(card, device);121 if (pcm == NULL)122 return -ENXIO;123 pstr = &pcm->streams[stream];124 if (pstr->substream_count == 0)125 return -ENOENT;126 if (subdevice >= pstr->substream_count)127 return -ENXIO;128 for (substream = pstr->substream; substream;129 substream = substream->next)130 if (substream->number == (int)subdevice)131 break;132 if (substream == NULL)133 return -ENXIO;134 guard(mutex)(&pcm->open_mutex);135 return snd_pcm_info_user(substream, info);136 }137 case SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE:138 {139 int val;140 141 if (get_user(val, (int __user *)arg))142 return -EFAULT;143 control->preferred_subdevice[SND_CTL_SUBDEV_PCM] = val;144 return 0;145 }146 }147 return -ENOIOCTLCMD;148}149 150#define FORMAT(v) [SNDRV_PCM_FORMAT_##v] = #v151 152static const char * const snd_pcm_format_names[] = {153 FORMAT(S8),154 FORMAT(U8),155 FORMAT(S16_LE),156 FORMAT(S16_BE),157 FORMAT(U16_LE),158 FORMAT(U16_BE),159 FORMAT(S24_LE),160 FORMAT(S24_BE),161 FORMAT(U24_LE),162 FORMAT(U24_BE),163 FORMAT(S32_LE),164 FORMAT(S32_BE),165 FORMAT(U32_LE),166 FORMAT(U32_BE),167 FORMAT(FLOAT_LE),168 FORMAT(FLOAT_BE),169 FORMAT(FLOAT64_LE),170 FORMAT(FLOAT64_BE),171 FORMAT(IEC958_SUBFRAME_LE),172 FORMAT(IEC958_SUBFRAME_BE),173 FORMAT(MU_LAW),174 FORMAT(A_LAW),175 FORMAT(IMA_ADPCM),176 FORMAT(MPEG),177 FORMAT(GSM),178 FORMAT(SPECIAL),179 FORMAT(S24_3LE),180 FORMAT(S24_3BE),181 FORMAT(U24_3LE),182 FORMAT(U24_3BE),183 FORMAT(S20_3LE),184 FORMAT(S20_3BE),185 FORMAT(U20_3LE),186 FORMAT(U20_3BE),187 FORMAT(S18_3LE),188 FORMAT(S18_3BE),189 FORMAT(U18_3LE),190 FORMAT(U18_3BE),191 FORMAT(G723_24),192 FORMAT(G723_24_1B),193 FORMAT(G723_40),194 FORMAT(G723_40_1B),195 FORMAT(DSD_U8),196 FORMAT(DSD_U16_LE),197 FORMAT(DSD_U32_LE),198 FORMAT(DSD_U16_BE),199 FORMAT(DSD_U32_BE),200 FORMAT(S20_LE),201 FORMAT(S20_BE),202 FORMAT(U20_LE),203 FORMAT(U20_BE),204};205 206/**207 * snd_pcm_format_name - Return a name string for the given PCM format208 * @format: PCM format209 *210 * Return: the format name string211 */212const char *snd_pcm_format_name(snd_pcm_format_t format)213{214 unsigned int format_num = (__force unsigned int)format;215 216 if (format_num >= ARRAY_SIZE(snd_pcm_format_names) || !snd_pcm_format_names[format_num])217 return "Unknown";218 return snd_pcm_format_names[format_num];219}220EXPORT_SYMBOL_GPL(snd_pcm_format_name);221 222#ifdef CONFIG_SND_VERBOSE_PROCFS223 224#define STATE(v) [SNDRV_PCM_STATE_##v] = #v225#define STREAM(v) [SNDRV_PCM_STREAM_##v] = #v226#define READY(v) [SNDRV_PCM_READY_##v] = #v227#define XRUN(v) [SNDRV_PCM_XRUN_##v] = #v228#define SILENCE(v) [SNDRV_PCM_SILENCE_##v] = #v229#define TSTAMP(v) [SNDRV_PCM_TSTAMP_##v] = #v230#define ACCESS(v) [SNDRV_PCM_ACCESS_##v] = #v231#define START(v) [SNDRV_PCM_START_##v] = #v232#define SUBFORMAT(v) [SNDRV_PCM_SUBFORMAT_##v] = #v 233 234static const char * const snd_pcm_stream_names[] = {235 STREAM(PLAYBACK),236 STREAM(CAPTURE),237};238 239static const char * const snd_pcm_state_names[] = {240 STATE(OPEN),241 STATE(SETUP),242 STATE(PREPARED),243 STATE(RUNNING),244 STATE(XRUN),245 STATE(DRAINING),246 STATE(PAUSED),247 STATE(SUSPENDED),248 STATE(DISCONNECTED),249};250 251static const char * const snd_pcm_access_names[] = {252 ACCESS(MMAP_INTERLEAVED), 253 ACCESS(MMAP_NONINTERLEAVED),254 ACCESS(MMAP_COMPLEX),255 ACCESS(RW_INTERLEAVED),256 ACCESS(RW_NONINTERLEAVED),257};258 259static const char * const snd_pcm_subformat_names[] = {260 SUBFORMAT(STD), 261 SUBFORMAT(MSBITS_MAX),262 SUBFORMAT(MSBITS_20),263 SUBFORMAT(MSBITS_24),264};265 266static const char * const snd_pcm_tstamp_mode_names[] = {267 TSTAMP(NONE),268 TSTAMP(ENABLE),269};270 271static const char *snd_pcm_stream_name(int stream)272{273 return snd_pcm_stream_names[stream];274}275 276static const char *snd_pcm_access_name(snd_pcm_access_t access)277{278 return snd_pcm_access_names[(__force int)access];279}280 281static const char *snd_pcm_subformat_name(snd_pcm_subformat_t subformat)282{283 return snd_pcm_subformat_names[(__force int)subformat];284}285 286static const char *snd_pcm_tstamp_mode_name(int mode)287{288 return snd_pcm_tstamp_mode_names[mode];289}290 291static const char *snd_pcm_state_name(snd_pcm_state_t state)292{293 return snd_pcm_state_names[(__force int)state];294}295 296#if IS_ENABLED(CONFIG_SND_PCM_OSS)297#include <linux/soundcard.h>298 299static const char *snd_pcm_oss_format_name(int format)300{301 switch (format) {302 case AFMT_MU_LAW:303 return "MU_LAW";304 case AFMT_A_LAW:305 return "A_LAW";306 case AFMT_IMA_ADPCM:307 return "IMA_ADPCM";308 case AFMT_U8:309 return "U8";310 case AFMT_S16_LE:311 return "S16_LE";312 case AFMT_S16_BE:313 return "S16_BE";314 case AFMT_S8:315 return "S8";316 case AFMT_U16_LE:317 return "U16_LE";318 case AFMT_U16_BE:319 return "U16_BE";320 case AFMT_MPEG:321 return "MPEG";322 default:323 return "unknown";324 }325}326#endif327 328static void snd_pcm_proc_info_read(struct snd_pcm_substream *substream,329 struct snd_info_buffer *buffer)330{331 struct snd_pcm_info *info __free(kfree) = NULL;332 int err;333 334 if (! substream)335 return;336 337 info = kmalloc(sizeof(*info), GFP_KERNEL);338 if (!info)339 return;340 341 err = snd_pcm_info(substream, info);342 if (err < 0) {343 snd_iprintf(buffer, "error %d\n", err);344 return;345 }346 snd_iprintf(buffer, "card: %d\n", info->card);347 snd_iprintf(buffer, "device: %d\n", info->device);348 snd_iprintf(buffer, "subdevice: %d\n", info->subdevice);349 snd_iprintf(buffer, "stream: %s\n", snd_pcm_stream_name(info->stream));350 snd_iprintf(buffer, "id: %s\n", info->id);351 snd_iprintf(buffer, "name: %s\n", info->name);352 snd_iprintf(buffer, "subname: %s\n", info->subname);353 snd_iprintf(buffer, "class: %d\n", info->dev_class);354 snd_iprintf(buffer, "subclass: %d\n", info->dev_subclass);355 snd_iprintf(buffer, "subdevices_count: %d\n", info->subdevices_count);356 snd_iprintf(buffer, "subdevices_avail: %d\n", info->subdevices_avail);357}358 359static void snd_pcm_stream_proc_info_read(struct snd_info_entry *entry,360 struct snd_info_buffer *buffer)361{362 snd_pcm_proc_info_read(((struct snd_pcm_str *)entry->private_data)->substream,363 buffer);364}365 366static void snd_pcm_substream_proc_info_read(struct snd_info_entry *entry,367 struct snd_info_buffer *buffer)368{369 snd_pcm_proc_info_read(entry->private_data, buffer);370}371 372static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry,373 struct snd_info_buffer *buffer)374{375 struct snd_pcm_substream *substream = entry->private_data;376 struct snd_pcm_runtime *runtime;377 378 guard(mutex)(&substream->pcm->open_mutex);379 runtime = substream->runtime;380 if (!runtime) {381 snd_iprintf(buffer, "closed\n");382 return;383 }384 if (runtime->state == SNDRV_PCM_STATE_OPEN) {385 snd_iprintf(buffer, "no setup\n");386 return;387 }388 snd_iprintf(buffer, "access: %s\n", snd_pcm_access_name(runtime->access));389 snd_iprintf(buffer, "format: %s\n", snd_pcm_format_name(runtime->format));390 snd_iprintf(buffer, "subformat: %s\n", snd_pcm_subformat_name(runtime->subformat));391 snd_iprintf(buffer, "channels: %u\n", runtime->channels); 392 snd_iprintf(buffer, "rate: %u (%u/%u)\n", runtime->rate, runtime->rate_num, runtime->rate_den); 393 snd_iprintf(buffer, "period_size: %lu\n", runtime->period_size); 394 snd_iprintf(buffer, "buffer_size: %lu\n", runtime->buffer_size); 395#if IS_ENABLED(CONFIG_SND_PCM_OSS)396 if (substream->oss.oss) {397 snd_iprintf(buffer, "OSS format: %s\n", snd_pcm_oss_format_name(runtime->oss.format));398 snd_iprintf(buffer, "OSS channels: %u\n", runtime->oss.channels); 399 snd_iprintf(buffer, "OSS rate: %u\n", runtime->oss.rate);400 snd_iprintf(buffer, "OSS period bytes: %lu\n", (unsigned long)runtime->oss.period_bytes);401 snd_iprintf(buffer, "OSS periods: %u\n", runtime->oss.periods);402 snd_iprintf(buffer, "OSS period frames: %lu\n", (unsigned long)runtime->oss.period_frames);403 }404#endif405}406 407static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry,408 struct snd_info_buffer *buffer)409{410 struct snd_pcm_substream *substream = entry->private_data;411 struct snd_pcm_runtime *runtime;412 413 guard(mutex)(&substream->pcm->open_mutex);414 runtime = substream->runtime;415 if (!runtime) {416 snd_iprintf(buffer, "closed\n");417 return;418 }419 if (runtime->state == SNDRV_PCM_STATE_OPEN) {420 snd_iprintf(buffer, "no setup\n");421 return;422 }423 snd_iprintf(buffer, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(runtime->tstamp_mode));424 snd_iprintf(buffer, "period_step: %u\n", runtime->period_step);425 snd_iprintf(buffer, "avail_min: %lu\n", runtime->control->avail_min);426 snd_iprintf(buffer, "start_threshold: %lu\n", runtime->start_threshold);427 snd_iprintf(buffer, "stop_threshold: %lu\n", runtime->stop_threshold);428 snd_iprintf(buffer, "silence_threshold: %lu\n", runtime->silence_threshold);429 snd_iprintf(buffer, "silence_size: %lu\n", runtime->silence_size);430 snd_iprintf(buffer, "boundary: %lu\n", runtime->boundary);431}432 433static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry,434 struct snd_info_buffer *buffer)435{436 struct snd_pcm_substream *substream = entry->private_data;437 struct snd_pcm_runtime *runtime;438 struct snd_pcm_status64 status;439 int err;440 441 guard(mutex)(&substream->pcm->open_mutex);442 runtime = substream->runtime;443 if (!runtime) {444 snd_iprintf(buffer, "closed\n");445 return;446 }447 memset(&status, 0, sizeof(status));448 err = snd_pcm_status64(substream, &status);449 if (err < 0) {450 snd_iprintf(buffer, "error %d\n", err);451 return;452 }453 snd_iprintf(buffer, "state: %s\n", snd_pcm_state_name(status.state));454 snd_iprintf(buffer, "owner_pid : %d\n", pid_vnr(substream->pid));455 snd_iprintf(buffer, "trigger_time: %lld.%09lld\n",456 status.trigger_tstamp_sec, status.trigger_tstamp_nsec);457 snd_iprintf(buffer, "tstamp : %lld.%09lld\n",458 status.tstamp_sec, status.tstamp_nsec);459 snd_iprintf(buffer, "delay : %ld\n", status.delay);460 snd_iprintf(buffer, "avail : %ld\n", status.avail);461 snd_iprintf(buffer, "avail_max : %ld\n", status.avail_max);462 snd_iprintf(buffer, "-----\n");463 snd_iprintf(buffer, "hw_ptr : %ld\n", runtime->status->hw_ptr);464 snd_iprintf(buffer, "appl_ptr : %ld\n", runtime->control->appl_ptr);465#ifdef CONFIG_SND_PCM_XRUN_DEBUG466 snd_iprintf(buffer, "xrun_counter: %d\n", substream->xrun_counter);467#endif468}469 470#ifdef CONFIG_SND_PCM_XRUN_DEBUG471static void snd_pcm_xrun_injection_write(struct snd_info_entry *entry,472 struct snd_info_buffer *buffer)473{474 struct snd_pcm_substream *substream = entry->private_data;475 476 snd_pcm_stop_xrun(substream);477}478 479static void snd_pcm_xrun_debug_read(struct snd_info_entry *entry,480 struct snd_info_buffer *buffer)481{482 struct snd_pcm_str *pstr = entry->private_data;483 snd_iprintf(buffer, "%d\n", pstr->xrun_debug);484}485 486static void snd_pcm_xrun_debug_write(struct snd_info_entry *entry,487 struct snd_info_buffer *buffer)488{489 struct snd_pcm_str *pstr = entry->private_data;490 char line[64];491 if (!snd_info_get_line(buffer, line, sizeof(line)))492 pstr->xrun_debug = simple_strtoul(line, NULL, 10);493}494#endif495 496static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr)497{498 struct snd_pcm *pcm = pstr->pcm;499 struct snd_info_entry *entry;500 char name[16];501 502 sprintf(name, "pcm%i%c", pcm->device, 503 pstr->stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c');504 entry = snd_info_create_card_entry(pcm->card, name,505 pcm->card->proc_root);506 if (!entry)507 return -ENOMEM;508 entry->mode = S_IFDIR | 0555;509 pstr->proc_root = entry;510 entry = snd_info_create_card_entry(pcm->card, "info", pstr->proc_root);511 if (entry)512 snd_info_set_text_ops(entry, pstr, snd_pcm_stream_proc_info_read);513#ifdef CONFIG_SND_PCM_XRUN_DEBUG514 entry = snd_info_create_card_entry(pcm->card, "xrun_debug",515 pstr->proc_root);516 if (entry) {517 snd_info_set_text_ops(entry, pstr, snd_pcm_xrun_debug_read);518 entry->c.text.write = snd_pcm_xrun_debug_write;519 entry->mode |= 0200;520 }521#endif522 return 0;523}524 525static int snd_pcm_stream_proc_done(struct snd_pcm_str *pstr)526{527 snd_info_free_entry(pstr->proc_root);528 pstr->proc_root = NULL;529 return 0;530}531 532static struct snd_info_entry *533create_substream_info_entry(struct snd_pcm_substream *substream,534 const char *name,535 void (*read)(struct snd_info_entry *,536 struct snd_info_buffer *))537{538 struct snd_info_entry *entry;539 540 entry = snd_info_create_card_entry(substream->pcm->card, name,541 substream->proc_root);542 if (entry)543 snd_info_set_text_ops(entry, substream, read);544 return entry;545}546 547static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)548{549 struct snd_info_entry *entry;550 struct snd_card *card;551 char name[16];552 553 card = substream->pcm->card;554 555 sprintf(name, "sub%i", substream->number);556 entry = snd_info_create_card_entry(card, name,557 substream->pstr->proc_root);558 if (!entry)559 return -ENOMEM;560 entry->mode = S_IFDIR | 0555;561 substream->proc_root = entry;562 563 create_substream_info_entry(substream, "info",564 snd_pcm_substream_proc_info_read);565 create_substream_info_entry(substream, "hw_params",566 snd_pcm_substream_proc_hw_params_read);567 create_substream_info_entry(substream, "sw_params",568 snd_pcm_substream_proc_sw_params_read);569 create_substream_info_entry(substream, "status",570 snd_pcm_substream_proc_status_read);571 572#ifdef CONFIG_SND_PCM_XRUN_DEBUG573 entry = create_substream_info_entry(substream, "xrun_injection", NULL);574 if (entry) {575 entry->c.text.write = snd_pcm_xrun_injection_write;576 entry->mode = S_IFREG | 0200;577 }578#endif /* CONFIG_SND_PCM_XRUN_DEBUG */579 580 return 0;581}582 583#else /* !CONFIG_SND_VERBOSE_PROCFS */584static inline int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr) { return 0; }585static inline int snd_pcm_stream_proc_done(struct snd_pcm_str *pstr) { return 0; }586static inline int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream) { return 0; }587#endif /* CONFIG_SND_VERBOSE_PROCFS */588 589static const struct attribute_group *pcm_dev_attr_groups[];590 591/*592 * PM callbacks: we need to deal only with suspend here, as the resume is593 * triggered either from user-space or the driver's resume callback594 */595#ifdef CONFIG_PM_SLEEP596static int do_pcm_suspend(struct device *dev)597{598 struct snd_pcm_str *pstr = dev_get_drvdata(dev);599 600 if (!pstr->pcm->no_device_suspend)601 snd_pcm_suspend_all(pstr->pcm);602 return 0;603}604#endif605 606static const struct dev_pm_ops pcm_dev_pm_ops = {607 SET_SYSTEM_SLEEP_PM_OPS(do_pcm_suspend, NULL)608};609 610/* device type for PCM -- basically only for passing PM callbacks */611static const struct device_type pcm_dev_type = {612 .name = "pcm",613 .pm = &pcm_dev_pm_ops,614};615 616/**617 * snd_pcm_new_stream - create a new PCM stream618 * @pcm: the pcm instance619 * @stream: the stream direction, SNDRV_PCM_STREAM_XXX620 * @substream_count: the number of substreams621 *622 * Creates a new stream for the pcm.623 * The corresponding stream on the pcm must have been empty before624 * calling this, i.e. zero must be given to the argument of625 * snd_pcm_new().626 *627 * Return: Zero if successful, or a negative error code on failure.628 */629int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)630{631 int idx, err;632 struct snd_pcm_str *pstr = &pcm->streams[stream];633 struct snd_pcm_substream *substream, *prev;634 635#if IS_ENABLED(CONFIG_SND_PCM_OSS)636 mutex_init(&pstr->oss.setup_mutex);637#endif638 pstr->stream = stream;639 pstr->pcm = pcm;640 pstr->substream_count = substream_count;641 if (!substream_count)642 return 0;643 644 err = snd_device_alloc(&pstr->dev, pcm->card);645 if (err < 0)646 return err;647 dev_set_name(pstr->dev, "pcmC%iD%i%c", pcm->card->number, pcm->device,648 stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c');649 pstr->dev->groups = pcm_dev_attr_groups;650 pstr->dev->type = &pcm_dev_type;651 dev_set_drvdata(pstr->dev, pstr);652 653 if (!pcm->internal) {654 err = snd_pcm_stream_proc_init(pstr);655 if (err < 0) {656 pcm_err(pcm, "Error in snd_pcm_stream_proc_init\n");657 return err;658 }659 }660 prev = NULL;661 for (idx = 0, prev = NULL; idx < substream_count; idx++) {662 substream = kzalloc(sizeof(*substream), GFP_KERNEL);663 if (!substream)664 return -ENOMEM;665 substream->pcm = pcm;666 substream->pstr = pstr;667 substream->number = idx;668 substream->stream = stream;669 sprintf(substream->name, "subdevice #%i", idx);670 substream->buffer_bytes_max = UINT_MAX;671 if (prev == NULL)672 pstr->substream = substream;673 else674 prev->next = substream;675 676 if (!pcm->internal) {677 err = snd_pcm_substream_proc_init(substream);678 if (err < 0) {679 pcm_err(pcm,680 "Error in snd_pcm_stream_proc_init\n");681 if (prev == NULL)682 pstr->substream = NULL;683 else684 prev->next = NULL;685 kfree(substream);686 return err;687 }688 }689 substream->group = &substream->self_group;690 snd_pcm_group_init(&substream->self_group);691 list_add_tail(&substream->link_list, &substream->self_group.substreams);692 atomic_set(&substream->mmap_count, 0);693 prev = substream;694 }695 return 0;696} 697EXPORT_SYMBOL(snd_pcm_new_stream);698 699static int _snd_pcm_new(struct snd_card *card, const char *id, int device,700 int playback_count, int capture_count, bool internal,701 struct snd_pcm **rpcm)702{703 struct snd_pcm *pcm;704 int err;705 static const struct snd_device_ops ops = {706 .dev_free = snd_pcm_dev_free,707 .dev_register = snd_pcm_dev_register,708 .dev_disconnect = snd_pcm_dev_disconnect,709 };710 static const struct snd_device_ops internal_ops = {711 .dev_free = snd_pcm_dev_free,712 };713 714 if (snd_BUG_ON(!card))715 return -ENXIO;716 if (rpcm)717 *rpcm = NULL;718 pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);719 if (!pcm)720 return -ENOMEM;721 pcm->card = card;722 pcm->device = device;723 pcm->internal = internal;724 mutex_init(&pcm->open_mutex);725 init_waitqueue_head(&pcm->open_wait);726 INIT_LIST_HEAD(&pcm->list);727 if (id)728 strscpy(pcm->id, id, sizeof(pcm->id));729 730 err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK,731 playback_count);732 if (err < 0)733 goto free_pcm;734 735 err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_CAPTURE, capture_count);736 if (err < 0)737 goto free_pcm;738 739 err = snd_device_new(card, SNDRV_DEV_PCM, pcm,740 internal ? &internal_ops : &ops);741 if (err < 0)742 goto free_pcm;743 744 if (rpcm)745 *rpcm = pcm;746 return 0;747 748free_pcm:749 snd_pcm_free(pcm);750 return err;751}752 753/**754 * snd_pcm_new - create a new PCM instance755 * @card: the card instance756 * @id: the id string757 * @device: the device index (zero based)758 * @playback_count: the number of substreams for playback759 * @capture_count: the number of substreams for capture760 * @rpcm: the pointer to store the new pcm instance761 *762 * Creates a new PCM instance.763 *764 * The pcm operators have to be set afterwards to the new instance765 * via snd_pcm_set_ops().766 *767 * Return: Zero if successful, or a negative error code on failure.768 */769int snd_pcm_new(struct snd_card *card, const char *id, int device,770 int playback_count, int capture_count, struct snd_pcm **rpcm)771{772 return _snd_pcm_new(card, id, device, playback_count, capture_count,773 false, rpcm);774}775EXPORT_SYMBOL(snd_pcm_new);776 777/**778 * snd_pcm_new_internal - create a new internal PCM instance779 * @card: the card instance780 * @id: the id string781 * @device: the device index (zero based - shared with normal PCMs)782 * @playback_count: the number of substreams for playback783 * @capture_count: the number of substreams for capture784 * @rpcm: the pointer to store the new pcm instance785 *786 * Creates a new internal PCM instance with no userspace device or procfs787 * entries. This is used by ASoC Back End PCMs in order to create a PCM that788 * will only be used internally by kernel drivers. i.e. it cannot be opened789 * by userspace. It provides existing ASoC components drivers with a substream790 * and access to any private data.791 *792 * The pcm operators have to be set afterwards to the new instance793 * via snd_pcm_set_ops().794 *795 * Return: Zero if successful, or a negative error code on failure.796 */797int snd_pcm_new_internal(struct snd_card *card, const char *id, int device,798 int playback_count, int capture_count,799 struct snd_pcm **rpcm)800{801 return _snd_pcm_new(card, id, device, playback_count, capture_count,802 true, rpcm);803}804EXPORT_SYMBOL(snd_pcm_new_internal);805 806static void free_chmap(struct snd_pcm_str *pstr)807{808 if (pstr->chmap_kctl) {809 struct snd_card *card = pstr->pcm->card;810 811 snd_ctl_remove(card, pstr->chmap_kctl);812 pstr->chmap_kctl = NULL;813 }814}815 816static void snd_pcm_free_stream(struct snd_pcm_str * pstr)817{818 struct snd_pcm_substream *substream, *substream_next;819#if IS_ENABLED(CONFIG_SND_PCM_OSS)820 struct snd_pcm_oss_setup *setup, *setupn;821#endif822 823 /* free all proc files under the stream */824 snd_pcm_stream_proc_done(pstr);825 826 substream = pstr->substream;827 while (substream) {828 substream_next = substream->next;829 snd_pcm_timer_done(substream);830 kfree(substream);831 substream = substream_next;832 }833#if IS_ENABLED(CONFIG_SND_PCM_OSS)834 for (setup = pstr->oss.setup_list; setup; setup = setupn) {835 setupn = setup->next;836 kfree(setup->task_name);837 kfree(setup);838 }839#endif840 free_chmap(pstr);841 if (pstr->substream_count)842 put_device(pstr->dev);843}844 845#if IS_ENABLED(CONFIG_SND_PCM_OSS)846#define pcm_call_notify(pcm, call) \847 do { \848 struct snd_pcm_notify *_notify; \849 list_for_each_entry(_notify, &snd_pcm_notify_list, list) \850 _notify->call(pcm); \851 } while (0)852#else853#define pcm_call_notify(pcm, call) do {} while (0)854#endif855 856static int snd_pcm_free(struct snd_pcm *pcm)857{858 if (!pcm)859 return 0;860 if (!pcm->internal)861 pcm_call_notify(pcm, n_unregister);862 if (pcm->private_free)863 pcm->private_free(pcm);864 snd_pcm_lib_preallocate_free_for_all(pcm);865 snd_pcm_free_stream(&pcm->streams[SNDRV_PCM_STREAM_PLAYBACK]);866 snd_pcm_free_stream(&pcm->streams[SNDRV_PCM_STREAM_CAPTURE]);867 kfree(pcm);868 return 0;869}870 871static int snd_pcm_dev_free(struct snd_device *device)872{873 struct snd_pcm *pcm = device->device_data;874 return snd_pcm_free(pcm);875}876 877int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,878 struct file *file,879 struct snd_pcm_substream **rsubstream)880{881 struct snd_pcm_str * pstr;882 struct snd_pcm_substream *substream;883 struct snd_pcm_runtime *runtime;884 struct snd_card *card;885 int prefer_subdevice;886 size_t size;887 888 if (snd_BUG_ON(!pcm || !rsubstream))889 return -ENXIO;890 if (snd_BUG_ON(stream != SNDRV_PCM_STREAM_PLAYBACK &&891 stream != SNDRV_PCM_STREAM_CAPTURE))892 return -EINVAL;893 *rsubstream = NULL;894 pstr = &pcm->streams[stream];895 if (pstr->substream == NULL || pstr->substream_count == 0)896 return -ENODEV;897 898 card = pcm->card;899 prefer_subdevice = snd_ctl_get_preferred_subdevice(card, SND_CTL_SUBDEV_PCM);900 901 if (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX) {902 int opposite = !stream;903 904 for (substream = pcm->streams[opposite].substream; substream;905 substream = substream->next) {906 if (SUBSTREAM_BUSY(substream))907 return -EAGAIN;908 }909 }910 911 if (file->f_flags & O_APPEND) {912 if (prefer_subdevice < 0) {913 if (pstr->substream_count > 1)914 return -EINVAL; /* must be unique */915 substream = pstr->substream;916 } else {917 for (substream = pstr->substream; substream;918 substream = substream->next)919 if (substream->number == prefer_subdevice)920 break;921 }922 if (! substream)923 return -ENODEV;924 if (! SUBSTREAM_BUSY(substream))925 return -EBADFD;926 substream->ref_count++;927 *rsubstream = substream;928 return 0;929 }930 931 for (substream = pstr->substream; substream; substream = substream->next) {932 if (!SUBSTREAM_BUSY(substream) &&933 (prefer_subdevice == -1 ||934 substream->number == prefer_subdevice))935 break;936 }937 if (substream == NULL)938 return -EAGAIN;939 940 runtime = kzalloc(sizeof(*runtime), GFP_KERNEL);941 if (runtime == NULL)942 return -ENOMEM;943 944 size = PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status));945 runtime->status = alloc_pages_exact(size, GFP_KERNEL);946 if (runtime->status == NULL) {947 kfree(runtime);948 return -ENOMEM;949 }950 memset(runtime->status, 0, size);951 952 size = PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control));953 runtime->control = alloc_pages_exact(size, GFP_KERNEL);954 if (runtime->control == NULL) {955 free_pages_exact(runtime->status,956 PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status)));957 kfree(runtime);958 return -ENOMEM;959 }960 memset(runtime->control, 0, size);961 962 init_waitqueue_head(&runtime->sleep);963 init_waitqueue_head(&runtime->tsleep);964 965 __snd_pcm_set_state(runtime, SNDRV_PCM_STATE_OPEN);966 mutex_init(&runtime->buffer_mutex);967 atomic_set(&runtime->buffer_accessing, 0);968 969 substream->runtime = runtime;970 substream->private_data = pcm->private_data;971 substream->ref_count = 1;972 substream->f_flags = file->f_flags;973 substream->pid = get_pid(task_pid(current));974 pstr->substream_opened++;975 *rsubstream = substream;976#ifdef CONFIG_SND_PCM_XRUN_DEBUG977 substream->xrun_counter = 0;978#endif /* CONFIG_SND_PCM_XRUN_DEBUG */979 return 0;980}981 982void snd_pcm_detach_substream(struct snd_pcm_substream *substream)983{984 struct snd_pcm_runtime *runtime;985 986 if (PCM_RUNTIME_CHECK(substream))987 return;988 runtime = substream->runtime;989 if (runtime->private_free != NULL)990 runtime->private_free(runtime);991 free_pages_exact(runtime->status,992 PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status)));993 free_pages_exact(runtime->control,994 PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control)));995 kfree(runtime->hw_constraints.rules);996 /* Avoid concurrent access to runtime via PCM timer interface */997 if (substream->timer) {998 scoped_guard(spinlock_irq, &substream->timer->lock)999 substream->runtime = NULL;1000 } else {1001 substream->runtime = NULL;1002 }1003 mutex_destroy(&runtime->buffer_mutex);1004 snd_fasync_free(runtime->fasync);1005 kfree(runtime);1006 put_pid(substream->pid);1007 substream->pid = NULL;1008 substream->pstr->substream_opened--;1009}1010 1011static ssize_t pcm_class_show(struct device *dev,1012 struct device_attribute *attr, char *buf)1013{1014 struct snd_pcm_str *pstr = dev_get_drvdata(dev);1015 struct snd_pcm *pcm = pstr->pcm;1016 const char *str;1017 static const char *strs[SNDRV_PCM_CLASS_LAST + 1] = {1018 [SNDRV_PCM_CLASS_GENERIC] = "generic",1019 [SNDRV_PCM_CLASS_MULTI] = "multi",1020 [SNDRV_PCM_CLASS_MODEM] = "modem",1021 [SNDRV_PCM_CLASS_DIGITIZER] = "digitizer",1022 };1023 1024 if (pcm->dev_class > SNDRV_PCM_CLASS_LAST)1025 str = "none";1026 else1027 str = strs[pcm->dev_class];1028 return sysfs_emit(buf, "%s\n", str);1029}1030 1031static DEVICE_ATTR_RO(pcm_class);1032static struct attribute *pcm_dev_attrs[] = {1033 &dev_attr_pcm_class.attr,1034 NULL1035};1036 1037static const struct attribute_group pcm_dev_attr_group = {1038 .attrs = pcm_dev_attrs,1039};1040 1041static const struct attribute_group *pcm_dev_attr_groups[] = {1042 &pcm_dev_attr_group,1043 NULL1044};1045 1046static int snd_pcm_dev_register(struct snd_device *device)1047{1048 int cidx, err;1049 struct snd_pcm_substream *substream;1050 struct snd_pcm *pcm;1051 1052 if (snd_BUG_ON(!device || !device->device_data))1053 return -ENXIO;1054 pcm = device->device_data;1055 1056 guard(mutex)(®ister_mutex);1057 err = snd_pcm_add(pcm);1058 if (err)1059 return err;1060 for (cidx = 0; cidx < 2; cidx++) {1061 int devtype = -1;1062 if (pcm->streams[cidx].substream == NULL)1063 continue;1064 switch (cidx) {1065 case SNDRV_PCM_STREAM_PLAYBACK:1066 devtype = SNDRV_DEVICE_TYPE_PCM_PLAYBACK;1067 break;1068 case SNDRV_PCM_STREAM_CAPTURE:1069 devtype = SNDRV_DEVICE_TYPE_PCM_CAPTURE;1070 break;1071 }1072 /* register pcm */1073 err = snd_register_device(devtype, pcm->card, pcm->device,1074 &snd_pcm_f_ops[cidx], pcm,1075 pcm->streams[cidx].dev);1076 if (err < 0) {1077 list_del_init(&pcm->list);1078 return err;1079 }1080 1081 for (substream = pcm->streams[cidx].substream; substream; substream = substream->next)1082 snd_pcm_timer_init(substream);1083 }1084 1085 pcm_call_notify(pcm, n_register);1086 return err;1087}1088 1089static int snd_pcm_dev_disconnect(struct snd_device *device)1090{1091 struct snd_pcm *pcm = device->device_data;1092 struct snd_pcm_substream *substream;1093 int cidx;1094 1095 guard(mutex)(®ister_mutex);1096 guard(mutex)(&pcm->open_mutex);1097 wake_up(&pcm->open_wait);1098 list_del_init(&pcm->list);1099 1100 for_each_pcm_substream(pcm, cidx, substream) {1101 snd_pcm_stream_lock_irq(substream);1102 if (substream->runtime) {1103 if (snd_pcm_running(substream))1104 snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);1105 /* to be sure, set the state unconditionally */1106 __snd_pcm_set_state(substream->runtime,1107 SNDRV_PCM_STATE_DISCONNECTED);1108 wake_up(&substream->runtime->sleep);1109 wake_up(&substream->runtime->tsleep);1110 }1111 snd_pcm_stream_unlock_irq(substream);1112 }1113 1114 for_each_pcm_substream(pcm, cidx, substream)1115 snd_pcm_sync_stop(substream, false);1116 1117 pcm_call_notify(pcm, n_disconnect);1118 for (cidx = 0; cidx < 2; cidx++) {1119 if (pcm->streams[cidx].dev)1120 snd_unregister_device(pcm->streams[cidx].dev);1121 free_chmap(&pcm->streams[cidx]);1122 }1123 return 0;1124}1125 1126#if IS_ENABLED(CONFIG_SND_PCM_OSS)1127/**1128 * snd_pcm_notify - Add/remove the notify list1129 * @notify: PCM notify list1130 * @nfree: 0 = register, 1 = unregister1131 *1132 * This adds the given notifier to the global list so that the callback is1133 * called for each registered PCM devices. This exists only for PCM OSS1134 * emulation, so far.1135 *1136 * Return: zero if successful, or a negative error code1137 */1138int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree)1139{1140 struct snd_pcm *pcm;1141 1142 if (snd_BUG_ON(!notify ||1143 !notify->n_register ||1144 !notify->n_unregister ||1145 !notify->n_disconnect))1146 return -EINVAL;1147 guard(mutex)(®ister_mutex);1148 if (nfree) {1149 list_del(¬ify->list);1150 list_for_each_entry(pcm, &snd_pcm_devices, list)1151 notify->n_unregister(pcm);1152 } else {1153 list_add_tail(¬ify->list, &snd_pcm_notify_list);1154 list_for_each_entry(pcm, &snd_pcm_devices, list)1155 notify->n_register(pcm);1156 }1157 return 0;1158}1159EXPORT_SYMBOL(snd_pcm_notify);1160#endif /* CONFIG_SND_PCM_OSS */1161 1162#ifdef CONFIG_SND_PROC_FS1163/*1164 * Info interface1165 */1166 1167static void snd_pcm_proc_read(struct snd_info_entry *entry,1168 struct snd_info_buffer *buffer)1169{1170 struct snd_pcm *pcm;1171 1172 guard(mutex)(®ister_mutex);1173 list_for_each_entry(pcm, &snd_pcm_devices, list) {1174 snd_iprintf(buffer, "%02i-%02i: %s : %s",1175 pcm->card->number, pcm->device, pcm->id, pcm->name);1176 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream)1177 snd_iprintf(buffer, " : playback %i",1178 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count);1179 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream)1180 snd_iprintf(buffer, " : capture %i",1181 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count);1182 snd_iprintf(buffer, "\n");1183 }1184}1185 1186static struct snd_info_entry *snd_pcm_proc_entry;1187 1188static void snd_pcm_proc_init(void)1189{1190 struct snd_info_entry *entry;1191 1192 entry = snd_info_create_module_entry(THIS_MODULE, "pcm", NULL);1193 if (entry) {1194 snd_info_set_text_ops(entry, NULL, snd_pcm_proc_read);1195 if (snd_info_register(entry) < 0) {1196 snd_info_free_entry(entry);1197 entry = NULL;1198 }1199 }1200 snd_pcm_proc_entry = entry;1201}1202 1203static void snd_pcm_proc_done(void)1204{1205 snd_info_free_entry(snd_pcm_proc_entry);1206}1207 1208#else /* !CONFIG_SND_PROC_FS */1209#define snd_pcm_proc_init()1210#define snd_pcm_proc_done()1211#endif /* CONFIG_SND_PROC_FS */1212 1213 1214/*1215 * ENTRY functions1216 */1217 1218static int __init alsa_pcm_init(void)1219{1220 snd_ctl_register_ioctl(snd_pcm_control_ioctl);1221 snd_ctl_register_ioctl_compat(snd_pcm_control_ioctl);1222 snd_pcm_proc_init();1223 return 0;1224}1225 1226static void __exit alsa_pcm_exit(void)1227{1228 snd_ctl_unregister_ioctl(snd_pcm_control_ioctl);1229 snd_ctl_unregister_ioctl_compat(snd_pcm_control_ioctl);1230 snd_pcm_proc_done();1231}1232 1233module_init(alsa_pcm_init)1234module_exit(alsa_pcm_exit)1235