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