diff options
-rw-r--r-- | drivers/block/Kconfig | 3 | ||||
-rw-r--r-- | drivers/block/ub.c | 23 | ||||
-rw-r--r-- | drivers/usb/Makefile | 1 | ||||
-rw-r--r-- | drivers/usb/storage/Kconfig | 14 | ||||
-rw-r--r-- | drivers/usb/storage/Makefile | 4 | ||||
-rw-r--r-- | drivers/usb/storage/libusual.c | 266 | ||||
-rw-r--r-- | drivers/usb/storage/protocol.h | 14 | ||||
-rw-r--r-- | drivers/usb/storage/transport.h | 31 | ||||
-rw-r--r-- | drivers/usb/storage/unusual_devs.h | 24 | ||||
-rw-r--r-- | drivers/usb/storage/usb.c | 119 | ||||
-rw-r--r-- | drivers/usb/storage/usb.h | 31 | ||||
-rw-r--r-- | include/linux/usb_usual.h | 123 |
12 files changed, 486 insertions, 167 deletions
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 7b1cd93892be..c4b9d2adfc08 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig | |||
@@ -358,7 +358,8 @@ config BLK_DEV_UB | |||
358 | This driver supports certain USB attached storage devices | 358 | This driver supports certain USB attached storage devices |
359 | such as flash keys. | 359 | such as flash keys. |
360 | 360 | ||
361 | Warning: Enabling this cripples the usb-storage driver. | 361 | If you enable this driver, it is recommended to avoid conflicts |
362 | with usb-storage by enabling USB_LIBUSUAL. | ||
362 | 363 | ||
363 | If unsure, say N. | 364 | If unsure, say N. |
364 | 365 | ||
diff --git a/drivers/block/ub.c b/drivers/block/ub.c index bfb23d543ff7..06d741d58a68 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/usb.h> | 31 | #include <linux/usb.h> |
32 | #include <linux/usb_usual.h> | ||
32 | #include <linux/blkdev.h> | 33 | #include <linux/blkdev.h> |
33 | #include <linux/devfs_fs_kernel.h> | 34 | #include <linux/devfs_fs_kernel.h> |
34 | #include <linux/timer.h> | 35 | #include <linux/timer.h> |
@@ -107,16 +108,6 @@ | |||
107 | */ | 108 | */ |
108 | 109 | ||
109 | /* | 110 | /* |
110 | * Definitions which have to be scattered once we understand the layout better. | ||
111 | */ | ||
112 | |||
113 | /* Transport (despite PR in the name) */ | ||
114 | #define US_PR_BULK 0x50 /* bulk only */ | ||
115 | |||
116 | /* Protocol */ | ||
117 | #define US_SC_SCSI 0x06 /* Transparent */ | ||
118 | |||
119 | /* | ||
120 | * This many LUNs per USB device. | 111 | * This many LUNs per USB device. |
121 | * Every one of them takes a host, see UB_MAX_HOSTS. | 112 | * Every one of them takes a host, see UB_MAX_HOSTS. |
122 | */ | 113 | */ |
@@ -422,13 +413,18 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum); | |||
422 | 413 | ||
423 | /* | 414 | /* |
424 | */ | 415 | */ |
416 | #ifdef CONFIG_USB_LIBUSUAL | ||
417 | |||
418 | #define ub_usb_ids storage_usb_ids | ||
419 | #else | ||
420 | |||
425 | static struct usb_device_id ub_usb_ids[] = { | 421 | static struct usb_device_id ub_usb_ids[] = { |
426 | // { USB_DEVICE_VER(0x0781, 0x0002, 0x0009, 0x0009) }, /* SDDR-31 */ | ||
427 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) }, | 422 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) }, |
428 | { } | 423 | { } |
429 | }; | 424 | }; |
430 | 425 | ||
431 | MODULE_DEVICE_TABLE(usb, ub_usb_ids); | 426 | MODULE_DEVICE_TABLE(usb, ub_usb_ids); |
427 | #endif /* CONFIG_USB_LIBUSUAL */ | ||
432 | 428 | ||
433 | /* | 429 | /* |
434 | * Find me a way to identify "next free minor" for add_disk(), | 430 | * Find me a way to identify "next free minor" for add_disk(), |
@@ -2172,6 +2168,9 @@ static int ub_probe(struct usb_interface *intf, | |||
2172 | int rc; | 2168 | int rc; |
2173 | int i; | 2169 | int i; |
2174 | 2170 | ||
2171 | if (usb_usual_check_type(dev_id, USB_US_TYPE_UB)) | ||
2172 | return -ENXIO; | ||
2173 | |||
2175 | rc = -ENOMEM; | 2174 | rc = -ENOMEM; |
2176 | if ((sc = kmalloc(sizeof(struct ub_dev), GFP_KERNEL)) == NULL) | 2175 | if ((sc = kmalloc(sizeof(struct ub_dev), GFP_KERNEL)) == NULL) |
2177 | goto err_core; | 2176 | goto err_core; |
@@ -2479,6 +2478,7 @@ static int __init ub_init(void) | |||
2479 | if ((rc = usb_register(&ub_driver)) != 0) | 2478 | if ((rc = usb_register(&ub_driver)) != 0) |
2480 | goto err_register; | 2479 | goto err_register; |
2481 | 2480 | ||
2481 | usb_usual_set_present(USB_US_TYPE_UB); | ||
2482 | return 0; | 2482 | return 0; |
2483 | 2483 | ||
2484 | err_register: | 2484 | err_register: |
@@ -2494,6 +2494,7 @@ static void __exit ub_exit(void) | |||
2494 | 2494 | ||
2495 | devfs_remove(DEVFS_NAME); | 2495 | devfs_remove(DEVFS_NAME); |
2496 | unregister_blkdev(UB_MAJOR, DRV_NAME); | 2496 | unregister_blkdev(UB_MAJOR, DRV_NAME); |
2497 | usb_usual_clear_present(USB_US_TYPE_UB); | ||
2497 | } | 2498 | } |
2498 | 2499 | ||
2499 | module_init(ub_init); | 2500 | module_init(ub_init); |
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index a50c2bc506f2..3639c3f8d357 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile | |||
@@ -22,6 +22,7 @@ obj-$(CONFIG_USB_MIDI) += class/ | |||
22 | obj-$(CONFIG_USB_PRINTER) += class/ | 22 | obj-$(CONFIG_USB_PRINTER) += class/ |
23 | 23 | ||
24 | obj-$(CONFIG_USB_STORAGE) += storage/ | 24 | obj-$(CONFIG_USB_STORAGE) += storage/ |
25 | obj-$(CONFIG_USB) += storage/ | ||
25 | 26 | ||
26 | obj-$(CONFIG_USB_AIPTEK) += input/ | 27 | obj-$(CONFIG_USB_AIPTEK) += input/ |
27 | obj-$(CONFIG_USB_ATI_REMOTE) += input/ | 28 | obj-$(CONFIG_USB_ATI_REMOTE) += input/ |
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index c41d64dbb0f0..bdfcb95d9c12 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig | |||
@@ -124,3 +124,17 @@ config USB_STORAGE_ONETOUCH | |||
124 | hard drive's as an input device. An action can be associated with | 124 | hard drive's as an input device. An action can be associated with |
125 | this input in any keybinding software. (e.g. gnome's keyboard short- | 125 | this input in any keybinding software. (e.g. gnome's keyboard short- |
126 | cuts) | 126 | cuts) |
127 | |||
128 | config USB_LIBUSUAL | ||
129 | bool "The shared table of common (or usual) storage devices" | ||
130 | depends on USB | ||
131 | help | ||
132 | This module contains a table of common (or usual) devices | ||
133 | for usb-storage and ub drivers, and allows to switch binding | ||
134 | of these devices without rebuilding modules. | ||
135 | |||
136 | Typical syntax of /etc/modprobe.conf is: | ||
137 | |||
138 | options libusual bias="ub" | ||
139 | |||
140 | If unsure, say N. | ||
diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile index 44ab8f9978fe..2d416e9028bb 100644 --- a/drivers/usb/storage/Makefile +++ b/drivers/usb/storage/Makefile | |||
@@ -22,3 +22,7 @@ usb-storage-obj-$(CONFIG_USB_STORAGE_ONETOUCH) += onetouch.o | |||
22 | 22 | ||
23 | usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \ | 23 | usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \ |
24 | initializers.o $(usb-storage-obj-y) | 24 | initializers.o $(usb-storage-obj-y) |
25 | |||
26 | ifneq ($(CONFIG_USB_LIBUSUAL),) | ||
27 | obj-$(CONFIG_USB) += libusual.o | ||
28 | endif | ||
diff --git a/drivers/usb/storage/libusual.c b/drivers/usb/storage/libusual.c new file mode 100644 index 000000000000..61f73d8a2c0f --- /dev/null +++ b/drivers/usb/storage/libusual.c | |||
@@ -0,0 +1,266 @@ | |||
1 | /* | ||
2 | * libusual | ||
3 | * | ||
4 | * The libusual contains the table of devices common for ub and usb-storage. | ||
5 | */ | ||
6 | #include <linux/kernel.h> | ||
7 | #include <linux/module.h> | ||
8 | #include <linux/usb.h> | ||
9 | #include <linux/usb_usual.h> | ||
10 | #include <linux/vmalloc.h> | ||
11 | |||
12 | /* | ||
13 | */ | ||
14 | #define USU_MOD_FL_THREAD 1 /* Thread is running */ | ||
15 | #define USU_MOD_FL_PRESENT 2 /* The module is loaded */ | ||
16 | |||
17 | struct mod_status { | ||
18 | unsigned long fls; | ||
19 | }; | ||
20 | |||
21 | static struct mod_status stat[3]; | ||
22 | static DEFINE_SPINLOCK(usu_lock); | ||
23 | |||
24 | /* | ||
25 | */ | ||
26 | #define USB_US_DEFAULT_BIAS USB_US_TYPE_STOR | ||
27 | |||
28 | #define BIAS_NAME_SIZE (sizeof("usb-storage")) | ||
29 | static char bias[BIAS_NAME_SIZE]; | ||
30 | static int usb_usual_bias; | ||
31 | static const char *bias_names[3] = { "none", "usb-storage", "ub" }; | ||
32 | |||
33 | static DECLARE_MUTEX_LOCKED(usu_init_notify); | ||
34 | static DECLARE_COMPLETION(usu_end_notify); | ||
35 | static atomic_t total_threads = ATOMIC_INIT(0); | ||
36 | |||
37 | static int usu_probe_thread(void *arg); | ||
38 | static int parse_bias(const char *bias_s); | ||
39 | |||
40 | /* | ||
41 | * The table. | ||
42 | */ | ||
43 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
44 | vendorName, productName,useProtocol, useTransport, \ | ||
45 | initFunction, flags) \ | ||
46 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \ | ||
47 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
48 | |||
49 | #define USUAL_DEV(useProto, useTrans, useType) \ | ||
50 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \ | ||
51 | .driver_info = ((useType)<<24) } | ||
52 | |||
53 | struct usb_device_id storage_usb_ids [] = { | ||
54 | # include "unusual_devs.h" | ||
55 | { } /* Terminating entry */ | ||
56 | }; | ||
57 | |||
58 | #undef USUAL_DEV | ||
59 | #undef UNUSUAL_DEV | ||
60 | |||
61 | MODULE_DEVICE_TABLE(usb, storage_usb_ids); | ||
62 | EXPORT_SYMBOL_GPL(storage_usb_ids); | ||
63 | |||
64 | /* | ||
65 | * @type: the module type as an integer | ||
66 | */ | ||
67 | void usb_usual_set_present(int type) | ||
68 | { | ||
69 | struct mod_status *st; | ||
70 | unsigned long flags; | ||
71 | |||
72 | if (type <= 0 || type >= 3) | ||
73 | return; | ||
74 | st = &stat[type]; | ||
75 | spin_lock_irqsave(&usu_lock, flags); | ||
76 | st->fls |= USU_MOD_FL_PRESENT; | ||
77 | spin_unlock_irqrestore(&usu_lock, flags); | ||
78 | } | ||
79 | EXPORT_SYMBOL_GPL(usb_usual_set_present); | ||
80 | |||
81 | void usb_usual_clear_present(int type) | ||
82 | { | ||
83 | struct mod_status *st; | ||
84 | unsigned long flags; | ||
85 | |||
86 | if (type <= 0 || type >= 3) | ||
87 | return; | ||
88 | st = &stat[type]; | ||
89 | spin_lock_irqsave(&usu_lock, flags); | ||
90 | st->fls &= ~USU_MOD_FL_PRESENT; | ||
91 | spin_unlock_irqrestore(&usu_lock, flags); | ||
92 | } | ||
93 | EXPORT_SYMBOL_GPL(usb_usual_clear_present); | ||
94 | |||
95 | /* | ||
96 | * Match the calling driver type against the table. | ||
97 | * Returns: 0 if the device matches. | ||
98 | */ | ||
99 | int usb_usual_check_type(const struct usb_device_id *id, int caller_type) | ||
100 | { | ||
101 | int id_type = USB_US_TYPE(id->driver_info); | ||
102 | |||
103 | if (caller_type <= 0 || caller_type >= 3) | ||
104 | return -EINVAL; | ||
105 | |||
106 | /* Drivers grab fixed assignment devices */ | ||
107 | if (id_type == caller_type) | ||
108 | return 0; | ||
109 | /* Drivers grab devices biased to them */ | ||
110 | if (id_type == USB_US_TYPE_NONE && caller_type == usb_usual_bias) | ||
111 | return 0; | ||
112 | return -ENODEV; | ||
113 | } | ||
114 | EXPORT_SYMBOL_GPL(usb_usual_check_type); | ||
115 | |||
116 | /* | ||
117 | */ | ||
118 | static int usu_probe(struct usb_interface *intf, | ||
119 | const struct usb_device_id *id) | ||
120 | { | ||
121 | int type; | ||
122 | int rc; | ||
123 | unsigned long flags; | ||
124 | |||
125 | type = USB_US_TYPE(id->driver_info); | ||
126 | if (type == 0) | ||
127 | type = usb_usual_bias; | ||
128 | |||
129 | spin_lock_irqsave(&usu_lock, flags); | ||
130 | if ((stat[type].fls & (USU_MOD_FL_THREAD|USU_MOD_FL_PRESENT)) != 0) { | ||
131 | spin_unlock_irqrestore(&usu_lock, flags); | ||
132 | return -ENXIO; | ||
133 | } | ||
134 | stat[type].fls |= USU_MOD_FL_THREAD; | ||
135 | spin_unlock_irqrestore(&usu_lock, flags); | ||
136 | |||
137 | rc = kernel_thread(usu_probe_thread, (void*)type, CLONE_VM); | ||
138 | if (rc < 0) { | ||
139 | printk(KERN_WARNING "libusual: " | ||
140 | "Unable to start the thread for %s: %d\n", | ||
141 | bias_names[type], rc); | ||
142 | spin_lock_irqsave(&usu_lock, flags); | ||
143 | stat[type].fls &= ~USU_MOD_FL_THREAD; | ||
144 | spin_unlock_irqrestore(&usu_lock, flags); | ||
145 | return rc; /* Not being -ENXIO causes a message printed */ | ||
146 | } | ||
147 | atomic_inc(&total_threads); | ||
148 | |||
149 | return -ENXIO; | ||
150 | } | ||
151 | |||
152 | static void usu_disconnect(struct usb_interface *intf) | ||
153 | { | ||
154 | ; /* We should not be here. */ | ||
155 | } | ||
156 | |||
157 | static struct usb_driver usu_driver = { | ||
158 | .owner = THIS_MODULE, | ||
159 | .name = "libusual", | ||
160 | .probe = usu_probe, | ||
161 | .disconnect = usu_disconnect, | ||
162 | .id_table = storage_usb_ids, | ||
163 | }; | ||
164 | |||
165 | /* | ||
166 | * A whole new thread for a purpose of request_module seems quite stupid. | ||
167 | * The request_module forks once inside again. However, if we attempt | ||
168 | * to load a storage module from our own modprobe thread, that module | ||
169 | * references our symbols, which cannot be resolved until our module is | ||
170 | * initialized. I wish there was a way to wait for the end of initialization. | ||
171 | * The module notifier reports MODULE_STATE_COMING only. | ||
172 | * So, we wait until module->init ends as the next best thing. | ||
173 | */ | ||
174 | static int usu_probe_thread(void *arg) | ||
175 | { | ||
176 | int type = (unsigned long) arg; | ||
177 | struct mod_status *st = &stat[type]; | ||
178 | int rc; | ||
179 | unsigned long flags; | ||
180 | |||
181 | daemonize("libusual_%d", type); /* "usb-storage" is kinda too long */ | ||
182 | |||
183 | /* A completion does not work here because it's counted. */ | ||
184 | down(&usu_init_notify); | ||
185 | up(&usu_init_notify); | ||
186 | |||
187 | rc = request_module(bias_names[type]); | ||
188 | spin_lock_irqsave(&usu_lock, flags); | ||
189 | if (rc == 0 && (st->fls & USU_MOD_FL_PRESENT) == 0) { | ||
190 | /* | ||
191 | * This should not happen, but let us keep tabs on it. | ||
192 | */ | ||
193 | printk(KERN_NOTICE "libusual: " | ||
194 | "modprobe for %s succeeded, but module is not present\n", | ||
195 | bias_names[type]); | ||
196 | } | ||
197 | st->fls &= ~USU_MOD_FL_THREAD; | ||
198 | spin_unlock_irqrestore(&usu_lock, flags); | ||
199 | |||
200 | complete_and_exit(&usu_end_notify, 0); | ||
201 | } | ||
202 | |||
203 | /* | ||
204 | */ | ||
205 | static int __init usb_usual_init(void) | ||
206 | { | ||
207 | int rc; | ||
208 | |||
209 | bias[BIAS_NAME_SIZE-1] = 0; | ||
210 | usb_usual_bias = parse_bias(bias); | ||
211 | |||
212 | rc = usb_register(&usu_driver); | ||
213 | up(&usu_init_notify); | ||
214 | return rc; | ||
215 | } | ||
216 | |||
217 | static void __exit usb_usual_exit(void) | ||
218 | { | ||
219 | /* | ||
220 | * We do not check for any drivers present, because | ||
221 | * they keep us pinned with symbol references. | ||
222 | */ | ||
223 | |||
224 | usb_deregister(&usu_driver); | ||
225 | |||
226 | while (atomic_read(&total_threads) > 0) { | ||
227 | wait_for_completion(&usu_end_notify); | ||
228 | atomic_dec(&total_threads); | ||
229 | } | ||
230 | } | ||
231 | |||
232 | /* | ||
233 | * Validate and accept the bias parameter. | ||
234 | * Maybe make an sysfs method later. XXX | ||
235 | */ | ||
236 | static int parse_bias(const char *bias_s) | ||
237 | { | ||
238 | int i; | ||
239 | int bias_n = 0; | ||
240 | |||
241 | if (bias_s[0] == 0 || bias_s[0] == ' ') { | ||
242 | bias_n = USB_US_DEFAULT_BIAS; | ||
243 | } else { | ||
244 | for (i = 1; i < 3; i++) { | ||
245 | if (strcmp(bias_s, bias_names[i]) == 0) { | ||
246 | bias_n = i; | ||
247 | break; | ||
248 | } | ||
249 | } | ||
250 | if (bias_n == 0) { | ||
251 | bias_n = USB_US_DEFAULT_BIAS; | ||
252 | printk(KERN_INFO | ||
253 | "libusual: unknown bias \"%s\", using \"%s\"\n", | ||
254 | bias_s, bias_names[bias_n]); | ||
255 | } | ||
256 | } | ||
257 | return bias_n; | ||
258 | } | ||
259 | |||
260 | module_init(usb_usual_init); | ||
261 | module_exit(usb_usual_exit); | ||
262 | |||
263 | module_param_string(bias, bias, BIAS_NAME_SIZE, S_IRUGO|S_IWUSR); | ||
264 | MODULE_PARM_DESC(bias, "Bias to usb-storage or ub"); | ||
265 | |||
266 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/storage/protocol.h b/drivers/usb/storage/protocol.h index 02bff01ab09c..845bed4b8031 100644 --- a/drivers/usb/storage/protocol.h +++ b/drivers/usb/storage/protocol.h | |||
@@ -41,20 +41,6 @@ | |||
41 | #ifndef _PROTOCOL_H_ | 41 | #ifndef _PROTOCOL_H_ |
42 | #define _PROTOCOL_H_ | 42 | #define _PROTOCOL_H_ |
43 | 43 | ||
44 | /* Sub Classes */ | ||
45 | |||
46 | #define US_SC_RBC 0x01 /* Typically, flash devices */ | ||
47 | #define US_SC_8020 0x02 /* CD-ROM */ | ||
48 | #define US_SC_QIC 0x03 /* QIC-157 Tapes */ | ||
49 | #define US_SC_UFI 0x04 /* Floppy */ | ||
50 | #define US_SC_8070 0x05 /* Removable media */ | ||
51 | #define US_SC_SCSI 0x06 /* Transparent */ | ||
52 | #define US_SC_ISD200 0x07 /* ISD200 ATA */ | ||
53 | #define US_SC_MIN US_SC_RBC | ||
54 | #define US_SC_MAX US_SC_ISD200 | ||
55 | |||
56 | #define US_SC_DEVICE 0xff /* Use device's value */ | ||
57 | |||
58 | /* Protocol handling routines */ | 44 | /* Protocol handling routines */ |
59 | extern void usb_stor_ATAPI_command(struct scsi_cmnd*, struct us_data*); | 45 | extern void usb_stor_ATAPI_command(struct scsi_cmnd*, struct us_data*); |
60 | extern void usb_stor_qic157_command(struct scsi_cmnd*, struct us_data*); | 46 | extern void usb_stor_qic157_command(struct scsi_cmnd*, struct us_data*); |
diff --git a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h index 0a362cc781ad..633a715850a4 100644 --- a/drivers/usb/storage/transport.h +++ b/drivers/usb/storage/transport.h | |||
@@ -41,39 +41,8 @@ | |||
41 | #ifndef _TRANSPORT_H_ | 41 | #ifndef _TRANSPORT_H_ |
42 | #define _TRANSPORT_H_ | 42 | #define _TRANSPORT_H_ |
43 | 43 | ||
44 | #include <linux/config.h> | ||
45 | #include <linux/blkdev.h> | 44 | #include <linux/blkdev.h> |
46 | 45 | ||
47 | /* Protocols */ | ||
48 | |||
49 | #define US_PR_CBI 0x00 /* Control/Bulk/Interrupt */ | ||
50 | #define US_PR_CB 0x01 /* Control/Bulk w/o interrupt */ | ||
51 | #define US_PR_BULK 0x50 /* bulk only */ | ||
52 | #ifdef CONFIG_USB_STORAGE_USBAT | ||
53 | #define US_PR_USBAT 0x80 /* SCM-ATAPI bridge */ | ||
54 | #endif | ||
55 | #ifdef CONFIG_USB_STORAGE_SDDR09 | ||
56 | #define US_PR_EUSB_SDDR09 0x81 /* SCM-SCSI bridge for SDDR-09 */ | ||
57 | #endif | ||
58 | #ifdef CONFIG_USB_STORAGE_SDDR55 | ||
59 | #define US_PR_SDDR55 0x82 /* SDDR-55 (made up) */ | ||
60 | #endif | ||
61 | #define US_PR_DPCM_USB 0xf0 /* Combination CB/SDDR09 */ | ||
62 | |||
63 | #ifdef CONFIG_USB_STORAGE_FREECOM | ||
64 | #define US_PR_FREECOM 0xf1 /* Freecom */ | ||
65 | #endif | ||
66 | |||
67 | #ifdef CONFIG_USB_STORAGE_DATAFAB | ||
68 | #define US_PR_DATAFAB 0xf2 /* Datafab chipsets */ | ||
69 | #endif | ||
70 | |||
71 | #ifdef CONFIG_USB_STORAGE_JUMPSHOT | ||
72 | #define US_PR_JUMPSHOT 0xf3 /* Lexar Jumpshot */ | ||
73 | #endif | ||
74 | |||
75 | #define US_PR_DEVICE 0xff /* Use device's value */ | ||
76 | |||
77 | /* | 46 | /* |
78 | * Bulk only data structures | 47 | * Bulk only data structures |
79 | */ | 48 | */ |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index f5f47a34b168..76904ad11241 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -1134,3 +1134,27 @@ UNUSUAL_DEV( 0x55aa, 0xa103, 0x0000, 0x9999, | |||
1134 | US_SC_SCSI, US_PR_SDDR55, NULL, | 1134 | US_SC_SCSI, US_PR_SDDR55, NULL, |
1135 | US_FL_SINGLE_LUN), | 1135 | US_FL_SINGLE_LUN), |
1136 | #endif | 1136 | #endif |
1137 | |||
1138 | /* Control/Bulk transport for all SubClass values */ | ||
1139 | USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR), | ||
1140 | USUAL_DEV(US_SC_8020, US_PR_CB, USB_US_TYPE_STOR), | ||
1141 | USUAL_DEV(US_SC_QIC, US_PR_CB, USB_US_TYPE_STOR), | ||
1142 | USUAL_DEV(US_SC_UFI, US_PR_CB, USB_US_TYPE_STOR), | ||
1143 | USUAL_DEV(US_SC_8070, US_PR_CB, USB_US_TYPE_STOR), | ||
1144 | USUAL_DEV(US_SC_SCSI, US_PR_CB, USB_US_TYPE_STOR), | ||
1145 | |||
1146 | /* Control/Bulk/Interrupt transport for all SubClass values */ | ||
1147 | USUAL_DEV(US_SC_RBC, US_PR_CBI, USB_US_TYPE_STOR), | ||
1148 | USUAL_DEV(US_SC_8020, US_PR_CBI, USB_US_TYPE_STOR), | ||
1149 | USUAL_DEV(US_SC_QIC, US_PR_CBI, USB_US_TYPE_STOR), | ||
1150 | USUAL_DEV(US_SC_UFI, US_PR_CBI, USB_US_TYPE_STOR), | ||
1151 | USUAL_DEV(US_SC_8070, US_PR_CBI, USB_US_TYPE_STOR), | ||
1152 | USUAL_DEV(US_SC_SCSI, US_PR_CBI, USB_US_TYPE_STOR), | ||
1153 | |||
1154 | /* Bulk-only transport for all SubClass values */ | ||
1155 | USUAL_DEV(US_SC_RBC, US_PR_BULK, USB_US_TYPE_STOR), | ||
1156 | USUAL_DEV(US_SC_8020, US_PR_BULK, USB_US_TYPE_STOR), | ||
1157 | USUAL_DEV(US_SC_QIC, US_PR_BULK, USB_US_TYPE_STOR), | ||
1158 | USUAL_DEV(US_SC_UFI, US_PR_BULK, USB_US_TYPE_STOR), | ||
1159 | USUAL_DEV(US_SC_8070, US_PR_BULK, USB_US_TYPE_STOR), | ||
1160 | USUAL_DEV(US_SC_SCSI, US_PR_BULK, 0), | ||
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 3847ebed2aa4..c8375aa62723 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c | |||
@@ -112,49 +112,33 @@ static atomic_t total_threads = ATOMIC_INIT(0); | |||
112 | static DECLARE_COMPLETION(threads_gone); | 112 | static DECLARE_COMPLETION(threads_gone); |
113 | 113 | ||
114 | 114 | ||
115 | /* The entries in this table, except for final ones here | 115 | /* |
116 | * (USB_MASS_STORAGE_CLASS and the empty entry), correspond, | 116 | * The entries in this table correspond, line for line, |
117 | * line for line with the entries of us_unsuaul_dev_list[]. | 117 | * with the entries of us_unusual_dev_list[]. |
118 | */ | 118 | */ |
119 | #ifndef CONFIG_USB_LIBUSUAL | ||
119 | 120 | ||
120 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | 121 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ |
121 | vendorName, productName,useProtocol, useTransport, \ | 122 | vendorName, productName,useProtocol, useTransport, \ |
122 | initFunction, flags) \ | 123 | initFunction, flags) \ |
123 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax) } | 124 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \ |
125 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
126 | |||
127 | #define USUAL_DEV(useProto, useTrans, useType) \ | ||
128 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \ | ||
129 | .driver_info = (USB_US_TYPE_STOR<<24) } | ||
124 | 130 | ||
125 | static struct usb_device_id storage_usb_ids [] = { | 131 | static struct usb_device_id storage_usb_ids [] = { |
126 | 132 | ||
127 | # include "unusual_devs.h" | 133 | # include "unusual_devs.h" |
128 | #undef UNUSUAL_DEV | 134 | #undef UNUSUAL_DEV |
129 | /* Control/Bulk transport for all SubClass values */ | 135 | #undef USUAL_DEV |
130 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_CB) }, | ||
131 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_CB) }, | ||
132 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_CB) }, | ||
133 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_CB) }, | ||
134 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_CB) }, | ||
135 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_CB) }, | ||
136 | |||
137 | /* Control/Bulk/Interrupt transport for all SubClass values */ | ||
138 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_CBI) }, | ||
139 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_CBI) }, | ||
140 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_CBI) }, | ||
141 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_CBI) }, | ||
142 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_CBI) }, | ||
143 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_CBI) }, | ||
144 | |||
145 | /* Bulk-only transport for all SubClass values */ | ||
146 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_BULK) }, | ||
147 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_BULK) }, | ||
148 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_BULK) }, | ||
149 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_BULK) }, | ||
150 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_BULK) }, | ||
151 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) }, | ||
152 | |||
153 | /* Terminating entry */ | 136 | /* Terminating entry */ |
154 | { } | 137 | { } |
155 | }; | 138 | }; |
156 | 139 | ||
157 | MODULE_DEVICE_TABLE (usb, storage_usb_ids); | 140 | MODULE_DEVICE_TABLE (usb, storage_usb_ids); |
141 | #endif /* CONFIG_USB_LIBUSUAL */ | ||
158 | 142 | ||
159 | /* This is the list of devices we recognize, along with their flag data */ | 143 | /* This is the list of devices we recognize, along with their flag data */ |
160 | 144 | ||
@@ -167,7 +151,6 @@ MODULE_DEVICE_TABLE (usb, storage_usb_ids); | |||
167 | * are free to use as many characters as you like. | 151 | * are free to use as many characters as you like. |
168 | */ | 152 | */ |
169 | 153 | ||
170 | #undef UNUSUAL_DEV | ||
171 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | 154 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ |
172 | vendor_name, product_name, use_protocol, use_transport, \ | 155 | vendor_name, product_name, use_protocol, use_transport, \ |
173 | init_function, Flags) \ | 156 | init_function, Flags) \ |
@@ -177,53 +160,18 @@ MODULE_DEVICE_TABLE (usb, storage_usb_ids); | |||
177 | .useProtocol = use_protocol, \ | 160 | .useProtocol = use_protocol, \ |
178 | .useTransport = use_transport, \ | 161 | .useTransport = use_transport, \ |
179 | .initFunction = init_function, \ | 162 | .initFunction = init_function, \ |
180 | .flags = Flags, \ | 163 | } |
164 | |||
165 | #define USUAL_DEV(use_protocol, use_transport, use_type) \ | ||
166 | { \ | ||
167 | .useProtocol = use_protocol, \ | ||
168 | .useTransport = use_transport, \ | ||
181 | } | 169 | } |
182 | 170 | ||
183 | static struct us_unusual_dev us_unusual_dev_list[] = { | 171 | static struct us_unusual_dev us_unusual_dev_list[] = { |
184 | # include "unusual_devs.h" | 172 | # include "unusual_devs.h" |
185 | # undef UNUSUAL_DEV | 173 | # undef UNUSUAL_DEV |
186 | /* Control/Bulk transport for all SubClass values */ | 174 | # undef USUAL_DEV |
187 | { .useProtocol = US_SC_RBC, | ||
188 | .useTransport = US_PR_CB}, | ||
189 | { .useProtocol = US_SC_8020, | ||
190 | .useTransport = US_PR_CB}, | ||
191 | { .useProtocol = US_SC_QIC, | ||
192 | .useTransport = US_PR_CB}, | ||
193 | { .useProtocol = US_SC_UFI, | ||
194 | .useTransport = US_PR_CB}, | ||
195 | { .useProtocol = US_SC_8070, | ||
196 | .useTransport = US_PR_CB}, | ||
197 | { .useProtocol = US_SC_SCSI, | ||
198 | .useTransport = US_PR_CB}, | ||
199 | |||
200 | /* Control/Bulk/Interrupt transport for all SubClass values */ | ||
201 | { .useProtocol = US_SC_RBC, | ||
202 | .useTransport = US_PR_CBI}, | ||
203 | { .useProtocol = US_SC_8020, | ||
204 | .useTransport = US_PR_CBI}, | ||
205 | { .useProtocol = US_SC_QIC, | ||
206 | .useTransport = US_PR_CBI}, | ||
207 | { .useProtocol = US_SC_UFI, | ||
208 | .useTransport = US_PR_CBI}, | ||
209 | { .useProtocol = US_SC_8070, | ||
210 | .useTransport = US_PR_CBI}, | ||
211 | { .useProtocol = US_SC_SCSI, | ||
212 | .useTransport = US_PR_CBI}, | ||
213 | |||
214 | /* Bulk-only transport for all SubClass values */ | ||
215 | { .useProtocol = US_SC_RBC, | ||
216 | .useTransport = US_PR_BULK}, | ||
217 | { .useProtocol = US_SC_8020, | ||
218 | .useTransport = US_PR_BULK}, | ||
219 | { .useProtocol = US_SC_QIC, | ||
220 | .useTransport = US_PR_BULK}, | ||
221 | { .useProtocol = US_SC_UFI, | ||
222 | .useTransport = US_PR_BULK}, | ||
223 | { .useProtocol = US_SC_8070, | ||
224 | .useTransport = US_PR_BULK}, | ||
225 | { .useProtocol = US_SC_SCSI, | ||
226 | .useTransport = US_PR_BULK}, | ||
227 | 175 | ||
228 | /* Terminating entry */ | 176 | /* Terminating entry */ |
229 | { NULL } | 177 | { NULL } |
@@ -484,14 +432,20 @@ static int associate_dev(struct us_data *us, struct usb_interface *intf) | |||
484 | return 0; | 432 | return 0; |
485 | } | 433 | } |
486 | 434 | ||
435 | /* Find an unusual_dev descriptor (always succeeds in the current code) */ | ||
436 | static struct us_unusual_dev *find_unusual(const struct usb_device_id *id) | ||
437 | { | ||
438 | const int id_index = id - storage_usb_ids; | ||
439 | return &us_unusual_dev_list[id_index]; | ||
440 | } | ||
441 | |||
487 | /* Get the unusual_devs entries and the string descriptors */ | 442 | /* Get the unusual_devs entries and the string descriptors */ |
488 | static void get_device_info(struct us_data *us, int id_index) | 443 | static void get_device_info(struct us_data *us, const struct usb_device_id *id) |
489 | { | 444 | { |
490 | struct usb_device *dev = us->pusb_dev; | 445 | struct usb_device *dev = us->pusb_dev; |
491 | struct usb_interface_descriptor *idesc = | 446 | struct usb_interface_descriptor *idesc = |
492 | &us->pusb_intf->cur_altsetting->desc; | 447 | &us->pusb_intf->cur_altsetting->desc; |
493 | struct us_unusual_dev *unusual_dev = &us_unusual_dev_list[id_index]; | 448 | struct us_unusual_dev *unusual_dev = find_unusual(id); |
494 | struct usb_device_id *id = &storage_usb_ids[id_index]; | ||
495 | 449 | ||
496 | /* Store the entries */ | 450 | /* Store the entries */ |
497 | us->unusual_dev = unusual_dev; | 451 | us->unusual_dev = unusual_dev; |
@@ -501,7 +455,7 @@ static void get_device_info(struct us_data *us, int id_index) | |||
501 | us->protocol = (unusual_dev->useTransport == US_PR_DEVICE) ? | 455 | us->protocol = (unusual_dev->useTransport == US_PR_DEVICE) ? |
502 | idesc->bInterfaceProtocol : | 456 | idesc->bInterfaceProtocol : |
503 | unusual_dev->useTransport; | 457 | unusual_dev->useTransport; |
504 | us->flags = unusual_dev->flags; | 458 | us->flags = USB_US_ORIG_FLAGS(id->driver_info); |
505 | 459 | ||
506 | /* | 460 | /* |
507 | * This flag is only needed when we're in high-speed, so let's | 461 | * This flag is only needed when we're in high-speed, so let's |
@@ -529,7 +483,7 @@ static void get_device_info(struct us_data *us, int id_index) | |||
529 | if (unusual_dev->useTransport != US_PR_DEVICE && | 483 | if (unusual_dev->useTransport != US_PR_DEVICE && |
530 | us->protocol == idesc->bInterfaceProtocol) | 484 | us->protocol == idesc->bInterfaceProtocol) |
531 | msg += 2; | 485 | msg += 2; |
532 | if (msg >= 0 && !(unusual_dev->flags & US_FL_NEED_OVERRIDE)) | 486 | if (msg >= 0 && !(us->flags & US_FL_NEED_OVERRIDE)) |
533 | printk(KERN_NOTICE USB_STORAGE "This device " | 487 | printk(KERN_NOTICE USB_STORAGE "This device " |
534 | "(%04x,%04x,%04x S %02x P %02x)" | 488 | "(%04x,%04x,%04x S %02x P %02x)" |
535 | " has %s in unusual_devs.h\n" | 489 | " has %s in unusual_devs.h\n" |
@@ -921,10 +875,12 @@ static int storage_probe(struct usb_interface *intf, | |||
921 | { | 875 | { |
922 | struct Scsi_Host *host; | 876 | struct Scsi_Host *host; |
923 | struct us_data *us; | 877 | struct us_data *us; |
924 | const int id_index = id - storage_usb_ids; | ||
925 | int result; | 878 | int result; |
926 | struct task_struct *th; | 879 | struct task_struct *th; |
927 | 880 | ||
881 | if (usb_usual_check_type(id, USB_US_TYPE_STOR)) | ||
882 | return -ENXIO; | ||
883 | |||
928 | US_DEBUGP("USB Mass Storage device detected\n"); | 884 | US_DEBUGP("USB Mass Storage device detected\n"); |
929 | 885 | ||
930 | /* | 886 | /* |
@@ -957,7 +913,7 @@ static int storage_probe(struct usb_interface *intf, | |||
957 | * of the match from the usb_device_id table, so we can find the | 913 | * of the match from the usb_device_id table, so we can find the |
958 | * corresponding entry in the private table. | 914 | * corresponding entry in the private table. |
959 | */ | 915 | */ |
960 | get_device_info(us, id_index); | 916 | get_device_info(us, id); |
961 | 917 | ||
962 | #ifdef CONFIG_USB_STORAGE_SDDR09 | 918 | #ifdef CONFIG_USB_STORAGE_SDDR09 |
963 | if (us->protocol == US_PR_EUSB_SDDR09 || | 919 | if (us->protocol == US_PR_EUSB_SDDR09 || |
@@ -1062,9 +1018,10 @@ static int __init usb_stor_init(void) | |||
1062 | 1018 | ||
1063 | /* register the driver, return usb_register return code if error */ | 1019 | /* register the driver, return usb_register return code if error */ |
1064 | retval = usb_register(&usb_storage_driver); | 1020 | retval = usb_register(&usb_storage_driver); |
1065 | if (retval == 0) | 1021 | if (retval == 0) { |
1066 | printk(KERN_INFO "USB Mass Storage support registered.\n"); | 1022 | printk(KERN_INFO "USB Mass Storage support registered.\n"); |
1067 | 1023 | usb_usual_set_present(USB_US_TYPE_STOR); | |
1024 | } | ||
1068 | return retval; | 1025 | return retval; |
1069 | } | 1026 | } |
1070 | 1027 | ||
@@ -1088,6 +1045,8 @@ static void __exit usb_stor_exit(void) | |||
1088 | wait_for_completion(&threads_gone); | 1045 | wait_for_completion(&threads_gone); |
1089 | atomic_dec(&total_threads); | 1046 | atomic_dec(&total_threads); |
1090 | } | 1047 | } |
1048 | |||
1049 | usb_usual_clear_present(USB_US_TYPE_STOR); | ||
1091 | } | 1050 | } |
1092 | 1051 | ||
1093 | module_init(usb_stor_init); | 1052 | module_init(usb_stor_init); |
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index 98b09711a739..0cd1eebc4497 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h | |||
@@ -45,6 +45,7 @@ | |||
45 | #define _USB_H_ | 45 | #define _USB_H_ |
46 | 46 | ||
47 | #include <linux/usb.h> | 47 | #include <linux/usb.h> |
48 | #include <linux/usb_usual.h> | ||
48 | #include <linux/blkdev.h> | 49 | #include <linux/blkdev.h> |
49 | #include <linux/smp_lock.h> | 50 | #include <linux/smp_lock.h> |
50 | #include <linux/completion.h> | 51 | #include <linux/completion.h> |
@@ -63,38 +64,8 @@ struct us_unusual_dev { | |||
63 | __u8 useProtocol; | 64 | __u8 useProtocol; |
64 | __u8 useTransport; | 65 | __u8 useTransport; |
65 | int (*initFunction)(struct us_data *); | 66 | int (*initFunction)(struct us_data *); |
66 | unsigned int flags; | ||
67 | }; | 67 | }; |
68 | 68 | ||
69 | /* | ||
70 | * Static flag definitions. We use this roundabout technique so that the | ||
71 | * proc_info() routine can automatically display a message for each flag. | ||
72 | */ | ||
73 | #define US_DO_ALL_FLAGS \ | ||
74 | US_FLAG(SINGLE_LUN, 0x00000001) \ | ||
75 | /* allow access to only LUN 0 */ \ | ||
76 | US_FLAG(NEED_OVERRIDE, 0x00000002) \ | ||
77 | /* unusual_devs entry is necessary */ \ | ||
78 | US_FLAG(SCM_MULT_TARG, 0x00000004) \ | ||
79 | /* supports multiple targets */ \ | ||
80 | US_FLAG(FIX_INQUIRY, 0x00000008) \ | ||
81 | /* INQUIRY response needs faking */ \ | ||
82 | US_FLAG(FIX_CAPACITY, 0x00000010) \ | ||
83 | /* READ CAPACITY response too big */ \ | ||
84 | US_FLAG(IGNORE_RESIDUE, 0x00000020) \ | ||
85 | /* reported residue is wrong */ \ | ||
86 | US_FLAG(BULK32, 0x00000040) \ | ||
87 | /* Uses 32-byte CBW length */ \ | ||
88 | US_FLAG(NOT_LOCKABLE, 0x00000080) \ | ||
89 | /* PREVENT/ALLOW not supported */ \ | ||
90 | US_FLAG(GO_SLOW, 0x00000100) \ | ||
91 | /* Need delay after Command phase */ \ | ||
92 | US_FLAG(NO_WP_DETECT, 0x00000200) \ | ||
93 | /* Don't check for write-protect */ \ | ||
94 | |||
95 | #define US_FLAG(name, value) US_FL_##name = value , | ||
96 | enum { US_DO_ALL_FLAGS }; | ||
97 | #undef US_FLAG | ||
98 | 69 | ||
99 | /* Dynamic flag definitions: used in set_bit() etc. */ | 70 | /* Dynamic flag definitions: used in set_bit() etc. */ |
100 | #define US_FLIDX_URB_ACTIVE 18 /* 0x00040000 current_urb is in use */ | 71 | #define US_FLIDX_URB_ACTIVE 18 /* 0x00040000 current_urb is in use */ |
diff --git a/include/linux/usb_usual.h b/include/linux/usb_usual.h new file mode 100644 index 000000000000..f9c058f33712 --- /dev/null +++ b/include/linux/usb_usual.h | |||
@@ -0,0 +1,123 @@ | |||
1 | /* | ||
2 | * Interface to the libusual. | ||
3 | * | ||
4 | * Copyright (c) 2005 Pete Zaitcev <zaitcev@redhat.com> | ||
5 | * Copyright (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net) | ||
6 | * Copyright (c) 1999 Michael Gee (michael@linuxspecific.com) | ||
7 | */ | ||
8 | |||
9 | #ifndef __LINUX_USB_USUAL_H | ||
10 | #define __LINUX_USB_USUAL_H | ||
11 | |||
12 | #include <linux/config.h> | ||
13 | |||
14 | /* We should do this for cleanliness... But other usb_foo.h do not do this. */ | ||
15 | /* #include <linux/usb.h> */ | ||
16 | |||
17 | /* | ||
18 | * The flags field, which we store in usb_device_id.driver_info. | ||
19 | * It is compatible with the old usb-storage flags in lower 24 bits. | ||
20 | */ | ||
21 | |||
22 | /* | ||
23 | * Static flag definitions. We use this roundabout technique so that the | ||
24 | * proc_info() routine can automatically display a message for each flag. | ||
25 | */ | ||
26 | #define US_DO_ALL_FLAGS \ | ||
27 | US_FLAG(SINGLE_LUN, 0x00000001) \ | ||
28 | /* allow access to only LUN 0 */ \ | ||
29 | US_FLAG(NEED_OVERRIDE, 0x00000002) \ | ||
30 | /* unusual_devs entry is necessary */ \ | ||
31 | US_FLAG(SCM_MULT_TARG, 0x00000004) \ | ||
32 | /* supports multiple targets */ \ | ||
33 | US_FLAG(FIX_INQUIRY, 0x00000008) \ | ||
34 | /* INQUIRY response needs faking */ \ | ||
35 | US_FLAG(FIX_CAPACITY, 0x00000010) \ | ||
36 | /* READ CAPACITY response too big */ \ | ||
37 | US_FLAG(IGNORE_RESIDUE, 0x00000020) \ | ||
38 | /* reported residue is wrong */ \ | ||
39 | US_FLAG(BULK32, 0x00000040) \ | ||
40 | /* Uses 32-byte CBW length */ \ | ||
41 | US_FLAG(NOT_LOCKABLE, 0x00000080) \ | ||
42 | /* PREVENT/ALLOW not supported */ \ | ||
43 | US_FLAG(GO_SLOW, 0x00000100) \ | ||
44 | /* Need delay after Command phase */ \ | ||
45 | US_FLAG(NO_WP_DETECT, 0x00000200) \ | ||
46 | /* Don't check for write-protect */ \ | ||
47 | |||
48 | #define US_FLAG(name, value) US_FL_##name = value , | ||
49 | enum { US_DO_ALL_FLAGS }; | ||
50 | #undef US_FLAG | ||
51 | |||
52 | /* | ||
53 | * The bias field for libusual and friends. | ||
54 | */ | ||
55 | #define USB_US_TYPE_NONE 0 | ||
56 | #define USB_US_TYPE_STOR 1 /* usb-storage */ | ||
57 | #define USB_US_TYPE_UB 2 /* ub */ | ||
58 | |||
59 | #define USB_US_TYPE(flags) (((flags) >> 24) & 0xFF) | ||
60 | #define USB_US_ORIG_FLAGS(flags) ((flags) & 0x00FFFFFF) | ||
61 | |||
62 | /* | ||
63 | * This is probably not the best place to keep these constants, conceptually. | ||
64 | * But it's the only header included into all places which need them. | ||
65 | */ | ||
66 | |||
67 | /* Sub Classes */ | ||
68 | |||
69 | #define US_SC_RBC 0x01 /* Typically, flash devices */ | ||
70 | #define US_SC_8020 0x02 /* CD-ROM */ | ||
71 | #define US_SC_QIC 0x03 /* QIC-157 Tapes */ | ||
72 | #define US_SC_UFI 0x04 /* Floppy */ | ||
73 | #define US_SC_8070 0x05 /* Removable media */ | ||
74 | #define US_SC_SCSI 0x06 /* Transparent */ | ||
75 | #define US_SC_ISD200 0x07 /* ISD200 ATA */ | ||
76 | #define US_SC_MIN US_SC_RBC | ||
77 | #define US_SC_MAX US_SC_ISD200 | ||
78 | |||
79 | #define US_SC_DEVICE 0xff /* Use device's value */ | ||
80 | |||
81 | /* Protocols */ | ||
82 | |||
83 | #define US_PR_CBI 0x00 /* Control/Bulk/Interrupt */ | ||
84 | #define US_PR_CB 0x01 /* Control/Bulk w/o interrupt */ | ||
85 | #define US_PR_BULK 0x50 /* bulk only */ | ||
86 | #ifdef CONFIG_USB_STORAGE_USBAT | ||
87 | #define US_PR_USBAT 0x80 /* SCM-ATAPI bridge */ | ||
88 | #endif | ||
89 | #ifdef CONFIG_USB_STORAGE_SDDR09 | ||
90 | #define US_PR_EUSB_SDDR09 0x81 /* SCM-SCSI bridge for SDDR-09 */ | ||
91 | #endif | ||
92 | #ifdef CONFIG_USB_STORAGE_SDDR55 | ||
93 | #define US_PR_SDDR55 0x82 /* SDDR-55 (made up) */ | ||
94 | #endif | ||
95 | #define US_PR_DPCM_USB 0xf0 /* Combination CB/SDDR09 */ | ||
96 | #ifdef CONFIG_USB_STORAGE_FREECOM | ||
97 | #define US_PR_FREECOM 0xf1 /* Freecom */ | ||
98 | #endif | ||
99 | #ifdef CONFIG_USB_STORAGE_DATAFAB | ||
100 | #define US_PR_DATAFAB 0xf2 /* Datafab chipsets */ | ||
101 | #endif | ||
102 | #ifdef CONFIG_USB_STORAGE_JUMPSHOT | ||
103 | #define US_PR_JUMPSHOT 0xf3 /* Lexar Jumpshot */ | ||
104 | #endif | ||
105 | |||
106 | #define US_PR_DEVICE 0xff /* Use device's value */ | ||
107 | |||
108 | /* | ||
109 | */ | ||
110 | #ifdef CONFIG_USB_LIBUSUAL | ||
111 | |||
112 | extern struct usb_device_id storage_usb_ids[]; | ||
113 | extern void usb_usual_set_present(int type); | ||
114 | extern void usb_usual_clear_present(int type); | ||
115 | extern int usb_usual_check_type(const struct usb_device_id *, int type); | ||
116 | #else | ||
117 | |||
118 | #define usb_usual_set_present(t) do { } while(0) | ||
119 | #define usb_usual_clear_present(t) do { } while(0) | ||
120 | #define usb_usual_check_type(id, t) (0) | ||
121 | #endif /* CONFIG_USB_LIBUSUAL */ | ||
122 | |||
123 | #endif /* __LINUX_USB_USUAL_H */ | ||