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