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