ALSA: oxfw: fix NULL pointer dereference to unused stream structure
[linux-2.6-block.git] / sound / firewire / oxfw / oxfw-stream.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * oxfw_stream.c - a part of driver for OXFW970/971 based devices
4  *
5  * Copyright (c) 2014 Takashi Sakamoto
6  */
7
8 #include "oxfw.h"
9 #include <linux/delay.h>
10
11 #define AVC_GENERIC_FRAME_MAXIMUM_BYTES 512
12 #define CALLBACK_TIMEOUT        200
13
14 /*
15  * According to datasheet of Oxford Semiconductor:
16  *  OXFW970: 32.0/44.1/48.0/96.0 Khz, 8 audio channels I/O
17  *  OXFW971: 32.0/44.1/48.0/88.2/96.0/192.0 kHz, 16 audio channels I/O, MIDI I/O
18  */
19 static const unsigned int oxfw_rate_table[] = {
20         [0] = 32000,
21         [1] = 44100,
22         [2] = 48000,
23         [3] = 88200,
24         [4] = 96000,
25         [5] = 192000,
26 };
27
28 /*
29  * See Table 5.7 – Sampling frequency for Multi-bit Audio
30  * in AV/C Stream Format Information Specification 1.1 (Apr 2005, 1394TA)
31  */
32 static const unsigned int avc_stream_rate_table[] = {
33         [0] = 0x02,
34         [1] = 0x03,
35         [2] = 0x04,
36         [3] = 0x0a,
37         [4] = 0x05,
38         [5] = 0x07,
39 };
40
41 static int set_rate(struct snd_oxfw *oxfw, unsigned int rate)
42 {
43         int err;
44
45         err = avc_general_set_sig_fmt(oxfw->unit, rate,
46                                       AVC_GENERAL_PLUG_DIR_IN, 0);
47         if (err < 0)
48                 goto end;
49
50         if (oxfw->has_output)
51                 err = avc_general_set_sig_fmt(oxfw->unit, rate,
52                                               AVC_GENERAL_PLUG_DIR_OUT, 0);
53 end:
54         return err;
55 }
56
57 static int set_stream_format(struct snd_oxfw *oxfw, struct amdtp_stream *s,
58                              unsigned int rate, unsigned int pcm_channels)
59 {
60         u8 **formats;
61         struct snd_oxfw_stream_formation formation;
62         enum avc_general_plug_dir dir;
63         unsigned int len;
64         int i, err;
65
66         if (s == &oxfw->tx_stream) {
67                 formats = oxfw->tx_stream_formats;
68                 dir = AVC_GENERAL_PLUG_DIR_OUT;
69         } else {
70                 formats = oxfw->rx_stream_formats;
71                 dir = AVC_GENERAL_PLUG_DIR_IN;
72         }
73
74         /* Seek stream format for requirements. */
75         for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
76                 err = snd_oxfw_stream_parse_format(formats[i], &formation);
77                 if (err < 0)
78                         return err;
79
80                 if ((formation.rate == rate) && (formation.pcm == pcm_channels))
81                         break;
82         }
83         if (i == SND_OXFW_STREAM_FORMAT_ENTRIES)
84                 return -EINVAL;
85
86         /* If assumed, just change rate. */
87         if (oxfw->assumed)
88                 return set_rate(oxfw, rate);
89
90         /* Calculate format length. */
91         len = 5 + formats[i][4] * 2;
92
93         err = avc_stream_set_format(oxfw->unit, dir, 0, formats[i], len);
94         if (err < 0)
95                 return err;
96
97         /* Some requests just after changing format causes freezing. */
98         msleep(100);
99
100         return 0;
101 }
102
103 static int start_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
104 {
105         struct cmp_connection *conn;
106         int err;
107
108         if (stream == &oxfw->rx_stream)
109                 conn = &oxfw->in_conn;
110         else
111                 conn = &oxfw->out_conn;
112
113         err = cmp_connection_establish(conn);
114         if (err < 0)
115                 return err;
116
117         err = amdtp_domain_add_stream(&oxfw->domain, stream,
118                                       conn->resources.channel, conn->speed);
119         if (err < 0) {
120                 cmp_connection_break(conn);
121                 return err;
122         }
123
124         return 0;
125 }
126
127 static int check_connection_used_by_others(struct snd_oxfw *oxfw,
128                                            struct amdtp_stream *stream)
129 {
130         struct cmp_connection *conn;
131         bool used;
132         int err;
133
134         if (stream == &oxfw->tx_stream)
135                 conn = &oxfw->out_conn;
136         else
137                 conn = &oxfw->in_conn;
138
139         err = cmp_connection_check_used(conn, &used);
140         if ((err >= 0) && used && !amdtp_stream_running(stream)) {
141                 dev_err(&oxfw->unit->device,
142                         "Connection established by others: %cPCR[%d]\n",
143                         (conn->direction == CMP_OUTPUT) ? 'o' : 'i',
144                         conn->pcr_index);
145                 err = -EBUSY;
146         }
147
148         return err;
149 }
150
151 static int init_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
152 {
153         struct cmp_connection *conn;
154         enum cmp_direction c_dir;
155         enum amdtp_stream_direction s_dir;
156         int err;
157
158         if (stream == &oxfw->tx_stream) {
159                 conn = &oxfw->out_conn;
160                 c_dir = CMP_OUTPUT;
161                 s_dir = AMDTP_IN_STREAM;
162         } else {
163                 conn = &oxfw->in_conn;
164                 c_dir = CMP_INPUT;
165                 s_dir = AMDTP_OUT_STREAM;
166         }
167
168         err = cmp_connection_init(conn, oxfw->unit, c_dir, 0);
169         if (err < 0)
170                 return err;
171
172         err = amdtp_am824_init(stream, oxfw->unit, s_dir, CIP_NONBLOCKING);
173         if (err < 0) {
174                 cmp_connection_destroy(conn);
175                 return err;
176         }
177
178         /*
179          * OXFW starts to transmit packets with non-zero dbc.
180          * OXFW postpone transferring packets till handling any asynchronous
181          * packets. As a result, next isochronous packet includes more data
182          * blocks than IEC 61883-6 defines.
183          */
184         if (stream == &oxfw->tx_stream) {
185                 oxfw->tx_stream.flags |= CIP_JUMBO_PAYLOAD;
186                 if (oxfw->wrong_dbs)
187                         oxfw->tx_stream.flags |= CIP_WRONG_DBS;
188         }
189
190         return 0;
191 }
192
193 static int keep_resources(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
194 {
195         enum avc_general_plug_dir dir;
196         u8 **formats;
197         struct snd_oxfw_stream_formation formation;
198         struct cmp_connection *conn;
199         int i;
200         int err;
201
202         if (stream == &oxfw->rx_stream) {
203                 dir = AVC_GENERAL_PLUG_DIR_IN;
204                 formats = oxfw->rx_stream_formats;
205                 conn = &oxfw->in_conn;
206         } else {
207                 dir = AVC_GENERAL_PLUG_DIR_OUT;
208                 formats = oxfw->tx_stream_formats;
209                 conn = &oxfw->out_conn;
210         }
211
212         err = snd_oxfw_stream_get_current_formation(oxfw, dir, &formation);
213         if (err < 0)
214                 return err;
215
216         for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
217                 struct snd_oxfw_stream_formation fmt;
218
219                 if (formats[i] == NULL)
220                         break;
221
222                 err = snd_oxfw_stream_parse_format(formats[i], &fmt);
223                 if (err < 0)
224                         return err;
225
226                 if (fmt.rate == formation.rate && fmt.pcm == formation.pcm &&
227                     fmt.midi == formation.midi)
228                         break;
229         }
230         if (i == SND_OXFW_STREAM_FORMAT_ENTRIES)
231                 return -EINVAL;
232
233         // The stream should have one pcm channels at least.
234         if (formation.pcm == 0)
235                 return -EINVAL;
236
237         err = amdtp_am824_set_parameters(stream, formation.rate, formation.pcm,
238                                          formation.midi * 8, false);
239         if (err < 0)
240                 return err;
241
242         return cmp_connection_reserve(conn, amdtp_stream_get_max_payload(stream));
243 }
244
245 int snd_oxfw_stream_reserve_duplex(struct snd_oxfw *oxfw,
246                                    struct amdtp_stream *stream,
247                                    unsigned int rate, unsigned int pcm_channels)
248 {
249         struct snd_oxfw_stream_formation formation;
250         enum avc_general_plug_dir dir;
251         int err;
252
253         // Considering JACK/FFADO streaming:
254         // TODO: This can be removed hwdep functionality becomes popular.
255         err = check_connection_used_by_others(oxfw, &oxfw->rx_stream);
256         if (err < 0)
257                 return err;
258         if (oxfw->has_output) {
259                 err = check_connection_used_by_others(oxfw, &oxfw->tx_stream);
260                 if (err < 0)
261                         return err;
262         }
263
264         if (stream == &oxfw->tx_stream)
265                 dir = AVC_GENERAL_PLUG_DIR_OUT;
266         else
267                 dir = AVC_GENERAL_PLUG_DIR_IN;
268
269         err = snd_oxfw_stream_get_current_formation(oxfw, dir, &formation);
270         if (err < 0)
271                 return err;
272         if (rate == 0) {
273                 rate = formation.rate;
274                 pcm_channels = formation.pcm;
275         }
276         if (formation.rate != rate || formation.pcm != pcm_channels) {
277                 amdtp_domain_stop(&oxfw->domain);
278
279                 cmp_connection_break(&oxfw->in_conn);
280                 cmp_connection_release(&oxfw->in_conn);
281
282                 if (oxfw->has_output) {
283                         cmp_connection_break(&oxfw->out_conn);
284                         cmp_connection_release(&oxfw->out_conn);
285                 }
286         }
287
288         if (oxfw->substreams_count == 0 ||
289             formation.rate != rate || formation.pcm != pcm_channels) {
290                 err = set_stream_format(oxfw, stream, rate, pcm_channels);
291                 if (err < 0) {
292                         dev_err(&oxfw->unit->device,
293                                 "fail to set stream format: %d\n", err);
294                         return err;
295                 }
296
297                 err = keep_resources(oxfw, &oxfw->rx_stream);
298                 if (err < 0)
299                         return err;
300
301                 if (oxfw->has_output) {
302                         err = keep_resources(oxfw, &oxfw->tx_stream);
303                         if (err < 0) {
304                                 cmp_connection_release(&oxfw->in_conn);
305                                 return err;
306                         }
307                 }
308         }
309
310         return 0;
311 }
312
313 int snd_oxfw_stream_start_duplex(struct snd_oxfw *oxfw)
314 {
315         int err;
316
317         if (oxfw->substreams_count == 0)
318                 return -EIO;
319
320         if (amdtp_streaming_error(&oxfw->rx_stream) ||
321             amdtp_streaming_error(&oxfw->tx_stream)) {
322                 amdtp_domain_stop(&oxfw->domain);
323
324                 cmp_connection_break(&oxfw->in_conn);
325                 if (oxfw->has_output)
326                         cmp_connection_break(&oxfw->out_conn);
327         }
328
329         if (!amdtp_stream_running(&oxfw->rx_stream)) {
330                 err = start_stream(oxfw, &oxfw->rx_stream);
331                 if (err < 0) {
332                         dev_err(&oxfw->unit->device,
333                                 "fail to prepare rx stream: %d\n", err);
334                         goto error;
335                 }
336
337                 if (oxfw->has_output &&
338                     !amdtp_stream_running(&oxfw->tx_stream)) {
339                         err = start_stream(oxfw, &oxfw->tx_stream);
340                         if (err < 0) {
341                                 dev_err(&oxfw->unit->device,
342                                         "fail to prepare tx stream: %d\n", err);
343                                 goto error;
344                         }
345                 }
346
347                 err = amdtp_domain_start(&oxfw->domain);
348                 if (err < 0)
349                         goto error;
350
351                 // Wait first packet.
352                 if (!amdtp_stream_wait_callback(&oxfw->rx_stream,
353                                                 CALLBACK_TIMEOUT)) {
354                         err = -ETIMEDOUT;
355                         goto error;
356                 }
357
358                 if (oxfw->has_output) {
359                         if (!amdtp_stream_wait_callback(&oxfw->tx_stream,
360                                                         CALLBACK_TIMEOUT)) {
361                                 err = -ETIMEDOUT;
362                                 goto error;
363                         }
364                 }
365         }
366
367         return 0;
368 error:
369         amdtp_domain_stop(&oxfw->domain);
370
371         cmp_connection_break(&oxfw->in_conn);
372         if (oxfw->has_output)
373                 cmp_connection_break(&oxfw->out_conn);
374
375         return err;
376 }
377
378 void snd_oxfw_stream_stop_duplex(struct snd_oxfw *oxfw)
379 {
380         if (oxfw->substreams_count == 0) {
381                 amdtp_domain_stop(&oxfw->domain);
382
383                 cmp_connection_break(&oxfw->in_conn);
384                 cmp_connection_release(&oxfw->in_conn);
385
386                 if (oxfw->has_output) {
387                         cmp_connection_break(&oxfw->out_conn);
388                         cmp_connection_release(&oxfw->out_conn);
389                 }
390         }
391 }
392
393 static void destroy_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
394 {
395         struct cmp_connection *conn;
396
397         if (stream == &oxfw->tx_stream)
398                 conn = &oxfw->out_conn;
399         else
400                 conn = &oxfw->in_conn;
401
402         amdtp_stream_destroy(stream);
403         cmp_connection_destroy(conn);
404 }
405
406 int snd_oxfw_stream_init_duplex(struct snd_oxfw *oxfw)
407 {
408         int err;
409
410         err = init_stream(oxfw, &oxfw->rx_stream);
411         if (err < 0)
412                 return err;
413
414         if (oxfw->has_output) {
415                 err = init_stream(oxfw, &oxfw->tx_stream);
416                 if (err < 0) {
417                         destroy_stream(oxfw, &oxfw->rx_stream);
418                         return err;
419                 }
420         }
421
422         err = amdtp_domain_init(&oxfw->domain);
423         if (err < 0) {
424                 destroy_stream(oxfw, &oxfw->rx_stream);
425                 if (oxfw->has_output)
426                         destroy_stream(oxfw, &oxfw->tx_stream);
427         }
428
429         return err;
430 }
431
432 // This function should be called before starting the stream or after stopping
433 // the streams.
434 void snd_oxfw_stream_destroy_duplex(struct snd_oxfw *oxfw)
435 {
436         amdtp_domain_destroy(&oxfw->domain);
437
438         destroy_stream(oxfw, &oxfw->rx_stream);
439
440         if (oxfw->has_output)
441                 destroy_stream(oxfw, &oxfw->tx_stream);
442 }
443
444 void snd_oxfw_stream_update_duplex(struct snd_oxfw *oxfw)
445 {
446         amdtp_domain_stop(&oxfw->domain);
447
448         cmp_connection_break(&oxfw->in_conn);
449
450         amdtp_stream_pcm_abort(&oxfw->rx_stream);
451
452         if (oxfw->has_output) {
453                 cmp_connection_break(&oxfw->out_conn);
454
455                 amdtp_stream_pcm_abort(&oxfw->tx_stream);
456         }
457 }
458
459 int snd_oxfw_stream_get_current_formation(struct snd_oxfw *oxfw,
460                                 enum avc_general_plug_dir dir,
461                                 struct snd_oxfw_stream_formation *formation)
462 {
463         u8 *format;
464         unsigned int len;
465         int err;
466
467         len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
468         format = kmalloc(len, GFP_KERNEL);
469         if (format == NULL)
470                 return -ENOMEM;
471
472         err = avc_stream_get_format_single(oxfw->unit, dir, 0, format, &len);
473         if (err < 0)
474                 goto end;
475         if (len < 3) {
476                 err = -EIO;
477                 goto end;
478         }
479
480         err = snd_oxfw_stream_parse_format(format, formation);
481 end:
482         kfree(format);
483         return err;
484 }
485
486 /*
487  * See Table 6.16 - AM824 Stream Format
488  *     Figure 6.19 - format_information field for AM824 Compound
489  * in AV/C Stream Format Information Specification 1.1 (Apr 2005, 1394TA)
490  * Also 'Clause 12 AM824 sequence adaption layers' in IEC 61883-6:2005
491  */
492 int snd_oxfw_stream_parse_format(u8 *format,
493                                  struct snd_oxfw_stream_formation *formation)
494 {
495         unsigned int i, e, channels, type;
496
497         memset(formation, 0, sizeof(struct snd_oxfw_stream_formation));
498
499         /*
500          * this module can support a hierarchy combination that:
501          *  Root:       Audio and Music (0x90)
502          *  Level 1:    AM824 Compound  (0x40)
503          */
504         if ((format[0] != 0x90) || (format[1] != 0x40))
505                 return -ENOSYS;
506
507         /* check the sampling rate */
508         for (i = 0; i < ARRAY_SIZE(avc_stream_rate_table); i++) {
509                 if (format[2] == avc_stream_rate_table[i])
510                         break;
511         }
512         if (i == ARRAY_SIZE(avc_stream_rate_table))
513                 return -ENOSYS;
514
515         formation->rate = oxfw_rate_table[i];
516
517         for (e = 0; e < format[4]; e++) {
518                 channels = format[5 + e * 2];
519                 type = format[6 + e * 2];
520
521                 switch (type) {
522                 /* IEC 60958 Conformant, currently handled as MBLA */
523                 case 0x00:
524                 /* Multi Bit Linear Audio (Raw) */
525                 case 0x06:
526                         formation->pcm += channels;
527                         break;
528                 /* MIDI Conformant */
529                 case 0x0d:
530                         formation->midi = channels;
531                         break;
532                 /* IEC 61937-3 to 7 */
533                 case 0x01:
534                 case 0x02:
535                 case 0x03:
536                 case 0x04:
537                 case 0x05:
538                 /* Multi Bit Linear Audio */
539                 case 0x07:      /* DVD-Audio */
540                 case 0x0c:      /* High Precision */
541                 /* One Bit Audio */
542                 case 0x08:      /* (Plain) Raw */
543                 case 0x09:      /* (Plain) SACD */
544                 case 0x0a:      /* (Encoded) Raw */
545                 case 0x0b:      /* (Encoded) SACD */
546                 /* SMPTE Time-Code conformant */
547                 case 0x0e:
548                 /* Sample Count */
549                 case 0x0f:
550                 /* Anciliary Data */
551                 case 0x10:
552                 /* Synchronization Stream (Stereo Raw audio) */
553                 case 0x40:
554                 /* Don't care */
555                 case 0xff:
556                 default:
557                         return -ENOSYS; /* not supported */
558                 }
559         }
560
561         if (formation->pcm  > AM824_MAX_CHANNELS_FOR_PCM ||
562             formation->midi > AM824_MAX_CHANNELS_FOR_MIDI)
563                 return -ENOSYS;
564
565         return 0;
566 }
567
568 static int
569 assume_stream_formats(struct snd_oxfw *oxfw, enum avc_general_plug_dir dir,
570                       unsigned int pid, u8 *buf, unsigned int *len,
571                       u8 **formats)
572 {
573         struct snd_oxfw_stream_formation formation;
574         unsigned int i, eid;
575         int err;
576
577         /* get format at current sampling rate */
578         err = avc_stream_get_format_single(oxfw->unit, dir, pid, buf, len);
579         if (err < 0) {
580                 dev_err(&oxfw->unit->device,
581                 "fail to get current stream format for isoc %s plug %d:%d\n",
582                         (dir == AVC_GENERAL_PLUG_DIR_IN) ? "in" : "out",
583                         pid, err);
584                 goto end;
585         }
586
587         /* parse and set stream format */
588         eid = 0;
589         err = snd_oxfw_stream_parse_format(buf, &formation);
590         if (err < 0)
591                 goto end;
592
593         formats[eid] = devm_kmemdup(&oxfw->card->card_dev, buf, *len,
594                                     GFP_KERNEL);
595         if (!formats[eid]) {
596                 err = -ENOMEM;
597                 goto end;
598         }
599
600         /* apply the format for each available sampling rate */
601         for (i = 0; i < ARRAY_SIZE(oxfw_rate_table); i++) {
602                 if (formation.rate == oxfw_rate_table[i])
603                         continue;
604
605                 err = avc_general_inquiry_sig_fmt(oxfw->unit,
606                                                   oxfw_rate_table[i],
607                                                   dir, pid);
608                 if (err < 0)
609                         continue;
610
611                 eid++;
612                 formats[eid] = devm_kmemdup(&oxfw->card->card_dev, buf, *len,
613                                             GFP_KERNEL);
614                 if (formats[eid] == NULL) {
615                         err = -ENOMEM;
616                         goto end;
617                 }
618                 formats[eid][2] = avc_stream_rate_table[i];
619         }
620
621         err = 0;
622         oxfw->assumed = true;
623 end:
624         return err;
625 }
626
627 static int fill_stream_formats(struct snd_oxfw *oxfw,
628                                enum avc_general_plug_dir dir,
629                                unsigned short pid)
630 {
631         u8 *buf, **formats;
632         unsigned int len, eid = 0;
633         struct snd_oxfw_stream_formation dummy;
634         int err;
635
636         buf = kmalloc(AVC_GENERIC_FRAME_MAXIMUM_BYTES, GFP_KERNEL);
637         if (buf == NULL)
638                 return -ENOMEM;
639
640         if (dir == AVC_GENERAL_PLUG_DIR_OUT)
641                 formats = oxfw->tx_stream_formats;
642         else
643                 formats = oxfw->rx_stream_formats;
644
645         /* get first entry */
646         len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
647         err = avc_stream_get_format_list(oxfw->unit, dir, 0, buf, &len, 0);
648         if (err == -ENOSYS) {
649                 /* LIST subfunction is not implemented */
650                 len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
651                 err = assume_stream_formats(oxfw, dir, pid, buf, &len,
652                                             formats);
653                 goto end;
654         } else if (err < 0) {
655                 dev_err(&oxfw->unit->device,
656                         "fail to get stream format %d for isoc %s plug %d:%d\n",
657                         eid, (dir == AVC_GENERAL_PLUG_DIR_IN) ? "in" : "out",
658                         pid, err);
659                 goto end;
660         }
661
662         /* LIST subfunction is implemented */
663         while (eid < SND_OXFW_STREAM_FORMAT_ENTRIES) {
664                 /* The format is too short. */
665                 if (len < 3) {
666                         err = -EIO;
667                         break;
668                 }
669
670                 /* parse and set stream format */
671                 err = snd_oxfw_stream_parse_format(buf, &dummy);
672                 if (err < 0)
673                         break;
674
675                 formats[eid] = devm_kmemdup(&oxfw->card->card_dev, buf, len,
676                                             GFP_KERNEL);
677                 if (!formats[eid]) {
678                         err = -ENOMEM;
679                         break;
680                 }
681
682                 /* get next entry */
683                 len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
684                 err = avc_stream_get_format_list(oxfw->unit, dir, 0,
685                                                  buf, &len, ++eid);
686                 /* No entries remained. */
687                 if (err == -EINVAL) {
688                         err = 0;
689                         break;
690                 } else if (err < 0) {
691                         dev_err(&oxfw->unit->device,
692                         "fail to get stream format %d for isoc %s plug %d:%d\n",
693                                 eid, (dir == AVC_GENERAL_PLUG_DIR_IN) ? "in" :
694                                                                         "out",
695                                 pid, err);
696                         break;
697                 }
698         }
699 end:
700         kfree(buf);
701         return err;
702 }
703
704 int snd_oxfw_stream_discover(struct snd_oxfw *oxfw)
705 {
706         u8 plugs[AVC_PLUG_INFO_BUF_BYTES];
707         struct snd_oxfw_stream_formation formation;
708         u8 *format;
709         unsigned int i;
710         int err;
711
712         /* the number of plugs for isoc in/out, ext in/out  */
713         err = avc_general_get_plug_info(oxfw->unit, 0x1f, 0x07, 0x00, plugs);
714         if (err < 0) {
715                 dev_err(&oxfw->unit->device,
716                 "fail to get info for isoc/external in/out plugs: %d\n",
717                         err);
718                 goto end;
719         } else if ((plugs[0] == 0) && (plugs[1] == 0)) {
720                 err = -ENOSYS;
721                 goto end;
722         }
723
724         /* use oPCR[0] if exists */
725         if (plugs[1] > 0) {
726                 err = fill_stream_formats(oxfw, AVC_GENERAL_PLUG_DIR_OUT, 0);
727                 if (err < 0)
728                         goto end;
729
730                 for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
731                         format = oxfw->tx_stream_formats[i];
732                         if (format == NULL)
733                                 continue;
734                         err = snd_oxfw_stream_parse_format(format, &formation);
735                         if (err < 0)
736                                 continue;
737
738                         /* Add one MIDI port. */
739                         if (formation.midi > 0)
740                                 oxfw->midi_input_ports = 1;
741                 }
742
743                 oxfw->has_output = true;
744         }
745
746         /* use iPCR[0] if exists */
747         if (plugs[0] > 0) {
748                 err = fill_stream_formats(oxfw, AVC_GENERAL_PLUG_DIR_IN, 0);
749                 if (err < 0)
750                         goto end;
751
752                 for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
753                         format = oxfw->rx_stream_formats[i];
754                         if (format == NULL)
755                                 continue;
756                         err = snd_oxfw_stream_parse_format(format, &formation);
757                         if (err < 0)
758                                 continue;
759
760                         /* Add one MIDI port. */
761                         if (formation.midi > 0)
762                                 oxfw->midi_output_ports = 1;
763                 }
764         }
765 end:
766         return err;
767 }
768
769 void snd_oxfw_stream_lock_changed(struct snd_oxfw *oxfw)
770 {
771         oxfw->dev_lock_changed = true;
772         wake_up(&oxfw->hwdep_wait);
773 }
774
775 int snd_oxfw_stream_lock_try(struct snd_oxfw *oxfw)
776 {
777         int err;
778
779         spin_lock_irq(&oxfw->lock);
780
781         /* user land lock this */
782         if (oxfw->dev_lock_count < 0) {
783                 err = -EBUSY;
784                 goto end;
785         }
786
787         /* this is the first time */
788         if (oxfw->dev_lock_count++ == 0)
789                 snd_oxfw_stream_lock_changed(oxfw);
790         err = 0;
791 end:
792         spin_unlock_irq(&oxfw->lock);
793         return err;
794 }
795
796 void snd_oxfw_stream_lock_release(struct snd_oxfw *oxfw)
797 {
798         spin_lock_irq(&oxfw->lock);
799
800         if (WARN_ON(oxfw->dev_lock_count <= 0))
801                 goto end;
802         if (--oxfw->dev_lock_count == 0)
803                 snd_oxfw_stream_lock_changed(oxfw);
804 end:
805         spin_unlock_irq(&oxfw->lock);
806 }