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 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 * 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). 535 */ 536 UMQ_FIXED_EP_DATA_DEF(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE, 2, 1) = { 537 /* out: ep# jacks */ 538 { 2, 2 }, 539 { 4, 2 }, 540 /* in: ep# jacks */ 541 { 0, 2 } 542 }; 543 UMQ_FIXED_EP_DEF(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE, 2, 1); 544 UMQ_FIXED_CN_DEF(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE) = { 545 0, 2, 1, 3, 0, 1 546 }; 547 UMQ_FIXED_MD_DEF(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE) = { 548 0, 0, 2, 1, 1, -1, 3, -1 549 }; 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), 555 UMQ_TERMINATOR 556 }; 557 558 /* 559 * quirk list 560 */ 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), 591 { .vendor = 0 }, 592 }; 593 594 595 /* 596 * quirk utilities 597 */ 598 599 const struct umidi_quirk * 600 umidi_search_quirk(int vendor, int product, int ifaceno) 601 { 602 struct umidi_quirk *p; 603 const struct umq_data *q; 604 605 DPRINTF(("umidi_search_quirk: v=%d, p=%d, i=%d\n", 606 vendor, product, ifaceno)); 607 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")); 615 if (!p->type_mask) 616 /* make quirk mask */ 617 for (q=p->quirks; q->type; q++) 618 p->type_mask |= 1<<(q->type-1); 619 return p; 620 } 621 DPRINTFN(10, ("\n")); 622 } 623 624 return NULL; 625 } 626 627 static const char *quirk_name[] = { 628 "NULL", 629 "Fixed Endpoint", 630 "Yamaha Specific", 631 "Midiman Packet Garbling", 632 "Cable Numbers per Endpoint", 633 "Cable Numbers Global", 634 "Cable Numbers Fixed", 635 "Unit Mapping Fixed", 636 }; 637 638 void 639 umidi_print_quirk(const struct umidi_quirk *q) 640 { 641 const struct umq_data *qd; 642 if (q) { 643 printf("("); 644 for (qd=q->quirks; qd->type; qd++) 645 printf("%s%s", quirk_name[qd->type], 646 (qd+1)->type?", ":")\n"); 647 } else { 648 printf("(genuine USB-MIDI)\n"); 649 } 650 } 651 652 const void * 653 umidi_get_quirk_data_from_type(const struct umidi_quirk *q, u_int32_t type) 654 { 655 const struct umq_data *qd; 656 if (q) { 657 for (qd=q->quirks; qd->type; qd++) 658 if (qd->type == type) 659 return qd->data; 660 } 661 return NULL; 662 } 663