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