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