File Index
Files and directories
Sign in
FILE

pcm.c

File preview with syntax highlighting.

linux-6.19.14/sound/core/pcm.c C
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 *  Digital Audio (PCM) abstract layer
   4 *  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#endif
  32
  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] = #v
 151
 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 format
 208 * @format: PCM format
 209 *
 210 * Return: the format name string
 211 */
 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_PROCFS
 223
 224#define STATE(v) [SNDRV_PCM_STATE_##v] = #v
 225#define STREAM(v) [SNDRV_PCM_STREAM_##v] = #v
 226#define READY(v) [SNDRV_PCM_READY_##v] = #v
 227#define XRUN(v) [SNDRV_PCM_XRUN_##v] = #v
 228#define SILENCE(v) [SNDRV_PCM_SILENCE_##v] = #v
 229#define TSTAMP(v) [SNDRV_PCM_TSTAMP_##v] = #v
 230#define ACCESS(v) [SNDRV_PCM_ACCESS_##v] = #v
 231#define START(v) [SNDRV_PCM_START_##v] = #v
 232#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#endif
 327
 328static void snd_pcm_proc_info_read(struct snd_pcm_substream *substream,
 329				   struct snd_info_buffer *buffer)
 330{
 331	int err;
 332
 333	if (! substream)
 334		return;
 335
 336	struct snd_pcm_info *info __free(kfree) =
 337		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#endif
 405}
 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_DEBUG
 466	snd_iprintf(buffer, "xrun_counter: %d\n", substream->xrun_counter);
 467#endif
 468}
 469
 470#ifdef CONFIG_SND_PCM_XRUN_DEBUG
 471static 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#endif
 495
 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_DEBUG
 514	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#endif
 522	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_DEBUG
 573	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 is
 593 * triggered either from user-space or the driver's resume callback
 594 */
 595static int do_pcm_suspend(struct device *dev)
 596{
 597	struct snd_pcm_str *pstr = dev_get_drvdata(dev);
 598
 599	if (!pstr->pcm->no_device_suspend)
 600		snd_pcm_suspend_all(pstr->pcm);
 601	return 0;
 602}
 603
 604static const struct dev_pm_ops pcm_dev_pm_ops = {
 605	SYSTEM_SLEEP_PM_OPS(do_pcm_suspend, NULL)
 606};
 607
 608/* device type for PCM -- basically only for passing PM callbacks */
 609static const struct device_type pcm_dev_type = {
 610	.name = "pcm",
 611	.pm = &pcm_dev_pm_ops,
 612};
 613
 614/**
 615 * snd_pcm_new_stream - create a new PCM stream
 616 * @pcm: the pcm instance
 617 * @stream: the stream direction, SNDRV_PCM_STREAM_XXX
 618 * @substream_count: the number of substreams
 619 *
 620 * Creates a new stream for the pcm.
 621 * The corresponding stream on the pcm must have been empty before
 622 * calling this, i.e. zero must be given to the argument of
 623 * snd_pcm_new().
 624 *
 625 * Return: Zero if successful, or a negative error code on failure.
 626 */
 627int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
 628{
 629	int idx, err;
 630	struct snd_pcm_str *pstr = &pcm->streams[stream];
 631	struct snd_pcm_substream *substream, *prev;
 632
 633#if IS_ENABLED(CONFIG_SND_PCM_OSS)
 634	mutex_init(&pstr->oss.setup_mutex);
 635#endif
 636	pstr->stream = stream;
 637	pstr->pcm = pcm;
 638	pstr->substream_count = substream_count;
 639	if (!substream_count)
 640		return 0;
 641
 642	err = snd_device_alloc(&pstr->dev, pcm->card);
 643	if (err < 0)
 644		return err;
 645	dev_set_name(pstr->dev, "pcmC%iD%i%c", pcm->card->number, pcm->device,
 646		     stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c');
 647	pstr->dev->groups = pcm_dev_attr_groups;
 648	pstr->dev->type = &pcm_dev_type;
 649	dev_set_drvdata(pstr->dev, pstr);
 650
 651	if (!pcm->internal) {
 652		err = snd_pcm_stream_proc_init(pstr);
 653		if (err < 0) {
 654			pcm_err(pcm, "Error in snd_pcm_stream_proc_init\n");
 655			return err;
 656		}
 657	}
 658	prev = NULL;
 659	for (idx = 0, prev = NULL; idx < substream_count; idx++) {
 660		substream = kzalloc(sizeof(*substream), GFP_KERNEL);
 661		if (!substream)
 662			return -ENOMEM;
 663		substream->pcm = pcm;
 664		substream->pstr = pstr;
 665		substream->number = idx;
 666		substream->stream = stream;
 667		sprintf(substream->name, "subdevice #%i", idx);
 668		substream->buffer_bytes_max = UINT_MAX;
 669		if (prev == NULL)
 670			pstr->substream = substream;
 671		else
 672			prev->next = substream;
 673
 674		if (!pcm->internal) {
 675			err = snd_pcm_substream_proc_init(substream);
 676			if (err < 0) {
 677				pcm_err(pcm,
 678					"Error in snd_pcm_stream_proc_init\n");
 679				if (prev == NULL)
 680					pstr->substream = NULL;
 681				else
 682					prev->next = NULL;
 683				kfree(substream);
 684				return err;
 685			}
 686		}
 687		substream->group = &substream->self_group;
 688		snd_pcm_group_init(&substream->self_group);
 689		list_add_tail(&substream->link_list, &substream->self_group.substreams);
 690		atomic_set(&substream->mmap_count, 0);
 691		prev = substream;
 692	}
 693	return 0;
 694}				
 695EXPORT_SYMBOL(snd_pcm_new_stream);
 696
 697static int _snd_pcm_new(struct snd_card *card, const char *id, int device,
 698		int playback_count, int capture_count, bool internal,
 699		struct snd_pcm **rpcm)
 700{
 701	struct snd_pcm *pcm;
 702	int err;
 703	static const struct snd_device_ops ops = {
 704		.dev_free = snd_pcm_dev_free,
 705		.dev_register =	snd_pcm_dev_register,
 706		.dev_disconnect = snd_pcm_dev_disconnect,
 707	};
 708	static const struct snd_device_ops internal_ops = {
 709		.dev_free = snd_pcm_dev_free,
 710	};
 711
 712	if (snd_BUG_ON(!card))
 713		return -ENXIO;
 714	if (rpcm)
 715		*rpcm = NULL;
 716	pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
 717	if (!pcm)
 718		return -ENOMEM;
 719	pcm->card = card;
 720	pcm->device = device;
 721	pcm->internal = internal;
 722	mutex_init(&pcm->open_mutex);
 723	init_waitqueue_head(&pcm->open_wait);
 724	INIT_LIST_HEAD(&pcm->list);
 725	if (id)
 726		strscpy(pcm->id, id, sizeof(pcm->id));
 727
 728	err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK,
 729				 playback_count);
 730	if (err < 0)
 731		goto free_pcm;
 732
 733	err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_CAPTURE, capture_count);
 734	if (err < 0)
 735		goto free_pcm;
 736
 737	err = snd_device_new(card, SNDRV_DEV_PCM, pcm,
 738			     internal ? &internal_ops : &ops);
 739	if (err < 0)
 740		goto free_pcm;
 741
 742	if (rpcm)
 743		*rpcm = pcm;
 744	return 0;
 745
 746free_pcm:
 747	snd_pcm_free(pcm);
 748	return err;
 749}
 750
 751/**
 752 * snd_pcm_new - create a new PCM instance
 753 * @card: the card instance
 754 * @id: the id string
 755 * @device: the device index (zero based)
 756 * @playback_count: the number of substreams for playback
 757 * @capture_count: the number of substreams for capture
 758 * @rpcm: the pointer to store the new pcm instance
 759 *
 760 * Creates a new PCM instance.
 761 *
 762 * The pcm operators have to be set afterwards to the new instance
 763 * via snd_pcm_set_ops().
 764 *
 765 * Return: Zero if successful, or a negative error code on failure.
 766 */
 767int snd_pcm_new(struct snd_card *card, const char *id, int device,
 768		int playback_count, int capture_count, struct snd_pcm **rpcm)
 769{
 770	return _snd_pcm_new(card, id, device, playback_count, capture_count,
 771			false, rpcm);
 772}
 773EXPORT_SYMBOL(snd_pcm_new);
 774
 775/**
 776 * snd_pcm_new_internal - create a new internal PCM instance
 777 * @card: the card instance
 778 * @id: the id string
 779 * @device: the device index (zero based - shared with normal PCMs)
 780 * @playback_count: the number of substreams for playback
 781 * @capture_count: the number of substreams for capture
 782 * @rpcm: the pointer to store the new pcm instance
 783 *
 784 * Creates a new internal PCM instance with no userspace device or procfs
 785 * entries. This is used by ASoC Back End PCMs in order to create a PCM that
 786 * will only be used internally by kernel drivers. i.e. it cannot be opened
 787 * by userspace. It provides existing ASoC components drivers with a substream
 788 * and access to any private data.
 789 *
 790 * The pcm operators have to be set afterwards to the new instance
 791 * via snd_pcm_set_ops().
 792 *
 793 * Return: Zero if successful, or a negative error code on failure.
 794 */
 795int snd_pcm_new_internal(struct snd_card *card, const char *id, int device,
 796	int playback_count, int capture_count,
 797	struct snd_pcm **rpcm)
 798{
 799	return _snd_pcm_new(card, id, device, playback_count, capture_count,
 800			true, rpcm);
 801}
 802EXPORT_SYMBOL(snd_pcm_new_internal);
 803
 804static void free_chmap(struct snd_pcm_str *pstr)
 805{
 806	if (pstr->chmap_kctl) {
 807		struct snd_card *card = pstr->pcm->card;
 808
 809		snd_ctl_remove(card, pstr->chmap_kctl);
 810		pstr->chmap_kctl = NULL;
 811	}
 812}
 813
 814static void snd_pcm_free_stream(struct snd_pcm_str * pstr)
 815{
 816	struct snd_pcm_substream *substream, *substream_next;
 817#if IS_ENABLED(CONFIG_SND_PCM_OSS)
 818	struct snd_pcm_oss_setup *setup, *setupn;
 819#endif
 820
 821	/* free all proc files under the stream */
 822	snd_pcm_stream_proc_done(pstr);
 823
 824	substream = pstr->substream;
 825	while (substream) {
 826		substream_next = substream->next;
 827		snd_pcm_timer_done(substream);
 828		kfree(substream);
 829		substream = substream_next;
 830	}
 831#if IS_ENABLED(CONFIG_SND_PCM_OSS)
 832	for (setup = pstr->oss.setup_list; setup; setup = setupn) {
 833		setupn = setup->next;
 834		kfree(setup->task_name);
 835		kfree(setup);
 836	}
 837#endif
 838	free_chmap(pstr);
 839	if (pstr->substream_count)
 840		put_device(pstr->dev);
 841}
 842
 843#if IS_ENABLED(CONFIG_SND_PCM_OSS)
 844#define pcm_call_notify(pcm, call)					\
 845	do {								\
 846		struct snd_pcm_notify *_notify;				\
 847		list_for_each_entry(_notify, &snd_pcm_notify_list, list) \
 848			_notify->call(pcm);				\
 849	} while (0)
 850#else
 851#define pcm_call_notify(pcm, call) do {} while (0)
 852#endif
 853
 854static int snd_pcm_free(struct snd_pcm *pcm)
 855{
 856	if (!pcm)
 857		return 0;
 858	if (!pcm->internal)
 859		pcm_call_notify(pcm, n_unregister);
 860	if (pcm->private_free)
 861		pcm->private_free(pcm);
 862	snd_pcm_lib_preallocate_free_for_all(pcm);
 863	snd_pcm_free_stream(&pcm->streams[SNDRV_PCM_STREAM_PLAYBACK]);
 864	snd_pcm_free_stream(&pcm->streams[SNDRV_PCM_STREAM_CAPTURE]);
 865	kfree(pcm);
 866	return 0;
 867}
 868
 869static int snd_pcm_dev_free(struct snd_device *device)
 870{
 871	struct snd_pcm *pcm = device->device_data;
 872	return snd_pcm_free(pcm);
 873}
 874
 875int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
 876			     struct file *file,
 877			     struct snd_pcm_substream **rsubstream)
 878{
 879	struct snd_pcm_str * pstr;
 880	struct snd_pcm_substream *substream;
 881	struct snd_pcm_runtime *runtime;
 882	struct snd_card *card;
 883	int prefer_subdevice;
 884	size_t size;
 885
 886	if (snd_BUG_ON(!pcm || !rsubstream))
 887		return -ENXIO;
 888	if (snd_BUG_ON(stream != SNDRV_PCM_STREAM_PLAYBACK &&
 889		       stream != SNDRV_PCM_STREAM_CAPTURE))
 890		return -EINVAL;
 891	*rsubstream = NULL;
 892	pstr = &pcm->streams[stream];
 893	if (pstr->substream == NULL || pstr->substream_count == 0)
 894		return -ENODEV;
 895
 896	card = pcm->card;
 897	prefer_subdevice = snd_ctl_get_preferred_subdevice(card, SND_CTL_SUBDEV_PCM);
 898
 899	if (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX) {
 900		int opposite = !stream;
 901
 902		for (substream = pcm->streams[opposite].substream; substream;
 903		     substream = substream->next) {
 904			if (SUBSTREAM_BUSY(substream))
 905				return -EAGAIN;
 906		}
 907	}
 908
 909	if (file->f_flags & O_APPEND) {
 910		if (prefer_subdevice < 0) {
 911			if (pstr->substream_count > 1)
 912				return -EINVAL; /* must be unique */
 913			substream = pstr->substream;
 914		} else {
 915			for (substream = pstr->substream; substream;
 916			     substream = substream->next)
 917				if (substream->number == prefer_subdevice)
 918					break;
 919		}
 920		if (! substream)
 921			return -ENODEV;
 922		if (! SUBSTREAM_BUSY(substream))
 923			return -EBADFD;
 924		substream->ref_count++;
 925		*rsubstream = substream;
 926		return 0;
 927	}
 928
 929	for (substream = pstr->substream; substream; substream = substream->next) {
 930		if (!SUBSTREAM_BUSY(substream) &&
 931		    (prefer_subdevice == -1 ||
 932		     substream->number == prefer_subdevice))
 933			break;
 934	}
 935	if (substream == NULL)
 936		return -EAGAIN;
 937
 938	runtime = kzalloc(sizeof(*runtime), GFP_KERNEL);
 939	if (runtime == NULL)
 940		return -ENOMEM;
 941
 942	size = PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status));
 943	runtime->status = alloc_pages_exact(size, GFP_KERNEL);
 944	if (runtime->status == NULL) {
 945		kfree(runtime);
 946		return -ENOMEM;
 947	}
 948	memset(runtime->status, 0, size);
 949
 950	size = PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control));
 951	runtime->control = alloc_pages_exact(size, GFP_KERNEL);
 952	if (runtime->control == NULL) {
 953		free_pages_exact(runtime->status,
 954			       PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status)));
 955		kfree(runtime);
 956		return -ENOMEM;
 957	}
 958	memset(runtime->control, 0, size);
 959
 960	init_waitqueue_head(&runtime->sleep);
 961	init_waitqueue_head(&runtime->tsleep);
 962
 963	__snd_pcm_set_state(runtime, SNDRV_PCM_STATE_OPEN);
 964	mutex_init(&runtime->buffer_mutex);
 965	atomic_set(&runtime->buffer_accessing, 0);
 966
 967	substream->runtime = runtime;
 968	substream->private_data = pcm->private_data;
 969	substream->ref_count = 1;
 970	substream->f_flags = file->f_flags;
 971	substream->pid = get_pid(task_pid(current));
 972	pstr->substream_opened++;
 973	*rsubstream = substream;
 974#ifdef CONFIG_SND_PCM_XRUN_DEBUG
 975	substream->xrun_counter = 0;
 976#endif /* CONFIG_SND_PCM_XRUN_DEBUG */
 977	return 0;
 978}
 979
 980void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
 981{
 982	struct snd_pcm_runtime *runtime;
 983
 984	if (PCM_RUNTIME_CHECK(substream))
 985		return;
 986	runtime = substream->runtime;
 987	if (runtime->private_free != NULL)
 988		runtime->private_free(runtime);
 989	free_pages_exact(runtime->status,
 990		       PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status)));
 991	free_pages_exact(runtime->control,
 992		       PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control)));
 993	kfree(runtime->hw_constraints.rules);
 994	/* Avoid concurrent access to runtime via PCM timer interface */
 995	if (substream->timer) {
 996		scoped_guard(spinlock_irq, &substream->timer->lock)
 997			substream->runtime = NULL;
 998	} else {
 999		substream->runtime = NULL;
1000	}
1001	mutex_destroy(&runtime->buffer_mutex);
1002	snd_fasync_free(runtime->fasync);
1003	kfree(runtime);
1004	put_pid(substream->pid);
1005	substream->pid = NULL;
1006	substream->pstr->substream_opened--;
1007}
1008
1009static ssize_t pcm_class_show(struct device *dev,
1010			      struct device_attribute *attr, char *buf)
1011{
1012	struct snd_pcm_str *pstr = dev_get_drvdata(dev);
1013	struct snd_pcm *pcm = pstr->pcm;
1014	const char *str;
1015	static const char *strs[SNDRV_PCM_CLASS_LAST + 1] = {
1016		[SNDRV_PCM_CLASS_GENERIC] = "generic",
1017		[SNDRV_PCM_CLASS_MULTI] = "multi",
1018		[SNDRV_PCM_CLASS_MODEM] = "modem",
1019		[SNDRV_PCM_CLASS_DIGITIZER] = "digitizer",
1020	};
1021
1022	if (pcm->dev_class > SNDRV_PCM_CLASS_LAST)
1023		str = "none";
1024	else
1025		str = strs[pcm->dev_class];
1026	return sysfs_emit(buf, "%s\n", str);
1027}
1028
1029static DEVICE_ATTR_RO(pcm_class);
1030static struct attribute *pcm_dev_attrs[] = {
1031	&dev_attr_pcm_class.attr,
1032	NULL
1033};
1034
1035static const struct attribute_group pcm_dev_attr_group = {
1036	.attrs	= pcm_dev_attrs,
1037};
1038
1039static const struct attribute_group *pcm_dev_attr_groups[] = {
1040	&pcm_dev_attr_group,
1041	NULL
1042};
1043
1044static int snd_pcm_dev_register(struct snd_device *device)
1045{
1046	int cidx, err;
1047	struct snd_pcm_substream *substream;
1048	struct snd_pcm *pcm;
1049
1050	if (snd_BUG_ON(!device || !device->device_data))
1051		return -ENXIO;
1052	pcm = device->device_data;
1053
1054	guard(mutex)(&register_mutex);
1055	err = snd_pcm_add(pcm);
1056	if (err)
1057		return err;
1058	for (cidx = 0; cidx < 2; cidx++) {
1059		int devtype = -1;
1060		if (pcm->streams[cidx].substream == NULL)
1061			continue;
1062		switch (cidx) {
1063		case SNDRV_PCM_STREAM_PLAYBACK:
1064			devtype = SNDRV_DEVICE_TYPE_PCM_PLAYBACK;
1065			break;
1066		case SNDRV_PCM_STREAM_CAPTURE:
1067			devtype = SNDRV_DEVICE_TYPE_PCM_CAPTURE;
1068			break;
1069		}
1070		/* register pcm */
1071		err = snd_register_device(devtype, pcm->card, pcm->device,
1072					  &snd_pcm_f_ops[cidx], pcm,
1073					  pcm->streams[cidx].dev);
1074		if (err < 0) {
1075			list_del_init(&pcm->list);
1076			return err;
1077		}
1078
1079		for (substream = pcm->streams[cidx].substream; substream; substream = substream->next)
1080			snd_pcm_timer_init(substream);
1081	}
1082
1083	pcm_call_notify(pcm, n_register);
1084	return err;
1085}
1086
1087static int snd_pcm_dev_disconnect(struct snd_device *device)
1088{
1089	struct snd_pcm *pcm = device->device_data;
1090	struct snd_pcm_substream *substream;
1091	int cidx;
1092
1093	guard(mutex)(&register_mutex);
1094	guard(mutex)(&pcm->open_mutex);
1095	wake_up(&pcm->open_wait);
1096	list_del_init(&pcm->list);
1097
1098	for_each_pcm_substream(pcm, cidx, substream) {
1099		snd_pcm_stream_lock_irq(substream);
1100		if (substream->runtime) {
1101			if (snd_pcm_running(substream))
1102				snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);
1103			/* to be sure, set the state unconditionally */
1104			__snd_pcm_set_state(substream->runtime,
1105					    SNDRV_PCM_STATE_DISCONNECTED);
1106			wake_up(&substream->runtime->sleep);
1107			wake_up(&substream->runtime->tsleep);
1108		}
1109		snd_pcm_stream_unlock_irq(substream);
1110	}
1111
1112	for_each_pcm_substream(pcm, cidx, substream)
1113		snd_pcm_sync_stop(substream, false);
1114
1115	pcm_call_notify(pcm, n_disconnect);
1116	for (cidx = 0; cidx < 2; cidx++) {
1117		if (pcm->streams[cidx].dev)
1118			snd_unregister_device(pcm->streams[cidx].dev);
1119		free_chmap(&pcm->streams[cidx]);
1120	}
1121	return 0;
1122}
1123
1124#if IS_ENABLED(CONFIG_SND_PCM_OSS)
1125/**
1126 * snd_pcm_notify - Add/remove the notify list
1127 * @notify: PCM notify list
1128 * @nfree: 0 = register, 1 = unregister
1129 *
1130 * This adds the given notifier to the global list so that the callback is
1131 * called for each registered PCM devices.  This exists only for PCM OSS
1132 * emulation, so far.
1133 *
1134 * Return: zero if successful, or a negative error code
1135 */
1136int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree)
1137{
1138	struct snd_pcm *pcm;
1139
1140	if (snd_BUG_ON(!notify ||
1141		       !notify->n_register ||
1142		       !notify->n_unregister ||
1143		       !notify->n_disconnect))
1144		return -EINVAL;
1145	guard(mutex)(&register_mutex);
1146	if (nfree) {
1147		list_del(&notify->list);
1148		list_for_each_entry(pcm, &snd_pcm_devices, list)
1149			notify->n_unregister(pcm);
1150	} else {
1151		list_add_tail(&notify->list, &snd_pcm_notify_list);
1152		list_for_each_entry(pcm, &snd_pcm_devices, list)
1153			notify->n_register(pcm);
1154	}
1155	return 0;
1156}
1157EXPORT_SYMBOL(snd_pcm_notify);
1158#endif /* CONFIG_SND_PCM_OSS */
1159
1160#ifdef CONFIG_SND_PROC_FS
1161/*
1162 *  Info interface
1163 */
1164
1165static void snd_pcm_proc_read(struct snd_info_entry *entry,
1166			      struct snd_info_buffer *buffer)
1167{
1168	struct snd_pcm *pcm;
1169
1170	guard(mutex)(&register_mutex);
1171	list_for_each_entry(pcm, &snd_pcm_devices, list) {
1172		snd_iprintf(buffer, "%02i-%02i: %s : %s",
1173			    pcm->card->number, pcm->device, pcm->id, pcm->name);
1174		if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream)
1175			snd_iprintf(buffer, " : playback %i",
1176				    pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count);
1177		if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream)
1178			snd_iprintf(buffer, " : capture %i",
1179				    pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count);
1180		snd_iprintf(buffer, "\n");
1181	}
1182}
1183
1184static struct snd_info_entry *snd_pcm_proc_entry;
1185
1186static void snd_pcm_proc_init(void)
1187{
1188	struct snd_info_entry *entry;
1189
1190	entry = snd_info_create_module_entry(THIS_MODULE, "pcm", NULL);
1191	if (entry) {
1192		snd_info_set_text_ops(entry, NULL, snd_pcm_proc_read);
1193		if (snd_info_register(entry) < 0) {
1194			snd_info_free_entry(entry);
1195			entry = NULL;
1196		}
1197	}
1198	snd_pcm_proc_entry = entry;
1199}
1200
1201static void snd_pcm_proc_done(void)
1202{
1203	snd_info_free_entry(snd_pcm_proc_entry);
1204}
1205
1206#else /* !CONFIG_SND_PROC_FS */
1207#define snd_pcm_proc_init()
1208#define snd_pcm_proc_done()
1209#endif /* CONFIG_SND_PROC_FS */
1210
1211
1212/*
1213 *  ENTRY functions
1214 */
1215
1216static int __init alsa_pcm_init(void)
1217{
1218	snd_ctl_register_ioctl(snd_pcm_control_ioctl);
1219	snd_ctl_register_ioctl_compat(snd_pcm_control_ioctl);
1220	snd_pcm_proc_init();
1221	return 0;
1222}
1223
1224static void __exit alsa_pcm_exit(void)
1225{
1226	snd_ctl_unregister_ioctl(snd_pcm_control_ioctl);
1227	snd_ctl_unregister_ioctl_compat(snd_pcm_control_ioctl);
1228	snd_pcm_proc_done();
1229}
1230
1231module_init(alsa_pcm_init)
1232module_exit(alsa_pcm_exit)
~/ Read-only file preview.