1 /* $NetBSD: umass_quirks.c,v 1.24 2002/10/05 01:11:47 gehenna 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/param.h> 40 #include <sys/systm.h> 41 #include <sys/device.h> 42 #include <sys/buf.h> 43 44 #include <dev/scsipi/scsipi_all.h> /* for scsiconf.h below */ 45 #include <dev/scsipi/scsiconf.h> /* for quirks defines */ 46 47 #include <dev/usb/usb.h> 48 #include <dev/usb/usbdi.h> 49 #include <dev/usb/usbdevs.h> 50 51 #include <dev/usb/umassvar.h> 52 #include <dev/usb/umass_quirks.h> 53 54 Static usbd_status umass_init_insystem(struct umass_softc *); 55 Static usbd_status umass_init_shuttle(struct umass_softc *); 56 57 Static void umass_fixup_yedata(struct umass_softc *); 58 59 Static const struct umass_quirk umass_quirks[] = { 60 { { USB_VENDOR_ATI, USB_PRODUCT_ATI2_205 }, 61 UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA, 62 0, 63 0, 64 UMATCH_VENDOR_PRODUCT, 65 NULL, NULL 66 }, 67 68 { { USB_VENDOR_DMI, USB_PRODUCT_DMI_SA2_0 }, 69 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 70 0, 71 PQUIRK_NOMODESENSE, 72 UMATCH_VENDOR_PRODUCT, 73 NULL, NULL 74 }, 75 76 { { USB_VENDOR_FUJIPHOTO, USB_PRODUCT_FUJIPHOTO_MASS0100 }, 77 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 78 UMASS_QUIRK_NO_START_STOP, 79 PQUIRK_NOTUR | PQUIRK_NOSENSE, 80 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 81 NULL, NULL 82 }, 83 84 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ADAPTERV2 }, 85 UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA, 86 0, 87 0, 88 UMATCH_VENDOR_PRODUCT, 89 NULL, NULL 90 }, 91 92 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ATAPI }, 93 UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA, 94 0, 95 0, 96 UMATCH_VENDOR_PRODUCT, 97 NULL, NULL 98 }, 99 100 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_DRIVEV2_5 }, 101 UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA, 102 0, 103 0, 104 UMATCH_VENDOR_PRODUCT, 105 NULL, NULL 106 }, 107 108 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_IDEUSB2 }, 109 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 110 0, 111 PQUIRK_NOMODESENSE, 112 UMATCH_VENDOR_PRODUCT, 113 NULL, NULL 114 }, 115 116 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_USBCABLE }, 117 UMASS_WPROTO_CBI, UMASS_CPROTO_ATAPI, 118 UMASS_QUIRK_NO_START_STOP, 119 PQUIRK_NOTUR, 120 UMATCH_VENDOR_PRODUCT, 121 umass_init_insystem, NULL 122 }, 123 124 { { USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_ZIP100 }, 125 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 126 0, 127 PQUIRK_NOTUR, 128 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 129 NULL, NULL 130 }, 131 132 { { USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_ZIP250 }, 133 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 134 0, 135 PQUIRK_NOTUR, 136 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 137 NULL, NULL 138 }, 139 140 { { USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_DPCM }, 141 UMASS_WPROTO_CBI, UMASS_CPROTO_ATAPI, 142 0, 143 0, 144 UMATCH_VENDOR_PRODUCT, 145 NULL, NULL 146 }, 147 148 { { USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_S304 }, 149 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 150 UMASS_QUIRK_NO_MAX_LUN | UMASS_QUIRK_NO_START_STOP, 151 0, 152 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 153 NULL, NULL 154 }, 155 156 { { USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_X }, 157 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 158 UMASS_QUIRK_NO_MAX_LUN | UMASS_QUIRK_NO_START_STOP, 159 0, 160 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 161 NULL, NULL 162 }, 163 164 { { USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY }, 165 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 166 UMASS_QUIRK_NO_MAX_LUN, 167 PQUIRK_NOMODESENSE | PQUIRK_NODOORLOCK | PQUIRK_NOBIGMODESENSE, 168 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 169 NULL, NULL 170 }, 171 172 { { USB_VENDOR_NEODIO, USB_PRODUCT_NEODIO_ND5010 }, 173 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 174 0, 175 PQUIRK_NOMODESENSE | PQUIRK_FORCELUNS, 176 UMATCH_VENDOR_PRODUCT, 177 NULL, NULL 178 }, 179 180 { { USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C1 }, 181 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 182 UMASS_QUIRK_WRONG_CSWSIG, 183 0, 184 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 185 NULL, NULL 186 }, 187 188 { { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MD1II }, 189 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 190 UMASS_QUIRK_NO_MAX_LUN | UMASS_QUIRK_NO_START_STOP, 191 PQUIRK_NOMODESENSE, 192 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 193 NULL, NULL 194 }, 195 196 { { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MD2 }, 197 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 198 0, 199 PQUIRK_NOMODESENSE, 200 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 201 NULL, NULL 202 }, 203 204 { { USB_VENDOR_PEN, USB_PRODUCT_PEN_USBDISK }, 205 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 206 UMASS_QUIRK_NO_MAX_LUN | UMASS_QUIRK_NO_START_STOP, 207 0, 208 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 209 NULL, NULL 210 }, 211 212 { { USB_VENDOR_PQI, USB_PRODUCT_PQI_TRAVELFLASH }, 213 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 214 0, 215 PQUIRK_NOMODESENSE | PQUIRK_NODOORLOCK, 216 UMATCH_VENDOR_PRODUCT, 217 NULL, NULL 218 }, 219 220 { { USB_VENDOR_SCANLOGIC, USB_PRODUCT_SCANLOGIC_SL11R }, 221 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UFI, 222 0, 223 0, 224 UMATCH_VENDOR_PRODUCT, 225 NULL, NULL 226 }, 227 228 { { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSB }, 229 UMASS_WPROTO_CBI_I, UMASS_CPROTO_ATAPI, 230 UMASS_QUIRK_NO_START_STOP, 231 PQUIRK_NOTUR, 232 UMATCH_VENDOR_PRODUCT, 233 umass_init_shuttle, NULL 234 }, 235 236 { { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_ZIOMMC }, 237 UMASS_WPROTO_CBI_I, UMASS_CPROTO_ATAPI, 238 UMASS_QUIRK_NO_START_STOP, 239 PQUIRK_NOTUR, 240 UMATCH_VENDOR_PRODUCT, 241 NULL, NULL 242 }, 243 244 { { USB_VENDOR_SONY, USB_PRODUCT_SONY_DRIVEV2 }, 245 UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA, 246 0, 247 0, 248 UMATCH_VENDOR_PRODUCT, 249 NULL, NULL 250 }, 251 252 { { USB_VENDOR_SONY, USB_PRODUCT_SONY_MSC }, 253 UMASS_WPROTO_CBI, UMASS_CPROTO_UFI, 254 UMASS_QUIRK_FORCE_SHORT_INQUIRY | UMASS_QUIRK_RS_NO_CLEAR_UA, 255 PQUIRK_NOMODESENSE, 256 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 257 NULL, NULL 258 }, 259 260 { { USB_VENDOR_TEAC, USB_PRODUCT_TEAC_FD05PUB }, 261 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 262 0, 263 PQUIRK_NOMODESENSE, 264 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 265 NULL, NULL 266 }, 267 268 { { USB_VENDOR_TRUMPION, USB_PRODUCT_TRUMPION_XXX1100 }, 269 UMASS_WPROTO_CBI, UMASS_CPROTO_ATAPI, 270 0, 271 0, 272 UMATCH_VENDOR_PRODUCT, 273 NULL, NULL 274 }, 275 276 { { USB_VENDOR_YANO, USB_PRODUCT_YANO_U640MO }, 277 UMASS_WPROTO_CBI_I, UMASS_CPROTO_ATAPI, 278 UMASS_QUIRK_FORCE_SHORT_INQUIRY, 279 0, 280 UMATCH_VENDOR_PRODUCT, 281 NULL, NULL 282 }, 283 284 { { USB_VENDOR_YEDATA, USB_PRODUCT_YEDATA_FLASHBUSTERU }, 285 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UFI, 286 UMASS_QUIRK_RS_NO_CLEAR_UA, 287 PQUIRK_NOMODESENSE, 288 UMATCH_VENDOR_PRODUCT_REV, 289 NULL, umass_fixup_yedata 290 }, 291 }; 292 293 const struct umass_quirk * 294 umass_lookup(u_int16_t vendor, u_int16_t product) 295 { 296 return ((const struct umass_quirk *) 297 usb_lookup(umass_quirks, vendor, product)); 298 } 299 300 Static usbd_status 301 umass_init_insystem(struct umass_softc *sc) 302 { 303 usbd_status err; 304 305 err = usbd_set_interface(sc->sc_iface, 1); 306 if (err) { 307 DPRINTF(UDMASS_USB, 308 ("%s: could not switch to Alt Interface 1\n", 309 USBDEVNAME(sc->sc_dev))); 310 return (err); 311 } 312 313 return (USBD_NORMAL_COMPLETION); 314 } 315 316 Static usbd_status 317 umass_init_shuttle(struct umass_softc *sc) 318 { 319 usb_device_request_t req; 320 u_int8_t status[2]; 321 322 /* The Linux driver does this */ 323 req.bmRequestType = UT_READ_VENDOR_DEVICE; 324 req.bRequest = 1; 325 USETW(req.wValue, 0); 326 USETW(req.wIndex, sc->sc_ifaceno); 327 USETW(req.wLength, sizeof(status)); 328 329 return (usbd_do_request(sc->sc_udev, &req, &status)); 330 } 331 332 Static void 333 umass_fixup_yedata(struct umass_softc *sc) 334 { 335 usb_device_descriptor_t *dd; 336 337 dd = usbd_get_device_descriptor(sc->sc_udev); 338 339 /* 340 * Revisions < 1.28 do not handle the interrupt endpoint very well. 341 */ 342 if (UGETW(dd->bcdDevice) < 0x128) 343 sc->sc_wire = UMASS_WPROTO_CBI; 344 else 345 sc->sc_wire = UMASS_WPROTO_CBI_I; 346 347 /* 348 * Revisions < 1.28 do not have the TEST UNIT READY command 349 * Revisions == 1.28 have a broken TEST UNIT READY 350 */ 351 if (UGETW(dd->bcdDevice) <= 0x128) 352 sc->sc_busquirks |= PQUIRK_NOTUR; 353 } 354