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