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