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