Home | History | Annotate | Line # | Download | only in usb
umidi_quirks.c revision 1.16
      1  1.16  gmcgarry /*	$NetBSD: umidi_quirks.c,v 1.16 2008/07/08 11:34:43 gmcgarry 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.16  gmcgarry __KERNEL_RCSID(0, "$NetBSD: umidi_quirks.c,v 1.16 2008/07/08 11:34:43 gmcgarry 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.16  gmcgarry UMQ_FIXED_EP_DATA_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.16  gmcgarry UMQ_FIXED_EP_DEF(YAMAHA, YAMAHA_UX256, ANYIFACE, 1, 1);
     84   1.1  tshiozak 
     85   1.1  tshiozak UMQ_DEF(YAMAHA, YAMAHA_UX256, ANYIFACE) = {
     86   1.1  tshiozak 	UMQ_FIXED_EP_REG(YAMAHA, YAMAHA_UX256, ANYIFACE),
     87   1.1  tshiozak #if 0
     88   1.1  tshiozak 	UMQ_YAMAHA_REG(YAMAHA, ANYPRODUCT, ANYIFACE),
     89   1.1  tshiozak #endif
     90   1.1  tshiozak 	UMQ_TERMINATOR
     91   1.1  tshiozak };
     92   1.1  tshiozak 
     93   1.1  tshiozak 
     94   1.1  tshiozak /*
     95   1.1  tshiozak  * YAMAHA generic
     96   1.1  tshiozak  */
     97   1.1  tshiozak UMQ_DEF(YAMAHA, ANYPRODUCT, ANYIFACE) = {
     98   1.1  tshiozak 	UMQ_YAMAHA_REG(YAMAHA, ANYPRODUCT, ANYIFACE),
     99   1.1  tshiozak 	UMQ_TERMINATOR
    100   1.1  tshiozak };
    101   1.1  tshiozak 
    102   1.1  tshiozak 
    103   1.1  tshiozak /*
    104   1.1  tshiozak  * ROLAND UM-1
    105   1.1  tshiozak  */
    106  1.16  gmcgarry UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UM1, 2, 1, 1) = {
    107   1.1  tshiozak 	/* out */
    108   1.1  tshiozak 	{ 0, 1 },
    109   1.1  tshiozak 	/* in */
    110   1.1  tshiozak 	{ 1, 1 }
    111   1.1  tshiozak };
    112  1.16  gmcgarry UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM1, 2, 1, 1);
    113   1.1  tshiozak 
    114   1.1  tshiozak UMQ_DEF(ROLAND, ROLAND_UM1, 2) = {
    115   1.1  tshiozak 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM1, 2),
    116   1.1  tshiozak 	UMQ_TERMINATOR
    117   1.1  tshiozak };
    118   1.1  tshiozak 
    119   1.4  tshiozak /*
    120   1.4  tshiozak  * ROLAND SC-8850
    121   1.4  tshiozak  */
    122  1.16  gmcgarry UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SC8850, 2, 1, 1) = {
    123   1.4  tshiozak 	/* out */
    124   1.4  tshiozak 	{ 0, 6 },
    125   1.4  tshiozak 	/* in */
    126   1.4  tshiozak 	{ 1, 6 }
    127   1.4  tshiozak };
    128  1.16  gmcgarry UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SC8850, 2, 1, 1);
    129   1.4  tshiozak 
    130   1.4  tshiozak UMQ_DEF(ROLAND, ROLAND_SC8850, 2) = {
    131   1.4  tshiozak 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_SC8850, 2),
    132   1.4  tshiozak 	UMQ_TERMINATOR
    133   1.4  tshiozak };
    134   1.4  tshiozak 
    135   1.4  tshiozak /*
    136   1.4  tshiozak  * ROLAND SD-90
    137   1.4  tshiozak  */
    138  1.16  gmcgarry UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SD90, 2, 1, 1) = {
    139   1.4  tshiozak 	/* out */
    140   1.4  tshiozak 	{ 0, 4 },
    141   1.4  tshiozak 	/* in */
    142   1.4  tshiozak 	{ 1, 4 }
    143   1.4  tshiozak };
    144  1.16  gmcgarry UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SD90, 2, 1, 1);
    145   1.4  tshiozak 
    146   1.4  tshiozak UMQ_DEF(ROLAND, ROLAND_SD90, 2) = {
    147   1.4  tshiozak 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_SD90, 2),
    148   1.4  tshiozak 	UMQ_TERMINATOR
    149   1.4  tshiozak };
    150   1.4  tshiozak 
    151   1.1  tshiozak 
    152   1.2  tshiozak /*
    153   1.2  tshiozak  * ROLAND UM-880 (native mode)
    154   1.2  tshiozak  */
    155  1.16  gmcgarry UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UM880N, 0, 1, 1) = {
    156   1.2  tshiozak 	/* out */
    157   1.2  tshiozak 	{ 0, 9 },
    158   1.2  tshiozak 	/* in */
    159   1.2  tshiozak 	{ 1, 9 }
    160   1.2  tshiozak };
    161  1.16  gmcgarry UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM880N, 0, 1, 1);
    162   1.2  tshiozak 
    163   1.2  tshiozak UMQ_DEF(ROLAND, ROLAND_UM880N, 0) = {
    164   1.2  tshiozak 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM880N, 0),
    165   1.2  tshiozak 	UMQ_TERMINATOR
    166   1.2  tshiozak };
    167   1.2  tshiozak 
    168   1.5  jdolecek /*
    169   1.5  jdolecek  * ROLAND UA-100
    170   1.5  jdolecek  */
    171  1.16  gmcgarry UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA100, 2, 1, 1) = {
    172   1.5  jdolecek 	/* out */
    173   1.5  jdolecek 	{ 0, 3 },
    174   1.5  jdolecek 	/* in */
    175   1.5  jdolecek 	{ 1, 3 }
    176   1.5  jdolecek };
    177  1.16  gmcgarry UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA100, 2, 1, 1);
    178   1.5  jdolecek 
    179   1.5  jdolecek UMQ_DEF(ROLAND, ROLAND_UA100, 2) = {
    180   1.5  jdolecek 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA100, 2),
    181   1.5  jdolecek 	UMQ_TERMINATOR
    182   1.5  jdolecek };
    183   1.5  jdolecek 
    184   1.5  jdolecek /*
    185   1.5  jdolecek  * ROLAND UM-4
    186   1.5  jdolecek  */
    187  1.16  gmcgarry UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UM4, 2, 1, 1) = {
    188   1.5  jdolecek 	/* out */
    189   1.5  jdolecek 	{ 0, 4 },
    190   1.5  jdolecek 	/* in */
    191   1.5  jdolecek 	{ 1, 4 }
    192   1.5  jdolecek };
    193  1.16  gmcgarry UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM4, 2, 1, 1);
    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.16  gmcgarry UMQ_FIXED_EP_DATA_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.16  gmcgarry UMQ_FIXED_EP_DEF(ROLAND, ROLAND_U8, 2, 1, 1);
    210   1.5  jdolecek 
    211   1.5  jdolecek UMQ_DEF(ROLAND, ROLAND_U8, 2) = {
    212   1.5  jdolecek 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_U8, 2),
    213   1.5  jdolecek 	UMQ_TERMINATOR
    214   1.5  jdolecek };
    215   1.5  jdolecek 
    216   1.5  jdolecek /*
    217   1.5  jdolecek  * ROLAND UM-2
    218   1.5  jdolecek  */
    219  1.16  gmcgarry UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UM2, 2, 1, 1) = {
    220   1.5  jdolecek 	/* out */
    221   1.5  jdolecek 	{ 0, 2 },
    222   1.5  jdolecek 	/* in */
    223   1.5  jdolecek 	{ 1, 2 }
    224   1.5  jdolecek };
    225  1.16  gmcgarry UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM2, 2, 1, 1);
    226   1.5  jdolecek 
    227   1.5  jdolecek UMQ_DEF(ROLAND, ROLAND_UM2, 2) = {
    228   1.5  jdolecek 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM2, 2),
    229   1.5  jdolecek 	UMQ_TERMINATOR
    230   1.5  jdolecek };
    231   1.5  jdolecek 
    232   1.5  jdolecek /*
    233   1.5  jdolecek  * ROLAND SC-8820
    234   1.5  jdolecek  */
    235  1.16  gmcgarry UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SC8820, 2, 1, 1) = {
    236   1.5  jdolecek 	/* out */
    237   1.5  jdolecek 	{ 0, 5 }, /* cables 0, 1, 4 only */
    238   1.5  jdolecek 	/* in */
    239   1.5  jdolecek 	{ 1, 5 } /* do. */
    240   1.5  jdolecek };
    241  1.16  gmcgarry UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SC8820, 2, 1, 1);
    242   1.5  jdolecek 
    243   1.5  jdolecek UMQ_DEF(ROLAND, ROLAND_SC8820, 2) = {
    244   1.5  jdolecek 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_SC8820, 2),
    245   1.5  jdolecek 	UMQ_TERMINATOR
    246   1.5  jdolecek };
    247   1.5  jdolecek 
    248   1.5  jdolecek /*
    249   1.5  jdolecek  * ROLAND PC-300
    250   1.5  jdolecek  */
    251  1.16  gmcgarry UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_PC300, 2, 1, 1) = {
    252   1.5  jdolecek 	/* out */
    253   1.5  jdolecek 	{ 0, 1 },
    254   1.5  jdolecek 	/* in */
    255   1.5  jdolecek 	{ 1, 1 }
    256   1.5  jdolecek };
    257  1.16  gmcgarry UMQ_FIXED_EP_DEF(ROLAND, ROLAND_PC300, 2, 1, 1);
    258   1.5  jdolecek 
    259   1.5  jdolecek UMQ_DEF(ROLAND, ROLAND_PC300, 2) = {
    260   1.5  jdolecek 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_PC300, 2),
    261   1.5  jdolecek 	UMQ_TERMINATOR
    262   1.5  jdolecek };
    263   1.5  jdolecek 
    264   1.5  jdolecek /*
    265   1.5  jdolecek  * ROLAND SK-500
    266   1.5  jdolecek  */
    267  1.16  gmcgarry UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SK500, 2, 1, 1) = {
    268   1.5  jdolecek 	/* out */
    269   1.5  jdolecek 	{ 0, 5 }, /* cables 0, 1, 4 only */
    270   1.5  jdolecek 	/* in */
    271   1.5  jdolecek 	{ 1, 5 } /* do. */
    272   1.5  jdolecek };
    273  1.16  gmcgarry UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SK500, 2, 1, 1);
    274   1.5  jdolecek 
    275   1.5  jdolecek UMQ_DEF(ROLAND, ROLAND_SK500, 2) = {
    276   1.5  jdolecek 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_SK500, 2),
    277   1.5  jdolecek 	UMQ_TERMINATOR
    278   1.5  jdolecek };
    279   1.5  jdolecek 
    280   1.5  jdolecek /*
    281   1.5  jdolecek  * ROLAND SC-D70
    282   1.5  jdolecek  */
    283  1.16  gmcgarry UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SCD70, 2, 1, 1) = {
    284   1.5  jdolecek 	/* out */
    285   1.5  jdolecek 	{ 0, 3 },
    286   1.5  jdolecek 	/* in */
    287   1.5  jdolecek 	{ 1, 3 }
    288   1.5  jdolecek };
    289  1.16  gmcgarry UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SCD70, 2, 1, 1);
    290   1.5  jdolecek 
    291   1.5  jdolecek UMQ_DEF(ROLAND, ROLAND_SCD70, 2) = {
    292   1.5  jdolecek 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_SCD70, 2),
    293   1.5  jdolecek 	UMQ_TERMINATOR
    294   1.5  jdolecek };
    295   1.5  jdolecek 
    296   1.5  jdolecek /*
    297   1.5  jdolecek  * ROLAND XV-5050
    298   1.5  jdolecek  */
    299  1.16  gmcgarry UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_XV5050, 0, 1, 1) = {
    300   1.5  jdolecek 	/* out */
    301   1.5  jdolecek 	{ 0, 1 },
    302   1.5  jdolecek 	/* in */
    303   1.5  jdolecek 	{ 1, 1 }
    304   1.5  jdolecek };
    305  1.16  gmcgarry UMQ_FIXED_EP_DEF(ROLAND, ROLAND_XV5050, 0, 1, 1);
    306   1.5  jdolecek 
    307   1.5  jdolecek UMQ_DEF(ROLAND, ROLAND_XV5050, 0) = {
    308   1.5  jdolecek 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_XV5050, 0),
    309   1.5  jdolecek 	UMQ_TERMINATOR
    310   1.5  jdolecek };
    311   1.5  jdolecek 
    312   1.5  jdolecek /*
    313   1.5  jdolecek  * ROLAND UM-550
    314   1.5  jdolecek  */
    315  1.16  gmcgarry UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UM550, 0, 1, 1) = {
    316   1.5  jdolecek 	/* out */
    317   1.5  jdolecek 	{ 0, 6 },
    318   1.5  jdolecek 	/* in */
    319   1.5  jdolecek 	{ 1, 6 }
    320   1.5  jdolecek };
    321  1.16  gmcgarry UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM550, 0, 1, 1);
    322   1.5  jdolecek 
    323   1.5  jdolecek UMQ_DEF(ROLAND, ROLAND_UM550, 0) = {
    324   1.5  jdolecek 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM550, 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-20
    330   1.5  jdolecek  */
    331  1.16  gmcgarry UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SD20, 0, 1, 1) = {
    332   1.5  jdolecek 	/* out */
    333   1.5  jdolecek 	{ 0, 2 },
    334   1.5  jdolecek 	/* in */
    335   1.5  jdolecek 	{ 1, 3 }
    336   1.5  jdolecek };
    337  1.16  gmcgarry UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SD20, 0, 1, 1);
    338   1.5  jdolecek 
    339   1.5  jdolecek UMQ_DEF(ROLAND, ROLAND_SD20, 0) = {
    340   1.5  jdolecek 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_SD20, 0),
    341   1.5  jdolecek 	UMQ_TERMINATOR
    342   1.5  jdolecek };
    343   1.5  jdolecek 
    344   1.5  jdolecek /*
    345   1.5  jdolecek  * ROLAND SD-80
    346   1.5  jdolecek  */
    347  1.16  gmcgarry UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SD80, 0, 1, 1) = {
    348   1.5  jdolecek 	/* out */
    349   1.5  jdolecek 	{ 0, 4 },
    350   1.5  jdolecek 	/* in */
    351   1.5  jdolecek 	{ 1, 4 }
    352   1.5  jdolecek };
    353  1.16  gmcgarry UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SD80, 0, 1, 1);
    354   1.5  jdolecek 
    355   1.5  jdolecek UMQ_DEF(ROLAND, ROLAND_SD80, 0) = {
    356   1.5  jdolecek 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_SD80, 0),
    357   1.5  jdolecek 	UMQ_TERMINATOR
    358   1.5  jdolecek };
    359   1.5  jdolecek 
    360   1.5  jdolecek /*
    361   1.5  jdolecek  * ROLAND UA-700
    362   1.5  jdolecek  */
    363  1.16  gmcgarry UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA700, 3, 1, 1) = {
    364   1.5  jdolecek 	/* out */
    365   1.5  jdolecek 	{ 0, 2 },
    366   1.5  jdolecek 	/* in */
    367   1.5  jdolecek 	{ 1, 2 }
    368   1.5  jdolecek };
    369  1.16  gmcgarry UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA700, 3, 1, 1);
    370   1.5  jdolecek 
    371   1.5  jdolecek UMQ_DEF(ROLAND, ROLAND_UA700, 3) = {
    372   1.5  jdolecek 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA700, 3),
    373   1.5  jdolecek 	UMQ_TERMINATOR
    374   1.5  jdolecek };
    375   1.5  jdolecek 
    376   1.8  augustss /*
    377   1.8  augustss  * ROLAND UA-1000
    378   1.8  augustss  */
    379  1.16  gmcgarry UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA1000, 3, 1, 1) = {
    380   1.8  augustss 	/* out */
    381   1.8  augustss 	{ 0, 2 },
    382   1.8  augustss 	/* in */
    383   1.8  augustss 	{ 1, 2 }
    384   1.8  augustss };
    385  1.16  gmcgarry UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA1000, 3, 1, 1);
    386   1.8  augustss 
    387   1.8  augustss UMQ_DEF(ROLAND, ROLAND_UA1000, 3) = {
    388   1.8  augustss 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA1000, 3),
    389   1.8  augustss 	UMQ_TERMINATOR
    390   1.8  augustss };
    391   1.8  augustss 
    392   1.8  augustss /*
    393   1.8  augustss  * ROLAND UA-101
    394   1.8  augustss  */
    395  1.16  gmcgarry UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA101, 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.16  gmcgarry UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA101, 2, 1, 1);
    402   1.2  tshiozak 
    403   1.8  augustss UMQ_DEF(ROLAND, ROLAND_UA101, 2) = {
    404   1.8  augustss 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA101, 2),
    405   1.8  augustss 	UMQ_TERMINATOR
    406   1.8  augustss };
    407   1.8  augustss 
    408  1.16  gmcgarry UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA101F, 2, 1, 1) = {
    409   1.8  augustss 	/* out */
    410   1.8  augustss 	{ 0, 2 },
    411   1.8  augustss 	/* in */
    412   1.8  augustss 	{ 1, 2 }
    413   1.8  augustss };
    414  1.16  gmcgarry UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA101F, 2, 1, 1);
    415   1.8  augustss 
    416   1.8  augustss UMQ_DEF(ROLAND, ROLAND_UA101F, 2) = {
    417   1.8  augustss 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA101F, 2),
    418   1.8  augustss 	UMQ_TERMINATOR
    419   1.8  augustss };
    420   1.8  augustss 
    421   1.8  augustss /*
    422   1.8  augustss  * ROLAND Fantom-X
    423   1.8  augustss  */
    424  1.16  gmcgarry UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_FANTOMX, 0, 1, 1) = {
    425   1.8  augustss 	/* out */
    426   1.8  augustss 	{ 0, 1 },
    427   1.8  augustss 	/* in */
    428   1.8  augustss 	{ 1, 1 }
    429   1.8  augustss };
    430  1.16  gmcgarry UMQ_FIXED_EP_DEF(ROLAND, ROLAND_FANTOMX, 0, 1, 1);
    431   1.8  augustss 
    432   1.8  augustss UMQ_DEF(ROLAND, ROLAND_FANTOMX, 0) = {
    433   1.8  augustss 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_FANTOMX, 0),
    434   1.8  augustss 	UMQ_TERMINATOR
    435   1.8  augustss };
    436   1.8  augustss 
    437   1.8  augustss /*
    438   1.8  augustss  * ROLAND PCR
    439   1.8  augustss  */
    440  1.16  gmcgarry UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_PCR, 0, 1, 1) = {
    441   1.8  augustss 	/* out */
    442   1.8  augustss 	{ 0, 3 },
    443   1.8  augustss 	/* in */
    444   1.8  augustss 	{ 1, 3 }
    445   1.8  augustss };
    446  1.16  gmcgarry UMQ_FIXED_EP_DEF(ROLAND, ROLAND_PCR, 0, 1, 1);
    447   1.8  augustss 
    448   1.8  augustss UMQ_DEF(ROLAND, ROLAND_PCR, 0) = {
    449   1.8  augustss 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_PCR, 0),
    450   1.8  augustss 	UMQ_TERMINATOR
    451   1.8  augustss };
    452   1.1  tshiozak 
    453   1.1  tshiozak /*
    454  1.10  christos  * ROLAND UM-3EX
    455  1.10  christos  */
    456  1.16  gmcgarry UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UM3, 0, 1, 1) = {
    457  1.10  christos 	/* out */
    458  1.10  christos 	{ 0, 3 },
    459  1.10  christos 	/* in */
    460  1.10  christos 	{ 1, 3 }
    461  1.10  christos };
    462  1.16  gmcgarry UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM3, 0, 1, 1);
    463  1.10  christos 
    464  1.10  christos UMQ_DEF(ROLAND, ROLAND_UM3, 0) = {
    465  1.10  christos 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM3, 0),
    466  1.10  christos 	UMQ_TERMINATOR
    467  1.10  christos };
    468  1.10  christos 
    469  1.10  christos /*
    470  1.13   xtraeme  * ROLAND UA-25
    471  1.13   xtraeme  */
    472  1.16  gmcgarry UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA25, 2, 1, 1) = {
    473  1.13   xtraeme 	/* out */
    474  1.13   xtraeme 	{ 0, 1 },
    475  1.13   xtraeme 	/* in */
    476  1.13   xtraeme 	{ 1, 1 }
    477  1.13   xtraeme };
    478  1.16  gmcgarry UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA25, 2, 1, 1);
    479  1.13   xtraeme 
    480  1.13   xtraeme UMQ_DEF(ROLAND, ROLAND_UA25, 2) = {
    481  1.13   xtraeme 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA25, 2),
    482  1.13   xtraeme 	UMQ_TERMINATOR
    483  1.13   xtraeme };
    484  1.13   xtraeme 
    485  1.13   xtraeme /*
    486  1.13   xtraeme  * ROLAND UA-4FX
    487  1.13   xtraeme  */
    488  1.16  gmcgarry UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA4FX, 2, 1, 1) = {
    489  1.13   xtraeme 	/* out */
    490  1.13   xtraeme 	{ 0, 1 },
    491  1.13   xtraeme 	/* in */
    492  1.13   xtraeme 	{ 1, 1 }
    493  1.13   xtraeme };
    494  1.16  gmcgarry UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA4FX, 2, 1, 1);
    495  1.13   xtraeme 
    496  1.13   xtraeme UMQ_DEF(ROLAND, ROLAND_UA4FX, 2) = {
    497  1.13   xtraeme 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA4FX, 2),
    498  1.13   xtraeme 	UMQ_TERMINATOR
    499  1.13   xtraeme };
    500  1.13   xtraeme 
    501  1.13   xtraeme /*
    502  1.13   xtraeme  * ROLAND SonicCell
    503  1.13   xtraeme  */
    504  1.16  gmcgarry UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SONICCELL, 2, 1, 1) = {
    505  1.13   xtraeme 	/* out */
    506  1.13   xtraeme 	{ 0, 1 },
    507  1.13   xtraeme 	/* in */
    508  1.13   xtraeme 	{ 1, 1 }
    509  1.13   xtraeme };
    510  1.16  gmcgarry UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SONICCELL, 2, 1, 1);
    511  1.13   xtraeme 
    512  1.13   xtraeme UMQ_DEF(ROLAND, ROLAND_SONICCELL, 2) = {
    513  1.13   xtraeme 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_SONICCELL, 2),
    514  1.13   xtraeme 	UMQ_TERMINATOR
    515  1.13   xtraeme };
    516  1.13   xtraeme 
    517  1.13   xtraeme /*
    518  1.11      chap  * Midiman Midisport 2x4. This has 2 physical MIDI IN jacks that are read
    519  1.11      chap  * on endpoint 0x81 (descriptor index 0). It has 4 physical MIDI OUT jacks
    520  1.11      chap  * that can be written on endpoints 2 or 4 (at descriptor index 2 or 4,
    521  1.11      chap  * coincidentally) interchangeably: either endpoint will accept a Cable Number
    522  1.11      chap  * field of 0 to 3, and data for a given CN will be routed to the same
    523  1.11      chap  * physical output regardless of the endpoint used for the transfer. But
    524  1.11      chap  * there's a catch: flow-control feedback only goes to endpoint 2 for
    525  1.11      chap  * CN 0 and 2, and only to endpoint 4 for CN 1 and 3. If you send output at
    526  1.11      chap  * high rates for CN 0 or 2 over endpoint 4, or for CN 1 or 3 over endpoint 2,
    527  1.11      chap  * the USB transfers complete as fast as possible, giving you an apparent data
    528  1.11      chap  * rate much higher than MIDI's 3125 cps (easy to measure using dd to blast a
    529  1.11      chap  * bunch of midi data to the rmidi device). Of course that isn't a way to make
    530  1.11      chap  * MIDI faster, just a way to overrun the device buffer and spray bits on the
    531  1.11      chap  * floor. So this device needs the fixed endpoint quirk, the fixed cable number
    532  1.11      chap  * quirk (to make sure CNs 0 and 2 are put on the first endpoint and 1 and 3
    533  1.11      chap  * on the other), and then the fixed mididev-assignment quirk (to match jacks
    534  1.11      chap  * to mididevs so the rmidi devices match the order of the blinkenlights).
    535  1.11      chap  */
    536  1.16  gmcgarry UMQ_FIXED_EP_DATA_DEF(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE, 2, 1) = {
    537  1.11      chap 	/* out: ep# jacks */
    538  1.11      chap 	{ 2, 2 },
    539  1.11      chap 	{ 4, 2 },
    540  1.11      chap 	/* in: ep# jacks */
    541  1.11      chap 	{ 0, 2 }
    542  1.11      chap };
    543  1.16  gmcgarry UMQ_FIXED_EP_DEF(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE, 2, 1);
    544  1.16  gmcgarry UMQ_FIXED_CN_DEF(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE) = {
    545  1.16  gmcgarry 	0, 2, 1, 3, 0, 1
    546  1.16  gmcgarry };
    547  1.16  gmcgarry UMQ_FIXED_MD_DEF(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE) = {
    548  1.16  gmcgarry 	 0, 0, 2, 1, 1, -1, 3, -1
    549  1.16  gmcgarry };
    550  1.11      chap UMQ_DEF(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE) = {
    551  1.11      chap 	UMQ_FIXED_EP_REG(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE),
    552  1.16  gmcgarry 	UMQ_FIXED_CN_REG(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE),
    553  1.16  gmcgarry 	UMQ_FIXED_MD_REG(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE),
    554  1.11      chap 	UMQ_TYPE(MIDIMAN_GARBLE),
    555  1.11      chap 	UMQ_TERMINATOR
    556  1.11      chap };
    557  1.11      chap 
    558  1.11      chap /*
    559   1.1  tshiozak  * quirk list
    560   1.1  tshiozak  */
    561  1.16  gmcgarry static struct umidi_quirk umidi_quirklist[] = {
    562   1.1  tshiozak 	UMQ_REG(YAMAHA, YAMAHA_UX256, ANYIFACE),
    563   1.1  tshiozak 	UMQ_REG(YAMAHA, ANYPRODUCT, ANYIFACE),
    564   1.1  tshiozak 	UMQ_REG(ROLAND, ROLAND_UM1, 2),
    565   1.4  tshiozak 	UMQ_REG(ROLAND, ROLAND_SC8850, 2),
    566   1.4  tshiozak 	UMQ_REG(ROLAND, ROLAND_SD90, 2),
    567   1.2  tshiozak 	UMQ_REG(ROLAND, ROLAND_UM880N, 0),
    568   1.5  jdolecek 	UMQ_REG(ROLAND, ROLAND_UA100, 2),
    569   1.5  jdolecek 	UMQ_REG(ROLAND, ROLAND_UM4, 2),
    570   1.5  jdolecek 	UMQ_REG(ROLAND, ROLAND_U8, 2),
    571   1.5  jdolecek 	UMQ_REG(ROLAND, ROLAND_UM2, 2),
    572   1.5  jdolecek 	UMQ_REG(ROLAND, ROLAND_SC8820, 2),
    573   1.5  jdolecek 	UMQ_REG(ROLAND, ROLAND_PC300, 2),
    574   1.5  jdolecek 	UMQ_REG(ROLAND, ROLAND_SK500, 2),
    575   1.5  jdolecek 	UMQ_REG(ROLAND, ROLAND_SCD70, 2),
    576   1.5  jdolecek 	UMQ_REG(ROLAND, ROLAND_XV5050, 0),
    577   1.5  jdolecek 	UMQ_REG(ROLAND, ROLAND_UM550, 0),
    578   1.5  jdolecek 	UMQ_REG(ROLAND, ROLAND_SD20, 0),
    579   1.5  jdolecek 	UMQ_REG(ROLAND, ROLAND_SD80, 0),
    580   1.5  jdolecek 	UMQ_REG(ROLAND, ROLAND_UA700, 3),
    581   1.8  augustss 	UMQ_REG(ROLAND, ROLAND_UA1000, 3),
    582   1.8  augustss 	UMQ_REG(ROLAND, ROLAND_UA101, 2),
    583   1.8  augustss 	UMQ_REG(ROLAND, ROLAND_UA101F, 2),
    584   1.8  augustss 	UMQ_REG(ROLAND, ROLAND_FANTOMX, 0),
    585   1.8  augustss 	UMQ_REG(ROLAND, ROLAND_PCR, 0),
    586  1.10  christos 	UMQ_REG(ROLAND, ROLAND_UM3, 0),
    587  1.13   xtraeme 	UMQ_REG(ROLAND, ROLAND_UA25, 2),
    588  1.13   xtraeme 	UMQ_REG(ROLAND, ROLAND_UA4FX, 2),
    589  1.13   xtraeme 	UMQ_REG(ROLAND, ROLAND_SONICCELL, 2),
    590  1.11      chap 	UMQ_REG(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE),
    591  1.12  christos 	{ .vendor = 0 },
    592   1.1  tshiozak };
    593   1.1  tshiozak 
    594   1.1  tshiozak 
    595   1.1  tshiozak /*
    596   1.1  tshiozak  * quirk utilities
    597   1.1  tshiozak  */
    598   1.1  tshiozak 
    599  1.16  gmcgarry const struct umidi_quirk *
    600   1.1  tshiozak umidi_search_quirk(int vendor, int product, int ifaceno)
    601   1.1  tshiozak {
    602   1.1  tshiozak 	struct umidi_quirk *p;
    603  1.16  gmcgarry 	const struct umq_data *q;
    604   1.1  tshiozak 
    605   1.1  tshiozak 	DPRINTF(("umidi_search_quirk: v=%d, p=%d, i=%d\n",
    606   1.1  tshiozak 		 vendor, product, ifaceno));
    607   1.1  tshiozak 
    608   1.1  tshiozak 	for (p=&umidi_quirklist[0]; p->vendor; p++) {
    609   1.1  tshiozak 		DPRINTFN(10, ("\tv=%d, p=%d, i=%d",
    610   1.1  tshiozak 			      p->vendor, p->product, p->iface));
    611   1.1  tshiozak 		if ((p->vendor==vendor || p->vendor==ANYVENDOR) &&
    612   1.1  tshiozak 		    (p->product==product || p->product==ANYPRODUCT) &&
    613   1.1  tshiozak 		    (p->iface==ifaceno || p->iface==ANYIFACE)) {
    614   1.1  tshiozak 			DPRINTFN(10, (" found\n"));
    615   1.1  tshiozak 			if (!p->type_mask)
    616   1.1  tshiozak 				/* make quirk mask */
    617   1.1  tshiozak 				for (q=p->quirks; q->type; q++)
    618   1.1  tshiozak 					p->type_mask |= 1<<(q->type-1);
    619   1.1  tshiozak 			return p;
    620   1.8  augustss 		}
    621   1.1  tshiozak 		DPRINTFN(10, ("\n"));
    622   1.1  tshiozak 	}
    623   1.1  tshiozak 
    624   1.1  tshiozak 	return NULL;
    625   1.1  tshiozak }
    626   1.1  tshiozak 
    627   1.7  christos static const char *quirk_name[] = {
    628   1.1  tshiozak 	"NULL",
    629   1.1  tshiozak 	"Fixed Endpoint",
    630   1.1  tshiozak 	"Yamaha Specific",
    631  1.11      chap 	"Midiman Packet Garbling",
    632  1.11      chap 	"Cable Numbers per Endpoint",
    633  1.11      chap 	"Cable Numbers Global",
    634  1.11      chap 	"Cable Numbers Fixed",
    635  1.11      chap 	"Unit Mapping Fixed",
    636   1.1  tshiozak };
    637   1.1  tshiozak 
    638   1.1  tshiozak void
    639  1.16  gmcgarry umidi_print_quirk(const struct umidi_quirk *q)
    640   1.1  tshiozak {
    641  1.16  gmcgarry 	const struct umq_data *qd;
    642   1.1  tshiozak 	if (q) {
    643   1.1  tshiozak 		printf("(");
    644   1.1  tshiozak 		for (qd=q->quirks; qd->type; qd++)
    645   1.1  tshiozak 			printf("%s%s", quirk_name[qd->type],
    646   1.1  tshiozak 			       (qd+1)->type?", ":")\n");
    647   1.1  tshiozak 	} else {
    648   1.1  tshiozak 		printf("(genuine USB-MIDI)\n");
    649   1.1  tshiozak 	}
    650   1.1  tshiozak }
    651   1.1  tshiozak 
    652  1.16  gmcgarry const void *
    653  1.16  gmcgarry umidi_get_quirk_data_from_type(const struct umidi_quirk *q, u_int32_t type)
    654   1.1  tshiozak {
    655  1.16  gmcgarry 	const struct umq_data *qd;
    656   1.1  tshiozak 	if (q) {
    657   1.1  tshiozak 		for (qd=q->quirks; qd->type; qd++)
    658   1.1  tshiozak 			if (qd->type == type)
    659   1.1  tshiozak 				return qd->data;
    660   1.1  tshiozak 	}
    661   1.1  tshiozak 	return NULL;
    662   1.1  tshiozak }
    663