1 /* $OpenBSD: umidi_quirks.c,v 1.16 2018/01/18 18:09:38 ratchov 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/device.h> 37 #include <sys/ioctl.h> 38 #include <sys/conf.h> 39 #include <sys/selinfo.h> 40 #include <sys/poll.h> 41 42 #include <dev/usb/usb.h> 43 #include <dev/usb/usbdi.h> 44 #include <dev/usb/usbdi_util.h> 45 46 #include <dev/usb/usbdevs.h> 47 #include <dev/usb/umidireg.h> 48 #include <dev/usb/umidivar.h> 49 #include <dev/usb/umidi_quirks.h> 50 51 /* 52 * quirk codes for UMIDI 53 */ 54 55 #ifdef UMIDIQUIRK_DEBUG 56 #define DPRINTF(x) if (umidiquirkdebug) printf x 57 #define DPRINTFN(n,x) if (umidiquirkdebug >= (n)) printf x 58 int umidiquirkdebug = 1; 59 #else 60 #define DPRINTF(x) 61 #define DPRINTFN(n,x) 62 #endif 63 64 65 /* 66 * YAMAHA UX-256 67 * --- this is a typical yamaha device, but has a broken descriptor :-< 68 */ 69 70 UMQ_FIXED_EP_DEF(YAMAHA, YAMAHA_UX256, ANYIFACE, 1, 1) = { 71 /* out */ 72 { 0, 16 }, 73 /* in */ 74 { 1, 8 } 75 }; 76 77 UMQ_DEF(YAMAHA, YAMAHA_UX256, ANYIFACE) = { 78 UMQ_FIXED_EP_REG(YAMAHA, YAMAHA_UX256, ANYIFACE), 79 UMQ_TERMINATOR 80 }; 81 82 /* 83 * ROLAND UM-1 84 */ 85 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM1, 2, 1, 1) = { 86 /* out */ 87 { 0, 1 }, 88 /* in */ 89 { 1, 1 } 90 }; 91 92 UMQ_DEF(ROLAND, ROLAND_UM1, 2) = { 93 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM1, 2), 94 UMQ_TERMINATOR 95 }; 96 97 /* 98 * ROLAND SC-8850 99 */ 100 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SC8850, 2, 1, 1) = { 101 /* out */ 102 { 0, 6 }, 103 /* in */ 104 { 1, 6 } 105 }; 106 107 UMQ_DEF(ROLAND, ROLAND_SC8850, 2) = { 108 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SC8850, 2), 109 UMQ_TERMINATOR 110 }; 111 112 /* 113 * ROLAND SD-90 114 */ 115 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SD90, 2, 1, 1) = { 116 /* out */ 117 { 0, 4 }, 118 /* in */ 119 { 1, 4 } 120 }; 121 122 UMQ_DEF(ROLAND, ROLAND_SD90, 2) = { 123 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SD90, 2), 124 UMQ_TERMINATOR 125 }; 126 127 128 /* 129 * ROLAND UM-880 (native mode) 130 */ 131 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM880N, 0, 1, 1) = { 132 /* out */ 133 { 0, 9 }, 134 /* in */ 135 { 1, 9 } 136 }; 137 138 UMQ_DEF(ROLAND, ROLAND_UM880N, 0) = { 139 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM880N, 0), 140 UMQ_TERMINATOR 141 }; 142 143 /* 144 * ROLAND UA-100 145 */ 146 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA100, 2, 1, 1) = { 147 /* out */ 148 { 0, 3 }, 149 /* in */ 150 { 1, 3 } 151 }; 152 153 UMQ_DEF(ROLAND, ROLAND_UA100, 2) = { 154 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA100, 2), 155 UMQ_TERMINATOR 156 }; 157 158 /* 159 * ROLAND UM-4 160 */ 161 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM4, 2, 1, 1) = { 162 /* out */ 163 { 0, 4 }, 164 /* in */ 165 { 1, 4 } 166 }; 167 168 UMQ_DEF(ROLAND, ROLAND_UM4, 2) = { 169 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM4, 2), 170 UMQ_TERMINATOR 171 }; 172 173 /* 174 * ROLAND U-8 175 */ 176 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_U8, 2, 1, 1) = { 177 /* out */ 178 { 0, 2 }, 179 /* in */ 180 { 1, 2 } 181 }; 182 183 UMQ_DEF(ROLAND, ROLAND_U8, 2) = { 184 UMQ_FIXED_EP_REG(ROLAND, ROLAND_U8, 2), 185 UMQ_TERMINATOR 186 }; 187 188 /* 189 * ROLAND UM-2 190 */ 191 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM2, 2, 1, 1) = { 192 /* out */ 193 { 0, 2 }, 194 /* in */ 195 { 1, 2 } 196 }; 197 198 UMQ_DEF(ROLAND, ROLAND_UM2, 2) = { 199 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM2, 2), 200 UMQ_TERMINATOR 201 }; 202 203 /* 204 * ROLAND SC-8820 205 */ 206 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SC8820, 2, 1, 1) = { 207 /* out */ 208 { 0, 5 }, /* cables 0, 1, 4 only */ 209 /* in */ 210 { 1, 5 } /* do. */ 211 }; 212 213 UMQ_DEF(ROLAND, ROLAND_SC8820, 2) = { 214 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SC8820, 2), 215 UMQ_TERMINATOR 216 }; 217 218 /* 219 * ROLAND PC-300 220 */ 221 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_PC300, 2, 1, 1) = { 222 /* out */ 223 { 0, 1 }, 224 /* in */ 225 { 1, 1 } 226 }; 227 228 UMQ_DEF(ROLAND, ROLAND_PC300, 2) = { 229 UMQ_FIXED_EP_REG(ROLAND, ROLAND_PC300, 2), 230 UMQ_TERMINATOR 231 }; 232 233 /* 234 * ROLAND SK-500 235 */ 236 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SK500, 2, 1, 1) = { 237 /* out */ 238 { 0, 5 }, /* cables 0, 1, 4 only */ 239 /* in */ 240 { 1, 5 } /* do. */ 241 }; 242 243 UMQ_DEF(ROLAND, ROLAND_SK500, 2) = { 244 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SK500, 2), 245 UMQ_TERMINATOR 246 }; 247 248 /* 249 * ROLAND SC-D70 250 */ 251 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SCD70, 2, 1, 1) = { 252 /* out */ 253 { 0, 3 }, 254 /* in */ 255 { 1, 3 } 256 }; 257 258 UMQ_DEF(ROLAND, ROLAND_SCD70, 2) = { 259 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SCD70, 2), 260 UMQ_TERMINATOR 261 }; 262 263 /* 264 * ROLAND UM-550 265 */ 266 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM550, 0, 1, 1) = { 267 /* out */ 268 { 0, 6 }, 269 /* in */ 270 { 1, 6 } 271 }; 272 273 UMQ_DEF(ROLAND, ROLAND_UM550, 0) = { 274 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM550, 0), 275 UMQ_TERMINATOR 276 }; 277 278 /* 279 * ROLAND SD-20 280 */ 281 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SD20, 0, 1, 1) = { 282 /* out */ 283 { 0, 2 }, 284 /* in */ 285 { 1, 3 } 286 }; 287 288 UMQ_DEF(ROLAND, ROLAND_SD20, 0) = { 289 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SD20, 0), 290 UMQ_TERMINATOR 291 }; 292 293 /* 294 * ROLAND SD-80 295 */ 296 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SD80, 0, 1, 1) = { 297 /* out */ 298 { 0, 4 }, 299 /* in */ 300 { 1, 4 } 301 }; 302 303 UMQ_DEF(ROLAND, ROLAND_SD80, 0) = { 304 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SD80, 0), 305 UMQ_TERMINATOR 306 }; 307 308 /* 309 * ROLAND UA-700 310 */ 311 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA700, 3, 1, 1) = { 312 /* out */ 313 { 0, 2 }, 314 /* in */ 315 { 1, 2 } 316 }; 317 318 UMQ_DEF(ROLAND, ROLAND_UA700, 3) = { 319 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA700, 3), 320 UMQ_TERMINATOR 321 }; 322 323 /* 324 * ROLAND UM-ONE 325 */ 326 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UMONE, ANYIFACE, 1, 1) = { 327 /* out */ 328 { 0, 1 }, 329 /* in */ 330 { 1, 1 } 331 }; 332 333 UMQ_DEF(ROLAND, ROLAND_UMONE, ANYIFACE) = { 334 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UMONE, ANYIFACE), 335 UMQ_TERMINATOR 336 }; 337 338 /* 339 * quirk list 340 */ 341 struct umidi_quirk umidi_quirklist[] = { 342 UMQ_REG(YAMAHA, YAMAHA_UX256, ANYIFACE), 343 UMQ_REG(ROLAND, ROLAND_UM1, 2), 344 UMQ_REG(ROLAND, ROLAND_SC8850, 2), 345 UMQ_REG(ROLAND, ROLAND_SD90, 2), 346 UMQ_REG(ROLAND, ROLAND_UM880N, 0), 347 UMQ_REG(ROLAND, ROLAND_UA100, 2), 348 UMQ_REG(ROLAND, ROLAND_UM4, 2), 349 UMQ_REG(ROLAND, ROLAND_U8, 2), 350 UMQ_REG(ROLAND, ROLAND_UM2, 2), 351 UMQ_REG(ROLAND, ROLAND_SC8820, 2), 352 UMQ_REG(ROLAND, ROLAND_PC300, 2), 353 UMQ_REG(ROLAND, ROLAND_SK500, 2), 354 UMQ_REG(ROLAND, ROLAND_SCD70, 2), 355 UMQ_REG(ROLAND, ROLAND_UM550, 0), 356 UMQ_REG(ROLAND, ROLAND_SD20, 0), 357 UMQ_REG(ROLAND, ROLAND_SD80, 0), 358 UMQ_REG(ROLAND, ROLAND_UA700, 3), 359 UMQ_REG(ROLAND, ROLAND_UMONE, ANYIFACE), 360 UMQ_TERMINATOR 361 }; 362 363 364 /* 365 * quirk utilities 366 */ 367 368 struct umidi_quirk * 369 umidi_search_quirk(int vendor, int product, int ifaceno) 370 { 371 struct umidi_quirk *p; 372 struct umq_data *q; 373 374 DPRINTF(("umidi_search_quirk: v=%d, p=%d, i=%d\n", 375 vendor, product, ifaceno)); 376 377 for (p=&umidi_quirklist[0]; p->vendor; p++) { 378 DPRINTFN(10, ("\tv=%d, p=%d, i=%d", 379 p->vendor, p->product, p->iface)); 380 if ((p->vendor==vendor || p->vendor==ANYVENDOR) && 381 (p->product==product || p->product==ANYPRODUCT) && 382 (p->iface==ifaceno || p->iface==ANYIFACE)) { 383 DPRINTFN(10, (" found\n")); 384 if (!p->type_mask) 385 /* make quirk mask */ 386 for (q=p->quirks; q->type; q++) 387 p->type_mask |= 1<<(q->type-1); 388 return p; 389 } 390 DPRINTFN(10, ("\n")); 391 } 392 393 return NULL; 394 } 395 396 static char *quirk_name[] = { 397 "NULL", 398 "Fixed Endpoint", 399 "Yamaha Specific", 400 }; 401 402 void 403 umidi_print_quirk(struct umidi_quirk *q) 404 { 405 struct umq_data *qd; 406 if (q) { 407 printf("("); 408 for (qd=q->quirks; qd->type; qd++) 409 printf("%s%s", quirk_name[qd->type], 410 (qd+1)->type?", ":")\n"); 411 } else { 412 printf("(genuine USB-MIDI)\n"); 413 } 414 } 415 416 void * 417 umidi_get_quirk_data_from_type(struct umidi_quirk *q, u_int32_t type) 418 { 419 struct umq_data *qd; 420 if (q) { 421 for (qd=q->quirks; qd->type; qd++) 422 if (qd->type == type) 423 return qd->data; 424 } 425 return NULL; 426 } 427