1 /* $NetBSD: umidi_quirks.c,v 1.17 2012/02/11 05:28:30 plunky 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.17 2012/02/11 05:28:30 plunky 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 65 int 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 77 UMQ_FIXED_EP_DATA_DEF(YAMAHA, YAMAHA_UX256, ANYIFACE, 1, 1) = { 78 /* out */ 79 { 0, 16 }, 80 /* in */ 81 { 1, 8 } 82 }; 83 UMQ_FIXED_EP_DEF(YAMAHA, YAMAHA_UX256, ANYIFACE, 1, 1); 84 85 UMQ_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 */ 97 UMQ_DEF(YAMAHA, ANYPRODUCT, ANYIFACE) = { 98 UMQ_YAMAHA_REG(YAMAHA, ANYPRODUCT, ANYIFACE), 99 UMQ_TERMINATOR 100 }; 101 102 103 /* 104 * ROLAND UM-1 105 */ 106 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UM1, 2, 1, 1) = { 107 /* out */ 108 { 0, 1 }, 109 /* in */ 110 { 1, 1 } 111 }; 112 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM1, 2, 1, 1); 113 114 UMQ_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 */ 122 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SC8850, 2, 1, 1) = { 123 /* out */ 124 { 0, 6 }, 125 /* in */ 126 { 1, 6 } 127 }; 128 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SC8850, 2, 1, 1); 129 130 UMQ_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 */ 138 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SD90, 2, 1, 1) = { 139 /* out */ 140 { 0, 4 }, 141 /* in */ 142 { 1, 4 } 143 }; 144 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SD90, 2, 1, 1); 145 146 UMQ_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 */ 155 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UM880N, 0, 1, 1) = { 156 /* out */ 157 { 0, 9 }, 158 /* in */ 159 { 1, 9 } 160 }; 161 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM880N, 0, 1, 1); 162 163 UMQ_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 */ 171 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA100, 2, 1, 1) = { 172 /* out */ 173 { 0, 3 }, 174 /* in */ 175 { 1, 3 } 176 }; 177 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA100, 2, 1, 1); 178 179 UMQ_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 */ 187 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UM4, 2, 1, 1) = { 188 /* out */ 189 { 0, 4 }, 190 /* in */ 191 { 1, 4 } 192 }; 193 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM4, 2, 1, 1); 194 195 UMQ_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 */ 203 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_U8, 2, 1, 1) = { 204 /* out */ 205 { 0, 2 }, 206 /* in */ 207 { 1, 2 } 208 }; 209 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_U8, 2, 1, 1); 210 211 UMQ_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 */ 219 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UM2, 2, 1, 1) = { 220 /* out */ 221 { 0, 2 }, 222 /* in */ 223 { 1, 2 } 224 }; 225 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM2, 2, 1, 1); 226 227 UMQ_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 */ 235 UMQ_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 }; 241 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SC8820, 2, 1, 1); 242 243 UMQ_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 */ 251 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_PC300, 2, 1, 1) = { 252 /* out */ 253 { 0, 1 }, 254 /* in */ 255 { 1, 1 } 256 }; 257 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_PC300, 2, 1, 1); 258 259 UMQ_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 */ 267 UMQ_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 }; 273 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SK500, 2, 1, 1); 274 275 UMQ_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 */ 283 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SCD70, 2, 1, 1) = { 284 /* out */ 285 { 0, 3 }, 286 /* in */ 287 { 1, 3 } 288 }; 289 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SCD70, 2, 1, 1); 290 291 UMQ_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 */ 299 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_XV5050, 0, 1, 1) = { 300 /* out */ 301 { 0, 1 }, 302 /* in */ 303 { 1, 1 } 304 }; 305 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_XV5050, 0, 1, 1); 306 307 UMQ_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 */ 315 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UM550, 0, 1, 1) = { 316 /* out */ 317 { 0, 6 }, 318 /* in */ 319 { 1, 6 } 320 }; 321 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM550, 0, 1, 1); 322 323 UMQ_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 */ 331 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SD20, 0, 1, 1) = { 332 /* out */ 333 { 0, 2 }, 334 /* in */ 335 { 1, 3 } 336 }; 337 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SD20, 0, 1, 1); 338 339 UMQ_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 */ 347 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SD80, 0, 1, 1) = { 348 /* out */ 349 { 0, 4 }, 350 /* in */ 351 { 1, 4 } 352 }; 353 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SD80, 0, 1, 1); 354 355 UMQ_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 */ 363 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA700, 3, 1, 1) = { 364 /* out */ 365 { 0, 2 }, 366 /* in */ 367 { 1, 2 } 368 }; 369 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA700, 3, 1, 1); 370 371 UMQ_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 */ 379 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA1000, 3, 1, 1) = { 380 /* out */ 381 { 0, 2 }, 382 /* in */ 383 { 1, 2 } 384 }; 385 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA1000, 3, 1, 1); 386 387 UMQ_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 */ 395 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA101, 2, 1, 1) = { 396 /* out */ 397 { 0, 2 }, 398 /* in */ 399 { 1, 2 } 400 }; 401 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA101, 2, 1, 1); 402 403 UMQ_DEF(ROLAND, ROLAND_UA101, 2) = { 404 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA101, 2), 405 UMQ_TERMINATOR 406 }; 407 408 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA101F, 2, 1, 1) = { 409 /* out */ 410 { 0, 2 }, 411 /* in */ 412 { 1, 2 } 413 }; 414 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA101F, 2, 1, 1); 415 416 UMQ_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 */ 424 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_FANTOMX, 0, 1, 1) = { 425 /* out */ 426 { 0, 1 }, 427 /* in */ 428 { 1, 1 } 429 }; 430 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_FANTOMX, 0, 1, 1); 431 432 UMQ_DEF(ROLAND, ROLAND_FANTOMX, 0) = { 433 UMQ_FIXED_EP_REG(ROLAND, ROLAND_FANTOMX, 0), 434 UMQ_TERMINATOR 435 }; 436 437 /* 438 * ROLAND PCR 439 */ 440 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_PCR, 0, 1, 1) = { 441 /* out */ 442 { 0, 3 }, 443 /* in */ 444 { 1, 3 } 445 }; 446 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_PCR, 0, 1, 1); 447 448 UMQ_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 */ 456 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UM3, 0, 1, 1) = { 457 /* out */ 458 { 0, 3 }, 459 /* in */ 460 { 1, 3 } 461 }; 462 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM3, 0, 1, 1); 463 464 UMQ_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 */ 472 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA25, 2, 1, 1) = { 473 /* out */ 474 { 0, 1 }, 475 /* in */ 476 { 1, 1 } 477 }; 478 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA25, 2, 1, 1); 479 480 UMQ_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 */ 488 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA4FX, 2, 1, 1) = { 489 /* out */ 490 { 0, 1 }, 491 /* in */ 492 { 1, 1 } 493 }; 494 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA4FX, 2, 1, 1); 495 496 UMQ_DEF(ROLAND, ROLAND_UA4FX, 2) = { 497 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA4FX, 2), 498 UMQ_TERMINATOR 499 }; 500 501 /* 502 * ROLAND SonicCell 503 */ 504 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SONICCELL, 2, 1, 1) = { 505 /* out */ 506 { 0, 1 }, 507 /* in */ 508 { 1, 1 } 509 }; 510 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SONICCELL, 2, 1, 1); 511 512 UMQ_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 */ 520 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UMONE, ANYIFACE, 1, 1) = { 521 /* out */ 522 { 0, 1 }, 523 /* in */ 524 { 1, 1 } 525 }; 526 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UMONE, ANYIFACE, 1, 1); 527 528 UMQ_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 */ 552 UMQ_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 }; 559 UMQ_FIXED_EP_DEF(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE, 2, 1); 560 UMQ_FIXED_CN_DEF(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE) = { 561 0, 2, 1, 3, 0, 1 562 }; 563 UMQ_FIXED_MD_DEF(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE) = { 564 0, 0, 2, 1, 1, -1, 3, -1 565 }; 566 UMQ_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 */ 577 static 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 616 const struct umidi_quirk * 617 umidi_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 644 static 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 655 void 656 umidi_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 669 const void * 670 umidi_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