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