Home | History | Annotate | Line # | Download | only in usb
umidi_quirks.c revision 1.13.10.1
      1  1.13.10.1    bouyer /*	$NetBSD: umidi_quirks.c,v 1.13.10.1 2008/01/08 22:11:23 bouyer Exp $	*/
      2        1.1  tshiozak 
      3        1.1  tshiozak /*
      4        1.1  tshiozak  * Copyright (c) 2001 The NetBSD Foundation, Inc.
      5        1.1  tshiozak  * All rights reserved.
      6        1.1  tshiozak  *
      7        1.1  tshiozak  * This code is derived from software contributed to The NetBSD Foundation
      8        1.6    keihan  * by Takuya SHIOZAKI (tshiozak (at) NetBSD.org).
      9        1.1  tshiozak  *
     10        1.1  tshiozak  * Redistribution and use in source and binary forms, with or without
     11        1.1  tshiozak  * modification, are permitted provided that the following conditions
     12        1.1  tshiozak  * are met:
     13        1.1  tshiozak  * 1. Redistributions of source code must retain the above copyright
     14        1.1  tshiozak  *    notice, this list of conditions and the following disclaimer.
     15        1.1  tshiozak  * 2. Redistributions in binary form must reproduce the above copyright
     16        1.1  tshiozak  *    notice, this list of conditions and the following disclaimer in the
     17        1.1  tshiozak  *    documentation and/or other materials provided with the distribution.
     18        1.1  tshiozak  * 3. All advertising materials mentioning features or use of this software
     19        1.1  tshiozak  *    must display the following acknowledgement:
     20        1.1  tshiozak  *	  This product includes software developed by the NetBSD
     21        1.1  tshiozak  *	  Foundation, Inc. and its contributors.
     22        1.1  tshiozak  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23        1.1  tshiozak  *    contributors may be used to endorse or promote products derived
     24        1.1  tshiozak  *    from this software without specific prior written permission.
     25        1.1  tshiozak  *
     26        1.1  tshiozak  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27        1.1  tshiozak  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28        1.1  tshiozak  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29        1.1  tshiozak  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30        1.1  tshiozak  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31        1.1  tshiozak  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32        1.1  tshiozak  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33        1.1  tshiozak  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34        1.1  tshiozak  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35        1.1  tshiozak  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36        1.1  tshiozak  * POSSIBILITY OF SUCH DAMAGE.
     37        1.1  tshiozak  */
     38        1.1  tshiozak 
     39        1.3     lukem #include <sys/cdefs.h>
     40  1.13.10.1    bouyer __KERNEL_RCSID(0, "$NetBSD: umidi_quirks.c,v 1.13.10.1 2008/01/08 22:11:23 bouyer Exp $");
     41        1.1  tshiozak 
     42        1.1  tshiozak #include <sys/param.h>
     43        1.1  tshiozak #include <sys/systm.h>
     44        1.1  tshiozak #include <sys/kernel.h>
     45        1.1  tshiozak #include <sys/malloc.h>
     46        1.1  tshiozak #include <sys/device.h>
     47        1.1  tshiozak #include <sys/ioctl.h>
     48        1.1  tshiozak #include <sys/conf.h>
     49        1.1  tshiozak #include <sys/file.h>
     50        1.1  tshiozak #include <sys/select.h>
     51        1.1  tshiozak #include <sys/proc.h>
     52        1.1  tshiozak #include <sys/vnode.h>
     53        1.1  tshiozak #include <sys/poll.h>
     54        1.1  tshiozak 
     55        1.1  tshiozak #include <dev/usb/usb.h>
     56        1.1  tshiozak #include <dev/usb/usbdi.h>
     57        1.1  tshiozak #include <dev/usb/usbdi_util.h>
     58        1.1  tshiozak 
     59        1.1  tshiozak #include <dev/usb/usbdevs.h>
     60        1.1  tshiozak #include <dev/usb/uaudioreg.h>
     61        1.1  tshiozak #include <dev/usb/umidireg.h>
     62        1.1  tshiozak #include <dev/usb/umidivar.h>
     63        1.1  tshiozak #include <dev/usb/umidi_quirks.h>
     64        1.1  tshiozak 
     65        1.1  tshiozak /*
     66        1.1  tshiozak  * quirk codes for UMIDI
     67        1.1  tshiozak  */
     68        1.1  tshiozak 
     69        1.1  tshiozak #ifdef UMIDIQUIRK_DEBUG
     70        1.1  tshiozak #define DPRINTF(x)	if (umidiquirkdebug) printf x
     71        1.1  tshiozak #define DPRINTFN(n,x)	if (umidiquirkdebug >= (n)) printf x
     72        1.1  tshiozak int	umidiquirkdebug = 1;
     73        1.1  tshiozak #else
     74        1.1  tshiozak #define DPRINTF(x)
     75        1.1  tshiozak #define DPRINTFN(n,x)
     76        1.1  tshiozak #endif
     77        1.1  tshiozak 
     78        1.1  tshiozak 
     79        1.1  tshiozak /*
     80        1.1  tshiozak  * YAMAHA UX-256
     81        1.1  tshiozak  *  --- this is a typical yamaha device, but has a broken descriptor :-<
     82        1.1  tshiozak  */
     83        1.1  tshiozak 
     84        1.1  tshiozak UMQ_FIXED_EP_DEF(YAMAHA, YAMAHA_UX256, ANYIFACE, 1, 1) = {
     85        1.1  tshiozak 	/* out */
     86        1.1  tshiozak 	{ 0, 16 },
     87        1.1  tshiozak 	/* in */
     88        1.1  tshiozak 	{ 1, 8 }
     89        1.1  tshiozak };
     90        1.1  tshiozak 
     91        1.1  tshiozak UMQ_DEF(YAMAHA, YAMAHA_UX256, ANYIFACE) = {
     92        1.1  tshiozak 	UMQ_FIXED_EP_REG(YAMAHA, YAMAHA_UX256, ANYIFACE),
     93        1.1  tshiozak #if 0
     94        1.1  tshiozak 	UMQ_YAMAHA_REG(YAMAHA, ANYPRODUCT, ANYIFACE),
     95        1.1  tshiozak #endif
     96        1.1  tshiozak 	UMQ_TERMINATOR
     97        1.1  tshiozak };
     98        1.1  tshiozak 
     99        1.1  tshiozak 
    100        1.1  tshiozak /*
    101        1.1  tshiozak  * YAMAHA generic
    102        1.1  tshiozak  */
    103        1.1  tshiozak UMQ_DEF(YAMAHA, ANYPRODUCT, ANYIFACE) = {
    104        1.1  tshiozak 	UMQ_YAMAHA_REG(YAMAHA, ANYPRODUCT, ANYIFACE),
    105        1.1  tshiozak 	UMQ_TERMINATOR
    106        1.1  tshiozak };
    107        1.1  tshiozak 
    108        1.1  tshiozak 
    109        1.1  tshiozak /*
    110        1.1  tshiozak  * ROLAND UM-1
    111        1.1  tshiozak  */
    112        1.1  tshiozak UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM1, 2, 1, 1) = {
    113        1.1  tshiozak 	/* out */
    114        1.1  tshiozak 	{ 0, 1 },
    115        1.1  tshiozak 	/* in */
    116        1.1  tshiozak 	{ 1, 1 }
    117        1.1  tshiozak };
    118        1.1  tshiozak 
    119        1.1  tshiozak UMQ_DEF(ROLAND, ROLAND_UM1, 2) = {
    120        1.1  tshiozak 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM1, 2),
    121        1.1  tshiozak 	UMQ_TERMINATOR
    122        1.1  tshiozak };
    123        1.1  tshiozak 
    124        1.4  tshiozak /*
    125        1.4  tshiozak  * ROLAND SC-8850
    126        1.4  tshiozak  */
    127        1.4  tshiozak UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SC8850, 2, 1, 1) = {
    128        1.4  tshiozak 	/* out */
    129        1.4  tshiozak 	{ 0, 6 },
    130        1.4  tshiozak 	/* in */
    131        1.4  tshiozak 	{ 1, 6 }
    132        1.4  tshiozak };
    133        1.4  tshiozak 
    134        1.4  tshiozak UMQ_DEF(ROLAND, ROLAND_SC8850, 2) = {
    135        1.4  tshiozak 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_SC8850, 2),
    136        1.4  tshiozak 	UMQ_TERMINATOR
    137        1.4  tshiozak };
    138        1.4  tshiozak 
    139        1.4  tshiozak /*
    140        1.4  tshiozak  * ROLAND SD-90
    141        1.4  tshiozak  */
    142        1.4  tshiozak UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SD90, 2, 1, 1) = {
    143        1.4  tshiozak 	/* out */
    144        1.4  tshiozak 	{ 0, 4 },
    145        1.4  tshiozak 	/* in */
    146        1.4  tshiozak 	{ 1, 4 }
    147        1.4  tshiozak };
    148        1.4  tshiozak 
    149        1.4  tshiozak UMQ_DEF(ROLAND, ROLAND_SD90, 2) = {
    150        1.4  tshiozak 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_SD90, 2),
    151        1.4  tshiozak 	UMQ_TERMINATOR
    152        1.4  tshiozak };
    153        1.4  tshiozak 
    154        1.1  tshiozak 
    155        1.2  tshiozak /*
    156        1.2  tshiozak  * ROLAND UM-880 (native mode)
    157        1.2  tshiozak  */
    158        1.2  tshiozak UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM880N, 0, 1, 1) = {
    159        1.2  tshiozak 	/* out */
    160        1.2  tshiozak 	{ 0, 9 },
    161        1.2  tshiozak 	/* in */
    162        1.2  tshiozak 	{ 1, 9 }
    163        1.2  tshiozak };
    164        1.2  tshiozak 
    165        1.2  tshiozak UMQ_DEF(ROLAND, ROLAND_UM880N, 0) = {
    166        1.2  tshiozak 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM880N, 0),
    167        1.2  tshiozak 	UMQ_TERMINATOR
    168        1.2  tshiozak };
    169        1.2  tshiozak 
    170        1.5  jdolecek /*
    171        1.5  jdolecek  * ROLAND UA-100
    172        1.5  jdolecek  */
    173        1.5  jdolecek UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA100, 2, 1, 1) = {
    174        1.5  jdolecek 	/* out */
    175        1.5  jdolecek 	{ 0, 3 },
    176        1.5  jdolecek 	/* in */
    177        1.5  jdolecek 	{ 1, 3 }
    178        1.5  jdolecek };
    179        1.5  jdolecek 
    180        1.5  jdolecek UMQ_DEF(ROLAND, ROLAND_UA100, 2) = {
    181        1.5  jdolecek 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA100, 2),
    182        1.5  jdolecek 	UMQ_TERMINATOR
    183        1.5  jdolecek };
    184        1.5  jdolecek 
    185        1.5  jdolecek /*
    186        1.5  jdolecek  * ROLAND UM-4
    187        1.5  jdolecek  */
    188        1.5  jdolecek UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM4, 2, 1, 1) = {
    189        1.5  jdolecek 	/* out */
    190        1.5  jdolecek 	{ 0, 4 },
    191        1.5  jdolecek 	/* in */
    192        1.5  jdolecek 	{ 1, 4 }
    193        1.5  jdolecek };
    194        1.5  jdolecek 
    195        1.5  jdolecek UMQ_DEF(ROLAND, ROLAND_UM4, 2) = {
    196        1.5  jdolecek 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM4, 2),
    197        1.5  jdolecek 	UMQ_TERMINATOR
    198        1.5  jdolecek };
    199        1.5  jdolecek 
    200        1.5  jdolecek /*
    201        1.5  jdolecek  * ROLAND U-8
    202        1.5  jdolecek  */
    203        1.5  jdolecek UMQ_FIXED_EP_DEF(ROLAND, ROLAND_U8, 2, 1, 1) = {
    204        1.5  jdolecek 	/* out */
    205        1.5  jdolecek 	{ 0, 2 },
    206        1.5  jdolecek 	/* in */
    207        1.5  jdolecek 	{ 1, 2 }
    208        1.5  jdolecek };
    209        1.5  jdolecek 
    210        1.5  jdolecek UMQ_DEF(ROLAND, ROLAND_U8, 2) = {
    211        1.5  jdolecek 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_U8, 2),
    212        1.5  jdolecek 	UMQ_TERMINATOR
    213        1.5  jdolecek };
    214        1.5  jdolecek 
    215        1.5  jdolecek /*
    216        1.5  jdolecek  * ROLAND UM-2
    217        1.5  jdolecek  */
    218        1.5  jdolecek UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM2, 2, 1, 1) = {
    219        1.5  jdolecek 	/* out */
    220        1.5  jdolecek 	{ 0, 2 },
    221        1.5  jdolecek 	/* in */
    222        1.5  jdolecek 	{ 1, 2 }
    223        1.5  jdolecek };
    224        1.5  jdolecek 
    225        1.5  jdolecek UMQ_DEF(ROLAND, ROLAND_UM2, 2) = {
    226        1.5  jdolecek 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM2, 2),
    227        1.5  jdolecek 	UMQ_TERMINATOR
    228        1.5  jdolecek };
    229        1.5  jdolecek 
    230        1.5  jdolecek /*
    231        1.5  jdolecek  * ROLAND SC-8820
    232        1.5  jdolecek  */
    233        1.5  jdolecek UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SC8820, 2, 1, 1) = {
    234        1.5  jdolecek 	/* out */
    235        1.5  jdolecek 	{ 0, 5 }, /* cables 0, 1, 4 only */
    236        1.5  jdolecek 	/* in */
    237        1.5  jdolecek 	{ 1, 5 } /* do. */
    238        1.5  jdolecek };
    239        1.5  jdolecek 
    240        1.5  jdolecek UMQ_DEF(ROLAND, ROLAND_SC8820, 2) = {
    241        1.5  jdolecek 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_SC8820, 2),
    242        1.5  jdolecek 	UMQ_TERMINATOR
    243        1.5  jdolecek };
    244        1.5  jdolecek 
    245        1.5  jdolecek /*
    246        1.5  jdolecek  * ROLAND PC-300
    247        1.5  jdolecek  */
    248        1.5  jdolecek UMQ_FIXED_EP_DEF(ROLAND, ROLAND_PC300, 2, 1, 1) = {
    249        1.5  jdolecek 	/* out */
    250        1.5  jdolecek 	{ 0, 1 },
    251        1.5  jdolecek 	/* in */
    252        1.5  jdolecek 	{ 1, 1 }
    253        1.5  jdolecek };
    254        1.5  jdolecek 
    255        1.5  jdolecek UMQ_DEF(ROLAND, ROLAND_PC300, 2) = {
    256        1.5  jdolecek 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_PC300, 2),
    257        1.5  jdolecek 	UMQ_TERMINATOR
    258        1.5  jdolecek };
    259        1.5  jdolecek 
    260        1.5  jdolecek /*
    261        1.5  jdolecek  * ROLAND SK-500
    262        1.5  jdolecek  */
    263        1.5  jdolecek UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SK500, 2, 1, 1) = {
    264        1.5  jdolecek 	/* out */
    265        1.5  jdolecek 	{ 0, 5 }, /* cables 0, 1, 4 only */
    266        1.5  jdolecek 	/* in */
    267        1.5  jdolecek 	{ 1, 5 } /* do. */
    268        1.5  jdolecek };
    269        1.5  jdolecek 
    270        1.5  jdolecek UMQ_DEF(ROLAND, ROLAND_SK500, 2) = {
    271        1.5  jdolecek 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_SK500, 2),
    272        1.5  jdolecek 	UMQ_TERMINATOR
    273        1.5  jdolecek };
    274        1.5  jdolecek 
    275        1.5  jdolecek /*
    276        1.5  jdolecek  * ROLAND SC-D70
    277        1.5  jdolecek  */
    278        1.5  jdolecek UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SCD70, 2, 1, 1) = {
    279        1.5  jdolecek 	/* out */
    280        1.5  jdolecek 	{ 0, 3 },
    281        1.5  jdolecek 	/* in */
    282        1.5  jdolecek 	{ 1, 3 }
    283        1.5  jdolecek };
    284        1.5  jdolecek 
    285        1.5  jdolecek UMQ_DEF(ROLAND, ROLAND_SCD70, 2) = {
    286        1.5  jdolecek 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_SCD70, 2),
    287        1.5  jdolecek 	UMQ_TERMINATOR
    288        1.5  jdolecek };
    289        1.5  jdolecek 
    290        1.5  jdolecek /*
    291        1.5  jdolecek  * ROLAND XV-5050
    292        1.5  jdolecek  */
    293        1.5  jdolecek UMQ_FIXED_EP_DEF(ROLAND, ROLAND_XV5050, 0, 1, 1) = {
    294        1.5  jdolecek 	/* out */
    295        1.5  jdolecek 	{ 0, 1 },
    296        1.5  jdolecek 	/* in */
    297        1.5  jdolecek 	{ 1, 1 }
    298        1.5  jdolecek };
    299        1.5  jdolecek 
    300        1.5  jdolecek UMQ_DEF(ROLAND, ROLAND_XV5050, 0) = {
    301        1.5  jdolecek 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_XV5050, 0),
    302        1.5  jdolecek 	UMQ_TERMINATOR
    303        1.5  jdolecek };
    304        1.5  jdolecek 
    305        1.5  jdolecek /*
    306        1.5  jdolecek  * ROLAND UM-550
    307        1.5  jdolecek  */
    308        1.5  jdolecek UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM550, 0, 1, 1) = {
    309        1.5  jdolecek 	/* out */
    310        1.5  jdolecek 	{ 0, 6 },
    311        1.5  jdolecek 	/* in */
    312        1.5  jdolecek 	{ 1, 6 }
    313        1.5  jdolecek };
    314        1.5  jdolecek 
    315        1.5  jdolecek UMQ_DEF(ROLAND, ROLAND_UM550, 0) = {
    316        1.5  jdolecek 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM550, 0),
    317        1.5  jdolecek 	UMQ_TERMINATOR
    318        1.5  jdolecek };
    319        1.5  jdolecek 
    320        1.5  jdolecek /*
    321        1.5  jdolecek  * ROLAND SD-20
    322        1.5  jdolecek  */
    323        1.5  jdolecek UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SD20, 0, 1, 1) = {
    324        1.5  jdolecek 	/* out */
    325        1.5  jdolecek 	{ 0, 2 },
    326        1.5  jdolecek 	/* in */
    327        1.5  jdolecek 	{ 1, 3 }
    328        1.5  jdolecek };
    329        1.5  jdolecek 
    330        1.5  jdolecek UMQ_DEF(ROLAND, ROLAND_SD20, 0) = {
    331        1.5  jdolecek 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_SD20, 0),
    332        1.5  jdolecek 	UMQ_TERMINATOR
    333        1.5  jdolecek };
    334        1.5  jdolecek 
    335        1.5  jdolecek /*
    336        1.5  jdolecek  * ROLAND SD-80
    337        1.5  jdolecek  */
    338        1.5  jdolecek UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SD80, 0, 1, 1) = {
    339        1.5  jdolecek 	/* out */
    340        1.5  jdolecek 	{ 0, 4 },
    341        1.5  jdolecek 	/* in */
    342        1.5  jdolecek 	{ 1, 4 }
    343        1.5  jdolecek };
    344        1.5  jdolecek 
    345        1.5  jdolecek UMQ_DEF(ROLAND, ROLAND_SD80, 0) = {
    346        1.5  jdolecek 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_SD80, 0),
    347        1.5  jdolecek 	UMQ_TERMINATOR
    348        1.5  jdolecek };
    349        1.5  jdolecek 
    350        1.5  jdolecek /*
    351        1.5  jdolecek  * ROLAND UA-700
    352        1.5  jdolecek  */
    353        1.5  jdolecek UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA700, 3, 1, 1) = {
    354        1.5  jdolecek 	/* out */
    355        1.5  jdolecek 	{ 0, 2 },
    356        1.5  jdolecek 	/* in */
    357        1.5  jdolecek 	{ 1, 2 }
    358        1.5  jdolecek };
    359        1.5  jdolecek 
    360        1.5  jdolecek UMQ_DEF(ROLAND, ROLAND_UA700, 3) = {
    361        1.5  jdolecek 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA700, 3),
    362        1.5  jdolecek 	UMQ_TERMINATOR
    363        1.5  jdolecek };
    364        1.5  jdolecek 
    365        1.8  augustss /*
    366        1.8  augustss  * ROLAND UA-1000
    367        1.8  augustss  */
    368        1.8  augustss UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA1000, 3, 1, 1) = {
    369        1.8  augustss 	/* out */
    370        1.8  augustss 	{ 0, 2 },
    371        1.8  augustss 	/* in */
    372        1.8  augustss 	{ 1, 2 }
    373        1.8  augustss };
    374        1.8  augustss 
    375        1.8  augustss UMQ_DEF(ROLAND, ROLAND_UA1000, 3) = {
    376        1.8  augustss 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA1000, 3),
    377        1.8  augustss 	UMQ_TERMINATOR
    378        1.8  augustss };
    379        1.8  augustss 
    380        1.8  augustss /*
    381        1.8  augustss  * ROLAND UA-101
    382        1.8  augustss  */
    383        1.8  augustss UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA101, 2, 1, 1) = {
    384        1.8  augustss 	/* out */
    385        1.8  augustss 	{ 0, 2 },
    386        1.8  augustss 	/* in */
    387        1.8  augustss 	{ 1, 2 }
    388        1.8  augustss };
    389        1.2  tshiozak 
    390        1.8  augustss UMQ_DEF(ROLAND, ROLAND_UA101, 2) = {
    391        1.8  augustss 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA101, 2),
    392        1.8  augustss 	UMQ_TERMINATOR
    393        1.8  augustss };
    394        1.8  augustss 
    395        1.8  augustss UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA101F, 2, 1, 1) = {
    396        1.8  augustss 	/* out */
    397        1.8  augustss 	{ 0, 2 },
    398        1.8  augustss 	/* in */
    399        1.8  augustss 	{ 1, 2 }
    400        1.8  augustss };
    401        1.8  augustss 
    402        1.8  augustss UMQ_DEF(ROLAND, ROLAND_UA101F, 2) = {
    403        1.8  augustss 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA101F, 2),
    404        1.8  augustss 	UMQ_TERMINATOR
    405        1.8  augustss };
    406        1.8  augustss 
    407        1.8  augustss /*
    408        1.8  augustss  * ROLAND Fantom-X
    409        1.8  augustss  */
    410        1.8  augustss UMQ_FIXED_EP_DEF(ROLAND, ROLAND_FANTOMX, 0, 1, 1) = {
    411        1.8  augustss 	/* out */
    412        1.8  augustss 	{ 0, 1 },
    413        1.8  augustss 	/* in */
    414        1.8  augustss 	{ 1, 1 }
    415        1.8  augustss };
    416        1.8  augustss 
    417        1.8  augustss UMQ_DEF(ROLAND, ROLAND_FANTOMX, 0) = {
    418        1.8  augustss 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_FANTOMX, 0),
    419        1.8  augustss 	UMQ_TERMINATOR
    420        1.8  augustss };
    421        1.8  augustss 
    422        1.8  augustss /*
    423        1.8  augustss  * ROLAND PCR
    424        1.8  augustss  */
    425        1.8  augustss UMQ_FIXED_EP_DEF(ROLAND, ROLAND_PCR, 0, 1, 1) = {
    426        1.8  augustss 	/* out */
    427        1.8  augustss 	{ 0, 3 },
    428        1.8  augustss 	/* in */
    429        1.8  augustss 	{ 1, 3 }
    430        1.8  augustss };
    431        1.8  augustss 
    432        1.8  augustss UMQ_DEF(ROLAND, ROLAND_PCR, 0) = {
    433        1.8  augustss 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_PCR, 0),
    434        1.8  augustss 	UMQ_TERMINATOR
    435        1.8  augustss };
    436        1.1  tshiozak 
    437        1.1  tshiozak /*
    438       1.10  christos  * ROLAND UM-3EX
    439       1.10  christos  */
    440       1.10  christos UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM3, 0, 1, 1) = {
    441       1.10  christos 	/* out */
    442       1.10  christos 	{ 0, 3 },
    443       1.10  christos 	/* in */
    444       1.10  christos 	{ 1, 3 }
    445       1.10  christos };
    446       1.10  christos 
    447       1.10  christos UMQ_DEF(ROLAND, ROLAND_UM3, 0) = {
    448       1.10  christos 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM3, 0),
    449       1.10  christos 	UMQ_TERMINATOR
    450       1.10  christos };
    451       1.10  christos 
    452       1.10  christos /*
    453       1.13   xtraeme  * ROLAND UA-25
    454       1.13   xtraeme  */
    455       1.13   xtraeme UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA25, 2, 1, 1) = {
    456       1.13   xtraeme 	/* out */
    457       1.13   xtraeme 	{ 0, 1 },
    458       1.13   xtraeme 	/* in */
    459       1.13   xtraeme 	{ 1, 1 }
    460       1.13   xtraeme };
    461       1.13   xtraeme 
    462       1.13   xtraeme UMQ_DEF(ROLAND, ROLAND_UA25, 2) = {
    463       1.13   xtraeme 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA25, 2),
    464       1.13   xtraeme 	UMQ_TERMINATOR
    465       1.13   xtraeme };
    466       1.13   xtraeme 
    467       1.13   xtraeme /*
    468       1.13   xtraeme  * ROLAND UA-4FX
    469       1.13   xtraeme  */
    470       1.13   xtraeme UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA4FX, 2, 1, 1) = {
    471       1.13   xtraeme 	/* out */
    472       1.13   xtraeme 	{ 0, 1 },
    473       1.13   xtraeme 	/* in */
    474       1.13   xtraeme 	{ 1, 1 }
    475       1.13   xtraeme };
    476       1.13   xtraeme 
    477       1.13   xtraeme UMQ_DEF(ROLAND, ROLAND_UA4FX, 2) = {
    478       1.13   xtraeme 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA4FX, 2),
    479       1.13   xtraeme 	UMQ_TERMINATOR
    480       1.13   xtraeme };
    481       1.13   xtraeme 
    482       1.13   xtraeme /*
    483       1.13   xtraeme  * ROLAND SonicCell
    484       1.13   xtraeme  */
    485       1.13   xtraeme UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SONICCELL, 2, 1, 1) = {
    486       1.13   xtraeme 	/* out */
    487       1.13   xtraeme 	{ 0, 1 },
    488       1.13   xtraeme 	/* in */
    489       1.13   xtraeme 	{ 1, 1 }
    490       1.13   xtraeme };
    491       1.13   xtraeme 
    492       1.13   xtraeme UMQ_DEF(ROLAND, ROLAND_SONICCELL, 2) = {
    493       1.13   xtraeme 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_SONICCELL, 2),
    494       1.13   xtraeme 	UMQ_TERMINATOR
    495       1.13   xtraeme };
    496       1.13   xtraeme 
    497       1.13   xtraeme /*
    498       1.11      chap  * Midiman Midisport 2x4. This has 2 physical MIDI IN jacks that are read
    499       1.11      chap  * on endpoint 0x81 (descriptor index 0). It has 4 physical MIDI OUT jacks
    500       1.11      chap  * that can be written on endpoints 2 or 4 (at descriptor index 2 or 4,
    501       1.11      chap  * coincidentally) interchangeably: either endpoint will accept a Cable Number
    502       1.11      chap  * field of 0 to 3, and data for a given CN will be routed to the same
    503       1.11      chap  * physical output regardless of the endpoint used for the transfer. But
    504       1.11      chap  * there's a catch: flow-control feedback only goes to endpoint 2 for
    505       1.11      chap  * CN 0 and 2, and only to endpoint 4 for CN 1 and 3. If you send output at
    506       1.11      chap  * high rates for CN 0 or 2 over endpoint 4, or for CN 1 or 3 over endpoint 2,
    507       1.11      chap  * the USB transfers complete as fast as possible, giving you an apparent data
    508       1.11      chap  * rate much higher than MIDI's 3125 cps (easy to measure using dd to blast a
    509       1.11      chap  * bunch of midi data to the rmidi device). Of course that isn't a way to make
    510       1.11      chap  * MIDI faster, just a way to overrun the device buffer and spray bits on the
    511       1.11      chap  * floor. So this device needs the fixed endpoint quirk, the fixed cable number
    512       1.11      chap  * quirk (to make sure CNs 0 and 2 are put on the first endpoint and 1 and 3
    513       1.11      chap  * on the other), and then the fixed mididev-assignment quirk (to match jacks
    514       1.11      chap  * to mididevs so the rmidi devices match the order of the blinkenlights).
    515       1.11      chap  */
    516       1.11      chap UMQ_FIXED_EP_DEF(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE, 2, 1) = {
    517       1.11      chap 	/* out: ep# jacks */
    518       1.11      chap 	{ 2, 2 },
    519       1.11      chap 	{ 4, 2 },
    520       1.11      chap 	/* in: ep# jacks */
    521       1.11      chap 	{ 0, 2 }
    522       1.11      chap };
    523       1.11      chap UMQ_DEF(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE) = {
    524       1.11      chap 	UMQ_FIXED_EP_REG(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE),
    525       1.11      chap 	UMQ_CN_FIXED_REG(0, 2, 1, 3, 0, 1),
    526       1.11      chap 	UMQ_MD_FIXED_REG(0, 0, 2, 1, 1, -1, 3, -1),
    527       1.11      chap 	UMQ_TYPE(MIDIMAN_GARBLE),
    528       1.11      chap 	UMQ_TERMINATOR
    529       1.11      chap };
    530       1.11      chap 
    531       1.11      chap /*
    532        1.1  tshiozak  * quirk list
    533        1.1  tshiozak  */
    534        1.1  tshiozak struct umidi_quirk umidi_quirklist[] = {
    535        1.1  tshiozak 	UMQ_REG(YAMAHA, YAMAHA_UX256, ANYIFACE),
    536        1.1  tshiozak 	UMQ_REG(YAMAHA, ANYPRODUCT, ANYIFACE),
    537        1.1  tshiozak 	UMQ_REG(ROLAND, ROLAND_UM1, 2),
    538        1.4  tshiozak 	UMQ_REG(ROLAND, ROLAND_SC8850, 2),
    539        1.4  tshiozak 	UMQ_REG(ROLAND, ROLAND_SD90, 2),
    540        1.2  tshiozak 	UMQ_REG(ROLAND, ROLAND_UM880N, 0),
    541        1.5  jdolecek 	UMQ_REG(ROLAND, ROLAND_UA100, 2),
    542        1.5  jdolecek 	UMQ_REG(ROLAND, ROLAND_UM4, 2),
    543        1.5  jdolecek 	UMQ_REG(ROLAND, ROLAND_U8, 2),
    544        1.5  jdolecek 	UMQ_REG(ROLAND, ROLAND_UM2, 2),
    545        1.5  jdolecek 	UMQ_REG(ROLAND, ROLAND_SC8820, 2),
    546        1.5  jdolecek 	UMQ_REG(ROLAND, ROLAND_PC300, 2),
    547        1.5  jdolecek 	UMQ_REG(ROLAND, ROLAND_SK500, 2),
    548        1.5  jdolecek 	UMQ_REG(ROLAND, ROLAND_SCD70, 2),
    549        1.5  jdolecek 	UMQ_REG(ROLAND, ROLAND_XV5050, 0),
    550        1.5  jdolecek 	UMQ_REG(ROLAND, ROLAND_UM550, 0),
    551        1.5  jdolecek 	UMQ_REG(ROLAND, ROLAND_SD20, 0),
    552        1.5  jdolecek 	UMQ_REG(ROLAND, ROLAND_SD80, 0),
    553        1.5  jdolecek 	UMQ_REG(ROLAND, ROLAND_UA700, 3),
    554        1.8  augustss 	UMQ_REG(ROLAND, ROLAND_UA1000, 3),
    555        1.8  augustss 	UMQ_REG(ROLAND, ROLAND_UA101, 2),
    556        1.8  augustss 	UMQ_REG(ROLAND, ROLAND_UA101F, 2),
    557        1.8  augustss 	UMQ_REG(ROLAND, ROLAND_FANTOMX, 0),
    558        1.8  augustss 	UMQ_REG(ROLAND, ROLAND_PCR, 0),
    559       1.10  christos 	UMQ_REG(ROLAND, ROLAND_UM3, 0),
    560       1.13   xtraeme 	UMQ_REG(ROLAND, ROLAND_UA25, 2),
    561       1.13   xtraeme 	UMQ_REG(ROLAND, ROLAND_UA4FX, 2),
    562       1.13   xtraeme 	UMQ_REG(ROLAND, ROLAND_SONICCELL, 2),
    563       1.11      chap 	UMQ_REG(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE),
    564       1.12  christos 	{ .vendor = 0 },
    565        1.1  tshiozak };
    566        1.1  tshiozak 
    567        1.1  tshiozak 
    568        1.1  tshiozak /*
    569        1.1  tshiozak  * quirk utilities
    570        1.1  tshiozak  */
    571        1.1  tshiozak 
    572        1.1  tshiozak struct umidi_quirk *
    573        1.1  tshiozak umidi_search_quirk(int vendor, int product, int ifaceno)
    574        1.1  tshiozak {
    575        1.1  tshiozak 	struct umidi_quirk *p;
    576        1.1  tshiozak 	struct umq_data *q;
    577        1.1  tshiozak 
    578        1.1  tshiozak 	DPRINTF(("umidi_search_quirk: v=%d, p=%d, i=%d\n",
    579        1.1  tshiozak 		 vendor, product, ifaceno));
    580        1.1  tshiozak 
    581        1.1  tshiozak 	for (p=&umidi_quirklist[0]; p->vendor; p++) {
    582        1.1  tshiozak 		DPRINTFN(10, ("\tv=%d, p=%d, i=%d",
    583        1.1  tshiozak 			      p->vendor, p->product, p->iface));
    584        1.1  tshiozak 		if ((p->vendor==vendor || p->vendor==ANYVENDOR) &&
    585        1.1  tshiozak 		    (p->product==product || p->product==ANYPRODUCT) &&
    586        1.1  tshiozak 		    (p->iface==ifaceno || p->iface==ANYIFACE)) {
    587        1.1  tshiozak 			DPRINTFN(10, (" found\n"));
    588        1.1  tshiozak 			if (!p->type_mask)
    589        1.1  tshiozak 				/* make quirk mask */
    590        1.1  tshiozak 				for (q=p->quirks; q->type; q++)
    591        1.1  tshiozak 					p->type_mask |= 1<<(q->type-1);
    592        1.1  tshiozak 			return p;
    593        1.8  augustss 		}
    594        1.1  tshiozak 		DPRINTFN(10, ("\n"));
    595        1.1  tshiozak 	}
    596        1.1  tshiozak 
    597        1.1  tshiozak 	return NULL;
    598        1.1  tshiozak }
    599        1.1  tshiozak 
    600        1.7  christos static const char *quirk_name[] = {
    601        1.1  tshiozak 	"NULL",
    602        1.1  tshiozak 	"Fixed Endpoint",
    603        1.1  tshiozak 	"Yamaha Specific",
    604       1.11      chap 	"Midiman Packet Garbling",
    605       1.11      chap 	"Cable Numbers per Endpoint",
    606       1.11      chap 	"Cable Numbers Global",
    607       1.11      chap 	"Cable Numbers Fixed",
    608       1.11      chap 	"Unit Mapping Fixed",
    609        1.1  tshiozak };
    610        1.1  tshiozak 
    611        1.1  tshiozak void
    612        1.1  tshiozak umidi_print_quirk(struct umidi_quirk *q)
    613        1.1  tshiozak {
    614        1.1  tshiozak 	struct umq_data *qd;
    615        1.1  tshiozak 	if (q) {
    616        1.1  tshiozak 		printf("(");
    617        1.1  tshiozak 		for (qd=q->quirks; qd->type; qd++)
    618        1.1  tshiozak 			printf("%s%s", quirk_name[qd->type],
    619        1.1  tshiozak 			       (qd+1)->type?", ":")\n");
    620        1.1  tshiozak 	} else {
    621        1.1  tshiozak 		printf("(genuine USB-MIDI)\n");
    622        1.1  tshiozak 	}
    623        1.1  tshiozak }
    624        1.1  tshiozak 
    625        1.1  tshiozak void *
    626        1.1  tshiozak umidi_get_quirk_data_from_type(struct umidi_quirk *q, u_int32_t type)
    627        1.1  tshiozak {
    628        1.1  tshiozak 	struct umq_data *qd;
    629        1.1  tshiozak 	if (q) {
    630        1.1  tshiozak 		for (qd=q->quirks; qd->type; qd++)
    631        1.1  tshiozak 			if (qd->type == type)
    632        1.1  tshiozak 				return qd->data;
    633        1.1  tshiozak 	}
    634        1.1  tshiozak 	return NULL;
    635        1.1  tshiozak }
    636