1 /* $NetBSD: umass_quirks.c,v 1.67 2004/06/28 07:49:16 mycroft 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.67 2004/06/28 07:49:16 mycroft 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 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 /* 77 * The following 3 In-System Design adapters use a non-standard ATA 78 * over BBB protocol. Force this protocol by quirk entries. 79 */ 80 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ADAPTERV2 }, 81 UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA, 82 0, 83 0, 84 UMATCH_VENDOR_PRODUCT, 85 NULL, NULL 86 }, 87 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ATAPI }, 88 UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA, 89 0, 90 0, 91 UMATCH_VENDOR_PRODUCT, 92 NULL, NULL 93 }, 94 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_DRIVEV2_5 }, 95 UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA, 96 0, 97 0, 98 UMATCH_VENDOR_PRODUCT, 99 NULL, NULL 100 }, 101 102 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_USBCABLE }, 103 UMASS_WPROTO_CBI, UMASS_CPROTO_ATAPI, 104 0, 105 0, 106 UMATCH_VENDOR_PRODUCT, 107 umass_init_insystem, NULL 108 }, 109 110 { { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSB }, 111 UMASS_WPROTO_CBI_I, UMASS_CPROTO_ATAPI, 112 0, 113 0, 114 UMATCH_VENDOR_PRODUCT, 115 umass_init_shuttle, NULL 116 }, 117 118 /* 119 * These work around genuine device bugs -- returning the wrong info in 120 * the CSW block. 121 */ 122 { { USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C1 }, 123 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 124 UMASS_QUIRK_WRONG_CSWSIG, 125 0, 126 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 127 NULL, NULL 128 }, 129 { { USB_VENDOR_SCANLOGIC, USB_PRODUCT_SCANLOGIC_SL11R }, 130 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 131 UMASS_QUIRK_WRONG_CSWTAG, 132 0, 133 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 134 NULL, NULL 135 }, 136 { { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_ORCA }, 137 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 138 UMASS_QUIRK_WRONG_CSWTAG, 139 0, 140 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 141 NULL, NULL 142 }, 143 144 /* 145 * Some Sony cameras advertise a subclass code of 0xff, so we force it 146 * to the correct value iff necessary. 147 */ 148 { { USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC }, 149 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 150 0, 151 0, 152 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 153 NULL, umass_fixup_sony 154 }, 155 156 /* 157 * Stupid device reports itself as SFF-8070, but actually returns a UFI 158 * interrupt descriptor. - mycroft, 2004/06/28 159 */ 160 { { USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40_MS }, 161 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UFI, 162 0, 163 0, 164 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 165 NULL, NULL 166 }, 167 168 /* 169 * The DiskOnKey does not reject commands it doesn't recognize in a 170 * sane way -- rather than STALLing the bulk pipe, it continually NAKs 171 * until we time out. To prevent being screwed by this, for now we 172 * disable 10-byte MODE SENSE the klugy way. - mycroft, 2003/10/16 173 */ 174 { { USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY }, 175 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 176 0, 177 PQUIRK_NOBIGMODESENSE, 178 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 179 NULL, NULL 180 }, 181 { { USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY2 }, 182 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 183 0, 184 PQUIRK_NOBIGMODESENSE, 185 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 186 NULL, NULL 187 }, 188 }; 189 190 const struct umass_quirk * 191 umass_lookup(u_int16_t vendor, u_int16_t product) 192 { 193 return ((const struct umass_quirk *) 194 usb_lookup(umass_quirks, vendor, product)); 195 } 196 197 Static usbd_status 198 umass_init_insystem(struct umass_softc *sc) 199 { 200 usbd_status err; 201 202 err = usbd_set_interface(sc->sc_iface, 1); 203 if (err) { 204 DPRINTF(UDMASS_USB, 205 ("%s: could not switch to Alt Interface 1\n", 206 USBDEVNAME(sc->sc_dev))); 207 return (err); 208 } 209 210 return (USBD_NORMAL_COMPLETION); 211 } 212 213 Static usbd_status 214 umass_init_shuttle(struct umass_softc *sc) 215 { 216 usb_device_request_t req; 217 u_int8_t status[2]; 218 219 /* The Linux driver does this */ 220 req.bmRequestType = UT_READ_VENDOR_DEVICE; 221 req.bRequest = 1; 222 USETW(req.wValue, 0); 223 USETW(req.wIndex, sc->sc_ifaceno); 224 USETW(req.wLength, sizeof(status)); 225 226 return (usbd_do_request(sc->sc_udev, &req, &status)); 227 } 228 229 Static void 230 umass_fixup_sony(struct umass_softc *sc) 231 { 232 usb_interface_descriptor_t *id; 233 234 id = usbd_get_interface_descriptor(sc->sc_iface); 235 if (id->bInterfaceSubClass == 0xff) 236 sc->sc_cmd = UMASS_CPROTO_SCSI; 237 } 238