1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32#include <linux/module.h>
33#include <linux/kernel.h>
34#include <linux/errno.h>
35#include <asm/uaccess.h>
36#include <linux/init.h>
37#include <linux/slab.h>
38#include <linux/delay.h>
39#include <linux/ioctl.h>
40#include <linux/sched.h>
41#include <linux/smp_lock.h>
42#include <linux/devfs_fs_kernel.h>
43#include <linux/usb_scanner_ioctl.h>
44
45
46
47#define DRIVER_VERSION "0.4.16"
48#define DRIVER_DESC "USB Scanner Driver"
49
50#include <linux/usb.h>
51
52static __s32 vendor=-1, product=-1, read_timeout=0;
53
54MODULE_AUTHOR("Henning Meier-Geinitz, henning@meier-geinitz.de");
55MODULE_DESCRIPTION(DRIVER_DESC" "DRIVER_VERSION);
56MODULE_LICENSE("GPL");
57
58MODULE_PARM(vendor, "i");
59MODULE_PARM_DESC(vendor, "User specified USB idVendor");
60
61MODULE_PARM(product, "i");
62MODULE_PARM_DESC(product, "User specified USB idProduct");
63
64MODULE_PARM(read_timeout, "i");
65MODULE_PARM_DESC(read_timeout, "User specified read timeout in seconds");
66
67
68
69
70
71
72static struct usb_device_id scanner_device_ids [] = {
73
74 { USB_DEVICE(0x04a5, 0x1a20) },
75 { USB_DEVICE(0x04a5, 0x1a2a) },
76 { USB_DEVICE(0x04a5, 0x2022) },
77 { USB_DEVICE(0x04a5, 0x2040) },
78 { USB_DEVICE(0x04a5, 0x2060) },
79 { USB_DEVICE(0x04a5, 0x207e) },
80 { USB_DEVICE(0x04a5, 0x20b0) },
81 { USB_DEVICE(0x04a5, 0x20be) },
82 { USB_DEVICE(0x04a5, 0x20c0) },
83 { USB_DEVICE(0x04a5, 0x20de) },
84 { USB_DEVICE(0x04a5, 0x20fc) },
85 { USB_DEVICE(0x04a5, 0x20fe) },
86
87 { USB_DEVICE(0x06bd, 0x0001) },
88 { USB_DEVICE(0x06bd, 0x0002) },
89 { USB_DEVICE(0x06bd, 0x0100) },
90 { USB_DEVICE(0x06bd, 0x2061) },
91 { USB_DEVICE(0x06bd, 0x208d) },
92 { USB_DEVICE(0x06bd, 0x208f) },
93 { USB_DEVICE(0x06bd, 0x2091) },
94 { USB_DEVICE(0x06bd, 0x2093) },
95 { USB_DEVICE(0x06bd, 0x2095) },
96 { USB_DEVICE(0x06bd, 0x2097) },
97 { USB_DEVICE(0x06bd, 0x20fd) },
98 { USB_DEVICE(0x06bd, 0x20ff) },
99
100 { USB_DEVICE(0x05d8, 0x4001) },
101 { USB_DEVICE(0x05d8, 0x4002) },
102 { USB_DEVICE(0x05d8, 0x4003) },
103 { USB_DEVICE(0x05d8, 0x4004) },
104
105 { USB_DEVICE(0x0638, 0x0268) },
106 { USB_DEVICE(0x0638, 0x0a10) },
107 { USB_DEVICE(0x0638, 0x0a20) },
108
109
110 { USB_DEVICE(0x04f9, 0x010f) },
111 { USB_DEVICE(0x04f9, 0x0111) },
112
113 { USB_DEVICE(0x04a9, 0x2201) },
114 { USB_DEVICE(0x04a9, 0x2202) },
115 { USB_DEVICE(0x04a9, 0x2204) },
116 { USB_DEVICE(0x04a9, 0x2205) },
117 { USB_DEVICE(0x04a9, 0x2206) },
118 { USB_DEVICE(0x04a9, 0x2207) },
119 { USB_DEVICE(0x04a9, 0x2208) },
120 { USB_DEVICE(0x04a9, 0x220a) },
121 { USB_DEVICE(0x04a9, 0x220b) },
122 { USB_DEVICE(0x04a9, 0x220c) },
123 { USB_DEVICE(0x04a9, 0x220d) },
124 { USB_DEVICE(0x04a9, 0x220e) },
125 { USB_DEVICE(0x04a9, 0x220f) },
126 { USB_DEVICE(0x04a9, 0x2210) },
127 { USB_DEVICE(0x04a9, 0x2212) },
128 { USB_DEVICE(0x04a9, 0x2213) },
129 { USB_DEVICE(0x04a9, 0x2215) },
130 { USB_DEVICE(0x04a9, 0x3042) },
131
132
133 { USB_DEVICE(0x049f, 0x001a) },
134 { USB_DEVICE(0x049f, 0x0021) },
135
136
137 { USB_DEVICE(0x04c5, 0x1041) },
138 { USB_DEVICE(0x04c5, 0x1042) },
139 { USB_DEVICE(0x04c5, 0x1029) },
140
141 { USB_DEVICE(0x0458, 0x2001) },
142 { USB_DEVICE(0x0458, 0x2007) },
143 { USB_DEVICE(0x0458, 0x2008) },
144 { USB_DEVICE(0x0458, 0x2009) },
145 { USB_DEVICE(0x0458, 0x2011) },
146 { USB_DEVICE(0x0458, 0x2013) },
147 { USB_DEVICE(0x0458, 0x2015) },
148 { USB_DEVICE(0x0458, 0x2016) },
149 { USB_DEVICE(0x0458, 0x2018) },
150 { USB_DEVICE(0x0458, 0x201b) },
151
152
153
154
155
156 { USB_DEVICE(0x03f0, 0x0101) },
157 { USB_DEVICE(0x03f0, 0x0102) },
158 { USB_DEVICE(0x03f0, 0x0105) },
159 { USB_DEVICE(0x03f0, 0x0201) },
160 { USB_DEVICE(0x03f0, 0x0205) },
161 { USB_DEVICE(0x03f0, 0x0305) },
162 { USB_DEVICE(0x03f0, 0x0401) },
163 { USB_DEVICE(0x03f0, 0x0405) },
164 { USB_DEVICE(0x03f0, 0x0505) },
165 { USB_DEVICE(0x03f0, 0x0601) },
166 { USB_DEVICE(0x03f0, 0x0605) },
167
168 { USB_DEVICE(0x03f0, 0x0705) },
169
170 { USB_DEVICE(0x03f0, 0x0805) },
171 { USB_DEVICE(0x03f0, 0x0901) },
172 { USB_DEVICE(0x03f0, 0x0a01) },
173 { USB_DEVICE(0x03F0, 0x1005) },
174 { USB_DEVICE(0x03F0, 0x1105) },
175 { USB_DEVICE(0x03f0, 0x1205) },
176 { USB_DEVICE(0x03f0, 0x1305) },
177
178 { USB_DEVICE(0x03f0, 0x2005) },
179 { USB_DEVICE(0x03f0, 0x2205) },
180
181
182 { USB_DEVICE(0x043d, 0x002d) },
183 { USB_DEVICE(0x043d, 0x003d) },
184
185 { USB_DEVICE(0x0461, 0x0364) },
186
187 { USB_DEVICE(0x0461, 0x0377) },
188
189 { USB_DEVICE(0x0461, 0x0346) },
190
191 { USB_DEVICE(0x05da, 0x20a7) },
192 { USB_DEVICE(0x05da, 0x20c9) },
193 { USB_DEVICE(0x05da, 0x30ce) },
194 { USB_DEVICE(0x05da, 0x30cf) },
195 { USB_DEVICE(0x05da, 0x30d4) },
196 { USB_DEVICE(0x05da, 0x30d8) },
197 { USB_DEVICE(0x04a7, 0x0224) },
198
199
200
201
202
203
204
205
206
207
208 { USB_DEVICE(0x0686, 0x400d) },
209
210
211
212
213
214 { USB_DEVICE(0x0400, 0x1000) },
215 { USB_DEVICE(0x0400, 0x1001) },
216 { USB_DEVICE(0x055f, 0x0001) },
217 { USB_DEVICE(0x055f, 0x0002) },
218 { USB_DEVICE(0x055f, 0x0003) },
219 { USB_DEVICE(0x055f, 0x0006) },
220 { USB_DEVICE(0x055f, 0x0007) },
221 { USB_DEVICE(0x055f, 0x0008) },
222 { USB_DEVICE(0x055f, 0x0010) },
223 { USB_DEVICE(0x055f, 0x0210) },
224 { USB_DEVICE(0x055f, 0x0218) },
225 { USB_DEVICE(0x055f, 0x0219) },
226 { USB_DEVICE(0x055f, 0x021c) },
227 { USB_DEVICE(0x055f, 0x021d) },
228 { USB_DEVICE(0x055f, 0x021e) },
229 { USB_DEVICE(0x055f, 0x0400) },
230 { USB_DEVICE(0x055f, 0x0401) },
231 { USB_DEVICE(0x055f, 0x0409) },
232 { USB_DEVICE(0x055f, 0x0873) },
233 { USB_DEVICE(0x055f, 0x1000) },
234
235
236 { USB_DEVICE(0x04b0, 0x4000) },
237
238 { USB_DEVICE(0x05e3, 0x0120) },
239
240 { USB_DEVICE(0x07b3, 0x0001) },
241 { USB_DEVICE(0x07b3, 0x0005) },
242 { USB_DEVICE(0x07b3, 0x0007) },
243 { USB_DEVICE(0x07b3, 0x000F) },
244 { USB_DEVICE(0x07b3, 0x0010) },
245 { USB_DEVICE(0x07b3, 0x0011) },
246 { USB_DEVICE(0x07b3, 0x0012) },
247 { USB_DEVICE(0x07b3, 0x0013) },
248 { USB_DEVICE(0x07b3, 0x0014) },
249 { USB_DEVICE(0x07b3, 0x0015) },
250 { USB_DEVICE(0x07b3, 0x0016) },
251 { USB_DEVICE(0x07b3, 0x0017) },
252 { USB_DEVICE(0x07b3, 0x0400) },
253 { USB_DEVICE(0x07b3, 0x0401) },
254 { USB_DEVICE(0x07b3, 0x0403) },
255 { USB_DEVICE(0x07b3, 0x0413) },
256
257 { USB_DEVICE(0x0461, 0x0300) },
258 { USB_DEVICE(0x0461, 0x0301) },
259 { USB_DEVICE(0x0461, 0x0302) },
260 { USB_DEVICE(0x0461, 0x0303) },
261 { USB_DEVICE(0x0461, 0x0340) },
262 { USB_DEVICE(0x0461, 0x0341) },
263 { USB_DEVICE(0x0461, 0x0347) },
264 { USB_DEVICE(0x0461, 0x0360) },
265 { USB_DEVICE(0x0461, 0x0361) },
266 { USB_DEVICE(0x0461, 0x0380) },
267 { USB_DEVICE(0x0461, 0x0381) },
268 { USB_DEVICE(0x0461, 0x0382) },
269 { USB_DEVICE(0x0461, 0x0383) },
270
271 { USB_DEVICE(0x06dc, 0x0014) },
272
273 { USB_DEVICE(0x05e3, 0x0120) },
274
275
276 { USB_DEVICE(0x0475, 0x0210) },
277
278 { USB_DEVICE(0x04b8, 0x0101) },
279 { USB_DEVICE(0x04b8, 0x0102) },
280 { USB_DEVICE(0x04b8, 0x0103) },
281 { USB_DEVICE(0x04b8, 0x0104) },
282 { USB_DEVICE(0x04b8, 0x0105) },
283 { USB_DEVICE(0x04b8, 0x0106) },
284 { USB_DEVICE(0x04b8, 0x0107) },
285 { USB_DEVICE(0x04b8, 0x0109) },
286 { USB_DEVICE(0x04b8, 0x010a) },
287 { USB_DEVICE(0x04b8, 0x010b) },
288 { USB_DEVICE(0x04b8, 0x010c) },
289 { USB_DEVICE(0x04b8, 0x010e) },
290 { USB_DEVICE(0x04b8, 0x010f) },
291 { USB_DEVICE(0x04b8, 0x0110) },
292 { USB_DEVICE(0x04b8, 0x0112) },
293 { USB_DEVICE(0x04b8, 0x0114) },
294 { USB_DEVICE(0x04b8, 0x011b) },
295 { USB_DEVICE(0x04b8, 0x011c) },
296 { USB_DEVICE(0x04b8, 0x011d) },
297 { USB_DEVICE(0x04b8, 0x011e) },
298 { USB_DEVICE(0x04b8, 0x011f) },
299 { USB_DEVICE(0x04b8, 0x0801) },
300 { USB_DEVICE(0x04b8, 0x0802) },
301
302 { USB_DEVICE(0x0681, 0x0005) },
303 { USB_DEVICE(0x0681, 0x0010) },
304
305 { USB_DEVICE(0x0a82, 0x4600) },
306
307 { USB_DEVICE(0x05cb, 0x1483) },
308 { USB_DEVICE(0x05d8, 0x4006) },
309
310 { USB_DEVICE(0x05d8, 0x4009) },
311 { USB_DEVICE(0x1606, 0x0010) },
312 { USB_DEVICE(0x1606, 0x0030) },
313 { USB_DEVICE(0x1606, 0x0060) },
314 { USB_DEVICE(0x1606, 0x0070) },
315 { USB_DEVICE(0x1606, 0x0130) },
316 { USB_DEVICE(0x1606, 0x0160) },
317 { USB_DEVICE(0x1606, 0x0230) },
318
319 { USB_DEVICE(0x04a7, 0x0211) },
320 { USB_DEVICE(0x04a7, 0x0221) },
321 { USB_DEVICE(0x04a7, 0x0224) },
322 { USB_DEVICE(0x04a7, 0x0226) },
323 { USB_DEVICE(0x04a7, 0x0229) },
324 { USB_DEVICE(0x04a7, 0x022c) },
325 { USB_DEVICE(0x04a7, 0x0231) },
326 { USB_DEVICE(0x04a7, 0x0311) },
327 { USB_DEVICE(0x04a7, 0x0321) },
328 { USB_DEVICE(0x04a7, 0x0331) },
329 { USB_DEVICE(0x0461, 0x0345) },
330 { USB_DEVICE(0x0461, 0x0371) },
331 { }
332};
333
334MODULE_DEVICE_TABLE (usb, scanner_device_ids);
335
336#define IS_EP_BULK(ep) ((ep).bmAttributes == USB_ENDPOINT_XFER_BULK ? 1 : 0)
337#define IS_EP_BULK_IN(ep) (IS_EP_BULK(ep) && ((ep).bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)
338#define IS_EP_BULK_OUT(ep) (IS_EP_BULK(ep) && ((ep).bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT)
339#define IS_EP_INTR(ep) ((ep).bmAttributes == USB_ENDPOINT_XFER_INT ? 1 : 0)
340
341#define USB_SCN_MINOR(X) MINOR((X)->i_rdev) - SCN_BASE_MNR
342
343#ifdef DEBUG
344#define SCN_DEBUG(X) X
345#else
346#define SCN_DEBUG(X)
347#endif
348
349#define IBUF_SIZE 32768
350#define OBUF_SIZE 4096
351
352
353#define RD_NAK_TIMEOUT (10*HZ)
354#define RD_EXPIRE 12
355
356
357
358
359#define SCN_CLASS_SCANJET 16
360
361#define SCN_MAX_MNR 16
362#define SCN_BASE_MNR 48
363
364static DECLARE_MUTEX (scn_mutex);
365
366struct scn_usb_data {
367 struct usb_device *scn_dev;
368 devfs_handle_t devfs;
369 struct urb scn_irq;
370 unsigned int ifnum;
371 kdev_t scn_minor;
372 unsigned char button;
373 char isopen;
374 char present;
375 char *obuf, *ibuf;
376 char bulk_in_ep, bulk_out_ep, intr_ep;
377 wait_queue_head_t rd_wait_q;
378 struct semaphore sem;
379 unsigned int rd_nak_timeout;
380};
381
382extern devfs_handle_t usb_devfs_handle;
383
384static struct scn_usb_data *p_scn_table[SCN_MAX_MNR] = { NULL, };
385
386static struct usb_driver scanner_driver;
387