1 /* $NetBSD: umass_quirks.c,v 1.70 2005/12/11 12:24:01 christos 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 * 3. All advertising materials mentioning features or use of this software 21 * must display the following acknowledgement: 22 * This product includes software developed by the NetBSD 23 * Foundation, Inc. and its contributors. 24 * 4. Neither the name of The NetBSD Foundation nor the names of its 25 * contributors may be used to endorse or promote products derived 26 * from this software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 29 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 31 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 32 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38 * POSSIBILITY OF SUCH DAMAGE. 39 */ 40 41 #include <sys/cdefs.h> 42 __KERNEL_RCSID(0, "$NetBSD: umass_quirks.c,v 1.70 2005/12/11 12:24:01 christos Exp $"); 43 44 #include <sys/param.h> 45 #include <sys/systm.h> 46 #include <sys/device.h> 47 #include <sys/buf.h> 48 49 #include <dev/scsipi/scsipi_all.h> /* for scsiconf.h below */ 50 #include <dev/scsipi/scsiconf.h> /* for quirks defines */ 51 52 #include <dev/usb/usb.h> 53 #include <dev/usb/usbdi.h> 54 #include <dev/usb/usbdevs.h> 55 56 #include <dev/usb/umassvar.h> 57 #include <dev/usb/umass_quirks.h> 58 59 Static usbd_status umass_init_insystem(struct umass_softc *); 60 Static usbd_status umass_init_shuttle(struct umass_softc *); 61 62 Static void umass_fixup_sony(struct umass_softc *); 63 64 /* 65 * XXX 66 * PLEASE NOTE that if you want quirk entries added to this table, you MUST 67 * compile a kernel with USB_DEBUG, and submit a full log of the output from 68 * whatever operation is "failing" with ?hcidebug=20 or higher and 69 * umassdebug=0xffffff. (It's usually helpful to also set MSGBUFSIZE to 70 * something "large" unless you're using a serial console.) Without this 71 * information, the source of the problem cannot be properly analyzed, and 72 * the quirk entry WILL NOT be accepted. 73 * Also, when an entry is committed to this table, a concise but clear 74 * description of the problem MUST accompany it. 75 * - mycroft 76 */ 77 Static const struct umass_quirk umass_quirks[] = { 78 /* 79 * The following 3 In-System Design adapters use a non-standard ATA 80 * over BBB protocol. Force this protocol by quirk entries. 81 */ 82 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ADAPTERV2 }, 83 UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA, 84 0, 85 0, 86 UMATCH_VENDOR_PRODUCT, 87 NULL, NULL 88 }, 89 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ATAPI }, 90 UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA, 91 0, 92 0, 93 UMATCH_VENDOR_PRODUCT, 94 NULL, NULL 95 }, 96 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_DRIVEV2_5 }, 97 UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA, 98 0, 99 0, 100 UMATCH_VENDOR_PRODUCT, 101 NULL, NULL 102 }, 103 104 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_USBCABLE }, 105 UMASS_WPROTO_CBI, UMASS_CPROTO_ATAPI, 106 0, 107 0, 108 UMATCH_VENDOR_PRODUCT, 109 umass_init_insystem, NULL 110 }, 111 112 { { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSB }, 113 UMASS_WPROTO_CBI_I, UMASS_CPROTO_ATAPI, 114 0, 115 0, 116 UMATCH_VENDOR_PRODUCT, 117 umass_init_shuttle, NULL 118 }, 119 120 /* 121 * These work around genuine device bugs -- returning the wrong info in 122 * the CSW block. 123 */ 124 { { USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C1 }, 125 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 126 UMASS_QUIRK_WRONG_CSWSIG, 127 0, 128 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 129 NULL, NULL 130 }, 131 { { USB_VENDOR_SCANLOGIC, USB_PRODUCT_SCANLOGIC_SL11R }, 132 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 133 UMASS_QUIRK_WRONG_CSWTAG, 134 0, 135 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 136 NULL, NULL 137 }, 138 { { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_ORCA }, 139 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 140 UMASS_QUIRK_WRONG_CSWTAG, 141 0, 142 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 143 NULL, NULL 144 }, 145 146 /* 147 * Some Sony cameras advertise a subclass code of 0xff, so we force it 148 * to the correct value iff necessary. 149 */ 150 { { USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC }, 151 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 152 0, 153 0, 154 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 155 NULL, umass_fixup_sony 156 }, 157 158 /* 159 * Stupid device reports itself as SFF-8070, but actually returns a UFI 160 * interrupt descriptor. - mycroft, 2004/06/28 161 */ 162 { { USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40_MS }, 163 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UFI, 164 0, 165 0, 166 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 167 NULL, NULL 168 }, 169 170 /* 171 * The DiskOnKey does not reject commands it doesn't recognize in a 172 * sane way -- rather than STALLing the bulk pipe, it continually NAKs 173 * until we time out. To prevent being screwed by this, for now we 174 * disable 10-byte MODE SENSE the klugy way. - mycroft, 2003/10/16 175 */ 176 { { USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY }, 177 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 178 0, 179 PQUIRK_NOBIGMODESENSE, 180 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 181 NULL, NULL 182 }, 183 { { USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY2 }, 184 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 185 0, 186 PQUIRK_NOBIGMODESENSE, 187 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 188 NULL, NULL 189 }, 190 { { USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY3 }, 191 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 192 0, 193 PQUIRK_NOBIGMODESENSE, 194 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO, 195 NULL, NULL 196 }, 197 }; 198 199 const struct umass_quirk * 200 umass_lookup(u_int16_t vendor, u_int16_t product) 201 { 202 return ((const struct umass_quirk *) 203 usb_lookup(umass_quirks, vendor, product)); 204 } 205 206 Static usbd_status 207 umass_init_insystem(struct umass_softc *sc) 208 { 209 usbd_status err; 210 211 err = usbd_set_interface(sc->sc_iface, 1); 212 if (err) { 213 DPRINTF(UDMASS_USB, 214 ("%s: could not switch to Alt Interface 1\n", 215 USBDEVNAME(sc->sc_dev))); 216 return (err); 217 } 218 219 return (USBD_NORMAL_COMPLETION); 220 } 221 222 Static usbd_status 223 umass_init_shuttle(struct umass_softc *sc) 224 { 225 usb_device_request_t req; 226 u_int8_t status[2]; 227 228 /* The Linux driver does this */ 229 req.bmRequestType = UT_READ_VENDOR_DEVICE; 230 req.bRequest = 1; 231 USETW(req.wValue, 0); 232 USETW(req.wIndex, sc->sc_ifaceno); 233 USETW(req.wLength, sizeof(status)); 234 235 return (usbd_do_request(sc->sc_udev, &req, &status)); 236 } 237 238 Static void 239 umass_fixup_sony(struct umass_softc *sc) 240 { 241 usb_interface_descriptor_t *id; 242 243 id = usbd_get_interface_descriptor(sc->sc_iface); 244 if (id->bInterfaceSubClass == 0xff) 245 sc->sc_cmd = UMASS_CPROTO_SCSI; 246 } 247