blob: fdf68479a1664fac31cf09164c2d6946c7fb8b37 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* -*- linux-c -*- */
2
3/*
4 * Driver for USB Rio 500
5 *
6 * Cesar Miquel (miquel@df.uba.ar)
7 *
8 * based on hp_scanner.c by David E. Nelson (dnelson@jump.net)
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of the
13 * License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 * Based upon mouse.c (Brad Keryan) and printer.c (Michael Gee).
25 *
26 * Changelog:
27 * 30/05/2003 replaced lock/unlock kernel with up/down
28 * Daniele Bellucci bellucda@tiscali.it
29 * */
30
31#include <linux/module.h>
32#include <linux/kernel.h>
33#include <linux/signal.h>
34#include <linux/sched.h>
35#include <linux/errno.h>
36#include <linux/random.h>
37#include <linux/poll.h>
38#include <linux/init.h>
39#include <linux/slab.h>
40#include <linux/spinlock.h>
41#include <linux/usb.h>
42#include <linux/smp_lock.h>
43#include <linux/wait.h>
44
45#include "rio500_usb.h"
46
47/*
48 * Version Information
49 */
50#define DRIVER_VERSION "v1.1"
51#define DRIVER_AUTHOR "Cesar Miquel <miquel@df.uba.ar>"
52#define DRIVER_DESC "USB Rio 500 driver"
53
54#define RIO_MINOR 64
55
56/* stall/wait timeout for rio */
57#define NAK_TIMEOUT (HZ)
58
59#define IBUF_SIZE 0x1000
60
61/* Size of the rio buffer */
62#define OBUF_SIZE 0x10000
63
64struct rio_usb_data {
65 struct usb_device *rio_dev; /* init: probe_rio */
66 unsigned int ifnum; /* Interface number of the USB device */
67 int isopen; /* nz if open */
68 int present; /* Device is present on the bus */
69 char *obuf, *ibuf; /* transfer buffers */
70 char bulk_in_ep, bulk_out_ep; /* Endpoint assignments */
71 wait_queue_head_t wait_q; /* for timeouts */
Oliver Neukum2cba72f2006-12-15 23:48:56 +010072 struct mutex lock; /* general race avoidance */
Linus Torvalds1da177e2005-04-16 15:20:36 -070073};
74
75static struct rio_usb_data rio_instance;
76
77static int open_rio(struct inode *inode, struct file *file)
78{
79 struct rio_usb_data *rio = &rio_instance;
80
Oliver Neukum2cba72f2006-12-15 23:48:56 +010081 mutex_lock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -070082
83 if (rio->isopen || !rio->present) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +010084 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -070085 return -EBUSY;
86 }
87 rio->isopen = 1;
88
89 init_waitqueue_head(&rio->wait_q);
90
Oliver Neukum2cba72f2006-12-15 23:48:56 +010091 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -070092
93 info("Rio opened.");
94
95 return 0;
96}
97
98static int close_rio(struct inode *inode, struct file *file)
99{
100 struct rio_usb_data *rio = &rio_instance;
101
102 rio->isopen = 0;
103
104 info("Rio closed.");
105 return 0;
106}
107
108static int
109ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd,
110 unsigned long arg)
111{
112 struct RioCommand rio_cmd;
113 struct rio_usb_data *rio = &rio_instance;
114 void __user *data;
115 unsigned char *buffer;
116 int result, requesttype;
117 int retries;
118 int retval=0;
119
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100120 mutex_lock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121 /* Sanity check to make sure rio is connected, powered, etc */
122 if ( rio == NULL ||
123 rio->present == 0 ||
124 rio->rio_dev == NULL )
125 {
126 retval = -ENODEV;
127 goto err_out;
128 }
129
130 switch (cmd) {
131 case RIO_RECV_COMMAND:
132 data = (void __user *) arg;
133 if (data == NULL)
134 break;
135 if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand))) {
136 retval = -EFAULT;
137 goto err_out;
138 }
139 if (rio_cmd.length < 0 || rio_cmd.length > PAGE_SIZE) {
140 retval = -EINVAL;
141 goto err_out;
142 }
143 buffer = (unsigned char *) __get_free_page(GFP_KERNEL);
144 if (buffer == NULL) {
145 retval = -ENOMEM;
146 goto err_out;
147 }
148 if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length)) {
149 retval = -EFAULT;
150 free_page((unsigned long) buffer);
151 goto err_out;
152 }
153
154 requesttype = rio_cmd.requesttype | USB_DIR_IN |
155 USB_TYPE_VENDOR | USB_RECIP_DEVICE;
156 dbg
157 ("sending command:reqtype=%0x req=%0x value=%0x index=%0x len=%0x",
158 requesttype, rio_cmd.request, rio_cmd.value,
159 rio_cmd.index, rio_cmd.length);
160 /* Send rio control message */
161 retries = 3;
162 while (retries) {
163 result = usb_control_msg(rio->rio_dev,
164 usb_rcvctrlpipe(rio-> rio_dev, 0),
165 rio_cmd.request,
166 requesttype,
167 rio_cmd.value,
168 rio_cmd.index, buffer,
169 rio_cmd.length,
170 jiffies_to_msecs(rio_cmd.timeout));
171 if (result == -ETIMEDOUT)
172 retries--;
173 else if (result < 0) {
174 err("Error executing ioctrl. code = %d", result);
175 retries = 0;
176 } else {
177 dbg("Executed ioctl. Result = %d (data=%02x)",
178 result, buffer[0]);
179 if (copy_to_user(rio_cmd.buffer, buffer,
180 rio_cmd.length)) {
181 free_page((unsigned long) buffer);
182 retval = -EFAULT;
183 goto err_out;
184 }
185 retries = 0;
186 }
187
188 /* rio_cmd.buffer contains a raw stream of single byte
189 data which has been returned from rio. Data is
190 interpreted at application level. For data that
191 will be cast to data types longer than 1 byte, data
192 will be little_endian and will potentially need to
193 be swapped at the app level */
194
195 }
196 free_page((unsigned long) buffer);
197 break;
198
199 case RIO_SEND_COMMAND:
200 data = (void __user *) arg;
201 if (data == NULL)
202 break;
203 if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand))) {
204 retval = -EFAULT;
205 goto err_out;
206 }
207 if (rio_cmd.length < 0 || rio_cmd.length > PAGE_SIZE) {
208 retval = -EINVAL;
209 goto err_out;
210 }
211 buffer = (unsigned char *) __get_free_page(GFP_KERNEL);
212 if (buffer == NULL) {
213 retval = -ENOMEM;
214 goto err_out;
215 }
216 if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length)) {
217 free_page((unsigned long)buffer);
218 retval = -EFAULT;
219 goto err_out;
220 }
221
222 requesttype = rio_cmd.requesttype | USB_DIR_OUT |
223 USB_TYPE_VENDOR | USB_RECIP_DEVICE;
224 dbg("sending command: reqtype=%0x req=%0x value=%0x index=%0x len=%0x",
225 requesttype, rio_cmd.request, rio_cmd.value,
226 rio_cmd.index, rio_cmd.length);
227 /* Send rio control message */
228 retries = 3;
229 while (retries) {
230 result = usb_control_msg(rio->rio_dev,
231 usb_sndctrlpipe(rio-> rio_dev, 0),
232 rio_cmd.request,
233 requesttype,
234 rio_cmd.value,
235 rio_cmd.index, buffer,
236 rio_cmd.length,
237 jiffies_to_msecs(rio_cmd.timeout));
238 if (result == -ETIMEDOUT)
239 retries--;
240 else if (result < 0) {
241 err("Error executing ioctrl. code = %d", result);
242 retries = 0;
243 } else {
244 dbg("Executed ioctl. Result = %d", result);
245 retries = 0;
246
247 }
248
249 }
250 free_page((unsigned long) buffer);
251 break;
252
253 default:
254 retval = -ENOTTY;
255 break;
256 }
257
258
259err_out:
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100260 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261 return retval;
262}
263
264static ssize_t
265write_rio(struct file *file, const char __user *buffer,
266 size_t count, loff_t * ppos)
267{
268 DEFINE_WAIT(wait);
269 struct rio_usb_data *rio = &rio_instance;
270
271 unsigned long copy_size;
272 unsigned long bytes_written = 0;
273 unsigned int partial;
274
275 int result = 0;
276 int maxretry;
277 int errn = 0;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100278 int intr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100280 intr = mutex_lock_interruptible(&(rio->lock));
281 if (intr)
282 return -EINTR;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283 /* Sanity check to make sure rio is connected, powered, etc */
284 if ( rio == NULL ||
285 rio->present == 0 ||
286 rio->rio_dev == NULL )
287 {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100288 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700289 return -ENODEV;
290 }
291
292
293
294 do {
295 unsigned long thistime;
296 char *obuf = rio->obuf;
297
298 thistime = copy_size =
299 (count >= OBUF_SIZE) ? OBUF_SIZE : count;
300 if (copy_from_user(rio->obuf, buffer, copy_size)) {
301 errn = -EFAULT;
302 goto error;
303 }
304 maxretry = 5;
305 while (thistime) {
306 if (!rio->rio_dev) {
307 errn = -ENODEV;
308 goto error;
309 }
310 if (signal_pending(current)) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100311 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700312 return bytes_written ? bytes_written : -EINTR;
313 }
314
315 result = usb_bulk_msg(rio->rio_dev,
316 usb_sndbulkpipe(rio->rio_dev, 2),
317 obuf, thistime, &partial, 5000);
318
319 dbg("write stats: result:%d thistime:%lu partial:%u",
320 result, thistime, partial);
321
322 if (result == -ETIMEDOUT) { /* NAK - so hold for a while */
323 if (!maxretry--) {
324 errn = -ETIME;
325 goto error;
326 }
327 prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE);
328 schedule_timeout(NAK_TIMEOUT);
329 finish_wait(&rio->wait_q, &wait);
330 continue;
331 } else if (!result && partial) {
332 obuf += partial;
333 thistime -= partial;
334 } else
335 break;
336 };
337 if (result) {
338 err("Write Whoops - %x", result);
339 errn = -EIO;
340 goto error;
341 }
342 bytes_written += copy_size;
343 count -= copy_size;
344 buffer += copy_size;
345 } while (count > 0);
346
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100347 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348
349 return bytes_written ? bytes_written : -EIO;
350
351error:
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100352 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353 return errn;
354}
355
356static ssize_t
357read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
358{
359 DEFINE_WAIT(wait);
360 struct rio_usb_data *rio = &rio_instance;
361 ssize_t read_count;
362 unsigned int partial;
363 int this_read;
364 int result;
365 int maxretry = 10;
366 char *ibuf;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100367 int intr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100369 intr = mutex_lock_interruptible(&(rio->lock));
370 if (intr)
371 return -EINTR;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372 /* Sanity check to make sure rio is connected, powered, etc */
373 if ( rio == NULL ||
374 rio->present == 0 ||
375 rio->rio_dev == NULL )
376 {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100377 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378 return -ENODEV;
379 }
380
381 ibuf = rio->ibuf;
382
383 read_count = 0;
384
385
386 while (count > 0) {
387 if (signal_pending(current)) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100388 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389 return read_count ? read_count : -EINTR;
390 }
391 if (!rio->rio_dev) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100392 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393 return -ENODEV;
394 }
395 this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count;
396
397 result = usb_bulk_msg(rio->rio_dev,
398 usb_rcvbulkpipe(rio->rio_dev, 1),
399 ibuf, this_read, &partial,
400 8000);
401
Greg Kroah-Hartman654f3112005-11-17 09:48:09 -0800402 dbg("read stats: result:%d this_read:%u partial:%u",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403 result, this_read, partial);
404
405 if (partial) {
406 count = this_read = partial;
407 } else if (result == -ETIMEDOUT || result == 15) { /* FIXME: 15 ??? */
408 if (!maxretry--) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100409 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410 err("read_rio: maxretry timeout");
411 return -ETIME;
412 }
413 prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE);
414 schedule_timeout(NAK_TIMEOUT);
415 finish_wait(&rio->wait_q, &wait);
416 continue;
417 } else if (result != -EREMOTEIO) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100418 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419 err("Read Whoops - result:%u partial:%u this_read:%u",
420 result, partial, this_read);
421 return -EIO;
422 } else {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100423 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424 return (0);
425 }
426
427 if (this_read) {
428 if (copy_to_user(buffer, ibuf, this_read)) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100429 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430 return -EFAULT;
431 }
432 count -= this_read;
433 read_count += this_read;
434 buffer += this_read;
435 }
436 }
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100437 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438 return read_count;
439}
440
441static struct
442file_operations usb_rio_fops = {
443 .owner = THIS_MODULE,
444 .read = read_rio,
445 .write = write_rio,
446 .ioctl = ioctl_rio,
447 .open = open_rio,
448 .release = close_rio,
449};
450
451static struct usb_class_driver usb_rio_class = {
Greg Kroah-Hartmand6e5bcf2005-06-20 21:15:16 -0700452 .name = "rio500%d",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453 .fops = &usb_rio_fops,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700454 .minor_base = RIO_MINOR,
455};
456
457static int probe_rio(struct usb_interface *intf,
458 const struct usb_device_id *id)
459{
460 struct usb_device *dev = interface_to_usbdev(intf);
461 struct rio_usb_data *rio = &rio_instance;
462 int retval;
463
464 info("USB Rio found at address %d", dev->devnum);
465
466 retval = usb_register_dev(intf, &usb_rio_class);
467 if (retval) {
468 err("Not able to get a minor for this device.");
469 return -ENOMEM;
470 }
471
472 rio->rio_dev = dev;
473
Jesper Juhl0e8eb0f2005-12-11 20:34:02 +0100474 if (!(rio->obuf = kmalloc(OBUF_SIZE, GFP_KERNEL))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700475 err("probe_rio: Not enough memory for the output buffer");
476 usb_deregister_dev(intf, &usb_rio_class);
477 return -ENOMEM;
478 }
479 dbg("probe_rio: obuf address:%p", rio->obuf);
480
Jesper Juhl0e8eb0f2005-12-11 20:34:02 +0100481 if (!(rio->ibuf = kmalloc(IBUF_SIZE, GFP_KERNEL))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700482 err("probe_rio: Not enough memory for the input buffer");
483 usb_deregister_dev(intf, &usb_rio_class);
484 kfree(rio->obuf);
485 return -ENOMEM;
486 }
487 dbg("probe_rio: ibuf address:%p", rio->ibuf);
488
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100489 mutex_init(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700490
491 usb_set_intfdata (intf, rio);
492 rio->present = 1;
493
494 return 0;
495}
496
497static void disconnect_rio(struct usb_interface *intf)
498{
499 struct rio_usb_data *rio = usb_get_intfdata (intf);
500
501 usb_set_intfdata (intf, NULL);
502 if (rio) {
503 usb_deregister_dev(intf, &usb_rio_class);
504
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100505 mutex_lock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700506 if (rio->isopen) {
507 rio->isopen = 0;
508 /* better let it finish - the release will do whats needed */
509 rio->rio_dev = NULL;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100510 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511 return;
512 }
513 kfree(rio->ibuf);
514 kfree(rio->obuf);
515
516 info("USB Rio disconnected.");
517
518 rio->present = 0;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100519 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520 }
521}
522
523static struct usb_device_id rio_table [] = {
524 { USB_DEVICE(0x0841, 1) }, /* Rio 500 */
525 { } /* Terminating entry */
526};
527
528MODULE_DEVICE_TABLE (usb, rio_table);
529
530static struct usb_driver rio_driver = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531 .name = "rio500",
532 .probe = probe_rio,
533 .disconnect = disconnect_rio,
534 .id_table = rio_table,
535};
536
537static int __init usb_rio_init(void)
538{
539 int retval;
540 retval = usb_register(&rio_driver);
541 if (retval)
542 goto out;
543
544 info(DRIVER_VERSION ":" DRIVER_DESC);
545
546out:
547 return retval;
548}
549
550
551static void __exit usb_rio_cleanup(void)
552{
553 struct rio_usb_data *rio = &rio_instance;
554
555 rio->present = 0;
556 usb_deregister(&rio_driver);
557
558
559}
560
561module_init(usb_rio_init);
562module_exit(usb_rio_cleanup);
563
564MODULE_AUTHOR( DRIVER_AUTHOR );
565MODULE_DESCRIPTION( DRIVER_DESC );
566MODULE_LICENSE("GPL");
567