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