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