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