1 /* $NetBSD: umass_quirks.c,v 1.95 2013/05/14 14:03:53 kiyohara Exp $ */ 2 3 /* 4 * Copyright (c) 2001, 2004 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 * This code is derived from software contributed to The NetBSD Foundation 10 * by Charles M. Hannum. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include <sys/cdefs.h> 35 __KERNEL_RCSID(0, "$NetBSD: umass_quirks.c,v 1.95 2013/05/14 14:03:53 kiyohara Exp $"); 36 37 #ifdef _KERNEL_OPT 38 #include "opt_umass.h" 39 #endif 40 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/device.h> 44 #include <sys/buf.h> 45 46 #include <dev/scsipi/scsipi_all.h> /* for scsiconf.h below */ 47 #include <dev/scsipi/scsiconf.h> /* for quirks defines */ 48 49 #include <dev/usb/usb.h> 50 #include <dev/usb/usbdi.h> 51 #include <dev/usb/usbdevs.h> 52 53 #include <dev/usb/umassvar.h> 54 #include <dev/usb/umass_quirks.h> 55 56 Static usbd_status umass_init_insystem(struct umass_softc *); 57 Static usbd_status umass_init_shuttle(struct umass_softc *); 58 59 Static void umass_fixup_sony(struct umass_softc *); 60 61 /* 62 * XXX 63 * PLEASE NOTE that if you want quirk entries added to this table, you MUST 64 * compile a kernel with USB_DEBUG, and submit a full log of the output from 65 * whatever operation is "failing" with ?hcidebug=20 or higher and 66 * umassdebug=0xffffff. (It's usually helpful to also set MSGBUFSIZE to 67 * something "large" unless you're using a serial console.) Without this 68 * information, the source of the problem cannot be properly analyzed, and 69 * the quirk entry WILL NOT be accepted. 70 * Also, when an entry is committed to this table, a concise but clear 71 * description of the problem MUST accompany it. 72 * - mycroft 73 */ 74 Static const struct umass_quirk umass_quirks[] = { 75 /* 76 * The following 3 In-System Design adapters use a non-standard ATA 77 * over BBB protocol. Force this protocol by quirk entries. 78 */ 79 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ADAPTERV2 }, 80 UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA, 81 0, 82 0, 83 UMATCH_VENDOR_PRODUCT, 84 NULL, NULL 85 }, 86 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ATAPI }, 87 UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA, 88 0, 89 0, 90 UMATCH_VENDOR_PRODUCT, 91 NULL, NULL 92 }, 93 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_DRIVEV2_5 }, 94 UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA, 95 0, 96 0, 97 UMATCH_VENDOR_PRODUCT, 98 NULL, NULL 99 }, 100 101 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_USBCABLE }, 102 UMASS_WPROTO_CBI, UMASS_CPROTO_ATAPI, 103 0, 104 0, 105 UMATCH_VENDOR_PRODUCT, 106 umass_init_insystem, NULL 107 }, 108 109 { { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSB }, 110 UMASS_WPROTO_CBI_I, UMASS_CPROTO_ATAPI, 111 0, 112 0, 113 UMATCH_VENDOR_PRODUCT, 114 umass_init_shuttle, NULL 115 }, 116 117 /* 118 * These work around genuine device bugs -- returning the wrong info in 119 * the CSW block. 120 */ 121 { { USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C1 }, 122 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 123 UMASS_QUIRK_WRONG_CSWSIG, 124 0, 125 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 126 NULL, NULL 127 }, 128 { { USB_VENDOR_SCANLOGIC, USB_PRODUCT_SCANLOGIC_SL11R }, 129 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 130 UMASS_QUIRK_WRONG_CSWTAG, 131 0, 132 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 133 NULL, NULL 134 }, 135 { { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_ORCA }, 136 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 137 UMASS_QUIRK_WRONG_CSWTAG, 138 0, 139 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 140 NULL, NULL 141 }, 142 143 /* 144 * Some Sony cameras advertise a subclass code of 0xff, so we force it 145 * to the correct value iff necessary. 146 */ 147 { { USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC }, 148 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 149 UMASS_QUIRK_RBC_PAD_TO_12, 150 0, 151 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 152 NULL, umass_fixup_sony 153 }, 154 155 /* 156 * Stupid device reports itself as SFF-8070, but actually returns a UFI 157 * interrupt descriptor. - mycroft, 2004/06/28 158 */ 159 { { USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40_MS }, 160 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UFI, 161 0, 162 0, 163 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 164 NULL, NULL 165 }, 166 167 /* 168 * The SONY Portable GPS strage device almost hangs up when request 169 * UR_BBB_GET_MAX_LUN - disable the query logic. 170 */ 171 { { USB_VENDOR_SONY, USB_PRODUCT_SONY_GPS_CS1 }, 172 UMASS_WPROTO_BBB, UMASS_CPROTO_UNSPEC, 173 UMASS_QUIRK_NOGETMAXLUN, 174 0, 175 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 176 NULL, NULL 177 }, 178 179 /* 180 * The DiskOnKey does not reject commands it doesn't recognize in a 181 * sane way -- rather than STALLing the bulk pipe, it continually NAKs 182 * until we time out. To prevent being screwed by this, for now we 183 * disable 10-byte MODE SENSE the klugy way. - mycroft, 2003/10/16 184 */ 185 { { USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY }, 186 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 187 0, 188 PQUIRK_NOBIGMODESENSE, 189 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 190 NULL, NULL 191 }, 192 { { USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY2 }, 193 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 194 0, 195 PQUIRK_NOBIGMODESENSE, 196 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 197 NULL, NULL 198 }, 199 { { USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY3 }, 200 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 201 0, 202 PQUIRK_NOBIGMODESENSE, 203 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 204 NULL, NULL 205 }, 206 /* Some Sigmatel-based devices don't like all SCSI commands */ 207 { { USB_VENDOR_SIGMATEL, USB_PRODUCT_SIGMATEL_MUSICSTICK }, 208 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 209 0, 210 PQUIRK_NODOORLOCK | PQUIRK_NOSYNCCACHE, 211 UMATCH_VENDOR_PRODUCT, 212 NULL, NULL 213 }, 214 { { USB_VENDOR_SIGMATEL, USB_PRODUCT_SIGMATEL_I_BEAD100 }, 215 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 216 0, 217 PQUIRK_NODOORLOCK | PQUIRK_NOSYNCCACHE, 218 UMATCH_VENDOR_PRODUCT, 219 NULL, NULL 220 }, 221 { { USB_VENDOR_SIGMATEL, USB_PRODUCT_SIGMATEL_I_BEAD150 }, 222 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 223 0, 224 PQUIRK_NODOORLOCK | PQUIRK_NOSYNCCACHE, 225 UMATCH_VENDOR_PRODUCT, 226 NULL, NULL 227 }, 228 { { USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_SA235 }, 229 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 230 0, 231 PQUIRK_NODOORLOCK | PQUIRK_NOSYNCCACHE, 232 UMATCH_VENDOR_PRODUCT, 233 NULL, NULL 234 }, 235 /* Creative Nomad MuVo, NetBSD PR 30389, FreeBSD PR 53094 */ 236 { { USB_VENDOR_CREATIVE, USB_PRODUCT_CREATIVE_NOMAD }, 237 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 238 0, 239 PQUIRK_NODOORLOCK | PQUIRK_NOSYNCCACHE, 240 UMATCH_VENDOR_PRODUCT, 241 NULL, NULL 242 }, 243 244 /* iRiver iFP-[135]xx players fail on PREVENT/ALLOW, see PR 25440 */ 245 { { USB_VENDOR_IRIVER, USB_PRODUCT_IRIVER_IFP_1XX }, 246 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 247 0, 248 PQUIRK_NODOORLOCK, 249 UMATCH_VENDOR_PRODUCT, 250 NULL, NULL 251 }, 252 { { USB_VENDOR_IRIVER, USB_PRODUCT_IRIVER_IFP_3XX }, 253 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 254 0, 255 PQUIRK_NODOORLOCK, 256 UMATCH_VENDOR_PRODUCT, 257 NULL, NULL 258 }, 259 { { USB_VENDOR_IRIVER, USB_PRODUCT_IRIVER_IFP_5XX }, 260 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 261 0, 262 PQUIRK_NODOORLOCK, 263 UMATCH_VENDOR_PRODUCT, 264 NULL, NULL 265 }, 266 267 /* Meizu M6 doesn't like synchronize-cache, see PR 40442 */ 268 { { USB_VENDOR_MEIZU, USB_PRODUCT_MEIZU_M6_SL }, 269 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 270 0, 271 PQUIRK_NOSYNCCACHE, 272 UMATCH_VENDOR_PRODUCT, 273 NULL, NULL 274 }, 275 276 /* 277 * SanDisk Sansa Clip rejects cache sync in unconventional way. 278 * However, unlike some other devices listed in this table, 279 * this is does not cause the device firmware to stop responding. 280 */ 281 { { USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SANSA_CLIP }, 282 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 283 0, 284 PQUIRK_NOSYNCCACHE, 285 UMATCH_VENDOR_PRODUCT, 286 NULL, NULL 287 }, 288 289 /* Kingston USB pendrives don't like being told to lock the door */ 290 { { USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_DT101_II }, 291 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 292 0, 293 PQUIRK_NODOORLOCK, 294 UMATCH_VENDOR_PRODUCT, 295 NULL, NULL 296 }, 297 298 { { USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_DT101_G2 }, 299 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 300 0, 301 PQUIRK_NODOORLOCK, 302 UMATCH_VENDOR_PRODUCT, 303 NULL, NULL 304 }, 305 306 { { USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_DT102_G2 }, 307 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 308 0, 309 PQUIRK_NODOORLOCK, 310 UMATCH_VENDOR_PRODUCT, 311 NULL, NULL 312 }, 313 314 { { USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_DTMINI10 }, 315 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 316 0, 317 PQUIRK_NODOORLOCK, 318 UMATCH_VENDOR_PRODUCT, 319 NULL, NULL 320 }, 321 322 /* Also, some Kingston pendrives have Toshiba vendor ID */ 323 { { USB_VENDOR_TOSHIBA, USB_PRODUCT_KINGSTON_DT100_G2 }, 324 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 325 0, 326 PQUIRK_NODOORLOCK, 327 UMATCH_VENDOR_PRODUCT, 328 NULL, NULL 329 }, 330 331 /* HP USB pendrives don't like being told to lock the door */ 332 { { USB_VENDOR_HP, USB_PRODUCT_HP_V125W }, 333 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 334 0, 335 PQUIRK_NODOORLOCK, 336 UMATCH_VENDOR_PRODUCT, 337 NULL, NULL 338 }, 339 340 { { USB_VENDOR_IODATA2, USB_PRODUCT_IODATA2_USB2SC }, 341 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 342 0, 343 0, 344 UMATCH_VENDOR_PRODUCT, 345 NULL, NULL 346 }, 347 }; 348 349 const struct umass_quirk * 350 umass_lookup(u_int16_t vendor, u_int16_t product) 351 { 352 return ((const struct umass_quirk *) 353 usb_lookup(umass_quirks, vendor, product)); 354 } 355 356 Static usbd_status 357 umass_init_insystem(struct umass_softc *sc) 358 { 359 usbd_status err; 360 361 err = usbd_set_interface(sc->sc_iface, 1); 362 if (err) { 363 DPRINTF(UDMASS_USB, 364 ("%s: could not switch to Alt Interface 1\n", 365 device_xname(sc->sc_dev))); 366 return (err); 367 } 368 369 return (USBD_NORMAL_COMPLETION); 370 } 371 372 Static usbd_status 373 umass_init_shuttle(struct umass_softc *sc) 374 { 375 usb_device_request_t req; 376 u_int8_t status[2]; 377 378 /* The Linux driver does this */ 379 req.bmRequestType = UT_READ_VENDOR_DEVICE; 380 req.bRequest = 1; 381 USETW(req.wValue, 0); 382 USETW(req.wIndex, sc->sc_ifaceno); 383 USETW(req.wLength, sizeof(status)); 384 385 return (usbd_do_request(sc->sc_udev, &req, &status)); 386 } 387 388 Static void 389 umass_fixup_sony(struct umass_softc *sc) 390 { 391 usb_interface_descriptor_t *id; 392 393 id = usbd_get_interface_descriptor(sc->sc_iface); 394 if (id->bInterfaceSubClass == 0xff) 395 sc->sc_cmd = UMASS_CPROTO_RBC; 396 } 397