brintos

brintos / linux-shallow public Read only

0
0
Text · 32.9 KiB · 290690f Raw
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, &register_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)(&register_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)(&register_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)(&register_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)(&register_mutex);1148	if (nfree) {1149		list_del(&notify->list);1150		list_for_each_entry(pcm, &snd_pcm_devices, list)1151			notify->n_unregister(pcm);1152	} else {1153		list_add_tail(&notify->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)(&register_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