1 /* $OpenBSD: umass_quirks.c,v 1.35 2024/05/23 03:21:09 jsg Exp $ */ 2 /* $NetBSD: umass_quirks.c,v 1.67 2004/06/28 07:49:16 mycroft 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 MAEKAWA Masahide (gehenna@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/device.h> 36 37 #include <scsi/scsi_all.h> 38 #include <scsi/scsiconf.h> 39 40 #include <dev/usb/usb.h> 41 #include <dev/usb/usbdi.h> 42 #include <dev/usb/usbdevs.h> 43 44 #include <dev/usb/umassvar.h> 45 #include <dev/usb/umass_quirks.h> 46 47 usbd_status umass_init_insystem(struct umass_softc *); 48 usbd_status umass_init_shuttle(struct umass_softc *); 49 50 void umass_fixup_sony(struct umass_softc *); 51 void umass_fixup_yedata(struct umass_softc *); 52 53 const struct umass_quirk umass_quirks[] = { 54 { { USB_VENDOR_ATI, USB_PRODUCT_ATI2_205 }, 55 UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA, 56 0, 57 0, 58 UMATCH_VENDOR_PRODUCT, 59 NULL, NULL 60 }, 61 62 { { USB_VENDOR_DMI, USB_PRODUCT_DMI_SA2_0 }, 63 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 64 0, 65 0, 66 UMATCH_VENDOR_PRODUCT, 67 NULL, NULL 68 }, 69 70 { { USB_VENDOR_DOMAIN, USB_PRODUCT_DOMAIN_ROCKCHIP }, 71 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 72 UMASS_QUIRK_WRONG_CSWTAG, 73 0, 74 UMATCH_VENDOR_PRODUCT, 75 NULL, NULL 76 }, 77 78 { { USB_VENDOR_EASYDISK, USB_PRODUCT_EASYDISK_EASYDISK }, 79 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 80 0, 81 0, 82 UMATCH_VENDOR_PRODUCT, 83 NULL, NULL 84 }, 85 86 { { USB_VENDOR_FUJIPHOTO, USB_PRODUCT_FUJIPHOTO_MASS0100 }, 87 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 88 0, 89 ADEV_NOSENSE, 90 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 91 NULL, NULL 92 }, 93 94 { { USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB }, 95 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 96 0, 97 0, 98 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 99 NULL, NULL 100 }, 101 102 { { USB_VENDOR_HP, USB_PRODUCT_HP_CDWRITERPLUS }, 103 UMASS_WPROTO_CBI, UMASS_CPROTO_ATAPI, 104 0, 105 ADEV_NOSENSE, 106 UMATCH_VENDOR_PRODUCT, 107 NULL, NULL 108 }, 109 110 { { USB_VENDOR_IMATION, USB_PRODUCT_IMATION_FLASHGO }, 111 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 112 0, 113 0, 114 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 115 NULL, NULL 116 }, 117 118 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ADAPTERV2 }, 119 UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA, 120 0, 121 0, 122 UMATCH_VENDOR_PRODUCT, 123 NULL, NULL 124 }, 125 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ATAPI }, 126 UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA, 127 0, 128 0, 129 UMATCH_VENDOR_PRODUCT, 130 NULL, NULL 131 }, 132 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_DRIVEV2_5 }, 133 UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA, 134 0, 135 0, 136 UMATCH_VENDOR_PRODUCT, 137 NULL, NULL 138 }, 139 140 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_IDEUSB2 }, 141 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 142 0, 143 0, 144 UMATCH_VENDOR_PRODUCT, 145 NULL, NULL 146 }, 147 148 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_USBCABLE }, 149 UMASS_WPROTO_CBI, UMASS_CPROTO_ATAPI, 150 0, 151 0, 152 UMATCH_VENDOR_PRODUCT, 153 umass_init_insystem, NULL 154 }, 155 156 { { USB_VENDOR_IODATA2, USB_PRODUCT_IODATA2_USB2SC }, 157 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 158 0, 159 0, 160 UMATCH_VENDOR_PRODUCT, 161 NULL, NULL 162 }, 163 164 { { USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_ZIP100 }, 165 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 166 0, 167 0, 168 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 169 NULL, NULL 170 }, 171 172 { { USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_ZIP250 }, 173 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 174 0, 175 0, 176 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 177 NULL, NULL 178 }, 179 180 { { USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_ZIP250_2 }, 181 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 182 0, 183 0, 184 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 185 NULL, NULL 186 }, 187 188 { { USB_VENDOR_IRIVER, USB_PRODUCT_IRIVER_IFP_1XX }, 189 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 190 0, 191 0, 192 UMATCH_VENDOR_PRODUCT, 193 NULL, NULL 194 }, 195 196 { { USB_VENDOR_IRIVER, USB_PRODUCT_IRIVER_IFP_3XX }, 197 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 198 0, 199 0, 200 UMATCH_VENDOR_PRODUCT, 201 NULL, NULL 202 }, 203 204 { { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_DUBPXXG }, 205 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 206 0, 207 0, 208 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 209 NULL, NULL 210 }, 211 212 { { USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_DPCM }, 213 UMASS_WPROTO_CBI, UMASS_CPROTO_ATAPI, 214 0, 215 0, 216 UMATCH_VENDOR_PRODUCT, 217 NULL, NULL 218 }, 219 220 { { USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_S304 }, 221 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 222 0, 223 0, 224 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 225 NULL, NULL 226 }, 227 228 { { USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_X }, 229 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 230 0, 231 0, 232 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 233 NULL, NULL 234 }, 235 236 { { USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_DIMAGEA1 }, 237 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 238 0, 239 0, 240 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 241 NULL, NULL 242 }, 243 244 { { USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY }, 245 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 246 0, 247 0, 248 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 249 NULL, NULL 250 }, 251 252 { { USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY2 }, 253 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_ATAPI, 254 0, 255 0, 256 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 257 NULL, NULL 258 }, 259 260 { { USB_VENDOR_NEODIO, USB_PRODUCT_NEODIO_ND3050 }, 261 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 262 0, 263 0, 264 UMATCH_VENDOR_PRODUCT, 265 NULL, NULL 266 }, 267 268 { { USB_VENDOR_NEODIO, USB_PRODUCT_NEODIO_ND5010 }, 269 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 270 0, 271 0, 272 UMATCH_VENDOR_PRODUCT, 273 NULL, NULL 274 }, 275 276 { { USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C1 }, 277 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 278 UMASS_QUIRK_WRONG_CSWSIG, 279 0, 280 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 281 NULL, NULL 282 }, 283 284 { { USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C700 }, 285 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 286 0, 287 SDEV_NOSYNCCACHE, 288 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 289 NULL, NULL 290 }, 291 292 { { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MD1II }, 293 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 294 0, 295 0, 296 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 297 NULL, NULL 298 }, 299 300 { { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MD2 }, 301 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 302 0, 303 0, 304 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 305 NULL, NULL 306 }, 307 308 { { USB_VENDOR_OTI, USB_PRODUCT_OTI_SOLID }, 309 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 310 0, 311 0, 312 UMATCH_VENDOR_PRODUCT, 313 NULL, NULL 314 }, 315 316 { { USB_VENDOR_PEN, USB_PRODUCT_PEN_MOBILEDRIVE }, 317 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 318 0, 319 0, 320 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 321 NULL, NULL 322 }, 323 324 { { USB_VENDOR_PEN, USB_PRODUCT_PEN_USBDISK }, 325 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 326 0, 327 0, 328 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 329 NULL, NULL 330 }, 331 332 { { USB_VENDOR_PEN, USB_PRODUCT_PEN_USBREADER }, 333 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 334 0, 335 0, 336 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 337 NULL, NULL 338 }, 339 340 { { USB_VENDOR_PILOTECH, USB_PRODUCT_PILOTECH_CRW600 }, 341 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 342 0, 343 0, 344 UMATCH_VENDOR_PRODUCT, 345 NULL, NULL 346 }, 347 348 { { USB_VENDOR_PQI, USB_PRODUCT_PQI_TRAVELFLASH }, 349 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 350 0, 351 0, 352 UMATCH_VENDOR_PRODUCT, 353 NULL, NULL 354 }, 355 356 { { USB_VENDOR_SCANLOGIC, USB_PRODUCT_SCANLOGIC_SL11R }, 357 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 358 UMASS_QUIRK_WRONG_CSWTAG, 359 0, 360 UMATCH_VENDOR_PRODUCT, 361 NULL, NULL 362 }, 363 364 { { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSB }, 365 UMASS_WPROTO_CBI_I, UMASS_CPROTO_ATAPI, 366 0, 367 ADEV_NOSENSE, 368 UMATCH_VENDOR_PRODUCT, 369 umass_init_shuttle, NULL 370 }, 371 372 { { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_ZIOMMC }, 373 UMASS_WPROTO_CBI_I, UMASS_CPROTO_ATAPI, 374 0, 375 0, 376 UMATCH_VENDOR_PRODUCT, 377 NULL, NULL 378 }, 379 380 { { USB_VENDOR_SIIG, USB_PRODUCT_SIIG_MULTICARDREADER }, 381 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 382 0, 383 0, 384 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 385 NULL,NULL 386 }, 387 388 { { USB_VENDOR_SONY, USB_PRODUCT_SONY_DRIVEV2 }, 389 UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA, 390 0, 391 0, 392 UMATCH_VENDOR_PRODUCT, 393 NULL, NULL 394 }, 395 396 { { USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC }, 397 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 398 0, 399 0, 400 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 401 NULL, umass_fixup_sony 402 }, 403 404 { { USB_VENDOR_SONY, USB_PRODUCT_SONY_MSC }, 405 UMASS_WPROTO_CBI, UMASS_CPROTO_UFI, 406 0, 407 0, 408 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 409 NULL, NULL 410 }, 411 412 { { USB_VENDOR_TEAC, USB_PRODUCT_TEAC_FD05PUB }, 413 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 414 0, 415 0, 416 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 417 NULL, NULL 418 }, 419 420 { { USB_VENDOR_TREK, USB_PRODUCT_TREK_THUMBDRIVE_8MB }, 421 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 422 0, 423 0, 424 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 425 NULL, NULL 426 }, 427 428 { { USB_VENDOR_TRUMPION, USB_PRODUCT_TRUMPION_XXX1100 }, 429 UMASS_WPROTO_CBI, UMASS_CPROTO_ATAPI, 430 0, 431 0, 432 UMATCH_VENDOR_PRODUCT, 433 NULL, NULL 434 }, 435 436 { { USB_VENDOR_YANO, USB_PRODUCT_YANO_U640MO }, 437 UMASS_WPROTO_CBI_I, UMASS_CPROTO_ATAPI, 438 0, 439 0, 440 UMATCH_VENDOR_PRODUCT, 441 NULL, NULL 442 }, 443 444 { { USB_VENDOR_YEDATA, USB_PRODUCT_YEDATA_FLASHBUSTERU }, 445 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UFI, 446 0, 447 0, 448 UMATCH_VENDOR_PRODUCT_REV, 449 NULL, umass_fixup_yedata 450 }, 451 452 { { USB_VENDOR_SIGMATEL, USB_PRODUCT_SIGMATEL_DNSSF7X}, 453 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 454 0, 455 SDEV_NOSYNCCACHE, 456 UMATCH_VENDOR_PRODUCT, 457 NULL, NULL 458 }, 459 460 { { USB_VENDOR_CREATIVE, USB_PRODUCT_CREATIVE_NOMAD}, 461 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 462 0, 463 SDEV_NOSYNCCACHE, 464 UMATCH_VENDOR_PRODUCT, 465 NULL, NULL 466 }, 467 468 { { USB_VENDOR_SUPERTOP, USB_PRODUCT_SUPERTOP_IDEBRIDGE }, 469 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 470 0, 471 ADEV_NOSENSE, 472 UMATCH_VENDOR_PRODUCT, 473 NULL, NULL 474 }, 475 476 { { USB_VENDOR_ERICSSON, USB_PRODUCT_ERICSSON_F5521GW }, 477 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 478 0, 479 0, 480 UMATCH_NONE, 481 NULL, NULL 482 }, 483 }; 484 485 const struct umass_quirk * 486 umass_lookup(u_int16_t vendor, u_int16_t product) 487 { 488 return ((const struct umass_quirk *) 489 usb_lookup(umass_quirks, vendor, product)); 490 } 491 492 usbd_status 493 umass_init_insystem(struct umass_softc *sc) 494 { 495 usbd_status err; 496 497 err = usbd_set_interface(sc->sc_iface, 1); 498 if (err) { 499 DPRINTF(UDMASS_USB, 500 ("%s: could not switch to Alt Interface 1\n", 501 sc->sc_dev.dv_xname)); 502 return (err); 503 } 504 505 return (USBD_NORMAL_COMPLETION); 506 } 507 508 usbd_status 509 umass_init_shuttle(struct umass_softc *sc) 510 { 511 usb_device_request_t req; 512 u_int8_t status[2]; 513 514 /* The Linux driver does this */ 515 req.bmRequestType = UT_READ_VENDOR_DEVICE; 516 req.bRequest = 1; 517 USETW(req.wValue, 0); 518 USETW(req.wIndex, sc->sc_ifaceno); 519 USETW(req.wLength, sizeof(status)); 520 521 return (usbd_do_request(sc->sc_udev, &req, &status)); 522 } 523 524 void 525 umass_fixup_sony(struct umass_softc *sc) 526 { 527 usb_interface_descriptor_t *id; 528 usb_device_descriptor_t *dd; 529 530 id = usbd_get_interface_descriptor(sc->sc_iface); 531 if (id->bInterfaceSubClass == 0xff) { 532 dd = usbd_get_device_descriptor(sc->sc_udev); 533 /* 534 * Many Sony DSC cameras share the same product ID, so the 535 * revision number is used to distinguish between them. 536 */ 537 switch (UGETW(dd->bcdDevice)) { 538 case 0x611: /* Sony DSC-T10, rev 6.11 */ 539 case 0x600: /* Sony DSC-W50, rev 6.00 */ 540 case 0x500: /* Sony DSC-P41, rev 5.00 */ 541 sc->sc_cmd = UMASS_CPROTO_UFI; 542 break; 543 default: 544 sc->sc_cmd = UMASS_CPROTO_SCSI; 545 } 546 } 547 } 548 549 void 550 umass_fixup_yedata(struct umass_softc *sc) 551 { 552 usb_device_descriptor_t *dd; 553 554 dd = usbd_get_device_descriptor(sc->sc_udev); 555 556 /* 557 * Revisions < 1.28 do not handle the interrupt endpoint very well. 558 */ 559 if (UGETW(dd->bcdDevice) < 0x128) 560 sc->sc_wire = UMASS_WPROTO_CBI; 561 else 562 sc->sc_wire = UMASS_WPROTO_CBI_I; 563 } 564