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