1 /* $NetBSD: umass_quirks.c,v 1.44 2003/07/14 15:47:29 lukem Exp $ */ 2 3 /* 4 * Copyright (c) 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by MAEKAWA Masahide (gehenna@NetBSD.org). 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 #include <sys/cdefs.h> 40 __KERNEL_RCSID(0, "$NetBSD: umass_quirks.c,v 1.44 2003/07/14 15:47:29 lukem Exp $"); 41 42 #include <sys/param.h> 43 #include <sys/systm.h> 44 #include <sys/device.h> 45 #include <sys/buf.h> 46 47 #include <dev/scsipi/scsipi_all.h> /* for scsiconf.h below */ 48 #include <dev/scsipi/scsiconf.h> /* for quirks defines */ 49 50 #include <dev/usb/usb.h> 51 #include <dev/usb/usbdi.h> 52 #include <dev/usb/usbdevs.h> 53 54 #include <dev/usb/umassvar.h> 55 #include <dev/usb/umass_quirks.h> 56 57 Static usbd_status umass_init_insystem(struct umass_softc *); 58 Static usbd_status umass_init_shuttle(struct umass_softc *); 59 60 Static void umass_fixup_sony(struct umass_softc *); 61 Static void umass_fixup_yedata(struct umass_softc *); 62 63 Static const struct umass_quirk umass_quirks[] = { 64 { { USB_VENDOR_LACIE, USB_PRODUCT_LACIE_PKTDRV}, 65 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 66 0, 67 PQUIRK_NOMODESENSE, 68 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 69 NULL, NULL 70 }, 71 72 { { USB_VENDOR_ACDC, USB_PRODUCT_ACDC_PEN }, 73 UMASS_WPROTO_BBB, UMASS_CPROTO_SCSI, 74 UMASS_QUIRK_NO_MAX_LUN | UMASS_QUIRK_NO_START_STOP, 75 PQUIRK_NOMODESENSE, 76 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 77 NULL, NULL 78 }, 79 80 { { USB_VENDOR_ATI, USB_PRODUCT_ATI2_205 }, 81 UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA, 82 0, 83 0, 84 UMATCH_VENDOR_PRODUCT, 85 NULL, NULL 86 }, 87 88 { { USB_VENDOR_DMI, USB_PRODUCT_DMI_SA2_0 }, 89 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 90 0, 91 PQUIRK_NOMODESENSE, 92 UMATCH_VENDOR_PRODUCT, 93 NULL, NULL 94 }, 95 96 { { USB_VENDOR_EASYDISK, USB_PRODUCT_EASYDISK_EASYDISK }, 97 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 98 0, 99 PQUIRK_NOMODESENSE, 100 UMATCH_VENDOR_PRODUCT, 101 NULL, NULL 102 }, 103 104 { { USB_VENDOR_FUJIPHOTO, USB_PRODUCT_FUJIPHOTO_MASS0100 }, 105 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 106 UMASS_QUIRK_NO_START_STOP, 107 PQUIRK_NOTUR | PQUIRK_NOSENSE, 108 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 109 NULL, NULL 110 }, 111 112 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ADAPTERV2 }, 113 UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA, 114 0, 115 0, 116 UMATCH_VENDOR_PRODUCT, 117 NULL, NULL 118 }, 119 120 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ATAPI }, 121 UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA, 122 0, 123 0, 124 UMATCH_VENDOR_PRODUCT, 125 NULL, NULL 126 }, 127 128 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_DRIVEV2_5 }, 129 UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA, 130 0, 131 0, 132 UMATCH_VENDOR_PRODUCT, 133 NULL, NULL 134 }, 135 136 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_IDEUSB2 }, 137 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 138 0, 139 PQUIRK_NOMODESENSE, 140 UMATCH_VENDOR_PRODUCT, 141 NULL, NULL 142 }, 143 144 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_USBCABLE }, 145 UMASS_WPROTO_CBI, UMASS_CPROTO_ATAPI, 146 UMASS_QUIRK_NO_START_STOP, 147 PQUIRK_NOTUR, 148 UMATCH_VENDOR_PRODUCT, 149 umass_init_insystem, NULL 150 }, 151 152 { { USB_VENDOR_IODATA2, USB_PRODUCT_IODATA2_USB2SC }, 153 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 154 0, 155 0, 156 UMATCH_VENDOR_PRODUCT, 157 NULL, NULL 158 }, 159 160 { { USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_ZIP100 }, 161 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 162 0, 163 PQUIRK_NOTUR, 164 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 165 NULL, NULL 166 }, 167 168 { { USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_ZIP250 }, 169 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 170 0, 171 PQUIRK_NOTUR, 172 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 173 NULL, NULL 174 }, 175 176 177 { { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_DUBPXXG }, 178 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 179 UMASS_QUIRK_FORCE_SHORT_INQUIRY | UMASS_QUIRK_NO_START_STOP, 180 PQUIRK_NOMODESENSE, 181 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 182 NULL, NULL 183 }, 184 185 { { USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_DPCM }, 186 UMASS_WPROTO_CBI, UMASS_CPROTO_ATAPI, 187 0, 188 0, 189 UMATCH_VENDOR_PRODUCT, 190 NULL, NULL 191 }, 192 193 { { USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_S304 }, 194 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 195 UMASS_QUIRK_NO_MAX_LUN | UMASS_QUIRK_NO_START_STOP, 196 0, 197 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 198 NULL, NULL 199 }, 200 201 { { USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_X }, 202 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 203 UMASS_QUIRK_NO_MAX_LUN | UMASS_QUIRK_NO_START_STOP, 204 0, 205 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 206 NULL, NULL 207 }, 208 209 { { USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY }, 210 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 211 UMASS_QUIRK_NO_MAX_LUN, 212 PQUIRK_NOMODESENSE | PQUIRK_NODOORLOCK | PQUIRK_NOBIGMODESENSE, 213 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 214 NULL, NULL 215 }, 216 217 { { USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY2 }, 218 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 219 UMASS_QUIRK_NO_MAX_LUN, 220 PQUIRK_NOMODESENSE | PQUIRK_NODOORLOCK | PQUIRK_NOBIGMODESENSE, 221 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 222 NULL, NULL 223 }, 224 225 { { USB_VENDOR_NEODIO, USB_PRODUCT_NEODIO_ND3050 }, 226 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 227 0, 228 PQUIRK_NOMODESENSE | PQUIRK_FORCELUNS, 229 UMATCH_VENDOR_PRODUCT, 230 NULL, NULL 231 }, 232 233 { { USB_VENDOR_NEODIO, USB_PRODUCT_NEODIO_ND5010 }, 234 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 235 0, 236 PQUIRK_NOMODESENSE | PQUIRK_FORCELUNS, 237 UMATCH_VENDOR_PRODUCT, 238 NULL, NULL 239 }, 240 241 { { USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C1 }, 242 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 243 UMASS_QUIRK_WRONG_CSWSIG, 244 0, 245 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 246 NULL, NULL 247 }, 248 249 { { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MD1II }, 250 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 251 UMASS_QUIRK_NO_MAX_LUN | UMASS_QUIRK_NO_START_STOP, 252 PQUIRK_NOMODESENSE, 253 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 254 NULL, NULL 255 }, 256 257 { { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MD2 }, 258 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 259 0, 260 PQUIRK_NOMODESENSE, 261 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 262 NULL, NULL 263 }, 264 265 { { USB_VENDOR_OTI, USB_PRODUCT_OTI_SOLID }, 266 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 267 0, 268 PQUIRK_NOMODESENSE | PQUIRK_NOBIGMODESENSE, 269 UMATCH_VENDOR_PRODUCT, 270 NULL, NULL 271 }, 272 273 { { USB_VENDOR_OTI, USB_PRODUCT_OTI_FLASHDISK }, 274 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 275 0, 276 PQUIRK_NOMODESENSE | PQUIRK_NOBIGMODESENSE, 277 UMATCH_VENDOR_PRODUCT, 278 NULL, NULL 279 }, 280 281 { { USB_VENDOR_PEN, USB_PRODUCT_PEN_MOBILEDRIVE }, 282 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 283 0, 284 PQUIRK_NOMODESENSE | PQUIRK_NODOORLOCK | PQUIRK_FORCELUNS, 285 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 286 NULL, NULL 287 }, 288 289 { { USB_VENDOR_PEN, USB_PRODUCT_PEN_USBDISKPRO }, 290 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 291 UMASS_QUIRK_NO_MAX_LUN, 292 PQUIRK_NOMODESENSE | PQUIRK_NOBIGMODESENSE, 293 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 294 NULL, NULL 295 }, 296 297 { { USB_VENDOR_PEN, USB_PRODUCT_PEN_USBDISK }, 298 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 299 UMASS_QUIRK_NO_MAX_LUN | UMASS_QUIRK_NO_START_STOP, 300 0, 301 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 302 NULL, NULL 303 }, 304 305 { { USB_VENDOR_PEN, USB_PRODUCT_PEN_USBREADER }, 306 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 307 0, 308 PQUIRK_NOMODESENSE, 309 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 310 NULL, NULL 311 }, 312 313 { { USB_VENDOR_PILOTECH, USB_PRODUCT_PILOTECH_CRW600 }, 314 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 315 0, 316 PQUIRK_NOMODESENSE | PQUIRK_FORCELUNS, 317 UMATCH_VENDOR_PRODUCT, 318 NULL, NULL 319 }, 320 321 { { USB_VENDOR_PQI, USB_PRODUCT_PQI_TRAVELFLASH }, 322 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 323 0, 324 PQUIRK_NOMODESENSE | PQUIRK_NODOORLOCK, 325 UMATCH_VENDOR_PRODUCT, 326 NULL, NULL 327 }, 328 329 { { USB_VENDOR_SCANLOGIC, USB_PRODUCT_SCANLOGIC_SL11R }, 330 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UFI, 331 UMASS_QUIRK_WRONG_CSWTAG, 332 0, 333 UMATCH_VENDOR_PRODUCT, 334 NULL, NULL 335 }, 336 337 { { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSB }, 338 UMASS_WPROTO_CBI_I, UMASS_CPROTO_ATAPI, 339 UMASS_QUIRK_NO_START_STOP, 340 PQUIRK_NOTUR, 341 UMATCH_VENDOR_PRODUCT, 342 umass_init_shuttle, NULL 343 }, 344 345 { { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_ZIOMMC }, 346 UMASS_WPROTO_CBI_I, UMASS_CPROTO_ATAPI, 347 UMASS_QUIRK_NO_START_STOP, 348 PQUIRK_NOTUR, 349 UMATCH_VENDOR_PRODUCT, 350 NULL, NULL 351 }, 352 353 { { USB_VENDOR_SIIG, USB_PRODUCT_SIIG_MULTICARDREADER }, 354 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 355 UMASS_QUIRK_NO_START_STOP, 356 0, 357 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 358 NULL,NULL 359 }, 360 361 { { USB_VENDOR_SONY, USB_PRODUCT_SONY_DRIVEV2 }, 362 UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA, 363 0, 364 0, 365 UMATCH_VENDOR_PRODUCT, 366 NULL, NULL 367 }, 368 369 { { USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC }, 370 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 371 0, 372 0, 373 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 374 NULL, umass_fixup_sony 375 }, 376 377 { { USB_VENDOR_SONY, USB_PRODUCT_SONY_MSC_U03 }, 378 UMASS_WPROTO_CBI, UMASS_CPROTO_UFI, 379 0, 380 0, 381 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 382 NULL, umass_fixup_sony 383 }, 384 385 { { USB_VENDOR_SONY, USB_PRODUCT_SONY_MSC }, 386 UMASS_WPROTO_CBI, UMASS_CPROTO_UFI, 387 UMASS_QUIRK_FORCE_SHORT_INQUIRY | UMASS_QUIRK_RS_NO_CLEAR_UA, 388 PQUIRK_NOMODESENSE, 389 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 390 NULL, NULL 391 }, 392 393 { { USB_VENDOR_TEAC, USB_PRODUCT_TEAC_FD05PUB }, 394 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 395 0, 396 PQUIRK_NOMODESENSE, 397 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 398 NULL, NULL 399 }, 400 401 { { USB_VENDOR_TRUMPION, USB_PRODUCT_TRUMPION_XXX1100 }, 402 UMASS_WPROTO_CBI, UMASS_CPROTO_ATAPI, 403 0, 404 0, 405 UMATCH_VENDOR_PRODUCT, 406 NULL, NULL 407 }, 408 409 { { USB_VENDOR_YANO, USB_PRODUCT_YANO_U640MO }, 410 UMASS_WPROTO_CBI_I, UMASS_CPROTO_ATAPI, 411 UMASS_QUIRK_FORCE_SHORT_INQUIRY, 412 0, 413 UMATCH_VENDOR_PRODUCT, 414 NULL, NULL 415 }, 416 417 { { USB_VENDOR_YEDATA, USB_PRODUCT_YEDATA_FLASHBUSTERU }, 418 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UFI, 419 UMASS_QUIRK_RS_NO_CLEAR_UA, 420 PQUIRK_NOMODESENSE, 421 UMATCH_VENDOR_PRODUCT_REV, 422 NULL, umass_fixup_yedata 423 }, 424 425 { { USB_VENDOR_GENESYS,USB_PRODUCT_GENESYS_GL641USB }, 426 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 427 UMASS_QUIRK_FORCE_SHORT_INQUIRY | UMASS_QUIRK_NO_START_STOP, 428 PQUIRK_NOMODESENSE, 429 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 430 NULL, NULL 431 }, 432 }; 433 434 const struct umass_quirk * 435 umass_lookup(u_int16_t vendor, u_int16_t product) 436 { 437 return ((const struct umass_quirk *) 438 usb_lookup(umass_quirks, vendor, product)); 439 } 440 441 Static usbd_status 442 umass_init_insystem(struct umass_softc *sc) 443 { 444 usbd_status err; 445 446 err = usbd_set_interface(sc->sc_iface, 1); 447 if (err) { 448 DPRINTF(UDMASS_USB, 449 ("%s: could not switch to Alt Interface 1\n", 450 USBDEVNAME(sc->sc_dev))); 451 return (err); 452 } 453 454 return (USBD_NORMAL_COMPLETION); 455 } 456 457 Static usbd_status 458 umass_init_shuttle(struct umass_softc *sc) 459 { 460 usb_device_request_t req; 461 u_int8_t status[2]; 462 463 /* The Linux driver does this */ 464 req.bmRequestType = UT_READ_VENDOR_DEVICE; 465 req.bRequest = 1; 466 USETW(req.wValue, 0); 467 USETW(req.wIndex, sc->sc_ifaceno); 468 USETW(req.wLength, sizeof(status)); 469 470 return (usbd_do_request(sc->sc_udev, &req, &status)); 471 } 472 473 Static void 474 umass_fixup_sony(struct umass_softc *sc) 475 { 476 usb_interface_descriptor_t *id; 477 478 id = usbd_get_interface_descriptor(sc->sc_iface); 479 if (id->bInterfaceSubClass == 0xff) { 480 sc->sc_cmd = UMASS_CPROTO_RBC; 481 } 482 } 483 484 Static void 485 umass_fixup_yedata(struct umass_softc *sc) 486 { 487 usb_device_descriptor_t *dd; 488 489 dd = usbd_get_device_descriptor(sc->sc_udev); 490 491 /* 492 * Revisions < 1.28 do not handle the interrupt endpoint very well. 493 */ 494 if (UGETW(dd->bcdDevice) < 0x128) 495 sc->sc_wire = UMASS_WPROTO_CBI; 496 else 497 sc->sc_wire = UMASS_WPROTO_CBI_I; 498 499 /* 500 * Revisions < 1.28 do not have the TEST UNIT READY command 501 * Revisions == 1.28 have a broken TEST UNIT READY 502 */ 503 if (UGETW(dd->bcdDevice) <= 0x128) 504 sc->sc_busquirks |= PQUIRK_NOTUR; 505 } 506