1 /* $NetBSD: umass_quirks.c,v 1.102 2020/06/19 11:52:42 flxd 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.102 2020/06/19 11:52:42 flxd Exp $"); 36 37 #ifdef _KERNEL_OPT 38 #include "opt_usb.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 #include <dev/usb/usbhist.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 62 /* 63 * XXX 64 * PLEASE NOTE that if you want quirk entries added to this table, you MUST 65 * compile a kernel with USB_DEBUG, and submit a full log of the output from 66 * whatever operation is "failing" with ?hcidebug=20 or higher and 67 * umassdebug=0xffffff. (It's usually helpful to also set MSGBUFSIZE to 68 * something "large" unless you're using a serial console.) Without this 69 * information, the source of the problem cannot be properly analyzed, and 70 * the quirk entry WILL NOT be accepted. 71 * Also, when an entry is committed to this table, a concise but clear 72 * description of the problem MUST accompany it. 73 * - mycroft 74 */ 75 Static const struct umass_quirk umass_quirks[] = { 76 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_USBCABLE }, 77 UMASS_WPROTO_CBI, UMASS_CPROTO_ATAPI, 78 0, 79 0, 80 UMATCH_VENDOR_PRODUCT, 81 umass_init_insystem, NULL 82 }, 83 84 { { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSB }, 85 UMASS_WPROTO_CBI_I, UMASS_CPROTO_ATAPI, 86 0, 87 0, 88 UMATCH_VENDOR_PRODUCT, 89 umass_init_shuttle, NULL 90 }, 91 92 /* 93 * These work around genuine device bugs -- returning the wrong info in 94 * the CSW block. 95 */ 96 { { USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C1 }, 97 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 98 UMASS_QUIRK_WRONG_CSWSIG, 99 0, 100 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 101 NULL, NULL 102 }, 103 { { USB_VENDOR_SCANLOGIC, USB_PRODUCT_SCANLOGIC_SL11R }, 104 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 105 UMASS_QUIRK_WRONG_CSWTAG, 106 0, 107 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 108 NULL, NULL 109 }, 110 { { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_ORCA }, 111 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 112 UMASS_QUIRK_WRONG_CSWTAG, 113 0, 114 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 115 NULL, NULL 116 }, 117 118 /* 119 * Some Sony cameras advertise a subclass code of 0xff, so we force it 120 * to the correct value iff necessary. 121 */ 122 { { USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC }, 123 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 124 UMASS_QUIRK_RBC_PAD_TO_12, 125 0, 126 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 127 NULL, umass_fixup_sony 128 }, 129 130 /* 131 * Stupid device reports itself as SFF-8070, but actually returns a UFI 132 * interrupt descriptor. - mycroft, 2004/06/28 133 */ 134 { { USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40_MS }, 135 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UFI, 136 0, 137 0, 138 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 139 NULL, NULL 140 }, 141 142 /* 143 * The SONY Portable GPS strage device almost hangs up when request 144 * UR_BBB_GET_MAX_LUN - disable the query logic. 145 */ 146 { { USB_VENDOR_SONY, USB_PRODUCT_SONY_GPS_CS1 }, 147 UMASS_WPROTO_BBB, UMASS_CPROTO_UNSPEC, 148 UMASS_QUIRK_NOGETMAXLUN, 149 0, 150 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 151 NULL, NULL 152 }, 153 154 /* 155 * The DiskOnKey does not reject commands it doesn't recognize in a 156 * sane way -- rather than STALLing the bulk pipe, it continually NAKs 157 * until we time out. To prevent being screwed by this, for now we 158 * disable 10-byte MODE SENSE the klugy way. - mycroft, 2003/10/16 159 */ 160 { { USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY }, 161 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 162 0, 163 PQUIRK_NOBIGMODESENSE, 164 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 165 NULL, NULL 166 }, 167 { { USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY2 }, 168 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 169 0, 170 PQUIRK_NOBIGMODESENSE, 171 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 172 NULL, NULL 173 }, 174 { { USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY3 }, 175 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 176 0, 177 PQUIRK_NOBIGMODESENSE, 178 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 179 NULL, NULL 180 }, 181 /* Some Sigmatel-based devices don't like all SCSI commands */ 182 { { USB_VENDOR_SIGMATEL, USB_PRODUCT_SIGMATEL_MUSICSTICK }, 183 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 184 0, 185 PQUIRK_NODOORLOCK | PQUIRK_NOSYNCCACHE, 186 UMATCH_VENDOR_PRODUCT, 187 NULL, NULL 188 }, 189 { { USB_VENDOR_SIGMATEL, USB_PRODUCT_SIGMATEL_I_BEAD100 }, 190 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 191 0, 192 PQUIRK_NODOORLOCK | PQUIRK_NOSYNCCACHE, 193 UMATCH_VENDOR_PRODUCT, 194 NULL, NULL 195 }, 196 { { USB_VENDOR_SIGMATEL, USB_PRODUCT_SIGMATEL_I_BEAD150 }, 197 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 198 0, 199 PQUIRK_NODOORLOCK | PQUIRK_NOSYNCCACHE, 200 UMATCH_VENDOR_PRODUCT, 201 NULL, NULL 202 }, 203 { { USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_SA235 }, 204 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 205 0, 206 PQUIRK_NODOORLOCK | PQUIRK_NOSYNCCACHE, 207 UMATCH_VENDOR_PRODUCT, 208 NULL, NULL 209 }, 210 /* Creative Nomad MuVo, NetBSD PR 30389, FreeBSD PR 53094 */ 211 { { USB_VENDOR_CREATIVE, USB_PRODUCT_CREATIVE_NOMAD }, 212 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 213 0, 214 PQUIRK_NODOORLOCK | PQUIRK_NOSYNCCACHE, 215 UMATCH_VENDOR_PRODUCT, 216 NULL, NULL 217 }, 218 219 /* iRiver iFP-[135]xx players fail on PREVENT/ALLOW, see PR 25440 */ 220 { { USB_VENDOR_IRIVER, USB_PRODUCT_IRIVER_IFP_1XX }, 221 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 222 0, 223 PQUIRK_NODOORLOCK, 224 UMATCH_VENDOR_PRODUCT, 225 NULL, NULL 226 }, 227 { { USB_VENDOR_IRIVER, USB_PRODUCT_IRIVER_IFP_3XX }, 228 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 229 0, 230 PQUIRK_NODOORLOCK, 231 UMATCH_VENDOR_PRODUCT, 232 NULL, NULL 233 }, 234 { { USB_VENDOR_IRIVER, USB_PRODUCT_IRIVER_IFP_5XX }, 235 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 236 0, 237 PQUIRK_NODOORLOCK, 238 UMATCH_VENDOR_PRODUCT, 239 NULL, NULL 240 }, 241 242 /* Meizu M6 doesn't like synchronize-cache, see PR 40442 */ 243 { { USB_VENDOR_MEIZU, USB_PRODUCT_MEIZU_M6_SL }, 244 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 245 0, 246 PQUIRK_NOSYNCCACHE, 247 UMATCH_VENDOR_PRODUCT, 248 NULL, NULL 249 }, 250 251 /* 252 * SanDisk Cruzer rejects cache sync. 253 */ 254 { { USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_CRUZER }, 255 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 256 0, 257 PQUIRK_NOSYNCCACHE, 258 UMATCH_VENDOR_PRODUCT, 259 NULL, NULL 260 }, 261 262 /* 263 * SanDisk Sansa Clip rejects cache sync in unconventional way. 264 * However, unlike some other devices listed in this table, 265 * this is does not cause the device firmware to stop responding. 266 */ 267 { { USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SANSA_CLIP }, 268 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 269 0, 270 PQUIRK_NOSYNCCACHE, 271 UMATCH_VENDOR_PRODUCT, 272 NULL, NULL 273 }, 274 275 /* Kingston USB pendrives don't like being told to lock the door */ 276 { { USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_DT101_II }, 277 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 278 0, 279 PQUIRK_NODOORLOCK, 280 UMATCH_VENDOR_PRODUCT, 281 NULL, NULL 282 }, 283 284 { { USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_DT101_G2 }, 285 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 286 0, 287 PQUIRK_NODOORLOCK, 288 UMATCH_VENDOR_PRODUCT, 289 NULL, NULL 290 }, 291 292 { { USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_DT102_G2 }, 293 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 294 0, 295 PQUIRK_NODOORLOCK, 296 UMATCH_VENDOR_PRODUCT, 297 NULL, NULL 298 }, 299 300 { { USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_DTMINI10 }, 301 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 302 0, 303 PQUIRK_NODOORLOCK, 304 UMATCH_VENDOR_PRODUCT, 305 NULL, NULL 306 }, 307 308 /* Also, some Kingston pendrives have Toshiba vendor ID */ 309 { { USB_VENDOR_TOSHIBA, USB_PRODUCT_KINGSTON_DT100_G2 }, 310 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 311 0, 312 PQUIRK_NODOORLOCK, 313 UMATCH_VENDOR_PRODUCT, 314 NULL, NULL 315 }, 316 317 /* HP USB pendrives don't like being told to lock the door */ 318 { { USB_VENDOR_HP, USB_PRODUCT_HP_V125W }, 319 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 320 0, 321 PQUIRK_NODOORLOCK, 322 UMATCH_VENDOR_PRODUCT, 323 NULL, NULL 324 }, 325 326 { { USB_VENDOR_IODATA2, USB_PRODUCT_IODATA2_USB2SC }, 327 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 328 0, 329 0, 330 UMATCH_VENDOR_PRODUCT, 331 NULL, NULL 332 }, 333 334 /* 335 * Fix Alcor multi-card readers in many HP machines (like net-tops). 336 * FreeBSD applies the no-sync-cache quirk for /all/ Alcor usb devices 337 * as well as a no-test-unit-ready quirk. Mine works without the latter. 338 */ 339 { { USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_AU6366 }, 340 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 341 0, 342 PQUIRK_NOSYNCCACHE, 343 UMATCH_VENDOR_PRODUCT, 344 NULL, NULL 345 }, 346 }; 347 348 const struct umass_quirk * 349 umass_lookup(uint16_t vendor, uint16_t product) 350 { 351 return (const struct umass_quirk *) 352 usb_lookup(umass_quirks, vendor, product); 353 } 354 355 Static usbd_status 356 umass_init_insystem(struct umass_softc *sc) 357 { 358 UMASSHIST_FUNC(); UMASSHIST_CALLED(); 359 usbd_status err; 360 361 err = usbd_set_interface(sc->sc_iface, 1); 362 if (err) { 363 DPRINTFM(UDMASS_USB, "sc %#jx: could not switch to Alt " 364 "Interface 1", (uintptr_t)sc, 0, 0, 0); 365 return err; 366 } 367 368 return USBD_NORMAL_COMPLETION; 369 } 370 371 Static usbd_status 372 umass_init_shuttle(struct umass_softc *sc) 373 { 374 usb_device_request_t req; 375 uint8_t status[2]; 376 377 /* The Linux driver does this */ 378 req.bmRequestType = UT_READ_VENDOR_DEVICE; 379 req.bRequest = 1; 380 USETW(req.wValue, 0); 381 USETW(req.wIndex, sc->sc_ifaceno); 382 USETW(req.wLength, sizeof(status)); 383 384 return usbd_do_request(sc->sc_udev, &req, &status); 385 } 386 387 Static void 388 umass_fixup_sony(struct umass_softc *sc) 389 { 390 usb_interface_descriptor_t *id; 391 392 id = usbd_get_interface_descriptor(sc->sc_iface); 393 if (id->bInterfaceSubClass == 0xff) 394 sc->sc_cmd = UMASS_CPROTO_RBC; 395 } 396