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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55#include <linux/config.h>
56#include <linux/kernel.h>
57#include <linux/sched.h>
58#include <linux/signal.h>
59#include <linux/errno.h>
60#include <linux/miscdevice.h>
61#include <linux/random.h>
62#include <linux/poll.h>
63#include <linux/init.h>
64#include <linux/slab.h>
65#include <linux/module.h>
66#include <linux/devfs_fs_kernel.h>
67
68#ifdef CONFIG_USB_DEBUG
69 #define DEBUG
70#else
71 #undef DEBUG
72#endif
73#include <linux/usb.h>
74
75
76
77extern devfs_handle_t usb_devfs_handle;
78
79
80
81
82#define DRIVER_VERSION "v1.0.0"
83#define DRIVER_AUTHOR "David Brownell, <dbrownell@users.sourceforge.net>"
84#define DRIVER_DESC "USB Camera Driver for Kodak DC-2xx series cameras"
85
86
87
88#define MAX_CAMERAS 16
89
90
91#define USB_CAMERA_MINOR_BASE 80
92
93
94
95
96
97#define MAX_PACKET_SIZE 0x2000
98
99#define MAX_READ_RETRY 5
100#define MAX_WRITE_RETRY 5
101#define RETRY_TIMEOUT (HZ)
102
103
104
105static struct usb_device_id camera_table [] = {
106
107 { USB_DEVICE(0x040a, 0x0120) },
108 { USB_DEVICE(0x040a, 0x0130) },
109 { USB_DEVICE(0x040a, 0x0131) },
110 { USB_DEVICE(0x040a, 0x0132) },
111
112
113
114
115
116
117 { USB_DEVICE(0x040a, 0x0100) },
118 { USB_DEVICE(0x040a, 0x0110) },
119 { USB_DEVICE(0x040a, 0x0111) },
120 { USB_DEVICE(0x040a, 0x0112) },
121 { USB_DEVICE(0xf003, 0x6002) },
122 { USB_DEVICE(0x03f0, 0x4102) },
123 { USB_DEVICE(0x0a17, 0x1001) },
124
125
126
127
128
129
130 { }
131};
132
133MODULE_DEVICE_TABLE (usb, camera_table);
134
135
136struct camera_state {
137 struct usb_device *dev;
138 int inEP;
139 int outEP;
140 const struct usb_device_id *info;
141 int subminor;
142 struct semaphore sem;
143
144
145 char *buf;
146
147 devfs_handle_t devfs;
148
149
150 wait_queue_head_t wait;
151};
152
153
154static struct camera_state *minor_data [MAX_CAMERAS];
155
156
157static DECLARE_MUTEX (state_table_mutex);
158
159static ssize_t camera_read (struct file *file,
160 char *buf, size_t len, loff_t *ppos)
161{
162 struct camera_state *camera;
163 int retries;
164 int retval = 0;
165
166 if (len > MAX_PACKET_SIZE)
167 return -EINVAL;
168
169 camera = (struct camera_state *) file->private_data;
170 down (&camera->sem);
171 if (!camera->dev) {
172 up (&camera->sem);
173 return -ENODEV;
174 }
175
176
177
178
179
180
181 for (retries = 0; retries < MAX_READ_RETRY; retries++) {
182 int count;
183
184 if (signal_pending (current)) {
185 retval = -EINTR;
186 break;
187 }
188
189 retval = usb_bulk_msg (camera->dev,
190 usb_rcvbulkpipe (camera->dev, camera->inEP),
191 camera->buf, len, &count, HZ*10);
192
193 dbg ("read (%Zd) - 0x%x %d", len, retval, count);
194
195 if (!retval) {
196 if (copy_to_user (buf, camera->buf, count))
197 retval = -EFAULT;
198 else
199 retval = count;
200 break;
201 }
202 if (retval != USB_ST_TIMEOUT)
203 break;
204 interruptible_sleep_on_timeout (&camera->wait, RETRY_TIMEOUT);
205
206 dbg ("read (%Zd) - retry", len);
207 }
208 up (&camera->sem);
209 return retval;
210}
211
212static ssize_t camera_write (struct file *file,
213 const char *buf, size_t len, loff_t *ppos)
214{
215 struct camera_state *camera;
216 ssize_t bytes_written = 0;
217
218 if (len > MAX_PACKET_SIZE)
219 return -EINVAL;
220
221 camera = (struct camera_state *) file->private_data;
222 down (&camera->sem);
223 if (!camera->dev) {
224 up (&camera->sem);
225 return -ENODEV;
226 }
227
228
229
230
231
232 while (len > 0) {
233 char *obuf = camera->buf;
234 int maxretry = MAX_WRITE_RETRY;
235 unsigned long copy_size, thistime;
236
237
238
239
240 thistime = copy_size = len;
241 if (copy_from_user (obuf, buf, copy_size)) {
242 bytes_written = -EFAULT;
243 break;
244 }
245 while (thistime) {
246 int result;
247 int count;
248
249 if (signal_pending (current)) {
250 if (!bytes_written)
251 bytes_written = -EINTR;
252 goto done;
253 }
254
255 result = usb_bulk_msg (camera->dev,
256 usb_sndbulkpipe (camera->dev, camera->outEP),
257 obuf, thistime, &count, HZ*10);
258
259 if (result)
260 dbg ("write USB err - %d", result);
261
262 if (count) {
263 obuf += count;
264 thistime -= count;
265 maxretry = MAX_WRITE_RETRY;
266 continue;
267 } else if (!result)
268 break;
269
270 if (result == USB_ST_TIMEOUT) {
271 if (!maxretry--) {
272 if (!bytes_written)
273 bytes_written = -ETIME;
274 goto done;
275 }
276 interruptible_sleep_on_timeout (&camera->wait,
277 RETRY_TIMEOUT);
278 continue;
279 }
280 if (!bytes_written)
281 bytes_written = -EIO;
282 goto done;
283 }
284 bytes_written += copy_size;
285 len -= copy_size;
286 buf += copy_size;
287 }
288done:
289 up (&camera->sem);
290 dbg ("wrote %Zd", bytes_written);
291 return bytes_written;
292}
293
294static int camera_open (struct inode *inode, struct file *file)
295{
296 struct camera_state *camera = NULL;
297 int subminor;
298 int value = 0;
299
300 down (&state_table_mutex);
301 subminor = MINOR (inode->i_rdev) - USB_CAMERA_MINOR_BASE;
302 if (subminor < 0 || subminor >= MAX_CAMERAS
303 || !(camera = minor_data [subminor])) {
304 up (&state_table_mutex);
305 return -ENODEV;
306 }
307 down (&camera->sem);
308 up (&state_table_mutex);
309
310 if (camera->buf) {
311 value = -EBUSY;
312 goto done;
313 }
314
315 if (!(camera->buf = (char *) kmalloc (MAX_PACKET_SIZE, GFP_KERNEL))) {
316 value = -ENOMEM;
317 goto done;
318 }
319
320 dbg ("open #%d", subminor);
321
322 file->private_data = camera;
323done:
324 up (&camera->sem);
325 return value;
326}
327
328static int camera_release (struct inode *inode, struct file *file)
329{
330 struct camera_state *camera;
331 int subminor;
332
333 camera = (struct camera_state *) file->private_data;
334 down (&state_table_mutex);
335 down (&camera->sem);
336
337 if (camera->buf) {
338 kfree (camera->buf);
339 camera->buf = 0;
340 }
341 subminor = camera->subminor;
342
343
344 if (!camera->dev) {
345 minor_data [subminor] = NULL;
346 kfree (camera);
347 } else
348 up (&camera->sem);
349
350 up (&state_table_mutex);
351
352 dbg ("close #%d", subminor);
353
354 return 0;
355}
356
357
358
359
360
361static struct file_operations usb_camera_fops = {
362
363 owner: THIS_MODULE,
364 read: camera_read,
365 write: camera_write,
366 open: camera_open,
367 release: camera_release,
368};
369
370
371
372static void *
373camera_probe (struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *camera_info)
374{
375 int i;
376 struct usb_interface_descriptor *interface;
377 struct usb_endpoint_descriptor *endpoint;
378 int direction, ep;
379 char name[8];
380 struct camera_state *camera = NULL;
381
382
383
384 if (dev->descriptor.bNumConfigurations != 1
385 || dev->config[0].bNumInterfaces != 1) {
386 dbg ("Bogus camera config info");
387 return NULL;
388 }
389
390
391 interface = &dev->actconfig->interface[ifnum].altsetting[0];
392 if ((interface->bInterfaceClass != USB_CLASS_PER_INTERFACE
393 && interface->bInterfaceClass != USB_CLASS_VENDOR_SPEC)
394 || interface->bInterfaceSubClass != 0
395 || interface->bInterfaceProtocol != 0
396 || interface->bNumEndpoints != 2
397 ) {
398 dbg ("Bogus camera interface info");
399 return NULL;
400 }
401
402
403
404 down (&state_table_mutex);
405 for (i = 0; i < MAX_CAMERAS; i++) {
406 if (!minor_data [i])
407 break;
408 }
409 if (i >= MAX_CAMERAS) {
410 info ("Ignoring additional USB Camera");
411 goto bye;
412 }
413
414
415 camera = minor_data [i] = kmalloc (sizeof *camera, GFP_KERNEL);
416 if (!camera) {
417 err ("no memory!");
418 goto bye;
419 }
420
421 init_MUTEX (&camera->sem);
422 camera->info = camera_info;
423 camera->subminor = i;
424 camera->buf = NULL;
425 init_waitqueue_head (&camera->wait);
426
427
428
429 endpoint = interface->endpoint;
430 camera->outEP = camera->inEP = -1;
431
432 ep = endpoint [0].bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
433 direction = endpoint [0].bEndpointAddress & USB_ENDPOINT_DIR_MASK;
434 if (direction == USB_DIR_IN)
435 camera->inEP = ep;
436 else
437 camera->outEP = ep;
438
439 ep = endpoint [1].bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
440 direction = endpoint [1].bEndpointAddress & USB_ENDPOINT_DIR_MASK;
441 if (direction == USB_DIR_IN)
442 camera->inEP = ep;
443 else
444 camera->outEP = ep;
445
446 if (camera->outEP == -1 || camera->inEP == -1
447 || endpoint [0].bmAttributes != USB_ENDPOINT_XFER_BULK
448 || endpoint [1].bmAttributes != USB_ENDPOINT_XFER_BULK
449 ) {
450 dbg ("Bogus endpoints");
451 goto error;
452 }
453
454 info ("USB Camera #%d connected, major/minor %d/%d", camera->subminor,
455 USB_MAJOR, USB_CAMERA_MINOR_BASE + camera->subminor);
456
457 camera->dev = dev;
458 usb_inc_dev_use (dev);
459
460
461 sprintf(name, "dc2xx%d", camera->subminor);
462 camera->devfs = devfs_register(usb_devfs_handle, name,
463 DEVFS_FL_DEFAULT, USB_MAJOR,
464 USB_CAMERA_MINOR_BASE + camera->subminor,
465 S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP |
466 S_IWGRP, &usb_camera_fops, NULL);
467
468 goto bye;
469
470error:
471 minor_data [camera->subminor] = NULL;
472 kfree (camera);
473 camera = NULL;
474bye:
475 up (&state_table_mutex);
476 return camera;
477}
478
479static void camera_disconnect(struct usb_device *dev, void *ptr)
480{
481 struct camera_state *camera = (struct camera_state *) ptr;
482 int subminor = camera->subminor;
483
484 down (&state_table_mutex);
485 down (&camera->sem);
486
487 devfs_unregister(camera->devfs);
488
489
490
491
492 if (!camera->buf) {
493 minor_data [subminor] = NULL;
494 kfree (camera);
495 camera = NULL;
496 } else
497 camera->dev = NULL;
498
499 info ("USB Camera #%d disconnected", subminor);
500 usb_dec_dev_use (dev);
501
502 if (camera != NULL)
503 up (&camera->sem);
504 up (&state_table_mutex);
505}
506
507static struct usb_driver camera_driver = {
508 name: "dc2xx",
509
510 id_table: camera_table,
511 probe: camera_probe,
512 disconnect: camera_disconnect,
513
514 fops: &usb_camera_fops,
515 minor: USB_CAMERA_MINOR_BASE
516};
517
518
519int __init usb_dc2xx_init(void)
520{
521 if (usb_register (&camera_driver) < 0)
522 return -1;
523 info(DRIVER_VERSION ":" DRIVER_DESC);
524 return 0;
525}
526
527void __exit usb_dc2xx_cleanup(void)
528{
529 usb_deregister (&camera_driver);
530}
531
532module_init (usb_dc2xx_init);
533module_exit (usb_dc2xx_cleanup);
534
535MODULE_AUTHOR( DRIVER_AUTHOR );
536MODULE_DESCRIPTION( DRIVER_DESC );
537MODULE_LICENSE("GPL");
538
539