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