Home | History | Annotate | Line # | Download | only in usb
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