]> Git Repo - linux.git/blob - sound/core/seq/oss/seq_oss_midi.c
scsi: zfcp: Trace when request remove fails after qdio send fails
[linux.git] / sound / core / seq / oss / seq_oss_midi.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * OSS compatible sequencer driver
4  *
5  * MIDI device handlers
6  *
7  * Copyright (C) 1998,99 Takashi Iwai <[email protected]>
8  */
9
10 #include <sound/asoundef.h>
11 #include "seq_oss_midi.h"
12 #include "seq_oss_readq.h"
13 #include "seq_oss_timer.h"
14 #include "seq_oss_event.h"
15 #include <sound/seq_midi_event.h>
16 #include "../seq_lock.h"
17 #include <linux/init.h>
18 #include <linux/slab.h>
19 #include <linux/nospec.h>
20
21
22 /*
23  * constants
24  */
25 #define SNDRV_SEQ_OSS_MAX_MIDI_NAME     30
26
27 /*
28  * definition of midi device record
29  */
30 struct seq_oss_midi {
31         int seq_device;         /* device number */
32         int client;             /* sequencer client number */
33         int port;               /* sequencer port number */
34         unsigned int flags;     /* port capability */
35         int opened;             /* flag for opening */
36         unsigned char name[SNDRV_SEQ_OSS_MAX_MIDI_NAME];
37         struct snd_midi_event *coder;   /* MIDI event coder */
38         struct seq_oss_devinfo *devinfo;        /* assigned OSSseq device */
39         snd_use_lock_t use_lock;
40 };
41
42
43 /*
44  * midi device table
45  */
46 static int max_midi_devs;
47 static struct seq_oss_midi *midi_devs[SNDRV_SEQ_OSS_MAX_MIDI_DEVS];
48
49 static DEFINE_SPINLOCK(register_lock);
50
51 /*
52  * prototypes
53  */
54 static struct seq_oss_midi *get_mdev(int dev);
55 static struct seq_oss_midi *get_mididev(struct seq_oss_devinfo *dp, int dev);
56 static int send_synth_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, int dev);
57 static int send_midi_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, struct seq_oss_midi *mdev);
58
59 /*
60  * look up the existing ports
61  * this looks a very exhausting job.
62  */
63 int
64 snd_seq_oss_midi_lookup_ports(int client)
65 {
66         struct snd_seq_client_info *clinfo;
67         struct snd_seq_port_info *pinfo;
68
69         clinfo = kzalloc(sizeof(*clinfo), GFP_KERNEL);
70         pinfo = kzalloc(sizeof(*pinfo), GFP_KERNEL);
71         if (! clinfo || ! pinfo) {
72                 kfree(clinfo);
73                 kfree(pinfo);
74                 return -ENOMEM;
75         }
76         clinfo->client = -1;
77         while (snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT, clinfo) == 0) {
78                 if (clinfo->client == client)
79                         continue; /* ignore myself */
80                 pinfo->addr.client = clinfo->client;
81                 pinfo->addr.port = -1;
82                 while (snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT, pinfo) == 0)
83                         snd_seq_oss_midi_check_new_port(pinfo);
84         }
85         kfree(clinfo);
86         kfree(pinfo);
87         return 0;
88 }
89
90
91 /*
92  */
93 static struct seq_oss_midi *
94 get_mdev(int dev)
95 {
96         struct seq_oss_midi *mdev;
97         unsigned long flags;
98
99         spin_lock_irqsave(&register_lock, flags);
100         mdev = midi_devs[dev];
101         if (mdev)
102                 snd_use_lock_use(&mdev->use_lock);
103         spin_unlock_irqrestore(&register_lock, flags);
104         return mdev;
105 }
106
107 /*
108  * look for the identical slot
109  */
110 static struct seq_oss_midi *
111 find_slot(int client, int port)
112 {
113         int i;
114         struct seq_oss_midi *mdev;
115         unsigned long flags;
116
117         spin_lock_irqsave(&register_lock, flags);
118         for (i = 0; i < max_midi_devs; i++) {
119                 mdev = midi_devs[i];
120                 if (mdev && mdev->client == client && mdev->port == port) {
121                         /* found! */
122                         snd_use_lock_use(&mdev->use_lock);
123                         spin_unlock_irqrestore(&register_lock, flags);
124                         return mdev;
125                 }
126         }
127         spin_unlock_irqrestore(&register_lock, flags);
128         return NULL;
129 }
130
131
132 #define PERM_WRITE (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_SUBS_WRITE)
133 #define PERM_READ (SNDRV_SEQ_PORT_CAP_READ|SNDRV_SEQ_PORT_CAP_SUBS_READ)
134 /*
135  * register a new port if it doesn't exist yet
136  */
137 int
138 snd_seq_oss_midi_check_new_port(struct snd_seq_port_info *pinfo)
139 {
140         int i;
141         struct seq_oss_midi *mdev;
142         unsigned long flags;
143
144         /* the port must include generic midi */
145         if (! (pinfo->type & SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC))
146                 return 0;
147         /* either read or write subscribable */
148         if ((pinfo->capability & PERM_WRITE) != PERM_WRITE &&
149             (pinfo->capability & PERM_READ) != PERM_READ)
150                 return 0;
151
152         /*
153          * look for the identical slot
154          */
155         mdev = find_slot(pinfo->addr.client, pinfo->addr.port);
156         if (mdev) {
157                 /* already exists */
158                 snd_use_lock_free(&mdev->use_lock);
159                 return 0;
160         }
161
162         /*
163          * allocate midi info record
164          */
165         mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
166         if (!mdev)
167                 return -ENOMEM;
168
169         /* copy the port information */
170         mdev->client = pinfo->addr.client;
171         mdev->port = pinfo->addr.port;
172         mdev->flags = pinfo->capability;
173         mdev->opened = 0;
174         snd_use_lock_init(&mdev->use_lock);
175
176         /* copy and truncate the name of synth device */
177         strscpy(mdev->name, pinfo->name, sizeof(mdev->name));
178
179         /* create MIDI coder */
180         if (snd_midi_event_new(MAX_MIDI_EVENT_BUF, &mdev->coder) < 0) {
181                 pr_err("ALSA: seq_oss: can't malloc midi coder\n");
182                 kfree(mdev);
183                 return -ENOMEM;
184         }
185         /* OSS sequencer adds running status to all sequences */
186         snd_midi_event_no_status(mdev->coder, 1);
187
188         /*
189          * look for en empty slot
190          */
191         spin_lock_irqsave(&register_lock, flags);
192         for (i = 0; i < max_midi_devs; i++) {
193                 if (midi_devs[i] == NULL)
194                         break;
195         }
196         if (i >= max_midi_devs) {
197                 if (max_midi_devs >= SNDRV_SEQ_OSS_MAX_MIDI_DEVS) {
198                         spin_unlock_irqrestore(&register_lock, flags);
199                         snd_midi_event_free(mdev->coder);
200                         kfree(mdev);
201                         return -ENOMEM;
202                 }
203                 max_midi_devs++;
204         }
205         mdev->seq_device = i;
206         midi_devs[mdev->seq_device] = mdev;
207         spin_unlock_irqrestore(&register_lock, flags);
208
209         return 0;
210 }
211
212 /*
213  * release the midi device if it was registered
214  */
215 int
216 snd_seq_oss_midi_check_exit_port(int client, int port)
217 {
218         struct seq_oss_midi *mdev;
219         unsigned long flags;
220         int index;
221
222         mdev = find_slot(client, port);
223         if (mdev) {
224                 spin_lock_irqsave(&register_lock, flags);
225                 midi_devs[mdev->seq_device] = NULL;
226                 spin_unlock_irqrestore(&register_lock, flags);
227                 snd_use_lock_free(&mdev->use_lock);
228                 snd_use_lock_sync(&mdev->use_lock);
229                 snd_midi_event_free(mdev->coder);
230                 kfree(mdev);
231         }
232         spin_lock_irqsave(&register_lock, flags);
233         for (index = max_midi_devs - 1; index >= 0; index--) {
234                 if (midi_devs[index])
235                         break;
236         }
237         max_midi_devs = index + 1;
238         spin_unlock_irqrestore(&register_lock, flags);
239         return 0;
240 }
241
242
243 /*
244  * release the midi device if it was registered
245  */
246 void
247 snd_seq_oss_midi_clear_all(void)
248 {
249         int i;
250         struct seq_oss_midi *mdev;
251         unsigned long flags;
252
253         spin_lock_irqsave(&register_lock, flags);
254         for (i = 0; i < max_midi_devs; i++) {
255                 mdev = midi_devs[i];
256                 if (mdev) {
257                         snd_midi_event_free(mdev->coder);
258                         kfree(mdev);
259                         midi_devs[i] = NULL;
260                 }
261         }
262         max_midi_devs = 0;
263         spin_unlock_irqrestore(&register_lock, flags);
264 }
265
266
267 /*
268  * set up midi tables
269  */
270 void
271 snd_seq_oss_midi_setup(struct seq_oss_devinfo *dp)
272 {
273         spin_lock_irq(&register_lock);
274         dp->max_mididev = max_midi_devs;
275         spin_unlock_irq(&register_lock);
276 }
277
278 /*
279  * clean up midi tables
280  */
281 void
282 snd_seq_oss_midi_cleanup(struct seq_oss_devinfo *dp)
283 {
284         int i;
285         for (i = 0; i < dp->max_mididev; i++)
286                 snd_seq_oss_midi_close(dp, i);
287         dp->max_mididev = 0;
288 }
289
290
291 /*
292  * open all midi devices.  ignore errors.
293  */
294 void
295 snd_seq_oss_midi_open_all(struct seq_oss_devinfo *dp, int file_mode)
296 {
297         int i;
298         for (i = 0; i < dp->max_mididev; i++)
299                 snd_seq_oss_midi_open(dp, i, file_mode);
300 }
301
302
303 /*
304  * get the midi device information
305  */
306 static struct seq_oss_midi *
307 get_mididev(struct seq_oss_devinfo *dp, int dev)
308 {
309         if (dev < 0 || dev >= dp->max_mididev)
310                 return NULL;
311         dev = array_index_nospec(dev, dp->max_mididev);
312         return get_mdev(dev);
313 }
314
315
316 /*
317  * open the midi device if not opened yet
318  */
319 int
320 snd_seq_oss_midi_open(struct seq_oss_devinfo *dp, int dev, int fmode)
321 {
322         int perm;
323         struct seq_oss_midi *mdev;
324         struct snd_seq_port_subscribe subs;
325
326         mdev = get_mididev(dp, dev);
327         if (!mdev)
328                 return -ENODEV;
329
330         /* already used? */
331         if (mdev->opened && mdev->devinfo != dp) {
332                 snd_use_lock_free(&mdev->use_lock);
333                 return -EBUSY;
334         }
335
336         perm = 0;
337         if (is_write_mode(fmode))
338                 perm |= PERM_WRITE;
339         if (is_read_mode(fmode))
340                 perm |= PERM_READ;
341         perm &= mdev->flags;
342         if (perm == 0) {
343                 snd_use_lock_free(&mdev->use_lock);
344                 return -ENXIO;
345         }
346
347         /* already opened? */
348         if ((mdev->opened & perm) == perm) {
349                 snd_use_lock_free(&mdev->use_lock);
350                 return 0;
351         }
352
353         perm &= ~mdev->opened;
354
355         memset(&subs, 0, sizeof(subs));
356
357         if (perm & PERM_WRITE) {
358                 subs.sender = dp->addr;
359                 subs.dest.client = mdev->client;
360                 subs.dest.port = mdev->port;
361                 if (snd_seq_kernel_client_ctl(dp->cseq, SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, &subs) >= 0)
362                         mdev->opened |= PERM_WRITE;
363         }
364         if (perm & PERM_READ) {
365                 subs.sender.client = mdev->client;
366                 subs.sender.port = mdev->port;
367                 subs.dest = dp->addr;
368                 subs.flags = SNDRV_SEQ_PORT_SUBS_TIMESTAMP;
369                 subs.queue = dp->queue;         /* queue for timestamps */
370                 if (snd_seq_kernel_client_ctl(dp->cseq, SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, &subs) >= 0)
371                         mdev->opened |= PERM_READ;
372         }
373
374         if (! mdev->opened) {
375                 snd_use_lock_free(&mdev->use_lock);
376                 return -ENXIO;
377         }
378
379         mdev->devinfo = dp;
380         snd_use_lock_free(&mdev->use_lock);
381         return 0;
382 }
383
384 /*
385  * close the midi device if already opened
386  */
387 int
388 snd_seq_oss_midi_close(struct seq_oss_devinfo *dp, int dev)
389 {
390         struct seq_oss_midi *mdev;
391         struct snd_seq_port_subscribe subs;
392
393         mdev = get_mididev(dp, dev);
394         if (!mdev)
395                 return -ENODEV;
396         if (! mdev->opened || mdev->devinfo != dp) {
397                 snd_use_lock_free(&mdev->use_lock);
398                 return 0;
399         }
400
401         memset(&subs, 0, sizeof(subs));
402         if (mdev->opened & PERM_WRITE) {
403                 subs.sender = dp->addr;
404                 subs.dest.client = mdev->client;
405                 subs.dest.port = mdev->port;
406                 snd_seq_kernel_client_ctl(dp->cseq, SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT, &subs);
407         }
408         if (mdev->opened & PERM_READ) {
409                 subs.sender.client = mdev->client;
410                 subs.sender.port = mdev->port;
411                 subs.dest = dp->addr;
412                 snd_seq_kernel_client_ctl(dp->cseq, SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT, &subs);
413         }
414
415         mdev->opened = 0;
416         mdev->devinfo = NULL;
417
418         snd_use_lock_free(&mdev->use_lock);
419         return 0;
420 }
421
422 /*
423  * change seq capability flags to file mode flags
424  */
425 int
426 snd_seq_oss_midi_filemode(struct seq_oss_devinfo *dp, int dev)
427 {
428         struct seq_oss_midi *mdev;
429         int mode;
430
431         mdev = get_mididev(dp, dev);
432         if (!mdev)
433                 return 0;
434
435         mode = 0;
436         if (mdev->opened & PERM_WRITE)
437                 mode |= SNDRV_SEQ_OSS_FILE_WRITE;
438         if (mdev->opened & PERM_READ)
439                 mode |= SNDRV_SEQ_OSS_FILE_READ;
440
441         snd_use_lock_free(&mdev->use_lock);
442         return mode;
443 }
444
445 /*
446  * reset the midi device and close it:
447  * so far, only close the device.
448  */
449 void
450 snd_seq_oss_midi_reset(struct seq_oss_devinfo *dp, int dev)
451 {
452         struct seq_oss_midi *mdev;
453
454         mdev = get_mididev(dp, dev);
455         if (!mdev)
456                 return;
457         if (! mdev->opened) {
458                 snd_use_lock_free(&mdev->use_lock);
459                 return;
460         }
461
462         if (mdev->opened & PERM_WRITE) {
463                 struct snd_seq_event ev;
464                 int c;
465
466                 memset(&ev, 0, sizeof(ev));
467                 ev.dest.client = mdev->client;
468                 ev.dest.port = mdev->port;
469                 ev.queue = dp->queue;
470                 ev.source.port = dp->port;
471                 if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_SYNTH) {
472                         ev.type = SNDRV_SEQ_EVENT_SENSING;
473                         snd_seq_oss_dispatch(dp, &ev, 0, 0);
474                 }
475                 for (c = 0; c < 16; c++) {
476                         ev.type = SNDRV_SEQ_EVENT_CONTROLLER;
477                         ev.data.control.channel = c;
478                         ev.data.control.param = MIDI_CTL_ALL_NOTES_OFF;
479                         snd_seq_oss_dispatch(dp, &ev, 0, 0);
480                         if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC) {
481                                 ev.data.control.param =
482                                         MIDI_CTL_RESET_CONTROLLERS;
483                                 snd_seq_oss_dispatch(dp, &ev, 0, 0);
484                                 ev.type = SNDRV_SEQ_EVENT_PITCHBEND;
485                                 ev.data.control.value = 0;
486                                 snd_seq_oss_dispatch(dp, &ev, 0, 0);
487                         }
488                 }
489         }
490         // snd_seq_oss_midi_close(dp, dev);
491         snd_use_lock_free(&mdev->use_lock);
492 }
493
494
495 /*
496  * get client/port of the specified MIDI device
497  */
498 void
499 snd_seq_oss_midi_get_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_addr *addr)
500 {
501         struct seq_oss_midi *mdev;
502
503         mdev = get_mididev(dp, dev);
504         if (!mdev)
505                 return;
506         addr->client = mdev->client;
507         addr->port = mdev->port;
508         snd_use_lock_free(&mdev->use_lock);
509 }
510
511
512 /*
513  * input callback - this can be atomic
514  */
515 int
516 snd_seq_oss_midi_input(struct snd_seq_event *ev, int direct, void *private_data)
517 {
518         struct seq_oss_devinfo *dp = (struct seq_oss_devinfo *)private_data;
519         struct seq_oss_midi *mdev;
520         int rc;
521
522         if (dp->readq == NULL)
523                 return 0;
524         mdev = find_slot(ev->source.client, ev->source.port);
525         if (!mdev)
526                 return 0;
527         if (! (mdev->opened & PERM_READ)) {
528                 snd_use_lock_free(&mdev->use_lock);
529                 return 0;
530         }
531
532         if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC)
533                 rc = send_synth_event(dp, ev, mdev->seq_device);
534         else
535                 rc = send_midi_event(dp, ev, mdev);
536
537         snd_use_lock_free(&mdev->use_lock);
538         return rc;
539 }
540
541 /*
542  * convert ALSA sequencer event to OSS synth event
543  */
544 static int
545 send_synth_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, int dev)
546 {
547         union evrec ossev;
548
549         memset(&ossev, 0, sizeof(ossev));
550
551         switch (ev->type) {
552         case SNDRV_SEQ_EVENT_NOTEON:
553                 ossev.v.cmd = MIDI_NOTEON; break;
554         case SNDRV_SEQ_EVENT_NOTEOFF:
555                 ossev.v.cmd = MIDI_NOTEOFF; break;
556         case SNDRV_SEQ_EVENT_KEYPRESS:
557                 ossev.v.cmd = MIDI_KEY_PRESSURE; break;
558         case SNDRV_SEQ_EVENT_CONTROLLER:
559                 ossev.l.cmd = MIDI_CTL_CHANGE; break;
560         case SNDRV_SEQ_EVENT_PGMCHANGE:
561                 ossev.l.cmd = MIDI_PGM_CHANGE; break;
562         case SNDRV_SEQ_EVENT_CHANPRESS:
563                 ossev.l.cmd = MIDI_CHN_PRESSURE; break;
564         case SNDRV_SEQ_EVENT_PITCHBEND:
565                 ossev.l.cmd = MIDI_PITCH_BEND; break;
566         default:
567                 return 0; /* not supported */
568         }
569
570         ossev.v.dev = dev;
571
572         switch (ev->type) {
573         case SNDRV_SEQ_EVENT_NOTEON:
574         case SNDRV_SEQ_EVENT_NOTEOFF:
575         case SNDRV_SEQ_EVENT_KEYPRESS:
576                 ossev.v.code = EV_CHN_VOICE;
577                 ossev.v.note = ev->data.note.note;
578                 ossev.v.parm = ev->data.note.velocity;
579                 ossev.v.chn = ev->data.note.channel;
580                 break;
581         case SNDRV_SEQ_EVENT_CONTROLLER:
582         case SNDRV_SEQ_EVENT_PGMCHANGE:
583         case SNDRV_SEQ_EVENT_CHANPRESS:
584                 ossev.l.code = EV_CHN_COMMON;
585                 ossev.l.p1 = ev->data.control.param;
586                 ossev.l.val = ev->data.control.value;
587                 ossev.l.chn = ev->data.control.channel;
588                 break;
589         case SNDRV_SEQ_EVENT_PITCHBEND:
590                 ossev.l.code = EV_CHN_COMMON;
591                 ossev.l.val = ev->data.control.value + 8192;
592                 ossev.l.chn = ev->data.control.channel;
593                 break;
594         }
595         
596         snd_seq_oss_readq_put_timestamp(dp->readq, ev->time.tick, dp->seq_mode);
597         snd_seq_oss_readq_put_event(dp->readq, &ossev);
598
599         return 0;
600 }
601
602 /*
603  * decode event and send MIDI bytes to read queue
604  */
605 static int
606 send_midi_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, struct seq_oss_midi *mdev)
607 {
608         char msg[32];
609         int len;
610         
611         snd_seq_oss_readq_put_timestamp(dp->readq, ev->time.tick, dp->seq_mode);
612         if (!dp->timer->running)
613                 len = snd_seq_oss_timer_start(dp->timer);
614         if (ev->type == SNDRV_SEQ_EVENT_SYSEX) {
615                 snd_seq_oss_readq_sysex(dp->readq, mdev->seq_device, ev);
616                 snd_midi_event_reset_decode(mdev->coder);
617         } else {
618                 len = snd_midi_event_decode(mdev->coder, msg, sizeof(msg), ev);
619                 if (len > 0)
620                         snd_seq_oss_readq_puts(dp->readq, mdev->seq_device, msg, len);
621         }
622
623         return 0;
624 }
625
626
627 /*
628  * dump midi data
629  * return 0 : enqueued
630  *        non-zero : invalid - ignored
631  */
632 int
633 snd_seq_oss_midi_putc(struct seq_oss_devinfo *dp, int dev, unsigned char c, struct snd_seq_event *ev)
634 {
635         struct seq_oss_midi *mdev;
636
637         mdev = get_mididev(dp, dev);
638         if (!mdev)
639                 return -ENODEV;
640         if (snd_midi_event_encode_byte(mdev->coder, c, ev)) {
641                 snd_seq_oss_fill_addr(dp, ev, mdev->client, mdev->port);
642                 snd_use_lock_free(&mdev->use_lock);
643                 return 0;
644         }
645         snd_use_lock_free(&mdev->use_lock);
646         return -EINVAL;
647 }
648
649 /*
650  * create OSS compatible midi_info record
651  */
652 int
653 snd_seq_oss_midi_make_info(struct seq_oss_devinfo *dp, int dev, struct midi_info *inf)
654 {
655         struct seq_oss_midi *mdev;
656
657         mdev = get_mididev(dp, dev);
658         if (!mdev)
659                 return -ENXIO;
660         inf->device = dev;
661         inf->dev_type = 0; /* FIXME: ?? */
662         inf->capabilities = 0; /* FIXME: ?? */
663         strscpy(inf->name, mdev->name, sizeof(inf->name));
664         snd_use_lock_free(&mdev->use_lock);
665         return 0;
666 }
667
668
669 #ifdef CONFIG_SND_PROC_FS
670 /*
671  * proc interface
672  */
673 static char *
674 capmode_str(int val)
675 {
676         val &= PERM_READ|PERM_WRITE;
677         if (val == (PERM_READ|PERM_WRITE))
678                 return "read/write";
679         else if (val == PERM_READ)
680                 return "read";
681         else if (val == PERM_WRITE)
682                 return "write";
683         else
684                 return "none";
685 }
686
687 void
688 snd_seq_oss_midi_info_read(struct snd_info_buffer *buf)
689 {
690         int i;
691         struct seq_oss_midi *mdev;
692
693         snd_iprintf(buf, "\nNumber of MIDI devices: %d\n", max_midi_devs);
694         for (i = 0; i < max_midi_devs; i++) {
695                 snd_iprintf(buf, "\nmidi %d: ", i);
696                 mdev = get_mdev(i);
697                 if (mdev == NULL) {
698                         snd_iprintf(buf, "*empty*\n");
699                         continue;
700                 }
701                 snd_iprintf(buf, "[%s] ALSA port %d:%d\n", mdev->name,
702                             mdev->client, mdev->port);
703                 snd_iprintf(buf, "  capability %s / opened %s\n",
704                             capmode_str(mdev->flags),
705                             capmode_str(mdev->opened));
706                 snd_use_lock_free(&mdev->use_lock);
707         }
708 }
709 #endif /* CONFIG_SND_PROC_FS */
This page took 0.076413 seconds and 4 git commands to generate.