1 /* $OpenBSD: umidi_quirks.c,v 1.13 2015/03/14 03:38:50 jsg Exp $ */ 2 /* $NetBSD: umidi_quirks.c,v 1.4 2002/06/19 13:55:30 tshiozak Exp $ */ 3 4 /* 5 * Copyright (c) 2001 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Takuya SHIOZAKI (tshiozak@netbsd.org). 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 #include <sys/kernel.h> 36 #include <sys/malloc.h> 37 #include <sys/device.h> 38 #include <sys/ioctl.h> 39 #include <sys/conf.h> 40 #include <sys/file.h> 41 #include <sys/selinfo.h> 42 #include <sys/poll.h> 43 44 #include <dev/usb/usb.h> 45 #include <dev/usb/usbdi.h> 46 #include <dev/usb/usbdi_util.h> 47 48 #include <dev/usb/usbdevs.h> 49 #include <dev/usb/umidireg.h> 50 #include <dev/usb/umidivar.h> 51 #include <dev/usb/umidi_quirks.h> 52 53 /* 54 * quirk codes for UMIDI 55 */ 56 57 #ifdef UMIDIQUIRK_DEBUG 58 #define DPRINTF(x) if (umidiquirkdebug) printf x 59 #define DPRINTFN(n,x) if (umidiquirkdebug >= (n)) printf x 60 int umidiquirkdebug = 1; 61 #else 62 #define DPRINTF(x) 63 #define DPRINTFN(n,x) 64 #endif 65 66 67 /* 68 * YAMAHA UX-256 69 * --- this is a typical yamaha device, but has a broken descriptor :-< 70 */ 71 72 UMQ_FIXED_EP_DEF(YAMAHA, YAMAHA_UX256, ANYIFACE, 1, 1) = { 73 /* out */ 74 { 0, 16 }, 75 /* in */ 76 { 1, 8 } 77 }; 78 79 UMQ_DEF(YAMAHA, YAMAHA_UX256, ANYIFACE) = { 80 UMQ_FIXED_EP_REG(YAMAHA, YAMAHA_UX256, ANYIFACE), 81 #if 0 82 UMQ_YAMAHA_REG(YAMAHA, ANYPRODUCT, ANYIFACE), 83 #endif 84 UMQ_TERMINATOR 85 }; 86 87 88 /* 89 * YAMAHA generic 90 */ 91 UMQ_DEF(YAMAHA, ANYPRODUCT, ANYIFACE) = { 92 UMQ_YAMAHA_REG(YAMAHA, ANYPRODUCT, ANYIFACE), 93 UMQ_TERMINATOR 94 }; 95 96 97 /* 98 * ROLAND UM-1 99 */ 100 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM1, 2, 1, 1) = { 101 /* out */ 102 { 0, 1 }, 103 /* in */ 104 { 1, 1 } 105 }; 106 107 UMQ_DEF(ROLAND, ROLAND_UM1, 2) = { 108 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM1, 2), 109 UMQ_TERMINATOR 110 }; 111 112 /* 113 * ROLAND SC-8850 114 */ 115 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SC8850, 2, 1, 1) = { 116 /* out */ 117 { 0, 6 }, 118 /* in */ 119 { 1, 6 } 120 }; 121 122 UMQ_DEF(ROLAND, ROLAND_SC8850, 2) = { 123 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SC8850, 2), 124 UMQ_TERMINATOR 125 }; 126 127 /* 128 * ROLAND SD-90 129 */ 130 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SD90, 2, 1, 1) = { 131 /* out */ 132 { 0, 4 }, 133 /* in */ 134 { 1, 4 } 135 }; 136 137 UMQ_DEF(ROLAND, ROLAND_SD90, 2) = { 138 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SD90, 2), 139 UMQ_TERMINATOR 140 }; 141 142 143 /* 144 * ROLAND UM-880 (native mode) 145 */ 146 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM880N, 0, 1, 1) = { 147 /* out */ 148 { 0, 9 }, 149 /* in */ 150 { 1, 9 } 151 }; 152 153 UMQ_DEF(ROLAND, ROLAND_UM880N, 0) = { 154 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM880N, 0), 155 UMQ_TERMINATOR 156 }; 157 158 /* 159 * ROLAND UA-100 160 */ 161 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA100, 2, 1, 1) = { 162 /* out */ 163 { 0, 3 }, 164 /* in */ 165 { 1, 3 } 166 }; 167 168 UMQ_DEF(ROLAND, ROLAND_UA100, 2) = { 169 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA100, 2), 170 UMQ_TERMINATOR 171 }; 172 173 /* 174 * ROLAND UM-4 175 */ 176 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM4, 2, 1, 1) = { 177 /* out */ 178 { 0, 4 }, 179 /* in */ 180 { 1, 4 } 181 }; 182 183 UMQ_DEF(ROLAND, ROLAND_UM4, 2) = { 184 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM4, 2), 185 UMQ_TERMINATOR 186 }; 187 188 /* 189 * ROLAND U-8 190 */ 191 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_U8, 2, 1, 1) = { 192 /* out */ 193 { 0, 2 }, 194 /* in */ 195 { 1, 2 } 196 }; 197 198 UMQ_DEF(ROLAND, ROLAND_U8, 2) = { 199 UMQ_FIXED_EP_REG(ROLAND, ROLAND_U8, 2), 200 UMQ_TERMINATOR 201 }; 202 203 /* 204 * ROLAND UM-2 205 */ 206 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM2, 2, 1, 1) = { 207 /* out */ 208 { 0, 2 }, 209 /* in */ 210 { 1, 2 } 211 }; 212 213 UMQ_DEF(ROLAND, ROLAND_UM2, 2) = { 214 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM2, 2), 215 UMQ_TERMINATOR 216 }; 217 218 /* 219 * ROLAND SC-8820 220 */ 221 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SC8820, 2, 1, 1) = { 222 /* out */ 223 { 0, 5 }, /* cables 0, 1, 4 only */ 224 /* in */ 225 { 1, 5 } /* do. */ 226 }; 227 228 UMQ_DEF(ROLAND, ROLAND_SC8820, 2) = { 229 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SC8820, 2), 230 UMQ_TERMINATOR 231 }; 232 233 /* 234 * ROLAND PC-300 235 */ 236 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_PC300, 2, 1, 1) = { 237 /* out */ 238 { 0, 1 }, 239 /* in */ 240 { 1, 1 } 241 }; 242 243 UMQ_DEF(ROLAND, ROLAND_PC300, 2) = { 244 UMQ_FIXED_EP_REG(ROLAND, ROLAND_PC300, 2), 245 UMQ_TERMINATOR 246 }; 247 248 /* 249 * ROLAND SK-500 250 */ 251 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SK500, 2, 1, 1) = { 252 /* out */ 253 { 0, 5 }, /* cables 0, 1, 4 only */ 254 /* in */ 255 { 1, 5 } /* do. */ 256 }; 257 258 UMQ_DEF(ROLAND, ROLAND_SK500, 2) = { 259 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SK500, 2), 260 UMQ_TERMINATOR 261 }; 262 263 /* 264 * ROLAND SC-D70 265 */ 266 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SCD70, 2, 1, 1) = { 267 /* out */ 268 { 0, 3 }, 269 /* in */ 270 { 1, 3 } 271 }; 272 273 UMQ_DEF(ROLAND, ROLAND_SCD70, 2) = { 274 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SCD70, 2), 275 UMQ_TERMINATOR 276 }; 277 278 /* 279 * ROLAND UM-550 280 */ 281 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM550, 0, 1, 1) = { 282 /* out */ 283 { 0, 6 }, 284 /* in */ 285 { 1, 6 } 286 }; 287 288 UMQ_DEF(ROLAND, ROLAND_UM550, 0) = { 289 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM550, 0), 290 UMQ_TERMINATOR 291 }; 292 293 /* 294 * ROLAND SD-20 295 */ 296 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SD20, 0, 1, 1) = { 297 /* out */ 298 { 0, 2 }, 299 /* in */ 300 { 1, 3 } 301 }; 302 303 UMQ_DEF(ROLAND, ROLAND_SD20, 0) = { 304 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SD20, 0), 305 UMQ_TERMINATOR 306 }; 307 308 /* 309 * ROLAND SD-80 310 */ 311 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SD80, 0, 1, 1) = { 312 /* out */ 313 { 0, 4 }, 314 /* in */ 315 { 1, 4 } 316 }; 317 318 UMQ_DEF(ROLAND, ROLAND_SD80, 0) = { 319 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SD80, 0), 320 UMQ_TERMINATOR 321 }; 322 323 /* 324 * ROLAND UA-700 325 */ 326 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA700, 3, 1, 1) = { 327 /* out */ 328 { 0, 2 }, 329 /* in */ 330 { 1, 2 } 331 }; 332 333 UMQ_DEF(ROLAND, ROLAND_UA700, 3) = { 334 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA700, 3), 335 UMQ_TERMINATOR 336 }; 337 338 /* 339 * ROLAND UM-ONE 340 */ 341 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UMONE, ANYIFACE, 1, 1) = { 342 /* out */ 343 { 0, 1 }, 344 /* in */ 345 { 1, 1 } 346 }; 347 348 UMQ_DEF(ROLAND, ROLAND_UMONE, ANYIFACE) = { 349 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UMONE, ANYIFACE), 350 UMQ_TERMINATOR 351 }; 352 353 /* 354 * quirk list 355 */ 356 struct umidi_quirk umidi_quirklist[] = { 357 UMQ_REG(YAMAHA, YAMAHA_UX256, ANYIFACE), 358 UMQ_REG(YAMAHA, ANYPRODUCT, ANYIFACE), 359 UMQ_REG(ROLAND, ROLAND_UM1, 2), 360 UMQ_REG(ROLAND, ROLAND_SC8850, 2), 361 UMQ_REG(ROLAND, ROLAND_SD90, 2), 362 UMQ_REG(ROLAND, ROLAND_UM880N, 0), 363 UMQ_REG(ROLAND, ROLAND_UA100, 2), 364 UMQ_REG(ROLAND, ROLAND_UM4, 2), 365 UMQ_REG(ROLAND, ROLAND_U8, 2), 366 UMQ_REG(ROLAND, ROLAND_UM2, 2), 367 UMQ_REG(ROLAND, ROLAND_SC8820, 2), 368 UMQ_REG(ROLAND, ROLAND_PC300, 2), 369 UMQ_REG(ROLAND, ROLAND_SK500, 2), 370 UMQ_REG(ROLAND, ROLAND_SCD70, 2), 371 UMQ_REG(ROLAND, ROLAND_UM550, 0), 372 UMQ_REG(ROLAND, ROLAND_SD20, 0), 373 UMQ_REG(ROLAND, ROLAND_SD80, 0), 374 UMQ_REG(ROLAND, ROLAND_UA700, 3), 375 UMQ_REG(ROLAND, ROLAND_UMONE, ANYIFACE), 376 UMQ_TERMINATOR 377 }; 378 379 380 /* 381 * quirk utilities 382 */ 383 384 struct umidi_quirk * 385 umidi_search_quirk(int vendor, int product, int ifaceno) 386 { 387 struct umidi_quirk *p; 388 struct umq_data *q; 389 390 DPRINTF(("umidi_search_quirk: v=%d, p=%d, i=%d\n", 391 vendor, product, ifaceno)); 392 393 for (p=&umidi_quirklist[0]; p->vendor; p++) { 394 DPRINTFN(10, ("\tv=%d, p=%d, i=%d", 395 p->vendor, p->product, p->iface)); 396 if ((p->vendor==vendor || p->vendor==ANYVENDOR) && 397 (p->product==product || p->product==ANYPRODUCT) && 398 (p->iface==ifaceno || p->iface==ANYIFACE)) { 399 DPRINTFN(10, (" found\n")); 400 if (!p->type_mask) 401 /* make quirk mask */ 402 for (q=p->quirks; q->type; q++) 403 p->type_mask |= 1<<(q->type-1); 404 return p; 405 } 406 DPRINTFN(10, ("\n")); 407 } 408 409 return NULL; 410 } 411 412 static char *quirk_name[] = { 413 "NULL", 414 "Fixed Endpoint", 415 "Yamaha Specific", 416 }; 417 418 void 419 umidi_print_quirk(struct umidi_quirk *q) 420 { 421 struct umq_data *qd; 422 if (q) { 423 printf("("); 424 for (qd=q->quirks; qd->type; qd++) 425 printf("%s%s", quirk_name[qd->type], 426 (qd+1)->type?", ":")\n"); 427 } else { 428 printf("(genuine USB-MIDI)\n"); 429 } 430 } 431 432 void * 433 umidi_get_quirk_data_from_type(struct umidi_quirk *q, u_int32_t type) 434 { 435 struct umq_data *qd; 436 if (q) { 437 for (qd=q->quirks; qd->type; qd++) 438 if (qd->type == type) 439 return qd->data; 440 } 441 return NULL; 442 } 443