Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
[linux-2.6-microblaze.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 <tiwai@suse.de>
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         dp->max_mididev = max_midi_devs;
274 }
275
276 /*
277  * clean up midi tables
278  */
279 void
280 snd_seq_oss_midi_cleanup(struct seq_oss_devinfo *dp)
281 {
282         int i;
283         for (i = 0; i < dp->max_mididev; i++)
284                 snd_seq_oss_midi_close(dp, i);
285         dp->max_mididev = 0;
286 }
287
288
289 /*
290  * open all midi devices.  ignore errors.
291  */
292 void
293 snd_seq_oss_midi_open_all(struct seq_oss_devinfo *dp, int file_mode)
294 {
295         int i;
296         for (i = 0; i < dp->max_mididev; i++)
297                 snd_seq_oss_midi_open(dp, i, file_mode);
298 }
299
300
301 /*
302  * get the midi device information
303  */
304 static struct seq_oss_midi *
305 get_mididev(struct seq_oss_devinfo *dp, int dev)
306 {
307         if (dev < 0 || dev >= dp->max_mididev)
308                 return NULL;
309         dev = array_index_nospec(dev, dp->max_mididev);
310         return get_mdev(dev);
311 }
312
313
314 /*
315  * open the midi device if not opened yet
316  */
317 int
318 snd_seq_oss_midi_open(struct seq_oss_devinfo *dp, int dev, int fmode)
319 {
320         int perm;
321         struct seq_oss_midi *mdev;
322         struct snd_seq_port_subscribe subs;
323
324         mdev = get_mididev(dp, dev);
325         if (!mdev)
326                 return -ENODEV;
327
328         /* already used? */
329         if (mdev->opened && mdev->devinfo != dp) {
330                 snd_use_lock_free(&mdev->use_lock);
331                 return -EBUSY;
332         }
333
334         perm = 0;
335         if (is_write_mode(fmode))
336                 perm |= PERM_WRITE;
337         if (is_read_mode(fmode))
338                 perm |= PERM_READ;
339         perm &= mdev->flags;
340         if (perm == 0) {
341                 snd_use_lock_free(&mdev->use_lock);
342                 return -ENXIO;
343         }
344
345         /* already opened? */
346         if ((mdev->opened & perm) == perm) {
347                 snd_use_lock_free(&mdev->use_lock);
348                 return 0;
349         }
350
351         perm &= ~mdev->opened;
352
353         memset(&subs, 0, sizeof(subs));
354
355         if (perm & PERM_WRITE) {
356                 subs.sender = dp->addr;
357                 subs.dest.client = mdev->client;
358                 subs.dest.port = mdev->port;
359                 if (snd_seq_kernel_client_ctl(dp->cseq, SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, &subs) >= 0)
360                         mdev->opened |= PERM_WRITE;
361         }
362         if (perm & PERM_READ) {
363                 subs.sender.client = mdev->client;
364                 subs.sender.port = mdev->port;
365                 subs.dest = dp->addr;
366                 subs.flags = SNDRV_SEQ_PORT_SUBS_TIMESTAMP;
367                 subs.queue = dp->queue;         /* queue for timestamps */
368                 if (snd_seq_kernel_client_ctl(dp->cseq, SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, &subs) >= 0)
369                         mdev->opened |= PERM_READ;
370         }
371
372         if (! mdev->opened) {
373                 snd_use_lock_free(&mdev->use_lock);
374                 return -ENXIO;
375         }
376
377         mdev->devinfo = dp;
378         snd_use_lock_free(&mdev->use_lock);
379         return 0;
380 }
381
382 /*
383  * close the midi device if already opened
384  */
385 int
386 snd_seq_oss_midi_close(struct seq_oss_devinfo *dp, int dev)
387 {
388         struct seq_oss_midi *mdev;
389         struct snd_seq_port_subscribe subs;
390
391         mdev = get_mididev(dp, dev);
392         if (!mdev)
393                 return -ENODEV;
394         if (! mdev->opened || mdev->devinfo != dp) {
395                 snd_use_lock_free(&mdev->use_lock);
396                 return 0;
397         }
398
399         memset(&subs, 0, sizeof(subs));
400         if (mdev->opened & PERM_WRITE) {
401                 subs.sender = dp->addr;
402                 subs.dest.client = mdev->client;
403                 subs.dest.port = mdev->port;
404                 snd_seq_kernel_client_ctl(dp->cseq, SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT, &subs);
405         }
406         if (mdev->opened & PERM_READ) {
407                 subs.sender.client = mdev->client;
408                 subs.sender.port = mdev->port;
409                 subs.dest = dp->addr;
410                 snd_seq_kernel_client_ctl(dp->cseq, SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT, &subs);
411         }
412
413         mdev->opened = 0;
414         mdev->devinfo = NULL;
415
416         snd_use_lock_free(&mdev->use_lock);
417         return 0;
418 }
419
420 /*
421  * change seq capability flags to file mode flags
422  */
423 int
424 snd_seq_oss_midi_filemode(struct seq_oss_devinfo *dp, int dev)
425 {
426         struct seq_oss_midi *mdev;
427         int mode;
428
429         mdev = get_mididev(dp, dev);
430         if (!mdev)
431                 return 0;
432
433         mode = 0;
434         if (mdev->opened & PERM_WRITE)
435                 mode |= SNDRV_SEQ_OSS_FILE_WRITE;
436         if (mdev->opened & PERM_READ)
437                 mode |= SNDRV_SEQ_OSS_FILE_READ;
438
439         snd_use_lock_free(&mdev->use_lock);
440         return mode;
441 }
442
443 /*
444  * reset the midi device and close it:
445  * so far, only close the device.
446  */
447 void
448 snd_seq_oss_midi_reset(struct seq_oss_devinfo *dp, int dev)
449 {
450         struct seq_oss_midi *mdev;
451
452         mdev = get_mididev(dp, dev);
453         if (!mdev)
454                 return;
455         if (! mdev->opened) {
456                 snd_use_lock_free(&mdev->use_lock);
457                 return;
458         }
459
460         if (mdev->opened & PERM_WRITE) {
461                 struct snd_seq_event ev;
462                 int c;
463
464                 memset(&ev, 0, sizeof(ev));
465                 ev.dest.client = mdev->client;
466                 ev.dest.port = mdev->port;
467                 ev.queue = dp->queue;
468                 ev.source.port = dp->port;
469                 if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_SYNTH) {
470                         ev.type = SNDRV_SEQ_EVENT_SENSING;
471                         snd_seq_oss_dispatch(dp, &ev, 0, 0);
472                 }
473                 for (c = 0; c < 16; c++) {
474                         ev.type = SNDRV_SEQ_EVENT_CONTROLLER;
475                         ev.data.control.channel = c;
476                         ev.data.control.param = MIDI_CTL_ALL_NOTES_OFF;
477                         snd_seq_oss_dispatch(dp, &ev, 0, 0);
478                         if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC) {
479                                 ev.data.control.param =
480                                         MIDI_CTL_RESET_CONTROLLERS;
481                                 snd_seq_oss_dispatch(dp, &ev, 0, 0);
482                                 ev.type = SNDRV_SEQ_EVENT_PITCHBEND;
483                                 ev.data.control.value = 0;
484                                 snd_seq_oss_dispatch(dp, &ev, 0, 0);
485                         }
486                 }
487         }
488         // snd_seq_oss_midi_close(dp, dev);
489         snd_use_lock_free(&mdev->use_lock);
490 }
491
492
493 /*
494  * get client/port of the specified MIDI device
495  */
496 void
497 snd_seq_oss_midi_get_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_addr *addr)
498 {
499         struct seq_oss_midi *mdev;
500
501         mdev = get_mididev(dp, dev);
502         if (!mdev)
503                 return;
504         addr->client = mdev->client;
505         addr->port = mdev->port;
506         snd_use_lock_free(&mdev->use_lock);
507 }
508
509
510 /*
511  * input callback - this can be atomic
512  */
513 int
514 snd_seq_oss_midi_input(struct snd_seq_event *ev, int direct, void *private_data)
515 {
516         struct seq_oss_devinfo *dp = (struct seq_oss_devinfo *)private_data;
517         struct seq_oss_midi *mdev;
518         int rc;
519
520         if (dp->readq == NULL)
521                 return 0;
522         mdev = find_slot(ev->source.client, ev->source.port);
523         if (!mdev)
524                 return 0;
525         if (! (mdev->opened & PERM_READ)) {
526                 snd_use_lock_free(&mdev->use_lock);
527                 return 0;
528         }
529
530         if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC)
531                 rc = send_synth_event(dp, ev, mdev->seq_device);
532         else
533                 rc = send_midi_event(dp, ev, mdev);
534
535         snd_use_lock_free(&mdev->use_lock);
536         return rc;
537 }
538
539 /*
540  * convert ALSA sequencer event to OSS synth event
541  */
542 static int
543 send_synth_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, int dev)
544 {
545         union evrec ossev;
546
547         memset(&ossev, 0, sizeof(ossev));
548
549         switch (ev->type) {
550         case SNDRV_SEQ_EVENT_NOTEON:
551                 ossev.v.cmd = MIDI_NOTEON; break;
552         case SNDRV_SEQ_EVENT_NOTEOFF:
553                 ossev.v.cmd = MIDI_NOTEOFF; break;
554         case SNDRV_SEQ_EVENT_KEYPRESS:
555                 ossev.v.cmd = MIDI_KEY_PRESSURE; break;
556         case SNDRV_SEQ_EVENT_CONTROLLER:
557                 ossev.l.cmd = MIDI_CTL_CHANGE; break;
558         case SNDRV_SEQ_EVENT_PGMCHANGE:
559                 ossev.l.cmd = MIDI_PGM_CHANGE; break;
560         case SNDRV_SEQ_EVENT_CHANPRESS:
561                 ossev.l.cmd = MIDI_CHN_PRESSURE; break;
562         case SNDRV_SEQ_EVENT_PITCHBEND:
563                 ossev.l.cmd = MIDI_PITCH_BEND; break;
564         default:
565                 return 0; /* not supported */
566         }
567
568         ossev.v.dev = dev;
569
570         switch (ev->type) {
571         case SNDRV_SEQ_EVENT_NOTEON:
572         case SNDRV_SEQ_EVENT_NOTEOFF:
573         case SNDRV_SEQ_EVENT_KEYPRESS:
574                 ossev.v.code = EV_CHN_VOICE;
575                 ossev.v.note = ev->data.note.note;
576                 ossev.v.parm = ev->data.note.velocity;
577                 ossev.v.chn = ev->data.note.channel;
578                 break;
579         case SNDRV_SEQ_EVENT_CONTROLLER:
580         case SNDRV_SEQ_EVENT_PGMCHANGE:
581         case SNDRV_SEQ_EVENT_CHANPRESS:
582                 ossev.l.code = EV_CHN_COMMON;
583                 ossev.l.p1 = ev->data.control.param;
584                 ossev.l.val = ev->data.control.value;
585                 ossev.l.chn = ev->data.control.channel;
586                 break;
587         case SNDRV_SEQ_EVENT_PITCHBEND:
588                 ossev.l.code = EV_CHN_COMMON;
589                 ossev.l.val = ev->data.control.value + 8192;
590                 ossev.l.chn = ev->data.control.channel;
591                 break;
592         }
593         
594         snd_seq_oss_readq_put_timestamp(dp->readq, ev->time.tick, dp->seq_mode);
595         snd_seq_oss_readq_put_event(dp->readq, &ossev);
596
597         return 0;
598 }
599
600 /*
601  * decode event and send MIDI bytes to read queue
602  */
603 static int
604 send_midi_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, struct seq_oss_midi *mdev)
605 {
606         char msg[32];
607         int len;
608         
609         snd_seq_oss_readq_put_timestamp(dp->readq, ev->time.tick, dp->seq_mode);
610         if (!dp->timer->running)
611                 len = snd_seq_oss_timer_start(dp->timer);
612         if (ev->type == SNDRV_SEQ_EVENT_SYSEX) {
613                 snd_seq_oss_readq_sysex(dp->readq, mdev->seq_device, ev);
614                 snd_midi_event_reset_decode(mdev->coder);
615         } else {
616                 len = snd_midi_event_decode(mdev->coder, msg, sizeof(msg), ev);
617                 if (len > 0)
618                         snd_seq_oss_readq_puts(dp->readq, mdev->seq_device, msg, len);
619         }
620
621         return 0;
622 }
623
624
625 /*
626  * dump midi data
627  * return 0 : enqueued
628  *        non-zero : invalid - ignored
629  */
630 int
631 snd_seq_oss_midi_putc(struct seq_oss_devinfo *dp, int dev, unsigned char c, struct snd_seq_event *ev)
632 {
633         struct seq_oss_midi *mdev;
634
635         mdev = get_mididev(dp, dev);
636         if (!mdev)
637                 return -ENODEV;
638         if (snd_midi_event_encode_byte(mdev->coder, c, ev)) {
639                 snd_seq_oss_fill_addr(dp, ev, mdev->client, mdev->port);
640                 snd_use_lock_free(&mdev->use_lock);
641                 return 0;
642         }
643         snd_use_lock_free(&mdev->use_lock);
644         return -EINVAL;
645 }
646
647 /*
648  * create OSS compatible midi_info record
649  */
650 int
651 snd_seq_oss_midi_make_info(struct seq_oss_devinfo *dp, int dev, struct midi_info *inf)
652 {
653         struct seq_oss_midi *mdev;
654
655         mdev = get_mididev(dp, dev);
656         if (!mdev)
657                 return -ENXIO;
658         inf->device = dev;
659         inf->dev_type = 0; /* FIXME: ?? */
660         inf->capabilities = 0; /* FIXME: ?? */
661         strscpy(inf->name, mdev->name, sizeof(inf->name));
662         snd_use_lock_free(&mdev->use_lock);
663         return 0;
664 }
665
666
667 #ifdef CONFIG_SND_PROC_FS
668 /*
669  * proc interface
670  */
671 static char *
672 capmode_str(int val)
673 {
674         val &= PERM_READ|PERM_WRITE;
675         if (val == (PERM_READ|PERM_WRITE))
676                 return "read/write";
677         else if (val == PERM_READ)
678                 return "read";
679         else if (val == PERM_WRITE)
680                 return "write";
681         else
682                 return "none";
683 }
684
685 void
686 snd_seq_oss_midi_info_read(struct snd_info_buffer *buf)
687 {
688         int i;
689         struct seq_oss_midi *mdev;
690
691         snd_iprintf(buf, "\nNumber of MIDI devices: %d\n", max_midi_devs);
692         for (i = 0; i < max_midi_devs; i++) {
693                 snd_iprintf(buf, "\nmidi %d: ", i);
694                 mdev = get_mdev(i);
695                 if (mdev == NULL) {
696                         snd_iprintf(buf, "*empty*\n");
697                         continue;
698                 }
699                 snd_iprintf(buf, "[%s] ALSA port %d:%d\n", mdev->name,
700                             mdev->client, mdev->port);
701                 snd_iprintf(buf, "  capability %s / opened %s\n",
702                             capmode_str(mdev->flags),
703                             capmode_str(mdev->opened));
704                 snd_use_lock_free(&mdev->use_lock);
705         }
706 }
707 #endif /* CONFIG_SND_PROC_FS */