umidi_quirks.c revision 1.16.32.2 1 /* $NetBSD: umidi_quirks.c,v 1.16.32.2 2012/06/02 11:09:30 mrg Exp $ */
2
3 /*
4 * Copyright (c) 2001 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Takuya SHIOZAKI (tshiozak (at) NetBSD.org).
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: umidi_quirks.c,v 1.16.32.2 2012/06/02 11:09:30 mrg Exp $");
34
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
38 #include <sys/malloc.h>
39 #include <sys/device.h>
40 #include <sys/ioctl.h>
41 #include <sys/conf.h>
42 #include <sys/file.h>
43 #include <sys/select.h>
44 #include <sys/proc.h>
45 #include <sys/vnode.h>
46 #include <sys/poll.h>
47
48 #include <dev/usb/usb.h>
49 #include <dev/usb/usbdi.h>
50 #include <dev/usb/usbdi_util.h>
51
52 #include <dev/auconv.h>
53 #include <dev/usb/usbdevs.h>
54 #include <dev/usb/uaudioreg.h>
55 #include <dev/usb/umidireg.h>
56 #include <dev/usb/umidivar.h>
57 #include <dev/usb/umidi_quirks.h>
58
59 /*
60 * quirk codes for UMIDI
61 */
62
63 #ifdef UMIDIQUIRK_DEBUG
64 #define DPRINTF(x) if (umidiquirkdebug) printf x
65 #define DPRINTFN(n,x) if (umidiquirkdebug >= (n)) printf x
66 int umidiquirkdebug = 1;
67 #else
68 #define DPRINTF(x)
69 #define DPRINTFN(n,x)
70 #endif
71
72
73 /*
74 * YAMAHA UX-256
75 * --- this is a typical yamaha device, but has a broken descriptor :-<
76 */
77
78 UMQ_FIXED_EP_DATA_DEF(YAMAHA, YAMAHA_UX256, ANYIFACE, 1, 1) = {
79 /* out */
80 { 0, 16 },
81 /* in */
82 { 1, 8 }
83 };
84 UMQ_FIXED_EP_DEF(YAMAHA, YAMAHA_UX256, ANYIFACE, 1, 1);
85
86 UMQ_DEF(YAMAHA, YAMAHA_UX256, ANYIFACE) = {
87 UMQ_FIXED_EP_REG(YAMAHA, YAMAHA_UX256, ANYIFACE),
88 #if 0
89 UMQ_YAMAHA_REG(YAMAHA, ANYPRODUCT, ANYIFACE),
90 #endif
91 UMQ_TERMINATOR
92 };
93
94
95 /*
96 * YAMAHA generic
97 */
98 UMQ_DEF(YAMAHA, ANYPRODUCT, ANYIFACE) = {
99 UMQ_YAMAHA_REG(YAMAHA, ANYPRODUCT, ANYIFACE),
100 UMQ_TERMINATOR
101 };
102
103
104 /*
105 * ROLAND UM-1
106 */
107 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UM1, 2, 1, 1) = {
108 /* out */
109 { 0, 1 },
110 /* in */
111 { 1, 1 }
112 };
113 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM1, 2, 1, 1);
114
115 UMQ_DEF(ROLAND, ROLAND_UM1, 2) = {
116 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM1, 2),
117 UMQ_TERMINATOR
118 };
119
120 /*
121 * ROLAND SC-8850
122 */
123 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SC8850, 2, 1, 1) = {
124 /* out */
125 { 0, 6 },
126 /* in */
127 { 1, 6 }
128 };
129 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SC8850, 2, 1, 1);
130
131 UMQ_DEF(ROLAND, ROLAND_SC8850, 2) = {
132 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SC8850, 2),
133 UMQ_TERMINATOR
134 };
135
136 /*
137 * ROLAND SD-90
138 */
139 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SD90, 2, 1, 1) = {
140 /* out */
141 { 0, 4 },
142 /* in */
143 { 1, 4 }
144 };
145 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SD90, 2, 1, 1);
146
147 UMQ_DEF(ROLAND, ROLAND_SD90, 2) = {
148 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SD90, 2),
149 UMQ_TERMINATOR
150 };
151
152
153 /*
154 * ROLAND UM-880 (native mode)
155 */
156 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UM880N, 0, 1, 1) = {
157 /* out */
158 { 0, 9 },
159 /* in */
160 { 1, 9 }
161 };
162 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM880N, 0, 1, 1);
163
164 UMQ_DEF(ROLAND, ROLAND_UM880N, 0) = {
165 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM880N, 0),
166 UMQ_TERMINATOR
167 };
168
169 /*
170 * ROLAND UA-100
171 */
172 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA100, 2, 1, 1) = {
173 /* out */
174 { 0, 3 },
175 /* in */
176 { 1, 3 }
177 };
178 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA100, 2, 1, 1);
179
180 UMQ_DEF(ROLAND, ROLAND_UA100, 2) = {
181 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA100, 2),
182 UMQ_TERMINATOR
183 };
184
185 /*
186 * ROLAND UM-4
187 */
188 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UM4, 2, 1, 1) = {
189 /* out */
190 { 0, 4 },
191 /* in */
192 { 1, 4 }
193 };
194 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM4, 2, 1, 1);
195
196 UMQ_DEF(ROLAND, ROLAND_UM4, 2) = {
197 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM4, 2),
198 UMQ_TERMINATOR
199 };
200
201 /*
202 * ROLAND U-8
203 */
204 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_U8, 2, 1, 1) = {
205 /* out */
206 { 0, 2 },
207 /* in */
208 { 1, 2 }
209 };
210 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_U8, 2, 1, 1);
211
212 UMQ_DEF(ROLAND, ROLAND_U8, 2) = {
213 UMQ_FIXED_EP_REG(ROLAND, ROLAND_U8, 2),
214 UMQ_TERMINATOR
215 };
216
217 /*
218 * ROLAND UM-2
219 */
220 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UM2, 2, 1, 1) = {
221 /* out */
222 { 0, 2 },
223 /* in */
224 { 1, 2 }
225 };
226 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM2, 2, 1, 1);
227
228 UMQ_DEF(ROLAND, ROLAND_UM2, 2) = {
229 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM2, 2),
230 UMQ_TERMINATOR
231 };
232
233 /*
234 * ROLAND SC-8820
235 */
236 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SC8820, 2, 1, 1) = {
237 /* out */
238 { 0, 5 }, /* cables 0, 1, 4 only */
239 /* in */
240 { 1, 5 } /* do. */
241 };
242 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SC8820, 2, 1, 1);
243
244 UMQ_DEF(ROLAND, ROLAND_SC8820, 2) = {
245 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SC8820, 2),
246 UMQ_TERMINATOR
247 };
248
249 /*
250 * ROLAND PC-300
251 */
252 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_PC300, 2, 1, 1) = {
253 /* out */
254 { 0, 1 },
255 /* in */
256 { 1, 1 }
257 };
258 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_PC300, 2, 1, 1);
259
260 UMQ_DEF(ROLAND, ROLAND_PC300, 2) = {
261 UMQ_FIXED_EP_REG(ROLAND, ROLAND_PC300, 2),
262 UMQ_TERMINATOR
263 };
264
265 /*
266 * ROLAND SK-500
267 */
268 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SK500, 2, 1, 1) = {
269 /* out */
270 { 0, 5 }, /* cables 0, 1, 4 only */
271 /* in */
272 { 1, 5 } /* do. */
273 };
274 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SK500, 2, 1, 1);
275
276 UMQ_DEF(ROLAND, ROLAND_SK500, 2) = {
277 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SK500, 2),
278 UMQ_TERMINATOR
279 };
280
281 /*
282 * ROLAND SC-D70
283 */
284 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SCD70, 2, 1, 1) = {
285 /* out */
286 { 0, 3 },
287 /* in */
288 { 1, 3 }
289 };
290 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SCD70, 2, 1, 1);
291
292 UMQ_DEF(ROLAND, ROLAND_SCD70, 2) = {
293 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SCD70, 2),
294 UMQ_TERMINATOR
295 };
296
297 /*
298 * ROLAND XV-5050
299 */
300 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_XV5050, 0, 1, 1) = {
301 /* out */
302 { 0, 1 },
303 /* in */
304 { 1, 1 }
305 };
306 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_XV5050, 0, 1, 1);
307
308 UMQ_DEF(ROLAND, ROLAND_XV5050, 0) = {
309 UMQ_FIXED_EP_REG(ROLAND, ROLAND_XV5050, 0),
310 UMQ_TERMINATOR
311 };
312
313 /*
314 * ROLAND UM-550
315 */
316 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UM550, 0, 1, 1) = {
317 /* out */
318 { 0, 6 },
319 /* in */
320 { 1, 6 }
321 };
322 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM550, 0, 1, 1);
323
324 UMQ_DEF(ROLAND, ROLAND_UM550, 0) = {
325 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM550, 0),
326 UMQ_TERMINATOR
327 };
328
329 /*
330 * ROLAND SD-20
331 */
332 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SD20, 0, 1, 1) = {
333 /* out */
334 { 0, 2 },
335 /* in */
336 { 1, 3 }
337 };
338 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SD20, 0, 1, 1);
339
340 UMQ_DEF(ROLAND, ROLAND_SD20, 0) = {
341 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SD20, 0),
342 UMQ_TERMINATOR
343 };
344
345 /*
346 * ROLAND SD-80
347 */
348 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SD80, 0, 1, 1) = {
349 /* out */
350 { 0, 4 },
351 /* in */
352 { 1, 4 }
353 };
354 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SD80, 0, 1, 1);
355
356 UMQ_DEF(ROLAND, ROLAND_SD80, 0) = {
357 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SD80, 0),
358 UMQ_TERMINATOR
359 };
360
361 /*
362 * ROLAND UA-700
363 */
364 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA700, 3, 1, 1) = {
365 /* out */
366 { 0, 2 },
367 /* in */
368 { 1, 2 }
369 };
370 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA700, 3, 1, 1);
371
372 UMQ_DEF(ROLAND, ROLAND_UA700, 3) = {
373 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA700, 3),
374 UMQ_TERMINATOR
375 };
376
377 /*
378 * ROLAND UA-1000
379 */
380 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA1000, 3, 1, 1) = {
381 /* out */
382 { 0, 2 },
383 /* in */
384 { 1, 2 }
385 };
386 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA1000, 3, 1, 1);
387
388 UMQ_DEF(ROLAND, ROLAND_UA1000, 3) = {
389 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA1000, 3),
390 UMQ_TERMINATOR
391 };
392
393 /*
394 * ROLAND UA-101
395 */
396 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA101, 2, 1, 1) = {
397 /* out */
398 { 0, 2 },
399 /* in */
400 { 1, 2 }
401 };
402 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA101, 2, 1, 1);
403
404 UMQ_DEF(ROLAND, ROLAND_UA101, 2) = {
405 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA101, 2),
406 UMQ_TERMINATOR
407 };
408
409 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA101F, 2, 1, 1) = {
410 /* out */
411 { 0, 2 },
412 /* in */
413 { 1, 2 }
414 };
415 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA101F, 2, 1, 1);
416
417 UMQ_DEF(ROLAND, ROLAND_UA101F, 2) = {
418 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA101F, 2),
419 UMQ_TERMINATOR
420 };
421
422 /*
423 * ROLAND Fantom-X
424 */
425 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_FANTOMX, 0, 1, 1) = {
426 /* out */
427 { 0, 1 },
428 /* in */
429 { 1, 1 }
430 };
431 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_FANTOMX, 0, 1, 1);
432
433 UMQ_DEF(ROLAND, ROLAND_FANTOMX, 0) = {
434 UMQ_FIXED_EP_REG(ROLAND, ROLAND_FANTOMX, 0),
435 UMQ_TERMINATOR
436 };
437
438 /*
439 * ROLAND PCR
440 */
441 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_PCR, 0, 1, 1) = {
442 /* out */
443 { 0, 3 },
444 /* in */
445 { 1, 3 }
446 };
447 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_PCR, 0, 1, 1);
448
449 UMQ_DEF(ROLAND, ROLAND_PCR, 0) = {
450 UMQ_FIXED_EP_REG(ROLAND, ROLAND_PCR, 0),
451 UMQ_TERMINATOR
452 };
453
454 /*
455 * ROLAND UM-3EX
456 */
457 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UM3, 0, 1, 1) = {
458 /* out */
459 { 0, 3 },
460 /* in */
461 { 1, 3 }
462 };
463 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM3, 0, 1, 1);
464
465 UMQ_DEF(ROLAND, ROLAND_UM3, 0) = {
466 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM3, 0),
467 UMQ_TERMINATOR
468 };
469
470 /*
471 * ROLAND UA-25
472 */
473 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA25, 2, 1, 1) = {
474 /* out */
475 { 0, 1 },
476 /* in */
477 { 1, 1 }
478 };
479 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA25, 2, 1, 1);
480
481 UMQ_DEF(ROLAND, ROLAND_UA25, 2) = {
482 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA25, 2),
483 UMQ_TERMINATOR
484 };
485
486 /*
487 * ROLAND UA-4FX
488 */
489 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA4FX, 2, 1, 1) = {
490 /* out */
491 { 0, 1 },
492 /* in */
493 { 1, 1 }
494 };
495 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA4FX, 2, 1, 1);
496
497 UMQ_DEF(ROLAND, ROLAND_UA4FX, 2) = {
498 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA4FX, 2),
499 UMQ_TERMINATOR
500 };
501
502 /*
503 * ROLAND SonicCell
504 */
505 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SONICCELL, 2, 1, 1) = {
506 /* out */
507 { 0, 1 },
508 /* in */
509 { 1, 1 }
510 };
511 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SONICCELL, 2, 1, 1);
512
513 UMQ_DEF(ROLAND, ROLAND_SONICCELL, 2) = {
514 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SONICCELL, 2),
515 UMQ_TERMINATOR
516 };
517
518 /*
519 * ROLAND UM-ONE
520 */
521 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UMONE, ANYIFACE, 1, 1) = {
522 /* out */
523 { 0, 1 },
524 /* in */
525 { 1, 1 }
526 };
527 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UMONE, ANYIFACE, 1, 1);
528
529 UMQ_DEF(ROLAND, ROLAND_UMONE, ANYIFACE) = {
530 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UMONE, ANYIFACE),
531 UMQ_TERMINATOR
532 };
533
534 /*
535 * Midiman Midisport 2x4. This has 2 physical MIDI IN jacks that are read
536 * on endpoint 0x81 (descriptor index 0). It has 4 physical MIDI OUT jacks
537 * that can be written on endpoints 2 or 4 (at descriptor index 2 or 4,
538 * coincidentally) interchangeably: either endpoint will accept a Cable Number
539 * field of 0 to 3, and data for a given CN will be routed to the same
540 * physical output regardless of the endpoint used for the transfer. But
541 * there's a catch: flow-control feedback only goes to endpoint 2 for
542 * CN 0 and 2, and only to endpoint 4 for CN 1 and 3. If you send output at
543 * high rates for CN 0 or 2 over endpoint 4, or for CN 1 or 3 over endpoint 2,
544 * the USB transfers complete as fast as possible, giving you an apparent data
545 * rate much higher than MIDI's 3125 cps (easy to measure using dd to blast a
546 * bunch of midi data to the rmidi device). Of course that isn't a way to make
547 * MIDI faster, just a way to overrun the device buffer and spray bits on the
548 * floor. So this device needs the fixed endpoint quirk, the fixed cable number
549 * quirk (to make sure CNs 0 and 2 are put on the first endpoint and 1 and 3
550 * on the other), and then the fixed mididev-assignment quirk (to match jacks
551 * to mididevs so the rmidi devices match the order of the blinkenlights).
552 */
553 UMQ_FIXED_EP_DATA_DEF(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE, 2, 1) = {
554 /* out: ep# jacks */
555 { 2, 2 },
556 { 4, 2 },
557 /* in: ep# jacks */
558 { 0, 2 }
559 };
560 UMQ_FIXED_EP_DEF(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE, 2, 1);
561 UMQ_FIXED_CN_DEF(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE) = {
562 0, 2, 1, 3, 0, 1
563 };
564 UMQ_FIXED_MD_DEF(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE) = {
565 0, 0, 2, 1, 1, -1, 3, -1
566 };
567 UMQ_DEF(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE) = {
568 UMQ_FIXED_EP_REG(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE),
569 UMQ_FIXED_CN_REG(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE),
570 UMQ_FIXED_MD_REG(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE),
571 UMQ_TYPE(MIDIMAN_GARBLE),
572 UMQ_TERMINATOR
573 };
574
575 /*
576 * quirk list
577 */
578 static struct umidi_quirk umidi_quirklist[] = {
579 UMQ_REG(YAMAHA, YAMAHA_UX256, ANYIFACE),
580 UMQ_REG(YAMAHA, ANYPRODUCT, ANYIFACE),
581 UMQ_REG(ROLAND, ROLAND_UM1, 2),
582 UMQ_REG(ROLAND, ROLAND_SC8850, 2),
583 UMQ_REG(ROLAND, ROLAND_SD90, 2),
584 UMQ_REG(ROLAND, ROLAND_UM880N, 0),
585 UMQ_REG(ROLAND, ROLAND_UA100, 2),
586 UMQ_REG(ROLAND, ROLAND_UM4, 2),
587 UMQ_REG(ROLAND, ROLAND_U8, 2),
588 UMQ_REG(ROLAND, ROLAND_UM2, 2),
589 UMQ_REG(ROLAND, ROLAND_SC8820, 2),
590 UMQ_REG(ROLAND, ROLAND_PC300, 2),
591 UMQ_REG(ROLAND, ROLAND_SK500, 2),
592 UMQ_REG(ROLAND, ROLAND_SCD70, 2),
593 UMQ_REG(ROLAND, ROLAND_XV5050, 0),
594 UMQ_REG(ROLAND, ROLAND_UM550, 0),
595 UMQ_REG(ROLAND, ROLAND_SD20, 0),
596 UMQ_REG(ROLAND, ROLAND_SD80, 0),
597 UMQ_REG(ROLAND, ROLAND_UA700, 3),
598 UMQ_REG(ROLAND, ROLAND_UA1000, 3),
599 UMQ_REG(ROLAND, ROLAND_UA101, 2),
600 UMQ_REG(ROLAND, ROLAND_UA101F, 2),
601 UMQ_REG(ROLAND, ROLAND_FANTOMX, 0),
602 UMQ_REG(ROLAND, ROLAND_PCR, 0),
603 UMQ_REG(ROLAND, ROLAND_UM3, 0),
604 UMQ_REG(ROLAND, ROLAND_UA25, 2),
605 UMQ_REG(ROLAND, ROLAND_UA4FX, 2),
606 UMQ_REG(ROLAND, ROLAND_SONICCELL, 2),
607 UMQ_REG(ROLAND, ROLAND_UMONE, ANYIFACE),
608 UMQ_REG(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE),
609 { .vendor = 0 },
610 };
611
612
613 /*
614 * quirk utilities
615 */
616
617 const struct umidi_quirk *
618 umidi_search_quirk(int vendor, int product, int ifaceno)
619 {
620 struct umidi_quirk *p;
621 const struct umq_data *q;
622
623 DPRINTF(("umidi_search_quirk: v=%d, p=%d, i=%d\n",
624 vendor, product, ifaceno));
625
626 for (p=&umidi_quirklist[0]; p->vendor; p++) {
627 DPRINTFN(10, ("\tv=%d, p=%d, i=%d",
628 p->vendor, p->product, p->iface));
629 if ((p->vendor==vendor || p->vendor==ANYVENDOR) &&
630 (p->product==product || p->product==ANYPRODUCT) &&
631 (p->iface==ifaceno || p->iface==ANYIFACE)) {
632 DPRINTFN(10, (" found\n"));
633 if (!p->type_mask)
634 /* make quirk mask */
635 for (q=p->quirks; q->type; q++)
636 p->type_mask |= 1<<(q->type-1);
637 return p;
638 }
639 DPRINTFN(10, ("\n"));
640 }
641
642 return NULL;
643 }
644
645 static const char *quirk_name[] = {
646 "NULL",
647 "Fixed Endpoint",
648 "Yamaha Specific",
649 "Midiman Packet Garbling",
650 "Cable Numbers per Endpoint",
651 "Cable Numbers Global",
652 "Cable Numbers Fixed",
653 "Unit Mapping Fixed",
654 };
655
656 void
657 umidi_print_quirk(const struct umidi_quirk *q)
658 {
659 const struct umq_data *qd;
660 if (q) {
661 printf("(");
662 for (qd=q->quirks; qd->type; qd++)
663 printf("%s%s", quirk_name[qd->type],
664 (qd+1)->type?", ":")\n");
665 } else {
666 printf("(genuine USB-MIDI)\n");
667 }
668 }
669
670 const void *
671 umidi_get_quirk_data_from_type(const struct umidi_quirk *q, u_int32_t type)
672 {
673 const struct umq_data *qd;
674 if (q) {
675 for (qd=q->quirks; qd->type; qd++)
676 if (qd->type == type)
677 return qd->data;
678 }
679 return NULL;
680 }
681