Home | History | Annotate | Line # | Download | only in usb
umidi_quirks.c revision 1.18.16.1
      1 /*	$NetBSD: umidi_quirks.c,v 1.18.16.1 2014/11/30 12:18:58 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.18.16.1 2014/11/30 12:18:58 skrll 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, uint32_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