cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

pcm.c (33775B)


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