1 /* $NetBSD: umidi_quirks.c,v 1.15 2008/04/28 20:24:00 martin Exp $ */
4 * Copyright (c) 2001 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Takuya SHIOZAKI (tshiozak@NetBSD.org).
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: umidi_quirks.c,v 1.15 2008/04/28 20:24:00 martin Exp $");
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
38 #include <sys/malloc.h>
39 #include <sys/device.h>
40 #include <sys/ioctl.h>
43 #include <sys/select.h>
45 #include <sys/vnode.h>
48 #include <dev/usb/usb.h>
49 #include <dev/usb/usbdi.h>
50 #include <dev/usb/usbdi_util.h>
52 #include <dev/usb/usbdevs.h>
53 #include <dev/usb/uaudioreg.h>
54 #include <dev/usb/umidireg.h>
55 #include <dev/usb/umidivar.h>
56 #include <dev/usb/umidi_quirks.h>
59 * quirk codes for UMIDI
62 #ifdef UMIDIQUIRK_DEBUG
63 #define DPRINTF(x) if (umidiquirkdebug) printf x
64 #define DPRINTFN(n,x) if (umidiquirkdebug >= (n)) printf x
65 int umidiquirkdebug
= 1;
74 * --- this is a typical yamaha device, but has a broken descriptor :-<
77 UMQ_FIXED_EP_DATA_DEF(YAMAHA
, YAMAHA_UX256
, ANYIFACE
, 1, 1) = {
83 UMQ_FIXED_EP_DEF(YAMAHA
, YAMAHA_UX256
, ANYIFACE
, 1, 1);
85 UMQ_DEF(YAMAHA
, YAMAHA_UX256
, ANYIFACE
) = {
86 UMQ_FIXED_EP_REG(YAMAHA
, YAMAHA_UX256
, ANYIFACE
),
88 UMQ_YAMAHA_REG(YAMAHA
, ANYPRODUCT
, ANYIFACE
),
97 UMQ_DEF(YAMAHA
, ANYPRODUCT
, ANYIFACE
) = {
98 UMQ_YAMAHA_REG(YAMAHA
, ANYPRODUCT
, ANYIFACE
),
106 UMQ_FIXED_EP_DATA_DEF(ROLAND
, ROLAND_UM1
, 2, 1, 1) = {
112 UMQ_FIXED_EP_DEF(ROLAND
, ROLAND_UM1
, 2, 1, 1);
114 UMQ_DEF(ROLAND
, ROLAND_UM1
, 2) = {
115 UMQ_FIXED_EP_REG(ROLAND
, ROLAND_UM1
, 2),
122 UMQ_FIXED_EP_DATA_DEF(ROLAND
, ROLAND_SC8850
, 2, 1, 1) = {
128 UMQ_FIXED_EP_DEF(ROLAND
, ROLAND_SC8850
, 2, 1, 1);
130 UMQ_DEF(ROLAND
, ROLAND_SC8850
, 2) = {
131 UMQ_FIXED_EP_REG(ROLAND
, ROLAND_SC8850
, 2),
138 UMQ_FIXED_EP_DATA_DEF(ROLAND
, ROLAND_SD90
, 2, 1, 1) = {
144 UMQ_FIXED_EP_DEF(ROLAND
, ROLAND_SD90
, 2, 1, 1);
146 UMQ_DEF(ROLAND
, ROLAND_SD90
, 2) = {
147 UMQ_FIXED_EP_REG(ROLAND
, ROLAND_SD90
, 2),
153 * ROLAND UM-880 (native mode)
155 UMQ_FIXED_EP_DATA_DEF(ROLAND
, ROLAND_UM880N
, 0, 1, 1) = {
161 UMQ_FIXED_EP_DEF(ROLAND
, ROLAND_UM880N
, 0, 1, 1);
163 UMQ_DEF(ROLAND
, ROLAND_UM880N
, 0) = {
164 UMQ_FIXED_EP_REG(ROLAND
, ROLAND_UM880N
, 0),
171 UMQ_FIXED_EP_DATA_DEF(ROLAND
, ROLAND_UA100
, 2, 1, 1) = {
177 UMQ_FIXED_EP_DEF(ROLAND
, ROLAND_UA100
, 2, 1, 1);
179 UMQ_DEF(ROLAND
, ROLAND_UA100
, 2) = {
180 UMQ_FIXED_EP_REG(ROLAND
, ROLAND_UA100
, 2),
187 UMQ_FIXED_EP_DATA_DEF(ROLAND
, ROLAND_UM4
, 2, 1, 1) = {
193 UMQ_FIXED_EP_DEF(ROLAND
, ROLAND_UM4
, 2, 1, 1);
195 UMQ_DEF(ROLAND
, ROLAND_UM4
, 2) = {
196 UMQ_FIXED_EP_REG(ROLAND
, ROLAND_UM4
, 2),
203 UMQ_FIXED_EP_DATA_DEF(ROLAND
, ROLAND_U8
, 2, 1, 1) = {
209 UMQ_FIXED_EP_DEF(ROLAND
, ROLAND_U8
, 2, 1, 1);
211 UMQ_DEF(ROLAND
, ROLAND_U8
, 2) = {
212 UMQ_FIXED_EP_REG(ROLAND
, ROLAND_U8
, 2),
219 UMQ_FIXED_EP_DATA_DEF(ROLAND
, ROLAND_UM2
, 2, 1, 1) = {
225 UMQ_FIXED_EP_DEF(ROLAND
, ROLAND_UM2
, 2, 1, 1);
227 UMQ_DEF(ROLAND
, ROLAND_UM2
, 2) = {
228 UMQ_FIXED_EP_REG(ROLAND
, ROLAND_UM2
, 2),
235 UMQ_FIXED_EP_DATA_DEF(ROLAND
, ROLAND_SC8820
, 2, 1, 1) = {
237 { 0, 5 }, /* cables 0, 1, 4 only */
241 UMQ_FIXED_EP_DEF(ROLAND
, ROLAND_SC8820
, 2, 1, 1);
243 UMQ_DEF(ROLAND
, ROLAND_SC8820
, 2) = {
244 UMQ_FIXED_EP_REG(ROLAND
, ROLAND_SC8820
, 2),
251 UMQ_FIXED_EP_DATA_DEF(ROLAND
, ROLAND_PC300
, 2, 1, 1) = {
257 UMQ_FIXED_EP_DEF(ROLAND
, ROLAND_PC300
, 2, 1, 1);
259 UMQ_DEF(ROLAND
, ROLAND_PC300
, 2) = {
260 UMQ_FIXED_EP_REG(ROLAND
, ROLAND_PC300
, 2),
267 UMQ_FIXED_EP_DATA_DEF(ROLAND
, ROLAND_SK500
, 2, 1, 1) = {
269 { 0, 5 }, /* cables 0, 1, 4 only */
273 UMQ_FIXED_EP_DEF(ROLAND
, ROLAND_SK500
, 2, 1, 1);
275 UMQ_DEF(ROLAND
, ROLAND_SK500
, 2) = {
276 UMQ_FIXED_EP_REG(ROLAND
, ROLAND_SK500
, 2),
283 UMQ_FIXED_EP_DATA_DEF(ROLAND
, ROLAND_SCD70
, 2, 1, 1) = {
289 UMQ_FIXED_EP_DEF(ROLAND
, ROLAND_SCD70
, 2, 1, 1);
291 UMQ_DEF(ROLAND
, ROLAND_SCD70
, 2) = {
292 UMQ_FIXED_EP_REG(ROLAND
, ROLAND_SCD70
, 2),
299 UMQ_FIXED_EP_DATA_DEF(ROLAND
, ROLAND_XV5050
, 0, 1, 1) = {
305 UMQ_FIXED_EP_DEF(ROLAND
, ROLAND_XV5050
, 0, 1, 1);
307 UMQ_DEF(ROLAND
, ROLAND_XV5050
, 0) = {
308 UMQ_FIXED_EP_REG(ROLAND
, ROLAND_XV5050
, 0),
315 UMQ_FIXED_EP_DATA_DEF(ROLAND
, ROLAND_UM550
, 0, 1, 1) = {
321 UMQ_FIXED_EP_DEF(ROLAND
, ROLAND_UM550
, 0, 1, 1);
323 UMQ_DEF(ROLAND
, ROLAND_UM550
, 0) = {
324 UMQ_FIXED_EP_REG(ROLAND
, ROLAND_UM550
, 0),
331 UMQ_FIXED_EP_DATA_DEF(ROLAND
, ROLAND_SD20
, 0, 1, 1) = {
337 UMQ_FIXED_EP_DEF(ROLAND
, ROLAND_SD20
, 0, 1, 1);
339 UMQ_DEF(ROLAND
, ROLAND_SD20
, 0) = {
340 UMQ_FIXED_EP_REG(ROLAND
, ROLAND_SD20
, 0),
347 UMQ_FIXED_EP_DATA_DEF(ROLAND
, ROLAND_SD80
, 0, 1, 1) = {
353 UMQ_FIXED_EP_DEF(ROLAND
, ROLAND_SD80
, 0, 1, 1);
355 UMQ_DEF(ROLAND
, ROLAND_SD80
, 0) = {
356 UMQ_FIXED_EP_REG(ROLAND
, ROLAND_SD80
, 0),
363 UMQ_FIXED_EP_DATA_DEF(ROLAND
, ROLAND_UA700
, 3, 1, 1) = {
369 UMQ_FIXED_EP_DEF(ROLAND
, ROLAND_UA700
, 3, 1, 1);
371 UMQ_DEF(ROLAND
, ROLAND_UA700
, 3) = {
372 UMQ_FIXED_EP_REG(ROLAND
, ROLAND_UA700
, 3),
379 UMQ_FIXED_EP_DATA_DEF(ROLAND
, ROLAND_UA1000
, 3, 1, 1) = {
385 UMQ_FIXED_EP_DEF(ROLAND
, ROLAND_UA1000
, 3, 1, 1);
387 UMQ_DEF(ROLAND
, ROLAND_UA1000
, 3) = {
388 UMQ_FIXED_EP_REG(ROLAND
, ROLAND_UA1000
, 3),
395 UMQ_FIXED_EP_DATA_DEF(ROLAND
, ROLAND_UA101
, 2, 1, 1) = {
401 UMQ_FIXED_EP_DEF(ROLAND
, ROLAND_UA101
, 2, 1, 1);
403 UMQ_DEF(ROLAND
, ROLAND_UA101
, 2) = {
404 UMQ_FIXED_EP_REG(ROLAND
, ROLAND_UA101
, 2),
408 UMQ_FIXED_EP_DATA_DEF(ROLAND
, ROLAND_UA101F
, 2, 1, 1) = {
414 UMQ_FIXED_EP_DEF(ROLAND
, ROLAND_UA101F
, 2, 1, 1);
416 UMQ_DEF(ROLAND
, ROLAND_UA101F
, 2) = {
417 UMQ_FIXED_EP_REG(ROLAND
, ROLAND_UA101F
, 2),
424 UMQ_FIXED_EP_DATA_DEF(ROLAND
, ROLAND_FANTOMX
, 0, 1, 1) = {
430 UMQ_FIXED_EP_DEF(ROLAND
, ROLAND_FANTOMX
, 0, 1, 1);
432 UMQ_DEF(ROLAND
, ROLAND_FANTOMX
, 0) = {
433 UMQ_FIXED_EP_REG(ROLAND
, ROLAND_FANTOMX
, 0),
440 UMQ_FIXED_EP_DATA_DEF(ROLAND
, ROLAND_PCR
, 0, 1, 1) = {
446 UMQ_FIXED_EP_DEF(ROLAND
, ROLAND_PCR
, 0, 1, 1);
448 UMQ_DEF(ROLAND
, ROLAND_PCR
, 0) = {
449 UMQ_FIXED_EP_REG(ROLAND
, ROLAND_PCR
, 0),
456 UMQ_FIXED_EP_DATA_DEF(ROLAND
, ROLAND_UM3
, 0, 1, 1) = {
462 UMQ_FIXED_EP_DEF(ROLAND
, ROLAND_UM3
, 0, 1, 1);
464 UMQ_DEF(ROLAND
, ROLAND_UM3
, 0) = {
465 UMQ_FIXED_EP_REG(ROLAND
, ROLAND_UM3
, 0),
472 UMQ_FIXED_EP_DATA_DEF(ROLAND
, ROLAND_UA25
, 2, 1, 1) = {
478 UMQ_FIXED_EP_DEF(ROLAND
, ROLAND_UA25
, 2, 1, 1);
480 UMQ_DEF(ROLAND
, ROLAND_UA25
, 2) = {
481 UMQ_FIXED_EP_REG(ROLAND
, ROLAND_UA25
, 2),
488 UMQ_FIXED_EP_DATA_DEF(ROLAND
, ROLAND_UA4FX
, 2, 1, 1) = {
494 UMQ_FIXED_EP_DEF(ROLAND
, ROLAND_UA4FX
, 2, 1, 1);
496 UMQ_DEF(ROLAND
, ROLAND_UA4FX
, 2) = {
497 UMQ_FIXED_EP_REG(ROLAND
, ROLAND_UA4FX
, 2),
504 UMQ_FIXED_EP_DATA_DEF(ROLAND
, ROLAND_SONICCELL
, 2, 1, 1) = {
510 UMQ_FIXED_EP_DEF(ROLAND
, ROLAND_SONICCELL
, 2, 1, 1);
512 UMQ_DEF(ROLAND
, ROLAND_SONICCELL
, 2) = {
513 UMQ_FIXED_EP_REG(ROLAND
, ROLAND_SONICCELL
, 2),
518 * Midiman Midisport 2x4. This has 2 physical MIDI IN jacks that are read
519 * on endpoint 0x81 (descriptor index 0). It has 4 physical MIDI OUT jacks
520 * that can be written on endpoints 2 or 4 (at descriptor index 2 or 4,
521 * coincidentally) interchangeably: either endpoint will accept a Cable Number
522 * field of 0 to 3, and data for a given CN will be routed to the same
523 * physical output regardless of the endpoint used for the transfer. But
524 * there's a catch: flow-control feedback only goes to endpoint 2 for
525 * CN 0 and 2, and only to endpoint 4 for CN 1 and 3. If you send output at
526 * high rates for CN 0 or 2 over endpoint 4, or for CN 1 or 3 over endpoint 2,
527 * the USB transfers complete as fast as possible, giving you an apparent data
528 * rate much higher than MIDI's 3125 cps (easy to measure using dd to blast a
529 * bunch of midi data to the rmidi device). Of course that isn't a way to make
530 * MIDI faster, just a way to overrun the device buffer and spray bits on the
531 * floor. So this device needs the fixed endpoint quirk, the fixed cable number
532 * quirk (to make sure CNs 0 and 2 are put on the first endpoint and 1 and 3
533 * on the other), and then the fixed mididev-assignment quirk (to match jacks
534 * to mididevs so the rmidi devices match the order of the blinkenlights).
536 UMQ_FIXED_EP_DATA_DEF(MIDIMAN
, MIDIMAN_MIDISPORT2X4
, ANYIFACE
, 2, 1) = {
543 UMQ_FIXED_EP_DEF(MIDIMAN
, MIDIMAN_MIDISPORT2X4
, ANYIFACE
, 2, 1);
544 UMQ_FIXED_CN_DEF(MIDIMAN
, MIDIMAN_MIDISPORT2X4
, ANYIFACE
) = {
547 UMQ_FIXED_MD_DEF(MIDIMAN
, MIDIMAN_MIDISPORT2X4
, ANYIFACE
) = {
548 0, 0, 2, 1, 1, -1, 3, -1
550 UMQ_DEF(MIDIMAN
, MIDIMAN_MIDISPORT2X4
, ANYIFACE
) = {
551 UMQ_FIXED_EP_REG(MIDIMAN
, MIDIMAN_MIDISPORT2X4
, ANYIFACE
),
552 UMQ_FIXED_CN_REG(MIDIMAN
, MIDIMAN_MIDISPORT2X4
, ANYIFACE
),
553 UMQ_FIXED_MD_REG(MIDIMAN
, MIDIMAN_MIDISPORT2X4
, ANYIFACE
),
554 UMQ_TYPE(MIDIMAN_GARBLE
),
561 static struct umidi_quirk umidi_quirklist
[] = {
562 UMQ_REG(YAMAHA
, YAMAHA_UX256
, ANYIFACE
),
563 UMQ_REG(YAMAHA
, ANYPRODUCT
, ANYIFACE
),
564 UMQ_REG(ROLAND
, ROLAND_UM1
, 2),
565 UMQ_REG(ROLAND
, ROLAND_SC8850
, 2),
566 UMQ_REG(ROLAND
, ROLAND_SD90
, 2),
567 UMQ_REG(ROLAND
, ROLAND_UM880N
, 0),
568 UMQ_REG(ROLAND
, ROLAND_UA100
, 2),
569 UMQ_REG(ROLAND
, ROLAND_UM4
, 2),
570 UMQ_REG(ROLAND
, ROLAND_U8
, 2),
571 UMQ_REG(ROLAND
, ROLAND_UM2
, 2),
572 UMQ_REG(ROLAND
, ROLAND_SC8820
, 2),
573 UMQ_REG(ROLAND
, ROLAND_PC300
, 2),
574 UMQ_REG(ROLAND
, ROLAND_SK500
, 2),
575 UMQ_REG(ROLAND
, ROLAND_SCD70
, 2),
576 UMQ_REG(ROLAND
, ROLAND_XV5050
, 0),
577 UMQ_REG(ROLAND
, ROLAND_UM550
, 0),
578 UMQ_REG(ROLAND
, ROLAND_SD20
, 0),
579 UMQ_REG(ROLAND
, ROLAND_SD80
, 0),
580 UMQ_REG(ROLAND
, ROLAND_UA700
, 3),
581 UMQ_REG(ROLAND
, ROLAND_UA1000
, 3),
582 UMQ_REG(ROLAND
, ROLAND_UA101
, 2),
583 UMQ_REG(ROLAND
, ROLAND_UA101F
, 2),
584 UMQ_REG(ROLAND
, ROLAND_FANTOMX
, 0),
585 UMQ_REG(ROLAND
, ROLAND_PCR
, 0),
586 UMQ_REG(ROLAND
, ROLAND_UM3
, 0),
587 UMQ_REG(ROLAND
, ROLAND_UA25
, 2),
588 UMQ_REG(ROLAND
, ROLAND_UA4FX
, 2),
589 UMQ_REG(ROLAND
, ROLAND_SONICCELL
, 2),
590 UMQ_REG(MIDIMAN
, MIDIMAN_MIDISPORT2X4
, ANYIFACE
),
599 const struct umidi_quirk
*
600 umidi_search_quirk(int vendor
, int product
, int ifaceno
)
602 struct umidi_quirk
*p
;
603 const struct umq_data
*q
;
605 DPRINTF(("umidi_search_quirk: v=%d, p=%d, i=%d\n",
606 vendor
, product
, ifaceno
));
608 for (p
=&umidi_quirklist
[0]; p
->vendor
; p
++) {
609 DPRINTFN(10, ("\tv=%d, p=%d, i=%d",
610 p
->vendor
, p
->product
, p
->iface
));
611 if ((p
->vendor
==vendor
|| p
->vendor
==ANYVENDOR
) &&
612 (p
->product
==product
|| p
->product
==ANYPRODUCT
) &&
613 (p
->iface
==ifaceno
|| p
->iface
==ANYIFACE
)) {
614 DPRINTFN(10, (" found\n"));
616 /* make quirk mask */
617 for (q
=p
->quirks
; q
->type
; q
++)
618 p
->type_mask
|= 1<<(q
->type
-1);
621 DPRINTFN(10, ("\n"));
627 static const char *quirk_name
[] = {
631 "Midiman Packet Garbling",
632 "Cable Numbers per Endpoint",
633 "Cable Numbers Global",
634 "Cable Numbers Fixed",
635 "Unit Mapping Fixed",
639 umidi_print_quirk(const struct umidi_quirk
*q
)
641 const struct umq_data
*qd
;
644 for (qd
=q
->quirks
; qd
->type
; qd
++)
645 printf("%s%s", quirk_name
[qd
->type
],
646 (qd
+1)->type
?", ":")\n");
648 printf("(genuine USB-MIDI)\n");
653 umidi_get_quirk_data_from_type(const struct umidi_quirk
*q
, u_int32_t type
)
655 const struct umq_data
*qd
;
657 for (qd
=q
->quirks
; qd
->type
; qd
++)
658 if (qd
->type
== type
)