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