Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / dev / usb / umidi_quirks.c
blobae2df079da469de329a2adf9e653b8d01663d2b0
1 /* $NetBSD: umidi_quirks.c,v 1.15 2008/04/28 20:24:00 martin Exp $ */
3 /*
4 * Copyright (c) 2001 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Takuya SHIOZAKI (tshiozak@NetBSD.org).
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.
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.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: umidi_quirks.c,v 1.15 2008/04/28 20:24:00 martin Exp $");
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>
48 #include <dev/usb/usb.h>
49 #include <dev/usb/usbdi.h>
50 #include <dev/usb/usbdi_util.h>
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>
59 * quirk codes for UMIDI
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
73 * YAMAHA UX-256
74 * --- this is a typical yamaha device, but has a broken descriptor :-<
77 UMQ_FIXED_EP_DATA_DEF(YAMAHA, YAMAHA_UX256, ANYIFACE, 1, 1) = {
78 /* out */
79 { 0, 16 },
80 /* in */
81 { 1, 8 }
83 UMQ_FIXED_EP_DEF(YAMAHA, YAMAHA_UX256, ANYIFACE, 1, 1);
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
95 * YAMAHA generic
97 UMQ_DEF(YAMAHA, ANYPRODUCT, ANYIFACE) = {
98 UMQ_YAMAHA_REG(YAMAHA, ANYPRODUCT, ANYIFACE),
99 UMQ_TERMINATOR
104 * ROLAND UM-1
106 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UM1, 2, 1, 1) = {
107 /* out */
108 { 0, 1 },
109 /* in */
110 { 1, 1 }
112 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM1, 2, 1, 1);
114 UMQ_DEF(ROLAND, ROLAND_UM1, 2) = {
115 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM1, 2),
116 UMQ_TERMINATOR
120 * ROLAND SC-8850
122 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SC8850, 2, 1, 1) = {
123 /* out */
124 { 0, 6 },
125 /* in */
126 { 1, 6 }
128 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SC8850, 2, 1, 1);
130 UMQ_DEF(ROLAND, ROLAND_SC8850, 2) = {
131 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SC8850, 2),
132 UMQ_TERMINATOR
136 * ROLAND SD-90
138 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SD90, 2, 1, 1) = {
139 /* out */
140 { 0, 4 },
141 /* in */
142 { 1, 4 }
144 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SD90, 2, 1, 1);
146 UMQ_DEF(ROLAND, ROLAND_SD90, 2) = {
147 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SD90, 2),
148 UMQ_TERMINATOR
153 * ROLAND UM-880 (native mode)
155 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UM880N, 0, 1, 1) = {
156 /* out */
157 { 0, 9 },
158 /* in */
159 { 1, 9 }
161 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM880N, 0, 1, 1);
163 UMQ_DEF(ROLAND, ROLAND_UM880N, 0) = {
164 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM880N, 0),
165 UMQ_TERMINATOR
169 * ROLAND UA-100
171 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA100, 2, 1, 1) = {
172 /* out */
173 { 0, 3 },
174 /* in */
175 { 1, 3 }
177 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA100, 2, 1, 1);
179 UMQ_DEF(ROLAND, ROLAND_UA100, 2) = {
180 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA100, 2),
181 UMQ_TERMINATOR
185 * ROLAND UM-4
187 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UM4, 2, 1, 1) = {
188 /* out */
189 { 0, 4 },
190 /* in */
191 { 1, 4 }
193 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM4, 2, 1, 1);
195 UMQ_DEF(ROLAND, ROLAND_UM4, 2) = {
196 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM4, 2),
197 UMQ_TERMINATOR
201 * ROLAND U-8
203 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_U8, 2, 1, 1) = {
204 /* out */
205 { 0, 2 },
206 /* in */
207 { 1, 2 }
209 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_U8, 2, 1, 1);
211 UMQ_DEF(ROLAND, ROLAND_U8, 2) = {
212 UMQ_FIXED_EP_REG(ROLAND, ROLAND_U8, 2),
213 UMQ_TERMINATOR
217 * ROLAND UM-2
219 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UM2, 2, 1, 1) = {
220 /* out */
221 { 0, 2 },
222 /* in */
223 { 1, 2 }
225 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM2, 2, 1, 1);
227 UMQ_DEF(ROLAND, ROLAND_UM2, 2) = {
228 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM2, 2),
229 UMQ_TERMINATOR
233 * ROLAND SC-8820
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. */
241 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SC8820, 2, 1, 1);
243 UMQ_DEF(ROLAND, ROLAND_SC8820, 2) = {
244 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SC8820, 2),
245 UMQ_TERMINATOR
249 * ROLAND PC-300
251 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_PC300, 2, 1, 1) = {
252 /* out */
253 { 0, 1 },
254 /* in */
255 { 1, 1 }
257 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_PC300, 2, 1, 1);
259 UMQ_DEF(ROLAND, ROLAND_PC300, 2) = {
260 UMQ_FIXED_EP_REG(ROLAND, ROLAND_PC300, 2),
261 UMQ_TERMINATOR
265 * ROLAND SK-500
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. */
273 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SK500, 2, 1, 1);
275 UMQ_DEF(ROLAND, ROLAND_SK500, 2) = {
276 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SK500, 2),
277 UMQ_TERMINATOR
281 * ROLAND SC-D70
283 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SCD70, 2, 1, 1) = {
284 /* out */
285 { 0, 3 },
286 /* in */
287 { 1, 3 }
289 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SCD70, 2, 1, 1);
291 UMQ_DEF(ROLAND, ROLAND_SCD70, 2) = {
292 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SCD70, 2),
293 UMQ_TERMINATOR
297 * ROLAND XV-5050
299 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_XV5050, 0, 1, 1) = {
300 /* out */
301 { 0, 1 },
302 /* in */
303 { 1, 1 }
305 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_XV5050, 0, 1, 1);
307 UMQ_DEF(ROLAND, ROLAND_XV5050, 0) = {
308 UMQ_FIXED_EP_REG(ROLAND, ROLAND_XV5050, 0),
309 UMQ_TERMINATOR
313 * ROLAND UM-550
315 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UM550, 0, 1, 1) = {
316 /* out */
317 { 0, 6 },
318 /* in */
319 { 1, 6 }
321 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM550, 0, 1, 1);
323 UMQ_DEF(ROLAND, ROLAND_UM550, 0) = {
324 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM550, 0),
325 UMQ_TERMINATOR
329 * ROLAND SD-20
331 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SD20, 0, 1, 1) = {
332 /* out */
333 { 0, 2 },
334 /* in */
335 { 1, 3 }
337 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SD20, 0, 1, 1);
339 UMQ_DEF(ROLAND, ROLAND_SD20, 0) = {
340 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SD20, 0),
341 UMQ_TERMINATOR
345 * ROLAND SD-80
347 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SD80, 0, 1, 1) = {
348 /* out */
349 { 0, 4 },
350 /* in */
351 { 1, 4 }
353 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SD80, 0, 1, 1);
355 UMQ_DEF(ROLAND, ROLAND_SD80, 0) = {
356 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SD80, 0),
357 UMQ_TERMINATOR
361 * ROLAND UA-700
363 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA700, 3, 1, 1) = {
364 /* out */
365 { 0, 2 },
366 /* in */
367 { 1, 2 }
369 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA700, 3, 1, 1);
371 UMQ_DEF(ROLAND, ROLAND_UA700, 3) = {
372 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA700, 3),
373 UMQ_TERMINATOR
377 * ROLAND UA-1000
379 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA1000, 3, 1, 1) = {
380 /* out */
381 { 0, 2 },
382 /* in */
383 { 1, 2 }
385 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA1000, 3, 1, 1);
387 UMQ_DEF(ROLAND, ROLAND_UA1000, 3) = {
388 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA1000, 3),
389 UMQ_TERMINATOR
393 * ROLAND UA-101
395 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA101, 2, 1, 1) = {
396 /* out */
397 { 0, 2 },
398 /* in */
399 { 1, 2 }
401 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA101, 2, 1, 1);
403 UMQ_DEF(ROLAND, ROLAND_UA101, 2) = {
404 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA101, 2),
405 UMQ_TERMINATOR
408 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA101F, 2, 1, 1) = {
409 /* out */
410 { 0, 2 },
411 /* in */
412 { 1, 2 }
414 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA101F, 2, 1, 1);
416 UMQ_DEF(ROLAND, ROLAND_UA101F, 2) = {
417 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA101F, 2),
418 UMQ_TERMINATOR
422 * ROLAND Fantom-X
424 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_FANTOMX, 0, 1, 1) = {
425 /* out */
426 { 0, 1 },
427 /* in */
428 { 1, 1 }
430 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_FANTOMX, 0, 1, 1);
432 UMQ_DEF(ROLAND, ROLAND_FANTOMX, 0) = {
433 UMQ_FIXED_EP_REG(ROLAND, ROLAND_FANTOMX, 0),
434 UMQ_TERMINATOR
438 * ROLAND PCR
440 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_PCR, 0, 1, 1) = {
441 /* out */
442 { 0, 3 },
443 /* in */
444 { 1, 3 }
446 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_PCR, 0, 1, 1);
448 UMQ_DEF(ROLAND, ROLAND_PCR, 0) = {
449 UMQ_FIXED_EP_REG(ROLAND, ROLAND_PCR, 0),
450 UMQ_TERMINATOR
454 * ROLAND UM-3EX
456 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UM3, 0, 1, 1) = {
457 /* out */
458 { 0, 3 },
459 /* in */
460 { 1, 3 }
462 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM3, 0, 1, 1);
464 UMQ_DEF(ROLAND, ROLAND_UM3, 0) = {
465 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM3, 0),
466 UMQ_TERMINATOR
470 * ROLAND UA-25
472 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA25, 2, 1, 1) = {
473 /* out */
474 { 0, 1 },
475 /* in */
476 { 1, 1 }
478 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA25, 2, 1, 1);
480 UMQ_DEF(ROLAND, ROLAND_UA25, 2) = {
481 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA25, 2),
482 UMQ_TERMINATOR
486 * ROLAND UA-4FX
488 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA4FX, 2, 1, 1) = {
489 /* out */
490 { 0, 1 },
491 /* in */
492 { 1, 1 }
494 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA4FX, 2, 1, 1);
496 UMQ_DEF(ROLAND, ROLAND_UA4FX, 2) = {
497 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA4FX, 2),
498 UMQ_TERMINATOR
502 * ROLAND SonicCell
504 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SONICCELL, 2, 1, 1) = {
505 /* out */
506 { 0, 1 },
507 /* in */
508 { 1, 1 }
510 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SONICCELL, 2, 1, 1);
512 UMQ_DEF(ROLAND, ROLAND_SONICCELL, 2) = {
513 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SONICCELL, 2),
514 UMQ_TERMINATOR
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).
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 }
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
547 UMQ_FIXED_MD_DEF(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE) = {
548 0, 0, 2, 1, 1, -1, 3, -1
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
559 * quirk list
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 },
596 * quirk utilities
599 const struct umidi_quirk *
600 umidi_search_quirk(int vendor, int product, int ifaceno)
602 struct umidi_quirk *p;
603 const struct umq_data *q;
605 DPRINTF(("umidi_search_quirk: v=%d, p=%d, i=%d\n",
606 vendor, product, ifaceno));
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;
621 DPRINTFN(10, ("\n"));
624 return NULL;
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",
638 void
639 umidi_print_quirk(const struct umidi_quirk *q)
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");
652 const void *
653 umidi_get_quirk_data_from_type(const struct umidi_quirk *q, u_int32_t type)
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;
661 return NULL;