1 /* $OpenBSD: umass_quirks.c,v 1.20 2005/06/02 02:03:33 krw Exp $ */
2 /* $NetBSD: umass_quirks.c,v 1.67 2004/06/28 07:49:16 mycroft Exp $ */
3
4 /*
5 * Copyright (c) 2001 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by MAEKAWA Masahide (gehenna@NetBSD.org).
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the NetBSD
22 * Foundation, Inc. and its contributors.
23 * 4. Neither the name of The NetBSD Foundation nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/device.h>
43 #include <sys/buf.h>
44
45 #if defined(__NetBSD__)
46 #include <dev/scsipi/scsipi_all.h> /* for scsiconf.h below */
47 #include <dev/scsipi/scsiconf.h> /* for quirks defines */
48 #elif defined(__OpenBSD__)
49 #include <scsi/scsi_all.h>
50 #include <scsi/scsiconf.h>
51 #endif
52
53 #include <dev/usb/usb.h>
54 #include <dev/usb/usbdi.h>
55 #include <dev/usb/usbdevs.h>
56
57 #include <dev/usb/umassvar.h>
58 #include <dev/usb/umass_quirks.h>
59
60 Static usbd_status umass_init_insystem(struct umass_softc *);
61 Static usbd_status umass_init_shuttle(struct umass_softc *);
62
63 Static void umass_fixup_sony(struct umass_softc *);
64 Static void umass_fixup_yedata(struct umass_softc *);
65
66 Static const struct umass_quirk umass_quirks[] = {
67 { { USB_VENDOR_ATI, USB_PRODUCT_ATI2_205 },
68 UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA,
69 0,
70 0,
71 UMATCH_VENDOR_PRODUCT,
72 NULL, NULL
73 },
74
75 { { USB_VENDOR_DMI, USB_PRODUCT_DMI_SA2_0 },
76 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
77 0,
78 0,
79 UMATCH_VENDOR_PRODUCT,
80 NULL, NULL
81 },
82
83 { { USB_VENDOR_EASYDISK, USB_PRODUCT_EASYDISK_EASYDISK },
84 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
85 0,
86 0,
87 UMATCH_VENDOR_PRODUCT,
88 NULL, NULL
89 },
90
91 { { USB_VENDOR_FUJIPHOTO, USB_PRODUCT_FUJIPHOTO_MASS0100 },
92 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
93 0,
94 PQUIRK_NOSENSE,
95 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
96 NULL, NULL
97 },
98
99 { { USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB },
100 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
101 0,
102 0,
103 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
104 NULL, NULL
105 },
106
107 { { USB_VENDOR_HP, USB_PRODUCT_HP_CDWRITERPLUS },
108 UMASS_WPROTO_CBI, UMASS_CPROTO_ATAPI,
109 0,
110 PQUIRK_NOSENSE,
111 UMATCH_VENDOR_PRODUCT,
112 NULL, NULL
113 },
114
115 { { USB_VENDOR_IMATION, USB_PRODUCT_IMATION_FLASHGO },
116 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
117 0,
118 0,
119 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
120 NULL, NULL
121 },
122
123 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ADAPTERV2 },
124 UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA,
125 0,
126 0,
127 UMATCH_VENDOR_PRODUCT,
128 NULL, NULL
129 },
130 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ATAPI },
131 UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA,
132 0,
133 0,
134 UMATCH_VENDOR_PRODUCT,
135 NULL, NULL
136 },
137 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_DRIVEV2_5 },
138 UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA,
139 0,
140 0,
141 UMATCH_VENDOR_PRODUCT,
142 NULL, NULL
143 },
144
145 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_IDEUSB2 },
146 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
147 0,
148 0,
149 UMATCH_VENDOR_PRODUCT,
150 NULL, NULL
151 },
152
153 { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_USBCABLE },
154 UMASS_WPROTO_CBI, UMASS_CPROTO_ATAPI,
155 0,
156 0,
157 UMATCH_VENDOR_PRODUCT,
158 umass_init_insystem, NULL
159 },
160
161 { { USB_VENDOR_IODATA2, USB_PRODUCT_IODATA2_USB2SC },
162 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
163 0,
164 0,
165 UMATCH_VENDOR_PRODUCT,
166 NULL, NULL
167 },
168
169 { { USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_ZIP100 },
170 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
171 0,
172 0,
173 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
174 NULL, NULL
175 },
176
177 { { USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_ZIP250 },
178 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
179 0,
180 0,
181 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
182 NULL, NULL
183 },
184
185 { { USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_ZIP250_2 },
186 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
187 0,
188 0,
189 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
190 NULL, NULL
191 },
192
193 { { USB_VENDOR_IRIVER, USB_PRODUCT_IRIVER_IFP_1XX },
194 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
195 0,
196 PQUIRK_ONLYBIG,
197 UMATCH_VENDOR_PRODUCT,
198 NULL, NULL
199 },
200
201 { { USB_VENDOR_IRIVER, USB_PRODUCT_IRIVER_IFP_3XX },
202 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
203 0,
204 0,
205 UMATCH_VENDOR_PRODUCT,
206 NULL, NULL
207 },
208
209 { { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_DUBPXXG },
210 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
211 0,
212 0,
213 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
214 NULL, NULL
215 },
216
217 { { USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_DPCM },
218 UMASS_WPROTO_CBI, UMASS_CPROTO_ATAPI,
219 0,
220 0,
221 UMATCH_VENDOR_PRODUCT,
222 NULL, NULL
223 },
224
225 { { USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_S304 },
226 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
227 0,
228 0,
229 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
230 NULL, NULL
231 },
232
233 { { USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_X },
234 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
235 0,
236 0,
237 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
238 NULL, NULL
239 },
240
241 { { USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_DIMAGEA1 },
242 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
243 0,
244 0,
245 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
246 NULL, NULL
247 },
248
249 { { USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY },
250 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
251 0,
252 0,
253 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
254 NULL, NULL
255 },
256
257 { { USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY2 },
258 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_ATAPI,
259 0,
260 0,
261 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
262 NULL, NULL
263 },
264
265 { { USB_VENDOR_NEODIO, USB_PRODUCT_NEODIO_ND3050 },
266 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
267 0,
268 0,
269 UMATCH_VENDOR_PRODUCT,
270 NULL, NULL
271 },
272
273 { { USB_VENDOR_NEODIO, USB_PRODUCT_NEODIO_ND5010 },
274 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
275 0,
276 0,
277 UMATCH_VENDOR_PRODUCT,
278 NULL, NULL
279 },
280
281 { { USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C1 },
282 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
283 UMASS_QUIRK_WRONG_CSWSIG,
284 0,
285 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
286 NULL, NULL
287 },
288
289 { { USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C700 },
290 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
291 0,
292 PQUIRK_ONLYBIG | SDEV_NOSYNCCACHE,
293 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
294 NULL, NULL
295 },
296
297 { { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MD1II },
298 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
299 0,
300 0,
301 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
302 NULL, NULL
303 },
304
305 { { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MD2 },
306 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
307 0,
308 0,
309 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
310 NULL, NULL
311 },
312
313 { { USB_VENDOR_OTI, USB_PRODUCT_OTI_SOLID },
314 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
315 0,
316 0,
317 UMATCH_VENDOR_PRODUCT,
318 NULL, NULL
319 },
320
321 { { USB_VENDOR_PEN, USB_PRODUCT_PEN_MOBILEDRIVE },
322 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
323 0,
324 0,
325 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
326 NULL, NULL
327 },
328
329 { { USB_VENDOR_PEN, USB_PRODUCT_PEN_USBDISK },
330 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
331 0,
332 0,
333 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
334 NULL, NULL
335 },
336
337 { { USB_VENDOR_PEN, USB_PRODUCT_PEN_USBREADER },
338 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
339 0,
340 0,
341 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
342 NULL, NULL
343 },
344
345 { { USB_VENDOR_PILOTECH, USB_PRODUCT_PILOTECH_CRW600 },
346 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
347 0,
348 0,
349 UMATCH_VENDOR_PRODUCT,
350 NULL, NULL
351 },
352
353 { { USB_VENDOR_PQI, USB_PRODUCT_PQI_TRAVELFLASH },
354 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
355 0,
356 0,
357 UMATCH_VENDOR_PRODUCT,
358 NULL, NULL
359 },
360
361 { { USB_VENDOR_SCANLOGIC, USB_PRODUCT_SCANLOGIC_SL11R },
362 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UFI,
363 UMASS_QUIRK_WRONG_CSWTAG,
364 0,
365 UMATCH_VENDOR_PRODUCT,
366 NULL, NULL
367 },
368
369 { { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSB },
370 UMASS_WPROTO_CBI_I, UMASS_CPROTO_ATAPI,
371 0,
372 PQUIRK_NOSENSE,
373 UMATCH_VENDOR_PRODUCT,
374 umass_init_shuttle, NULL
375 },
376
377 { { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_ZIOMMC },
378 UMASS_WPROTO_CBI_I, UMASS_CPROTO_ATAPI,
379 0,
380 0,
381 UMATCH_VENDOR_PRODUCT,
382 NULL, NULL
383 },
384
385 { { USB_VENDOR_SIIG, USB_PRODUCT_SIIG_MULTICARDREADER },
386 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
387 0,
388 0,
389 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
390 NULL,NULL
391 },
392
393 { { USB_VENDOR_SONY, USB_PRODUCT_SONY_DRIVEV2 },
394 UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA,
395 0,
396 0,
397 UMATCH_VENDOR_PRODUCT,
398 NULL, NULL
399 },
400
401 { { USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC },
402 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
403 0,
404 0,
405 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
406 NULL, umass_fixup_sony
407 },
408
409 { { USB_VENDOR_SONY, USB_PRODUCT_SONY_MSC },
410 UMASS_WPROTO_CBI, UMASS_CPROTO_UFI,
411 0,
412 0,
413 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
414 NULL, NULL
415 },
416
417 { { USB_VENDOR_TEAC, USB_PRODUCT_TEAC_FD05PUB },
418 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
419 0,
420 0,
421 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
422 NULL, NULL
423 },
424
425 { { USB_VENDOR_TREK, USB_PRODUCT_TREK_THUMBDRIVE_8MB },
426 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
427 0,
428 0,
429 UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
430 NULL, NULL
431 },
432
433 { { USB_VENDOR_TRUMPION, USB_PRODUCT_TRUMPION_XXX1100 },
434 UMASS_WPROTO_CBI, UMASS_CPROTO_ATAPI,
435 0,
436 0,
437 UMATCH_VENDOR_PRODUCT,
438 NULL, NULL
439 },
440
441 { { USB_VENDOR_YANO, USB_PRODUCT_YANO_U640MO },
442 UMASS_WPROTO_CBI_I, UMASS_CPROTO_ATAPI,
443 0,
444 0,
445 UMATCH_VENDOR_PRODUCT,
446 NULL, NULL
447 },
448
449 { { USB_VENDOR_YEDATA, USB_PRODUCT_YEDATA_FLASHBUSTERU },
450 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UFI,
451 0,
452 0,
453 UMATCH_VENDOR_PRODUCT_REV,
454 NULL, umass_fixup_yedata
455 },
456
457 { { USB_VENDOR_SIGMATEL, USB_PRODUCT_SIGMATEL_DNSSF7X},
458 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
459 0,
460 SDEV_NOSYNCCACHE,
461 UMATCH_VENDOR_PRODUCT,
462 NULL, NULL
463 },
464
465 { { USB_VENDOR_CREATIVE, USB_PRODUCT_CREATIVE_NOMAD},
466 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
467 0,
468 SDEV_NOSYNCCACHE,
469 UMATCH_VENDOR_PRODUCT,
470 NULL, NULL
471 },
472 };
473
474 const struct umass_quirk *
umass_lookup(u_int16_t vendor,u_int16_t product)475 umass_lookup(u_int16_t vendor, u_int16_t product)
476 {
477 return ((const struct umass_quirk *)
478 usb_lookup(umass_quirks, vendor, product));
479 }
480
481 Static usbd_status
umass_init_insystem(struct umass_softc * sc)482 umass_init_insystem(struct umass_softc *sc)
483 {
484 usbd_status err;
485
486 err = usbd_set_interface(sc->sc_iface, 1);
487 if (err) {
488 DPRINTF(UDMASS_USB,
489 ("%s: could not switch to Alt Interface 1\n",
490 USBDEVNAME(sc->sc_dev)));
491 return (err);
492 }
493
494 return (USBD_NORMAL_COMPLETION);
495 }
496
497 Static usbd_status
umass_init_shuttle(struct umass_softc * sc)498 umass_init_shuttle(struct umass_softc *sc)
499 {
500 usb_device_request_t req;
501 u_int8_t status[2];
502
503 /* The Linux driver does this */
504 req.bmRequestType = UT_READ_VENDOR_DEVICE;
505 req.bRequest = 1;
506 USETW(req.wValue, 0);
507 USETW(req.wIndex, sc->sc_ifaceno);
508 USETW(req.wLength, sizeof(status));
509
510 return (usbd_do_request(sc->sc_udev, &req, &status));
511 }
512
513 Static void
umass_fixup_sony(struct umass_softc * sc)514 umass_fixup_sony(struct umass_softc *sc)
515 {
516 usb_interface_descriptor_t *id;
517
518 id = usbd_get_interface_descriptor(sc->sc_iface);
519 if (id->bInterfaceSubClass == 0xff)
520 sc->sc_cmd = UMASS_CPROTO_SCSI;
521 }
522
523 Static void
umass_fixup_yedata(struct umass_softc * sc)524 umass_fixup_yedata(struct umass_softc *sc)
525 {
526 usb_device_descriptor_t *dd;
527
528 dd = usbd_get_device_descriptor(sc->sc_udev);
529
530 /*
531 * Revisions < 1.28 do not handle the interrupt endpoint very well.
532 */
533 if (UGETW(dd->bcdDevice) < 0x128)
534 sc->sc_wire = UMASS_WPROTO_CBI;
535 else
536 sc->sc_wire = UMASS_WPROTO_CBI_I;
537 }
538