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