1 | #include <machine/rtems-bsd-kernel-space.h> |
---|
2 | |
---|
3 | /* $FreeBSD$ */ |
---|
4 | /*- |
---|
5 | * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved. |
---|
6 | * Copyright (c) 1998 Lennart Augustsson. All rights reserved. |
---|
7 | * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. |
---|
8 | * |
---|
9 | * Redistribution and use in source and binary forms, with or without |
---|
10 | * modification, are permitted provided that the following conditions |
---|
11 | * are met: |
---|
12 | * 1. Redistributions of source code must retain the above copyright |
---|
13 | * notice, this list of conditions and the following disclaimer. |
---|
14 | * 2. Redistributions in binary form must reproduce the above copyright |
---|
15 | * notice, this list of conditions and the following disclaimer in the |
---|
16 | * documentation and/or other materials provided with the distribution. |
---|
17 | * |
---|
18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
---|
19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
---|
20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
---|
21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
---|
22 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
---|
23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
---|
24 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
---|
25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
---|
26 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
---|
27 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
---|
28 | * SUCH DAMAGE. |
---|
29 | */ |
---|
30 | |
---|
31 | #include <sys/stdint.h> |
---|
32 | #include <sys/stddef.h> |
---|
33 | #include <rtems/bsd/sys/param.h> |
---|
34 | #include <sys/queue.h> |
---|
35 | #include <rtems/bsd/sys/types.h> |
---|
36 | #include <sys/systm.h> |
---|
37 | #include <sys/kernel.h> |
---|
38 | #include <sys/bus.h> |
---|
39 | #include <sys/module.h> |
---|
40 | #include <rtems/bsd/sys/lock.h> |
---|
41 | #include <sys/mutex.h> |
---|
42 | #include <sys/condvar.h> |
---|
43 | #include <sys/sysctl.h> |
---|
44 | #include <sys/sx.h> |
---|
45 | #include <rtems/bsd/sys/unistd.h> |
---|
46 | #include <sys/callout.h> |
---|
47 | #include <sys/malloc.h> |
---|
48 | #include <sys/priv.h> |
---|
49 | |
---|
50 | #include <dev/usb/usb.h> |
---|
51 | #include <dev/usb/usb_ioctl.h> |
---|
52 | #include <dev/usb/usbdi.h> |
---|
53 | #include <rtems/bsd/local/usbdevs.h> |
---|
54 | |
---|
55 | #define USB_DEBUG_VAR usb_debug |
---|
56 | #include <dev/usb/usb_debug.h> |
---|
57 | #include <dev/usb/usb_dynamic.h> |
---|
58 | |
---|
59 | #include <dev/usb/quirk/usb_quirk.h> |
---|
60 | |
---|
61 | MODULE_DEPEND(usb_quirk, usb, 1, 1, 1); |
---|
62 | MODULE_VERSION(usb_quirk, 1); |
---|
63 | |
---|
64 | #define USB_DEV_QUIRKS_MAX 384 |
---|
65 | #define USB_SUB_QUIRKS_MAX 8 |
---|
66 | |
---|
67 | struct usb_quirk_entry { |
---|
68 | uint16_t vid; |
---|
69 | uint16_t pid; |
---|
70 | uint16_t lo_rev; |
---|
71 | uint16_t hi_rev; |
---|
72 | uint16_t quirks[USB_SUB_QUIRKS_MAX]; |
---|
73 | }; |
---|
74 | |
---|
75 | static struct mtx usb_quirk_mtx; |
---|
76 | |
---|
77 | #define USB_QUIRK_VP(v,p,l,h,...) \ |
---|
78 | { .vid = (v), .pid = (p), .lo_rev = (l), .hi_rev = (h), \ |
---|
79 | .quirks = { __VA_ARGS__ } } |
---|
80 | #define USB_QUIRK(v,p,l,h,...) \ |
---|
81 | USB_QUIRK_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, l, h, __VA_ARGS__) |
---|
82 | |
---|
83 | static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = { |
---|
84 | USB_QUIRK(ASUS, LCM, 0x0000, 0xffff, UQ_HID_IGNORE), |
---|
85 | USB_QUIRK(INSIDEOUT, EDGEPORT4, 0x094, 0x094, UQ_SWAP_UNICODE), |
---|
86 | USB_QUIRK(DALLAS, J6502, 0x0a2, 0x0a2, UQ_BAD_ADC), |
---|
87 | USB_QUIRK(DALLAS, J6502, 0x0a2, 0x0a2, UQ_AU_NO_XU), |
---|
88 | USB_QUIRK(ALTEC, ADA70, 0x103, 0x103, UQ_BAD_ADC), |
---|
89 | USB_QUIRK(ALTEC, ASC495, 0x000, 0x000, UQ_BAD_AUDIO), |
---|
90 | USB_QUIRK(QTRONIX, 980N, 0x110, 0x110, UQ_SPUR_BUT_UP), |
---|
91 | USB_QUIRK(ALCOR2, KBD_HUB, 0x001, 0x001, UQ_SPUR_BUT_UP), |
---|
92 | USB_QUIRK(MCT, HUB0100, 0x102, 0x102, UQ_BUS_POWERED), |
---|
93 | USB_QUIRK(MCT, USB232, 0x102, 0x102, UQ_BUS_POWERED), |
---|
94 | USB_QUIRK(TI, UTUSB41, 0x110, 0x110, UQ_POWER_CLAIM), |
---|
95 | USB_QUIRK(TELEX, MIC1, 0x009, 0x009, UQ_AU_NO_FRAC), |
---|
96 | USB_QUIRK(SILICONPORTALS, YAPPHONE, 0x100, 0x100, UQ_AU_INP_ASYNC), |
---|
97 | USB_QUIRK(LOGITECH, UN53B, 0x0000, 0xffff, UQ_NO_STRINGS), |
---|
98 | USB_QUIRK(REALTEK, RTL8196EU, 0x0000, 0xffff, UQ_CFG_INDEX_1), |
---|
99 | USB_QUIRK(ELSA, MODEM1, 0x0000, 0xffff, UQ_CFG_INDEX_1), |
---|
100 | USB_QUIRK(PLANEX2, MZKUE150N, 0x0000, 0xffff, UQ_CFG_INDEX_1), |
---|
101 | /* Quirks for printer devices */ |
---|
102 | USB_QUIRK(HP, 895C, 0x0000, 0xffff, UQ_BROKEN_BIDIR), |
---|
103 | USB_QUIRK(HP, 880C, 0x0000, 0xffff, UQ_BROKEN_BIDIR), |
---|
104 | USB_QUIRK(HP, 815C, 0x0000, 0xffff, UQ_BROKEN_BIDIR), |
---|
105 | USB_QUIRK(HP, 810C, 0x0000, 0xffff, UQ_BROKEN_BIDIR), |
---|
106 | USB_QUIRK(HP, 830C, 0x0000, 0xffff, UQ_BROKEN_BIDIR), |
---|
107 | USB_QUIRK(HP, 1220C, 0x0000, 0xffff, UQ_BROKEN_BIDIR), |
---|
108 | USB_QUIRK(XEROX, WCM15, 0x0000, 0xffff, UQ_BROKEN_BIDIR), |
---|
109 | /* Devices which should be ignored by uhid */ |
---|
110 | USB_QUIRK(APC, UPS, 0x0000, 0xffff, UQ_HID_IGNORE), |
---|
111 | USB_QUIRK(BELKIN, F6C550AVR, 0x0000, 0xffff, UQ_HID_IGNORE), |
---|
112 | USB_QUIRK(CYBERPOWER, 1500CAVRLCD, 0x0000, 0xffff, UQ_HID_IGNORE), |
---|
113 | USB_QUIRK(CYPRESS, SILVERSHIELD, 0x0000, 0xffff, UQ_HID_IGNORE), |
---|
114 | USB_QUIRK(DELORME, EARTHMATE, 0x0000, 0xffff, UQ_HID_IGNORE), |
---|
115 | USB_QUIRK(ITUNERNET, USBLCD2X20, 0x0000, 0xffff, UQ_HID_IGNORE), |
---|
116 | USB_QUIRK(ITUNERNET, USBLCD4X20, 0x0000, 0xffff, UQ_HID_IGNORE), |
---|
117 | USB_QUIRK(LIEBERT, POWERSURE_PXT, 0x0000, 0xffff, UQ_HID_IGNORE), |
---|
118 | USB_QUIRK(LIEBERT2, PSI1000, 0x0000, 0xffff, UQ_HID_IGNORE), |
---|
119 | USB_QUIRK(MGE, UPS1, 0x0000, 0xffff, UQ_HID_IGNORE), |
---|
120 | USB_QUIRK(MGE, UPS2, 0x0000, 0xffff, UQ_HID_IGNORE), |
---|
121 | USB_QUIRK(APPLE, IPHONE, 0x0000, 0xffff, UQ_HID_IGNORE), |
---|
122 | USB_QUIRK(APPLE, IPHONE_3G, 0x0000, 0xffff, UQ_HID_IGNORE), |
---|
123 | USB_QUIRK(MEGATEC, UPS, 0x0000, 0xffff, UQ_HID_IGNORE), |
---|
124 | /* Devices which should be ignored by both ukbd and uhid */ |
---|
125 | USB_QUIRK(CYPRESS, WISPY1A, 0x0000, 0xffff, UQ_KBD_IGNORE, UQ_HID_IGNORE), |
---|
126 | USB_QUIRK(METAGEEK, WISPY1B, 0x0000, 0xffff, UQ_KBD_IGNORE, UQ_HID_IGNORE), |
---|
127 | USB_QUIRK(METAGEEK, WISPY24X, 0x0000, 0xffff, UQ_KBD_IGNORE, UQ_HID_IGNORE), |
---|
128 | USB_QUIRK(METAGEEK2, WISPYDBX, 0x0000, 0xffff, UQ_KBD_IGNORE, UQ_HID_IGNORE), |
---|
129 | USB_QUIRK(TENX, UAUDIO0, 0x0101, 0x0101, UQ_AUDIO_SWAP_LR), |
---|
130 | /* MS keyboards do weird things */ |
---|
131 | USB_QUIRK(MICROSOFT, NATURAL4000, 0x0000, 0xFFFF, UQ_KBD_BOOTPROTO), |
---|
132 | USB_QUIRK(MICROSOFT, WLINTELLIMOUSE, 0x0000, 0xffff, UQ_MS_LEADING_BYTE), |
---|
133 | /* Quirk for Corsair Vengeance K60 keyboard */ |
---|
134 | USB_QUIRK(CORSAIR, K60, 0x0000, 0xffff, UQ_KBD_BOOTPROTO), |
---|
135 | /* Quirk for Corsair Vengeance K70 keyboard */ |
---|
136 | USB_QUIRK(CORSAIR, K70, 0x0000, 0xffff, UQ_KBD_BOOTPROTO), |
---|
137 | /* umodem(4) device quirks */ |
---|
138 | USB_QUIRK(METRICOM, RICOCHET_GS, 0x100, 0x100, UQ_ASSUME_CM_OVER_DATA), |
---|
139 | USB_QUIRK(SANYO, SCP4900, 0x000, 0x000, UQ_ASSUME_CM_OVER_DATA), |
---|
140 | USB_QUIRK(MOTOROLA2, T720C, 0x001, 0x001, UQ_ASSUME_CM_OVER_DATA), |
---|
141 | USB_QUIRK(EICON, DIVA852, 0x100, 0x100, UQ_ASSUME_CM_OVER_DATA), |
---|
142 | USB_QUIRK(SIEMENS2, ES75, 0x000, 0x000, UQ_ASSUME_CM_OVER_DATA), |
---|
143 | USB_QUIRK(QUALCOMM, CDMA_MSM, 0x0000, 0xffff, UQ_ASSUME_CM_OVER_DATA), |
---|
144 | USB_QUIRK(QUALCOMM2, CDMA_MSM, 0x0000, 0xffff, UQ_ASSUME_CM_OVER_DATA), |
---|
145 | USB_QUIRK(CURITEL, UM150, 0x0000, 0xffff, UQ_ASSUME_CM_OVER_DATA), |
---|
146 | USB_QUIRK(CURITEL, UM175, 0x0000, 0xffff, UQ_ASSUME_CM_OVER_DATA), |
---|
147 | USB_QUIRK(VERTEX, VW110L, 0x0000, 0xffff, UQ_ASSUME_CM_OVER_DATA), |
---|
148 | |
---|
149 | /* USB Mass Storage Class Quirks */ |
---|
150 | USB_QUIRK_VP(USB_VENDOR_ASAHIOPTICAL, 0, UQ_MSC_NO_RS_CLEAR_UA, |
---|
151 | UQ_MATCH_VENDOR_ONLY), |
---|
152 | USB_QUIRK(ADDON, ATTACHE, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
153 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_IGNORE_RESIDUE), |
---|
154 | USB_QUIRK(ADDON, A256MB, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
155 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_IGNORE_RESIDUE), |
---|
156 | USB_QUIRK(ADDON, DISKPRO512, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
157 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_IGNORE_RESIDUE), |
---|
158 | USB_QUIRK(ADDONICS2, CABLE_205, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
159 | UQ_MSC_FORCE_PROTO_SCSI), |
---|
160 | USB_QUIRK(AIPTEK, POCKETCAM3M, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
161 | UQ_MSC_FORCE_PROTO_SCSI), |
---|
162 | USB_QUIRK(ALCOR, UMCR_9361, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
163 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_GETMAXLUN), |
---|
164 | USB_QUIRK(ALCOR, TRANSCEND, 0x0000, 0xffff, UQ_MSC_NO_GETMAXLUN, |
---|
165 | UQ_MSC_NO_SYNC_CACHE, UQ_MSC_NO_TEST_UNIT_READY), |
---|
166 | USB_QUIRK(APACER, HT202, 0x0000, 0xffff, UQ_MSC_NO_TEST_UNIT_READY, |
---|
167 | UQ_MSC_NO_SYNC_CACHE), |
---|
168 | USB_QUIRK(ASAHIOPTICAL, OPTIO230, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
169 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY), |
---|
170 | USB_QUIRK(ASAHIOPTICAL, OPTIO330, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
171 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY), |
---|
172 | USB_QUIRK(ATP, EUSB, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), |
---|
173 | USB_QUIRK(BELKIN, USB2SCSI, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
174 | UQ_MSC_FORCE_PROTO_SCSI), |
---|
175 | USB_QUIRK(CASIO, QV_DIGICAM, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI, |
---|
176 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY), |
---|
177 | USB_QUIRK(CCYU, ED1064, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
178 | UQ_MSC_FORCE_PROTO_SCSI), |
---|
179 | USB_QUIRK(CENTURY, EX35QUAT, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
180 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_FORCE_SHORT_INQ, |
---|
181 | UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE), |
---|
182 | USB_QUIRK(CYPRESS, XX6830XX, 0x0000, 0xffff, UQ_MSC_NO_GETMAXLUN, |
---|
183 | UQ_MSC_NO_SYNC_CACHE), |
---|
184 | USB_QUIRK(DESKNOTE, UCR_61S2B, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
185 | UQ_MSC_FORCE_PROTO_SCSI), |
---|
186 | USB_QUIRK(DMI, CFSM_RW, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI, |
---|
187 | UQ_MSC_NO_GETMAXLUN), |
---|
188 | USB_QUIRK(EMTEC, RUF2PS, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), |
---|
189 | USB_QUIRK(EPSON, STYLUS_875DC, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI, |
---|
190 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY), |
---|
191 | USB_QUIRK(EPSON, STYLUS_895, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
192 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_GETMAXLUN), |
---|
193 | USB_QUIRK(FEIYA, 5IN1, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
194 | UQ_MSC_FORCE_PROTO_SCSI), |
---|
195 | USB_QUIRK(FEIYA, ELANGO, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), |
---|
196 | USB_QUIRK(FREECOM, DVD, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI), |
---|
197 | USB_QUIRK(FUJIPHOTO, MASS0100, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI_I, |
---|
198 | UQ_MSC_FORCE_PROTO_ATAPI, UQ_MSC_NO_RS_CLEAR_UA, UQ_MSC_NO_SYNC_CACHE), |
---|
199 | USB_QUIRK(GENESYS, GL641USB2IDE, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
200 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_FORCE_SHORT_INQ, |
---|
201 | UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE, UQ_MSC_NO_SYNC_CACHE), |
---|
202 | USB_QUIRK(GENESYS, GL641USB2IDE_2, 0x0000, 0xffff, |
---|
203 | UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_ATAPI, |
---|
204 | UQ_MSC_FORCE_SHORT_INQ, UQ_MSC_NO_START_STOP, |
---|
205 | UQ_MSC_IGNORE_RESIDUE), |
---|
206 | USB_QUIRK(GENESYS, GL641USB, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
207 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_FORCE_SHORT_INQ, |
---|
208 | UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE), |
---|
209 | USB_QUIRK(GENESYS, GL641USB_2, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
210 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_WRONG_CSWSIG), |
---|
211 | USB_QUIRK(HAGIWARA, FG, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
212 | UQ_MSC_FORCE_PROTO_SCSI), |
---|
213 | USB_QUIRK(HAGIWARA, FGSM, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
214 | UQ_MSC_FORCE_PROTO_SCSI), |
---|
215 | USB_QUIRK(HITACHI, DVDCAM_DZ_MV100A, 0x0000, 0xffff, |
---|
216 | UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_SCSI, |
---|
217 | UQ_MSC_NO_GETMAXLUN), |
---|
218 | USB_QUIRK(HITACHI, DVDCAM_USB, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI_I, |
---|
219 | UQ_MSC_FORCE_PROTO_ATAPI, UQ_MSC_NO_INQUIRY), |
---|
220 | USB_QUIRK(HP, CDW4E, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_ATAPI), |
---|
221 | USB_QUIRK(HP, CDW8200, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI_I, |
---|
222 | UQ_MSC_FORCE_PROTO_ATAPI, UQ_MSC_NO_TEST_UNIT_READY, |
---|
223 | UQ_MSC_NO_START_STOP), |
---|
224 | USB_QUIRK(IMAGINATION, DBX1, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
225 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_WRONG_CSWSIG), |
---|
226 | USB_QUIRK(INSYSTEM, USBCABLE, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI, |
---|
227 | UQ_MSC_FORCE_PROTO_ATAPI, UQ_MSC_NO_TEST_UNIT_READY, |
---|
228 | UQ_MSC_NO_START_STOP, UQ_MSC_ALT_IFACE_1), |
---|
229 | USB_QUIRK(INSYSTEM, ATAPI, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI, |
---|
230 | UQ_MSC_FORCE_PROTO_RBC), |
---|
231 | USB_QUIRK(INSYSTEM, STORAGE_V2, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI, |
---|
232 | UQ_MSC_FORCE_PROTO_RBC), |
---|
233 | USB_QUIRK(IODATA, IU_CD2, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
234 | UQ_MSC_FORCE_PROTO_SCSI), |
---|
235 | USB_QUIRK(IODATA, DVR_UEH8, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
236 | UQ_MSC_FORCE_PROTO_SCSI), |
---|
237 | USB_QUIRK(IOMEGA, ZIP100, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
238 | UQ_MSC_FORCE_PROTO_SCSI, |
---|
239 | UQ_MSC_NO_TEST_UNIT_READY), /* XXX ZIP drives can also use ATAPI */ |
---|
240 | USB_QUIRK(JMICRON, JM20337, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
241 | UQ_MSC_FORCE_PROTO_SCSI, |
---|
242 | UQ_MSC_NO_SYNC_CACHE), |
---|
243 | USB_QUIRK(KINGSTON, HYPERX3_0, 0x0000, 0xffff, UQ_MSC_NO_INQUIRY), |
---|
244 | USB_QUIRK(KYOCERA, FINECAM_L3, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
245 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY), |
---|
246 | USB_QUIRK(KYOCERA, FINECAM_S3X, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI, |
---|
247 | UQ_MSC_FORCE_PROTO_ATAPI, UQ_MSC_NO_INQUIRY), |
---|
248 | USB_QUIRK(KYOCERA, FINECAM_S4, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI, |
---|
249 | UQ_MSC_FORCE_PROTO_ATAPI, UQ_MSC_NO_INQUIRY), |
---|
250 | USB_QUIRK(KYOCERA, FINECAM_S5, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
251 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY), |
---|
252 | USB_QUIRK(LACIE, HD, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI, |
---|
253 | UQ_MSC_FORCE_PROTO_RBC), |
---|
254 | USB_QUIRK(LEXAR, CF_READER, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
255 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY), |
---|
256 | USB_QUIRK(LEXAR, JUMPSHOT, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI), |
---|
257 | USB_QUIRK(LEXAR, JUMPDRIVE, 0x0000, 0xffff, UQ_MSC_NO_INQUIRY), |
---|
258 | USB_QUIRK(LOGITEC, LDR_H443SU2, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI), |
---|
259 | USB_QUIRK(LOGITEC, LDR_H443U2, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
260 | UQ_MSC_FORCE_PROTO_SCSI,), |
---|
261 | USB_QUIRK(MELCO, DUBPXXG, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
262 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_FORCE_SHORT_INQ, |
---|
263 | UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE), |
---|
264 | USB_QUIRK(MICROTECH, DPCM, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI, |
---|
265 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_TEST_UNIT_READY, |
---|
266 | UQ_MSC_NO_START_STOP), |
---|
267 | USB_QUIRK(MICRON, REALSSD, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), |
---|
268 | USB_QUIRK(MICROTECH, SCSIDB25, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
269 | UQ_MSC_FORCE_PROTO_SCSI), |
---|
270 | USB_QUIRK(MICROTECH, SCSIHD50, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
271 | UQ_MSC_FORCE_PROTO_SCSI), |
---|
272 | USB_QUIRK(MINOLTA, E223, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI), |
---|
273 | USB_QUIRK(MINOLTA, F300, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
274 | UQ_MSC_FORCE_PROTO_SCSI), |
---|
275 | USB_QUIRK(MITSUMI, CDRRW, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI | |
---|
276 | UQ_MSC_FORCE_PROTO_ATAPI), |
---|
277 | USB_QUIRK(MOTOROLA2, E398, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
278 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_FORCE_SHORT_INQ, |
---|
279 | UQ_MSC_NO_INQUIRY_EVPD, UQ_MSC_NO_GETMAXLUN), |
---|
280 | USB_QUIRK_VP(USB_VENDOR_MPMAN, 0, UQ_MSC_NO_SYNC_CACHE, |
---|
281 | UQ_MATCH_VENDOR_ONLY), |
---|
282 | USB_QUIRK(MSYSTEMS, DISKONKEY, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
283 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_IGNORE_RESIDUE, UQ_MSC_NO_GETMAXLUN, |
---|
284 | UQ_MSC_NO_RS_CLEAR_UA), |
---|
285 | USB_QUIRK(MSYSTEMS, DISKONKEY2, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
286 | UQ_MSC_FORCE_PROTO_ATAPI), |
---|
287 | USB_QUIRK(MYSON, HEDEN, 0x0000, 0xffff, UQ_MSC_IGNORE_RESIDUE, |
---|
288 | UQ_MSC_NO_SYNC_CACHE), |
---|
289 | USB_QUIRK(NEODIO, ND3260, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
290 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_FORCE_SHORT_INQ), |
---|
291 | USB_QUIRK(NETAC, CF_CARD, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
292 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY), |
---|
293 | USB_QUIRK(NETAC, ONLYDISK, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
294 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_IGNORE_RESIDUE), |
---|
295 | USB_QUIRK(NETCHIP, CLIK_40, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_ATAPI, |
---|
296 | UQ_MSC_NO_INQUIRY), |
---|
297 | USB_QUIRK(NETCHIP, POCKETBOOK, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), |
---|
298 | USB_QUIRK(NIKON, D300, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
299 | UQ_MSC_FORCE_PROTO_SCSI), |
---|
300 | USB_QUIRK(OLYMPUS, C1, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
301 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_WRONG_CSWSIG), |
---|
302 | USB_QUIRK(OLYMPUS, C700, 0x0000, 0xffff, UQ_MSC_NO_GETMAXLUN), |
---|
303 | USB_QUIRK(ONSPEC, SDS_HOTFIND_D, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
304 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_GETMAXLUN, UQ_MSC_NO_SYNC_CACHE), |
---|
305 | USB_QUIRK(ONSPEC, CFMS_RW, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI), |
---|
306 | USB_QUIRK(ONSPEC, CFSM_COMBO, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI), |
---|
307 | USB_QUIRK(ONSPEC, CFSM_READER, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI), |
---|
308 | USB_QUIRK(ONSPEC, CFSM_READER2, 0x0000, 0xffff, |
---|
309 | UQ_MSC_FORCE_PROTO_SCSI), |
---|
310 | USB_QUIRK(ONSPEC, MDCFE_B_CF_READER, 0x0000, 0xffff, |
---|
311 | UQ_MSC_FORCE_PROTO_SCSI), |
---|
312 | USB_QUIRK(ONSPEC, MDSM_B_READER, 0x0000, 0xffff, |
---|
313 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY), |
---|
314 | USB_QUIRK(ONSPEC, READER, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI), |
---|
315 | USB_QUIRK(ONSPEC, UCF100, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
316 | UQ_MSC_FORCE_PROTO_ATAPI, UQ_MSC_NO_INQUIRY, UQ_MSC_NO_GETMAXLUN), |
---|
317 | USB_QUIRK(ONSPEC2, IMAGEMATE_SDDR55, 0x0000, 0xffff, |
---|
318 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_GETMAXLUN), |
---|
319 | USB_QUIRK(PANASONIC, KXL840AN, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
320 | UQ_MSC_FORCE_PROTO_ATAPI, UQ_MSC_NO_GETMAXLUN), |
---|
321 | USB_QUIRK(PANASONIC, KXLCB20AN, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
322 | UQ_MSC_FORCE_PROTO_SCSI), |
---|
323 | USB_QUIRK(PANASONIC, KXLCB35AN, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
324 | UQ_MSC_FORCE_PROTO_SCSI), |
---|
325 | USB_QUIRK(PANASONIC, LS120CAM, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_UFI), |
---|
326 | USB_QUIRK(PLEXTOR, 40_12_40U, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
327 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_TEST_UNIT_READY), |
---|
328 | USB_QUIRK(PNY, ATTACHE2, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
329 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_IGNORE_RESIDUE, |
---|
330 | UQ_MSC_NO_START_STOP), |
---|
331 | USB_QUIRK(PROLIFIC, PL2506, 0x0000, 0xffff, |
---|
332 | UQ_MSC_NO_SYNC_CACHE), |
---|
333 | USB_QUIRK_VP(USB_VENDOR_SAMSUNG_TECHWIN, |
---|
334 | USB_PRODUCT_SAMSUNG_TECHWIN_DIGIMAX_410, UQ_MSC_FORCE_WIRE_BBB, |
---|
335 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY), |
---|
336 | USB_QUIRK(SANDISK, SDDR05A, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI, |
---|
337 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_READ_CAP_OFFBY1, |
---|
338 | UQ_MSC_NO_GETMAXLUN), |
---|
339 | USB_QUIRK(SANDISK, SDDR09, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI, |
---|
340 | UQ_MSC_READ_CAP_OFFBY1, UQ_MSC_NO_GETMAXLUN), |
---|
341 | USB_QUIRK(SANDISK, SDDR12, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI, |
---|
342 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_READ_CAP_OFFBY1, |
---|
343 | UQ_MSC_NO_GETMAXLUN), |
---|
344 | USB_QUIRK(SANDISK, SDCZ2_128, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
345 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_IGNORE_RESIDUE, |
---|
346 | UQ_MSC_NO_SYNC_CACHE), |
---|
347 | USB_QUIRK(SANDISK, SDCZ2_256, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
348 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_IGNORE_RESIDUE), |
---|
349 | USB_QUIRK(SANDISK, SDCZ4_128, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
350 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_IGNORE_RESIDUE), |
---|
351 | USB_QUIRK(SANDISK, SDCZ4_256, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
352 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_IGNORE_RESIDUE), |
---|
353 | USB_QUIRK(SANDISK, SDDR31, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
354 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_READ_CAP_OFFBY1), |
---|
355 | USB_QUIRK(SANDISK, IMAGEMATE_SDDR289, 0x0000, 0xffff, |
---|
356 | UQ_MSC_NO_SYNC_CACHE, UQ_MSC_NO_GETMAXLUN), |
---|
357 | USB_QUIRK(SCANLOGIC, SL11R, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
358 | UQ_MSC_FORCE_PROTO_ATAPI, UQ_MSC_NO_INQUIRY), |
---|
359 | USB_QUIRK(SHUTTLE, EUSB, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI_I, |
---|
360 | UQ_MSC_FORCE_PROTO_ATAPI, UQ_MSC_NO_TEST_UNIT_READY, |
---|
361 | UQ_MSC_NO_START_STOP, UQ_MSC_SHUTTLE_INIT), |
---|
362 | USB_QUIRK(SHUTTLE, CDRW, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI, |
---|
363 | UQ_MSC_FORCE_PROTO_ATAPI), |
---|
364 | USB_QUIRK(SHUTTLE, CF, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI, |
---|
365 | UQ_MSC_FORCE_PROTO_ATAPI), |
---|
366 | USB_QUIRK(SHUTTLE, EUSBATAPI, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI, |
---|
367 | UQ_MSC_FORCE_PROTO_ATAPI), |
---|
368 | USB_QUIRK(SHUTTLE, EUSBCFSM, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI), |
---|
369 | USB_QUIRK(SHUTTLE, EUSCSI, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
370 | UQ_MSC_FORCE_PROTO_SCSI), |
---|
371 | USB_QUIRK(SHUTTLE, HIFD, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI, |
---|
372 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_GETMAXLUN), |
---|
373 | USB_QUIRK(SHUTTLE, SDDR09, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI, |
---|
374 | UQ_MSC_NO_GETMAXLUN), |
---|
375 | USB_QUIRK(SHUTTLE, ZIOMMC, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI, |
---|
376 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_GETMAXLUN), |
---|
377 | USB_QUIRK(SIGMATEL, I_BEAD100, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
378 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_SHUTTLE_INIT), |
---|
379 | USB_QUIRK(SIIG, WINTERREADER, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
380 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_IGNORE_RESIDUE), |
---|
381 | USB_QUIRK(SKANHEX, MD_7425, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
382 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY), |
---|
383 | USB_QUIRK(SKANHEX, SX_520Z, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
384 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY), |
---|
385 | USB_QUIRK(SONY, HANDYCAM, 0x0500, 0x0500, UQ_MSC_FORCE_WIRE_CBI, |
---|
386 | UQ_MSC_FORCE_PROTO_RBC, UQ_MSC_RBC_PAD_TO_12), |
---|
387 | USB_QUIRK(SONY, CLIE_40_MS, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
388 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY), |
---|
389 | USB_QUIRK(SONY, DSC, 0x0500, 0x0500, UQ_MSC_FORCE_WIRE_CBI, |
---|
390 | UQ_MSC_FORCE_PROTO_RBC, UQ_MSC_RBC_PAD_TO_12), |
---|
391 | USB_QUIRK(SONY, DSC, 0x0600, 0x0600, UQ_MSC_FORCE_WIRE_CBI, |
---|
392 | UQ_MSC_FORCE_PROTO_RBC, UQ_MSC_RBC_PAD_TO_12), |
---|
393 | USB_QUIRK(SONY, DSC, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI, |
---|
394 | UQ_MSC_FORCE_PROTO_RBC), |
---|
395 | USB_QUIRK(SONY, HANDYCAM, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI, |
---|
396 | UQ_MSC_FORCE_PROTO_RBC), |
---|
397 | USB_QUIRK(SONY, MSC, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI, |
---|
398 | UQ_MSC_FORCE_PROTO_RBC), |
---|
399 | USB_QUIRK(SONY, MS_MSC_U03, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI, |
---|
400 | UQ_MSC_FORCE_PROTO_UFI, UQ_MSC_NO_GETMAXLUN), |
---|
401 | USB_QUIRK(SONY, MS_NW_MS7, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
402 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_GETMAXLUN), |
---|
403 | USB_QUIRK(SONY, MS_PEG_N760C, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
404 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY), |
---|
405 | USB_QUIRK(SONY, MSACUS1, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
406 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_GETMAXLUN), |
---|
407 | USB_QUIRK(SONY, PORTABLE_HDD_V2, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
408 | UQ_MSC_FORCE_PROTO_SCSI), |
---|
409 | USB_QUIRK(STMICRO, ST72682, 0x0000, 0xffff, UQ_MSC_NO_PREVENT_ALLOW), |
---|
410 | USB_QUIRK(SUPERTOP, IDE, 0x0000, 0xffff, UQ_MSC_IGNORE_RESIDUE, |
---|
411 | UQ_MSC_NO_SYNC_CACHE), |
---|
412 | USB_QUIRK(SUPERTOP, FLASHDRIVE, 0x0000, 0xffff, UQ_MSC_NO_TEST_UNIT_READY, |
---|
413 | UQ_MSC_NO_SYNC_CACHE), |
---|
414 | USB_QUIRK(TAUGA, CAMERAMATE, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI), |
---|
415 | USB_QUIRK(TEAC, FD05PUB, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI, |
---|
416 | UQ_MSC_FORCE_PROTO_UFI), |
---|
417 | USB_QUIRK(TECLAST, TLC300, 0x0000, 0xffff, UQ_MSC_NO_TEST_UNIT_READY, |
---|
418 | UQ_MSC_NO_SYNC_CACHE), |
---|
419 | USB_QUIRK(TREK, MEMKEY, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
420 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY), |
---|
421 | USB_QUIRK(TREK, THUMBDRIVE_8MB, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
422 | UQ_MSC_FORCE_PROTO_ATAPI, UQ_MSC_IGNORE_RESIDUE), |
---|
423 | USB_QUIRK(TRUMPION, C3310, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI, |
---|
424 | UQ_MSC_FORCE_PROTO_UFI), |
---|
425 | USB_QUIRK(TRUMPION, MP3, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_RBC), |
---|
426 | USB_QUIRK(TRUMPION, T33520, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI), |
---|
427 | USB_QUIRK(TWINMOS, MDIV, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
428 | UQ_MSC_FORCE_PROTO_SCSI), |
---|
429 | USB_QUIRK(VIA, USB2IDEBRIDGE, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
430 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_SYNC_CACHE), |
---|
431 | USB_QUIRK(VIVITAR, 35XX, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
432 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY), |
---|
433 | USB_QUIRK(WESTERN, COMBO, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
434 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_FORCE_SHORT_INQ, |
---|
435 | UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE), |
---|
436 | USB_QUIRK(WESTERN, EXTHDD, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
437 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_FORCE_SHORT_INQ, |
---|
438 | UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE), |
---|
439 | USB_QUIRK(WESTERN, MYBOOK, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
440 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY_EVPD, |
---|
441 | UQ_MSC_NO_SYNC_CACHE), |
---|
442 | USB_QUIRK(WESTERN, MYPASSPORT_00, 0x0000, 0xffff, UQ_MSC_FORCE_SHORT_INQ), |
---|
443 | USB_QUIRK(WESTERN, MYPASSPORT_01, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), |
---|
444 | USB_QUIRK(WESTERN, MYPASSPORT_02, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), |
---|
445 | USB_QUIRK(WESTERN, MYPASSPORT_03, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), |
---|
446 | USB_QUIRK(WESTERN, MYPASSPORT_04, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), |
---|
447 | USB_QUIRK(WESTERN, MYPASSPORT_05, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), |
---|
448 | USB_QUIRK(WESTERN, MYPASSPORT_06, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), |
---|
449 | USB_QUIRK(WESTERN, MYPASSPORT_07, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), |
---|
450 | USB_QUIRK(WESTERN, MYPASSPORT_08, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), |
---|
451 | USB_QUIRK(WESTERN, MYPASSPORT_09, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), |
---|
452 | USB_QUIRK(WESTERN, MYPASSPORT_10, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), |
---|
453 | USB_QUIRK(WESTERN, MYPASSPORT_11, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), |
---|
454 | USB_QUIRK(WESTERN, MYPASSPORTES_00, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), |
---|
455 | USB_QUIRK(WESTERN, MYPASSPORTES_01, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), |
---|
456 | USB_QUIRK(WESTERN, MYPASSPORTES_02, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), |
---|
457 | USB_QUIRK(WESTERN, MYPASSPORTES_03, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), |
---|
458 | USB_QUIRK(WESTERN, MYPASSPORTES_04, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), |
---|
459 | USB_QUIRK(WESTERN, MYPASSPORTES_05, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), |
---|
460 | USB_QUIRK(WESTERN, MYPASSPORTES_06, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), |
---|
461 | USB_QUIRK(WESTERN, MYPASSPORTES_07, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), |
---|
462 | USB_QUIRK(WESTERN, MYPASSPORTES_08, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), |
---|
463 | USB_QUIRK(WESTERN, MYPASSPORTES_09, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), |
---|
464 | USB_QUIRK(WINMAXGROUP, FLASH64MC, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
465 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY), |
---|
466 | USB_QUIRK(YANO, FW800HD, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
467 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_FORCE_SHORT_INQ, |
---|
468 | UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE), |
---|
469 | USB_QUIRK(YANO, U640MO, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI_I, |
---|
470 | UQ_MSC_FORCE_PROTO_ATAPI, UQ_MSC_FORCE_SHORT_INQ), |
---|
471 | USB_QUIRK(YEDATA, FLASHBUSTERU, 0x0000, 0x007F, UQ_MSC_FORCE_WIRE_CBI, |
---|
472 | UQ_MSC_FORCE_PROTO_UFI, UQ_MSC_NO_RS_CLEAR_UA, UQ_MSC_FLOPPY_SPEED, |
---|
473 | UQ_MSC_NO_TEST_UNIT_READY, UQ_MSC_NO_GETMAXLUN), |
---|
474 | USB_QUIRK(YEDATA, FLASHBUSTERU, 0x0080, 0x0080, UQ_MSC_FORCE_WIRE_CBI_I, |
---|
475 | UQ_MSC_FORCE_PROTO_UFI, UQ_MSC_NO_RS_CLEAR_UA, UQ_MSC_FLOPPY_SPEED, |
---|
476 | UQ_MSC_NO_TEST_UNIT_READY, UQ_MSC_NO_GETMAXLUN), |
---|
477 | USB_QUIRK(YEDATA, FLASHBUSTERU, 0x0081, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI_I, |
---|
478 | UQ_MSC_FORCE_PROTO_UFI, UQ_MSC_NO_RS_CLEAR_UA, UQ_MSC_FLOPPY_SPEED, |
---|
479 | UQ_MSC_NO_GETMAXLUN), |
---|
480 | USB_QUIRK(ZORAN, EX20DSC, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI, |
---|
481 | UQ_MSC_FORCE_PROTO_ATAPI), |
---|
482 | USB_QUIRK(MEIZU, M6_SL, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, |
---|
483 | UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY, UQ_MSC_NO_SYNC_CACHE), |
---|
484 | USB_QUIRK(TOSHIBA, TRANSMEMORY, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE, |
---|
485 | UQ_MSC_NO_PREVENT_ALLOW), |
---|
486 | USB_QUIRK(VIALABS, USB30SATABRIDGE, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), |
---|
487 | USB_QUIRK(QUALCOMMINC, ZTE_MF730M, 0x0000, 0xffff, UQ_MSC_NO_GETMAXLUN, |
---|
488 | UQ_MSC_NO_INQUIRY, UQ_CFG_INDEX_0), |
---|
489 | /* Non-standard USB MIDI devices */ |
---|
490 | USB_QUIRK(ROLAND, UM1, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS), |
---|
491 | USB_QUIRK(ROLAND, SC8850, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS), |
---|
492 | USB_QUIRK(ROLAND, SD90, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS), |
---|
493 | USB_QUIRK(ROLAND, UM880N, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS), |
---|
494 | USB_QUIRK(ROLAND, UA100, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS), |
---|
495 | USB_QUIRK(ROLAND, UM4, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS), |
---|
496 | USB_QUIRK(ROLAND, U8, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS), |
---|
497 | USB_QUIRK(ROLAND, UM2, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS), |
---|
498 | USB_QUIRK(ROLAND, SC8820, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS), |
---|
499 | USB_QUIRK(ROLAND, PC300, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS), |
---|
500 | USB_QUIRK(ROLAND, SK500, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS), |
---|
501 | USB_QUIRK(ROLAND, SCD70, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS), |
---|
502 | USB_QUIRK(ROLAND, UM550, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS), |
---|
503 | USB_QUIRK(ROLAND, SD20, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS), |
---|
504 | USB_QUIRK(ROLAND, SD80, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS), |
---|
505 | USB_QUIRK(ROLAND, UA700, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS), |
---|
506 | USB_QUIRK(EGO, M4U, 0x0000, 0xffff, UQ_SINGLE_CMD_MIDI), |
---|
507 | USB_QUIRK(LOGILINK, U2M, 0x0000, 0xffff, UQ_SINGLE_CMD_MIDI), |
---|
508 | USB_QUIRK(MEDELI, DD305, 0x0000, 0xffff, UQ_SINGLE_CMD_MIDI, UQ_MATCH_VENDOR_ONLY), |
---|
509 | USB_QUIRK(REDOCTANE, GHMIDI, 0x0000, 0xffff, UQ_SINGLE_CMD_MIDI), |
---|
510 | USB_QUIRK(TEXTECH, U2M_1, 0x0000, 0xffff, UQ_SINGLE_CMD_MIDI), |
---|
511 | USB_QUIRK(TEXTECH, U2M_2, 0x0000, 0xffff, UQ_SINGLE_CMD_MIDI), |
---|
512 | USB_QUIRK(WCH2, U2M, 0x0000, 0xffff, UQ_SINGLE_CMD_MIDI), |
---|
513 | |
---|
514 | /* Non-standard USB AUDIO devices */ |
---|
515 | USB_QUIRK(MAUDIO, FASTTRACKULTRA, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS), |
---|
516 | USB_QUIRK(MAUDIO, FASTTRACKULTRA8R, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS), |
---|
517 | |
---|
518 | /* |
---|
519 | * Quirks for manufacturers which USB devices does not respond |
---|
520 | * after issuing non-supported commands: |
---|
521 | */ |
---|
522 | USB_QUIRK(ALCOR, DUMMY, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE, UQ_MSC_NO_TEST_UNIT_READY, UQ_MATCH_VENDOR_ONLY), |
---|
523 | USB_QUIRK(APPLE, DUMMY, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE, UQ_MATCH_VENDOR_ONLY), |
---|
524 | USB_QUIRK(FEIYA, DUMMY, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE, UQ_MATCH_VENDOR_ONLY), |
---|
525 | USB_QUIRK(REALTEK, DUMMY, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE, UQ_MATCH_VENDOR_ONLY), |
---|
526 | USB_QUIRK(INITIO, DUMMY, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE, UQ_MATCH_VENDOR_ONLY), |
---|
527 | }; |
---|
528 | #undef USB_QUIRK_VP |
---|
529 | #undef USB_QUIRK |
---|
530 | |
---|
531 | static const char *usb_quirk_str[USB_QUIRK_MAX] = { |
---|
532 | [UQ_NONE] = "UQ_NONE", |
---|
533 | [UQ_MATCH_VENDOR_ONLY] = "UQ_MATCH_VENDOR_ONLY", |
---|
534 | [UQ_AUDIO_SWAP_LR] = "UQ_AUDIO_SWAP_LR", |
---|
535 | [UQ_AU_INP_ASYNC] = "UQ_AU_INP_ASYNC", |
---|
536 | [UQ_AU_NO_FRAC] = "UQ_AU_NO_FRAC", |
---|
537 | [UQ_AU_NO_XU] = "UQ_AU_NO_XU", |
---|
538 | [UQ_BAD_ADC] = "UQ_BAD_ADC", |
---|
539 | [UQ_BAD_AUDIO] = "UQ_BAD_AUDIO", |
---|
540 | [UQ_BROKEN_BIDIR] = "UQ_BROKEN_BIDIR", |
---|
541 | [UQ_BUS_POWERED] = "UQ_BUS_POWERED", |
---|
542 | [UQ_HID_IGNORE] = "UQ_HID_IGNORE", |
---|
543 | [UQ_KBD_IGNORE] = "UQ_KBD_IGNORE", |
---|
544 | [UQ_KBD_BOOTPROTO] = "UQ_KBD_BOOTPROTO", |
---|
545 | [UQ_UMS_IGNORE] = "UQ_UMS_IGNORE", |
---|
546 | [UQ_MS_BAD_CLASS] = "UQ_MS_BAD_CLASS", |
---|
547 | [UQ_MS_LEADING_BYTE] = "UQ_MS_LEADING_BYTE", |
---|
548 | [UQ_MS_REVZ] = "UQ_MS_REVZ", |
---|
549 | [UQ_NO_STRINGS] = "UQ_NO_STRINGS", |
---|
550 | [UQ_OPEN_CLEARSTALL] = "UQ_OPEN_CLEARSTALL", |
---|
551 | [UQ_POWER_CLAIM] = "UQ_POWER_CLAIM", |
---|
552 | [UQ_SPUR_BUT_UP] = "UQ_SPUR_BUT_UP", |
---|
553 | [UQ_SWAP_UNICODE] = "UQ_SWAP_UNICODE", |
---|
554 | [UQ_CFG_INDEX_1] = "UQ_CFG_INDEX_1", |
---|
555 | [UQ_CFG_INDEX_2] = "UQ_CFG_INDEX_2", |
---|
556 | [UQ_CFG_INDEX_3] = "UQ_CFG_INDEX_3", |
---|
557 | [UQ_CFG_INDEX_4] = "UQ_CFG_INDEX_4", |
---|
558 | [UQ_CFG_INDEX_0] = "UQ_CFG_INDEX_0", |
---|
559 | [UQ_ASSUME_CM_OVER_DATA] = "UQ_ASSUME_CM_OVER_DATA", |
---|
560 | [UQ_MSC_NO_TEST_UNIT_READY] = "UQ_MSC_NO_TEST_UNIT_READY", |
---|
561 | [UQ_MSC_NO_RS_CLEAR_UA] = "UQ_MSC_NO_RS_CLEAR_UA", |
---|
562 | [UQ_MSC_NO_START_STOP] = "UQ_MSC_NO_START_STOP", |
---|
563 | [UQ_MSC_NO_GETMAXLUN] = "UQ_MSC_NO_GETMAXLUN", |
---|
564 | [UQ_MSC_NO_INQUIRY] = "UQ_MSC_NO_INQUIRY", |
---|
565 | [UQ_MSC_NO_INQUIRY_EVPD] = "UQ_MSC_NO_INQUIRY_EVPD", |
---|
566 | [UQ_MSC_NO_PREVENT_ALLOW] = "UQ_MSC_NO_PREVENT_ALLOW", |
---|
567 | [UQ_MSC_NO_SYNC_CACHE] = "UQ_MSC_NO_SYNC_CACHE", |
---|
568 | [UQ_MSC_SHUTTLE_INIT] = "UQ_MSC_SHUTTLE_INIT", |
---|
569 | [UQ_MSC_ALT_IFACE_1] = "UQ_MSC_ALT_IFACE_1", |
---|
570 | [UQ_MSC_FLOPPY_SPEED] = "UQ_MSC_FLOPPY_SPEED", |
---|
571 | [UQ_MSC_IGNORE_RESIDUE] = "UQ_MSC_IGNORE_RESIDUE", |
---|
572 | [UQ_MSC_WRONG_CSWSIG] = "UQ_MSC_WRONG_CSWSIG", |
---|
573 | [UQ_MSC_RBC_PAD_TO_12] = "UQ_MSC_RBC_PAD_TO_12", |
---|
574 | [UQ_MSC_READ_CAP_OFFBY1] = "UQ_MSC_READ_CAP_OFFBY1", |
---|
575 | [UQ_MSC_FORCE_SHORT_INQ] = "UQ_MSC_FORCE_SHORT_INQ", |
---|
576 | [UQ_MSC_FORCE_WIRE_BBB] = "UQ_MSC_FORCE_WIRE_BBB", |
---|
577 | [UQ_MSC_FORCE_WIRE_CBI] = "UQ_MSC_FORCE_WIRE_CBI", |
---|
578 | [UQ_MSC_FORCE_WIRE_CBI_I] = "UQ_MSC_FORCE_WIRE_CBI_I", |
---|
579 | [UQ_MSC_FORCE_PROTO_SCSI] = "UQ_MSC_FORCE_PROTO_SCSI", |
---|
580 | [UQ_MSC_FORCE_PROTO_ATAPI] = "UQ_MSC_FORCE_PROTO_ATAPI", |
---|
581 | [UQ_MSC_FORCE_PROTO_UFI] = "UQ_MSC_FORCE_PROTO_UFI", |
---|
582 | [UQ_MSC_FORCE_PROTO_RBC] = "UQ_MSC_FORCE_PROTO_RBC", |
---|
583 | [UQ_MSC_EJECT_HUAWEI] = "UQ_MSC_EJECT_HUAWEI", |
---|
584 | [UQ_MSC_EJECT_SIERRA] = "UQ_MSC_EJECT_SIERRA", |
---|
585 | [UQ_MSC_EJECT_SCSIEJECT] = "UQ_MSC_EJECT_SCSIEJECT", |
---|
586 | [UQ_MSC_EJECT_REZERO] = "UQ_MSC_EJECT_REZERO", |
---|
587 | [UQ_MSC_EJECT_ZTESTOR] = "UQ_MSC_EJECT_ZTESTOR", |
---|
588 | [UQ_MSC_EJECT_CMOTECH] = "UQ_MSC_EJECT_CMOTECH", |
---|
589 | [UQ_MSC_EJECT_WAIT] = "UQ_MSC_EJECT_WAIT", |
---|
590 | [UQ_MSC_EJECT_SAEL_M460] = "UQ_MSC_EJECT_SAEL_M460", |
---|
591 | [UQ_MSC_EJECT_HUAWEISCSI] = "UQ_MSC_EJECT_HUAWEISCSI", |
---|
592 | [UQ_MSC_EJECT_HUAWEISCSI2] = "UQ_MSC_EJECT_HUAWEISCSI2", |
---|
593 | [UQ_MSC_EJECT_TCT] = "UQ_MSC_EJECT_TCT", |
---|
594 | [UQ_BAD_MIDI] = "UQ_BAD_MIDI", |
---|
595 | [UQ_AU_VENDOR_CLASS] = "UQ_AU_VENDOR_CLASS", |
---|
596 | [UQ_SINGLE_CMD_MIDI] = "UQ_SINGLE_CMD_MIDI", |
---|
597 | }; |
---|
598 | |
---|
599 | /*------------------------------------------------------------------------* |
---|
600 | * usb_quirkstr |
---|
601 | * |
---|
602 | * This function converts an USB quirk code into a string. |
---|
603 | *------------------------------------------------------------------------*/ |
---|
604 | static const char * |
---|
605 | usb_quirkstr(uint16_t quirk) |
---|
606 | { |
---|
607 | return ((quirk < USB_QUIRK_MAX) ? |
---|
608 | usb_quirk_str[quirk] : "USB_QUIRK_UNKNOWN"); |
---|
609 | } |
---|
610 | |
---|
611 | /*------------------------------------------------------------------------* |
---|
612 | * usb_test_quirk_by_info |
---|
613 | * |
---|
614 | * Returns: |
---|
615 | * 0: Quirk not found |
---|
616 | * Else: Quirk found |
---|
617 | *------------------------------------------------------------------------*/ |
---|
618 | static uint8_t |
---|
619 | usb_test_quirk_by_info(const struct usbd_lookup_info *info, uint16_t quirk) |
---|
620 | { |
---|
621 | uint16_t x; |
---|
622 | uint16_t y; |
---|
623 | |
---|
624 | if (quirk == UQ_NONE) |
---|
625 | goto done; |
---|
626 | |
---|
627 | mtx_lock(&usb_quirk_mtx); |
---|
628 | |
---|
629 | for (x = 0; x != USB_DEV_QUIRKS_MAX; x++) { |
---|
630 | /* see if quirk information does not match */ |
---|
631 | if ((usb_quirks[x].vid != info->idVendor) || |
---|
632 | (usb_quirks[x].lo_rev > info->bcdDevice) || |
---|
633 | (usb_quirks[x].hi_rev < info->bcdDevice)) { |
---|
634 | continue; |
---|
635 | } |
---|
636 | /* see if quirk only should match vendor ID */ |
---|
637 | if (usb_quirks[x].pid != info->idProduct) { |
---|
638 | if (usb_quirks[x].pid != 0) |
---|
639 | continue; |
---|
640 | |
---|
641 | for (y = 0; y != USB_SUB_QUIRKS_MAX; y++) { |
---|
642 | if (usb_quirks[x].quirks[y] == UQ_MATCH_VENDOR_ONLY) |
---|
643 | break; |
---|
644 | } |
---|
645 | if (y == USB_SUB_QUIRKS_MAX) |
---|
646 | continue; |
---|
647 | } |
---|
648 | /* lookup quirk */ |
---|
649 | for (y = 0; y != USB_SUB_QUIRKS_MAX; y++) { |
---|
650 | if (usb_quirks[x].quirks[y] == quirk) { |
---|
651 | mtx_unlock(&usb_quirk_mtx); |
---|
652 | DPRINTF("Found quirk '%s'.\n", usb_quirkstr(quirk)); |
---|
653 | return (1); |
---|
654 | } |
---|
655 | } |
---|
656 | /* no quirk found */ |
---|
657 | break; |
---|
658 | } |
---|
659 | mtx_unlock(&usb_quirk_mtx); |
---|
660 | done: |
---|
661 | return (0); /* no quirk match */ |
---|
662 | } |
---|
663 | |
---|
664 | static struct usb_quirk_entry * |
---|
665 | usb_quirk_get_entry(uint16_t vid, uint16_t pid, |
---|
666 | uint16_t lo_rev, uint16_t hi_rev, uint8_t do_alloc) |
---|
667 | { |
---|
668 | uint16_t x; |
---|
669 | |
---|
670 | mtx_assert(&usb_quirk_mtx, MA_OWNED); |
---|
671 | |
---|
672 | if ((vid | pid | lo_rev | hi_rev) == 0) { |
---|
673 | /* all zero - special case */ |
---|
674 | return (usb_quirks + USB_DEV_QUIRKS_MAX - 1); |
---|
675 | } |
---|
676 | /* search for an existing entry */ |
---|
677 | for (x = 0; x != USB_DEV_QUIRKS_MAX; x++) { |
---|
678 | /* see if quirk information does not match */ |
---|
679 | if ((usb_quirks[x].vid != vid) || |
---|
680 | (usb_quirks[x].pid != pid) || |
---|
681 | (usb_quirks[x].lo_rev != lo_rev) || |
---|
682 | (usb_quirks[x].hi_rev != hi_rev)) { |
---|
683 | continue; |
---|
684 | } |
---|
685 | return (usb_quirks + x); |
---|
686 | } |
---|
687 | |
---|
688 | if (do_alloc == 0) { |
---|
689 | /* no match */ |
---|
690 | return (NULL); |
---|
691 | } |
---|
692 | /* search for a free entry */ |
---|
693 | for (x = 0; x != USB_DEV_QUIRKS_MAX; x++) { |
---|
694 | /* see if quirk information does not match */ |
---|
695 | if ((usb_quirks[x].vid | |
---|
696 | usb_quirks[x].pid | |
---|
697 | usb_quirks[x].lo_rev | |
---|
698 | usb_quirks[x].hi_rev) != 0) { |
---|
699 | continue; |
---|
700 | } |
---|
701 | usb_quirks[x].vid = vid; |
---|
702 | usb_quirks[x].pid = pid; |
---|
703 | usb_quirks[x].lo_rev = lo_rev; |
---|
704 | usb_quirks[x].hi_rev = hi_rev; |
---|
705 | |
---|
706 | return (usb_quirks + x); |
---|
707 | } |
---|
708 | |
---|
709 | /* no entry found */ |
---|
710 | return (NULL); |
---|
711 | } |
---|
712 | |
---|
713 | /*------------------------------------------------------------------------* |
---|
714 | * usb_quirk_ioctl - handle quirk IOCTLs |
---|
715 | * |
---|
716 | * Returns: |
---|
717 | * 0: Success |
---|
718 | * Else: Failure |
---|
719 | *------------------------------------------------------------------------*/ |
---|
720 | static int |
---|
721 | usb_quirk_ioctl(unsigned long cmd, caddr_t data, |
---|
722 | int fflag, struct thread *td) |
---|
723 | { |
---|
724 | struct usb_gen_quirk *pgq; |
---|
725 | struct usb_quirk_entry *pqe; |
---|
726 | uint32_t x; |
---|
727 | uint32_t y; |
---|
728 | int err; |
---|
729 | |
---|
730 | switch (cmd) { |
---|
731 | case USB_DEV_QUIRK_GET: |
---|
732 | pgq = (void *)data; |
---|
733 | x = pgq->index % USB_SUB_QUIRKS_MAX; |
---|
734 | y = pgq->index / USB_SUB_QUIRKS_MAX; |
---|
735 | if (y >= USB_DEV_QUIRKS_MAX) { |
---|
736 | return (EINVAL); |
---|
737 | } |
---|
738 | mtx_lock(&usb_quirk_mtx); |
---|
739 | /* copy out data */ |
---|
740 | pgq->vid = usb_quirks[y].vid; |
---|
741 | pgq->pid = usb_quirks[y].pid; |
---|
742 | pgq->bcdDeviceLow = usb_quirks[y].lo_rev; |
---|
743 | pgq->bcdDeviceHigh = usb_quirks[y].hi_rev; |
---|
744 | strlcpy(pgq->quirkname, |
---|
745 | usb_quirkstr(usb_quirks[y].quirks[x]), |
---|
746 | sizeof(pgq->quirkname)); |
---|
747 | mtx_unlock(&usb_quirk_mtx); |
---|
748 | return (0); /* success */ |
---|
749 | |
---|
750 | case USB_QUIRK_NAME_GET: |
---|
751 | pgq = (void *)data; |
---|
752 | x = pgq->index; |
---|
753 | if (x >= USB_QUIRK_MAX) { |
---|
754 | return (EINVAL); |
---|
755 | } |
---|
756 | strlcpy(pgq->quirkname, |
---|
757 | usb_quirkstr(x), sizeof(pgq->quirkname)); |
---|
758 | return (0); /* success */ |
---|
759 | |
---|
760 | case USB_DEV_QUIRK_ADD: |
---|
761 | pgq = (void *)data; |
---|
762 | |
---|
763 | /* check privileges */ |
---|
764 | err = priv_check(curthread, PRIV_DRIVER); |
---|
765 | if (err) { |
---|
766 | return (err); |
---|
767 | } |
---|
768 | /* convert quirk string into numerical */ |
---|
769 | for (y = 0; y != USB_DEV_QUIRKS_MAX; y++) { |
---|
770 | if (strcmp(pgq->quirkname, usb_quirkstr(y)) == 0) { |
---|
771 | break; |
---|
772 | } |
---|
773 | } |
---|
774 | if (y == USB_DEV_QUIRKS_MAX) { |
---|
775 | return (EINVAL); |
---|
776 | } |
---|
777 | if (y == UQ_NONE) { |
---|
778 | return (EINVAL); |
---|
779 | } |
---|
780 | mtx_lock(&usb_quirk_mtx); |
---|
781 | pqe = usb_quirk_get_entry(pgq->vid, pgq->pid, |
---|
782 | pgq->bcdDeviceLow, pgq->bcdDeviceHigh, 1); |
---|
783 | if (pqe == NULL) { |
---|
784 | mtx_unlock(&usb_quirk_mtx); |
---|
785 | return (EINVAL); |
---|
786 | } |
---|
787 | for (x = 0; x != USB_SUB_QUIRKS_MAX; x++) { |
---|
788 | if (pqe->quirks[x] == UQ_NONE) { |
---|
789 | pqe->quirks[x] = y; |
---|
790 | break; |
---|
791 | } |
---|
792 | } |
---|
793 | mtx_unlock(&usb_quirk_mtx); |
---|
794 | if (x == USB_SUB_QUIRKS_MAX) { |
---|
795 | return (ENOMEM); |
---|
796 | } |
---|
797 | return (0); /* success */ |
---|
798 | |
---|
799 | case USB_DEV_QUIRK_REMOVE: |
---|
800 | pgq = (void *)data; |
---|
801 | /* check privileges */ |
---|
802 | err = priv_check(curthread, PRIV_DRIVER); |
---|
803 | if (err) { |
---|
804 | return (err); |
---|
805 | } |
---|
806 | /* convert quirk string into numerical */ |
---|
807 | for (y = 0; y != USB_DEV_QUIRKS_MAX; y++) { |
---|
808 | if (strcmp(pgq->quirkname, usb_quirkstr(y)) == 0) { |
---|
809 | break; |
---|
810 | } |
---|
811 | } |
---|
812 | if (y == USB_DEV_QUIRKS_MAX) { |
---|
813 | return (EINVAL); |
---|
814 | } |
---|
815 | if (y == UQ_NONE) { |
---|
816 | return (EINVAL); |
---|
817 | } |
---|
818 | mtx_lock(&usb_quirk_mtx); |
---|
819 | pqe = usb_quirk_get_entry(pgq->vid, pgq->pid, |
---|
820 | pgq->bcdDeviceLow, pgq->bcdDeviceHigh, 0); |
---|
821 | if (pqe == NULL) { |
---|
822 | mtx_unlock(&usb_quirk_mtx); |
---|
823 | return (EINVAL); |
---|
824 | } |
---|
825 | for (x = 0; x != USB_SUB_QUIRKS_MAX; x++) { |
---|
826 | if (pqe->quirks[x] == y) { |
---|
827 | pqe->quirks[x] = UQ_NONE; |
---|
828 | break; |
---|
829 | } |
---|
830 | } |
---|
831 | if (x == USB_SUB_QUIRKS_MAX) { |
---|
832 | mtx_unlock(&usb_quirk_mtx); |
---|
833 | return (ENOMEM); |
---|
834 | } |
---|
835 | for (x = 0; x != USB_SUB_QUIRKS_MAX; x++) { |
---|
836 | if (pqe->quirks[x] != UQ_NONE) { |
---|
837 | break; |
---|
838 | } |
---|
839 | } |
---|
840 | if (x == USB_SUB_QUIRKS_MAX) { |
---|
841 | /* all quirk entries are unused - release */ |
---|
842 | memset(pqe, 0, sizeof(*pqe)); |
---|
843 | } |
---|
844 | mtx_unlock(&usb_quirk_mtx); |
---|
845 | return (0); /* success */ |
---|
846 | |
---|
847 | default: |
---|
848 | break; |
---|
849 | } |
---|
850 | return (ENOIOCTL); |
---|
851 | } |
---|
852 | |
---|
853 | static void |
---|
854 | usb_quirk_init(void *arg) |
---|
855 | { |
---|
856 | /* initialize mutex */ |
---|
857 | mtx_init(&usb_quirk_mtx, "USB quirk", NULL, MTX_DEF); |
---|
858 | |
---|
859 | /* register our function */ |
---|
860 | usb_test_quirk_p = &usb_test_quirk_by_info; |
---|
861 | usb_quirk_ioctl_p = &usb_quirk_ioctl; |
---|
862 | } |
---|
863 | |
---|
864 | #ifndef __rtems__ |
---|
865 | static void |
---|
866 | usb_quirk_uninit(void *arg) |
---|
867 | { |
---|
868 | usb_quirk_unload(arg); |
---|
869 | |
---|
870 | /* destroy mutex */ |
---|
871 | mtx_destroy(&usb_quirk_mtx); |
---|
872 | } |
---|
873 | #endif /* __rtems__ */ |
---|
874 | |
---|
875 | SYSINIT(usb_quirk_init, SI_SUB_LOCK, SI_ORDER_FIRST, usb_quirk_init, NULL); |
---|
876 | SYSUNINIT(usb_quirk_uninit, SI_SUB_LOCK, SI_ORDER_ANY, usb_quirk_uninit, NULL); |
---|