blob: deb95bb49fd195d333a77152e21fef88f2d26ae3 [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>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042#include <linux/wait.h>
43
44#include "rio500_usb.h"
45
46/*
47 * Version Information
48 */
49#define DRIVER_VERSION "v1.1"
50#define DRIVER_AUTHOR "Cesar Miquel <miquel@df.uba.ar>"
51#define DRIVER_DESC "USB Rio 500 driver"
52
53#define RIO_MINOR 64
54
55/* stall/wait timeout for rio */
56#define NAK_TIMEOUT (HZ)
57
58#define IBUF_SIZE 0x1000
59
60/* Size of the rio buffer */
61#define OBUF_SIZE 0x10000
62
63struct rio_usb_data {
64 struct usb_device *rio_dev; /* init: probe_rio */
65 unsigned int ifnum; /* Interface number of the USB device */
66 int isopen; /* nz if open */
67 int present; /* Device is present on the bus */
68 char *obuf, *ibuf; /* transfer buffers */
69 char bulk_in_ep, bulk_out_ep; /* Endpoint assignments */
70 wait_queue_head_t wait_q; /* for timeouts */
Oliver Neukum2cba72f2006-12-15 23:48:56 +010071 struct mutex lock; /* general race avoidance */
Linus Torvalds1da177e2005-04-16 15:20:36 -070072};
73
74static struct rio_usb_data rio_instance;
75
76static int open_rio(struct inode *inode, struct file *file)
77{
78 struct rio_usb_data *rio = &rio_instance;
79
Oliver Neukum2cba72f2006-12-15 23:48:56 +010080 mutex_lock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -070081
82 if (rio->isopen || !rio->present) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +010083 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -070084 return -EBUSY;
85 }
86 rio->isopen = 1;
87
88 init_waitqueue_head(&rio->wait_q);
89
Oliver Neukum2cba72f2006-12-15 23:48:56 +010090 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -070091
Greg Kroah-Hartman1b29a372008-08-18 13:21:04 -070092 dev_info(&rio->rio_dev->dev, "Rio opened.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -070093
94 return 0;
95}
96
97static int close_rio(struct inode *inode, struct file *file)
98{
99 struct rio_usb_data *rio = &rio_instance;
100
101 rio->isopen = 0;
102
Greg Kroah-Hartman1b29a372008-08-18 13:21:04 -0700103 dev_info(&rio->rio_dev->dev, "Rio closed.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104 return 0;
105}
106
Alan Cox54592152008-05-22 22:47:31 +0100107static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108{
109 struct RioCommand rio_cmd;
110 struct rio_usb_data *rio = &rio_instance;
111 void __user *data;
112 unsigned char *buffer;
113 int result, requesttype;
114 int retries;
115 int retval=0;
116
Alan Cox54592152008-05-22 22:47:31 +0100117 lock_kernel();
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100118 mutex_lock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119 /* Sanity check to make sure rio is connected, powered, etc */
Adrian Bunk3328d972007-10-18 12:53:07 +0200120 if (rio->present == 0 || rio->rio_dev == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121 retval = -ENODEV;
122 goto err_out;
123 }
124
125 switch (cmd) {
126 case RIO_RECV_COMMAND:
127 data = (void __user *) arg;
128 if (data == NULL)
129 break;
130 if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand))) {
131 retval = -EFAULT;
132 goto err_out;
133 }
134 if (rio_cmd.length < 0 || rio_cmd.length > PAGE_SIZE) {
135 retval = -EINVAL;
136 goto err_out;
137 }
138 buffer = (unsigned char *) __get_free_page(GFP_KERNEL);
139 if (buffer == NULL) {
140 retval = -ENOMEM;
141 goto err_out;
142 }
143 if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length)) {
144 retval = -EFAULT;
145 free_page((unsigned long) buffer);
146 goto err_out;
147 }
148
149 requesttype = rio_cmd.requesttype | USB_DIR_IN |
150 USB_TYPE_VENDOR | USB_RECIP_DEVICE;
151 dbg
152 ("sending command:reqtype=%0x req=%0x value=%0x index=%0x len=%0x",
153 requesttype, rio_cmd.request, rio_cmd.value,
154 rio_cmd.index, rio_cmd.length);
155 /* Send rio control message */
156 retries = 3;
157 while (retries) {
158 result = usb_control_msg(rio->rio_dev,
159 usb_rcvctrlpipe(rio-> rio_dev, 0),
160 rio_cmd.request,
161 requesttype,
162 rio_cmd.value,
163 rio_cmd.index, buffer,
164 rio_cmd.length,
165 jiffies_to_msecs(rio_cmd.timeout));
166 if (result == -ETIMEDOUT)
167 retries--;
168 else if (result < 0) {
169 err("Error executing ioctrl. code = %d", result);
170 retries = 0;
171 } else {
172 dbg("Executed ioctl. Result = %d (data=%02x)",
173 result, buffer[0]);
174 if (copy_to_user(rio_cmd.buffer, buffer,
175 rio_cmd.length)) {
176 free_page((unsigned long) buffer);
177 retval = -EFAULT;
178 goto err_out;
179 }
180 retries = 0;
181 }
182
183 /* rio_cmd.buffer contains a raw stream of single byte
184 data which has been returned from rio. Data is
185 interpreted at application level. For data that
186 will be cast to data types longer than 1 byte, data
187 will be little_endian and will potentially need to
188 be swapped at the app level */
189
190 }
191 free_page((unsigned long) buffer);
192 break;
193
194 case RIO_SEND_COMMAND:
195 data = (void __user *) arg;
196 if (data == NULL)
197 break;
198 if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand))) {
199 retval = -EFAULT;
200 goto err_out;
201 }
202 if (rio_cmd.length < 0 || rio_cmd.length > PAGE_SIZE) {
203 retval = -EINVAL;
204 goto err_out;
205 }
206 buffer = (unsigned char *) __get_free_page(GFP_KERNEL);
207 if (buffer == NULL) {
208 retval = -ENOMEM;
209 goto err_out;
210 }
211 if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length)) {
212 free_page((unsigned long)buffer);
213 retval = -EFAULT;
214 goto err_out;
215 }
216
217 requesttype = rio_cmd.requesttype | USB_DIR_OUT |
218 USB_TYPE_VENDOR | USB_RECIP_DEVICE;
219 dbg("sending command: reqtype=%0x req=%0x value=%0x index=%0x len=%0x",
220 requesttype, rio_cmd.request, rio_cmd.value,
221 rio_cmd.index, rio_cmd.length);
222 /* Send rio control message */
223 retries = 3;
224 while (retries) {
225 result = usb_control_msg(rio->rio_dev,
226 usb_sndctrlpipe(rio-> rio_dev, 0),
227 rio_cmd.request,
228 requesttype,
229 rio_cmd.value,
230 rio_cmd.index, buffer,
231 rio_cmd.length,
232 jiffies_to_msecs(rio_cmd.timeout));
233 if (result == -ETIMEDOUT)
234 retries--;
235 else if (result < 0) {
236 err("Error executing ioctrl. code = %d", result);
237 retries = 0;
238 } else {
239 dbg("Executed ioctl. Result = %d", result);
240 retries = 0;
241
242 }
243
244 }
245 free_page((unsigned long) buffer);
246 break;
247
248 default:
249 retval = -ENOTTY;
250 break;
251 }
252
253
254err_out:
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100255 mutex_unlock(&(rio->lock));
Alan Cox54592152008-05-22 22:47:31 +0100256 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700257 return retval;
258}
259
260static ssize_t
261write_rio(struct file *file, const char __user *buffer,
262 size_t count, loff_t * ppos)
263{
264 DEFINE_WAIT(wait);
265 struct rio_usb_data *rio = &rio_instance;
266
267 unsigned long copy_size;
268 unsigned long bytes_written = 0;
269 unsigned int partial;
270
271 int result = 0;
272 int maxretry;
273 int errn = 0;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100274 int intr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700275
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100276 intr = mutex_lock_interruptible(&(rio->lock));
277 if (intr)
278 return -EINTR;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279 /* Sanity check to make sure rio is connected, powered, etc */
Adrian Bunk3328d972007-10-18 12:53:07 +0200280 if (rio->present == 0 || rio->rio_dev == NULL) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100281 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282 return -ENODEV;
283 }
284
285
286
287 do {
288 unsigned long thistime;
289 char *obuf = rio->obuf;
290
291 thistime = copy_size =
292 (count >= OBUF_SIZE) ? OBUF_SIZE : count;
293 if (copy_from_user(rio->obuf, buffer, copy_size)) {
294 errn = -EFAULT;
295 goto error;
296 }
297 maxretry = 5;
298 while (thistime) {
299 if (!rio->rio_dev) {
300 errn = -ENODEV;
301 goto error;
302 }
303 if (signal_pending(current)) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100304 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305 return bytes_written ? bytes_written : -EINTR;
306 }
307
308 result = usb_bulk_msg(rio->rio_dev,
309 usb_sndbulkpipe(rio->rio_dev, 2),
310 obuf, thistime, &partial, 5000);
311
312 dbg("write stats: result:%d thistime:%lu partial:%u",
313 result, thistime, partial);
314
315 if (result == -ETIMEDOUT) { /* NAK - so hold for a while */
316 if (!maxretry--) {
317 errn = -ETIME;
318 goto error;
319 }
320 prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE);
321 schedule_timeout(NAK_TIMEOUT);
322 finish_wait(&rio->wait_q, &wait);
323 continue;
324 } else if (!result && partial) {
325 obuf += partial;
326 thistime -= partial;
327 } else
328 break;
329 };
330 if (result) {
331 err("Write Whoops - %x", result);
332 errn = -EIO;
333 goto error;
334 }
335 bytes_written += copy_size;
336 count -= copy_size;
337 buffer += copy_size;
338 } while (count > 0);
339
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100340 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341
342 return bytes_written ? bytes_written : -EIO;
343
344error:
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100345 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700346 return errn;
347}
348
349static ssize_t
350read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
351{
352 DEFINE_WAIT(wait);
353 struct rio_usb_data *rio = &rio_instance;
354 ssize_t read_count;
355 unsigned int partial;
356 int this_read;
357 int result;
358 int maxretry = 10;
359 char *ibuf;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100360 int intr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100362 intr = mutex_lock_interruptible(&(rio->lock));
363 if (intr)
364 return -EINTR;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365 /* Sanity check to make sure rio is connected, powered, etc */
Adrian Bunk3328d972007-10-18 12:53:07 +0200366 if (rio->present == 0 || rio->rio_dev == NULL) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100367 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368 return -ENODEV;
369 }
370
371 ibuf = rio->ibuf;
372
373 read_count = 0;
374
375
376 while (count > 0) {
377 if (signal_pending(current)) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100378 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379 return read_count ? read_count : -EINTR;
380 }
381 if (!rio->rio_dev) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100382 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383 return -ENODEV;
384 }
385 this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count;
386
387 result = usb_bulk_msg(rio->rio_dev,
388 usb_rcvbulkpipe(rio->rio_dev, 1),
389 ibuf, this_read, &partial,
390 8000);
391
Greg Kroah-Hartman654f3112005-11-17 09:48:09 -0800392 dbg("read stats: result:%d this_read:%u partial:%u",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393 result, this_read, partial);
394
395 if (partial) {
396 count = this_read = partial;
397 } else if (result == -ETIMEDOUT || result == 15) { /* FIXME: 15 ??? */
398 if (!maxretry--) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100399 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400 err("read_rio: maxretry timeout");
401 return -ETIME;
402 }
403 prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE);
404 schedule_timeout(NAK_TIMEOUT);
405 finish_wait(&rio->wait_q, &wait);
406 continue;
407 } else if (result != -EREMOTEIO) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100408 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409 err("Read Whoops - result:%u partial:%u this_read:%u",
410 result, partial, this_read);
411 return -EIO;
412 } else {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100413 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414 return (0);
415 }
416
417 if (this_read) {
418 if (copy_to_user(buffer, ibuf, this_read)) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100419 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420 return -EFAULT;
421 }
422 count -= this_read;
423 read_count += this_read;
424 buffer += this_read;
425 }
426 }
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100427 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428 return read_count;
429}
430
431static struct
432file_operations usb_rio_fops = {
433 .owner = THIS_MODULE,
434 .read = read_rio,
435 .write = write_rio,
Alan Cox54592152008-05-22 22:47:31 +0100436 .unlocked_ioctl = ioctl_rio,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437 .open = open_rio,
438 .release = close_rio,
439};
440
441static struct usb_class_driver usb_rio_class = {
Greg Kroah-Hartmand6e5bcf2005-06-20 21:15:16 -0700442 .name = "rio500%d",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443 .fops = &usb_rio_fops,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444 .minor_base = RIO_MINOR,
445};
446
447static int probe_rio(struct usb_interface *intf,
448 const struct usb_device_id *id)
449{
450 struct usb_device *dev = interface_to_usbdev(intf);
451 struct rio_usb_data *rio = &rio_instance;
452 int retval;
453
Greg Kroah-Hartman1b29a372008-08-18 13:21:04 -0700454 dev_info(&intf->dev, "USB Rio found at address %d\n", dev->devnum);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455
456 retval = usb_register_dev(intf, &usb_rio_class);
457 if (retval) {
458 err("Not able to get a minor for this device.");
459 return -ENOMEM;
460 }
461
462 rio->rio_dev = dev;
463
Jesper Juhl0e8eb0f2005-12-11 20:34:02 +0100464 if (!(rio->obuf = kmalloc(OBUF_SIZE, GFP_KERNEL))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465 err("probe_rio: Not enough memory for the output buffer");
466 usb_deregister_dev(intf, &usb_rio_class);
467 return -ENOMEM;
468 }
469 dbg("probe_rio: obuf address:%p", rio->obuf);
470
Jesper Juhl0e8eb0f2005-12-11 20:34:02 +0100471 if (!(rio->ibuf = kmalloc(IBUF_SIZE, GFP_KERNEL))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472 err("probe_rio: Not enough memory for the input buffer");
473 usb_deregister_dev(intf, &usb_rio_class);
474 kfree(rio->obuf);
475 return -ENOMEM;
476 }
477 dbg("probe_rio: ibuf address:%p", rio->ibuf);
478
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100479 mutex_init(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480
481 usb_set_intfdata (intf, rio);
482 rio->present = 1;
483
484 return 0;
485}
486
487static void disconnect_rio(struct usb_interface *intf)
488{
489 struct rio_usb_data *rio = usb_get_intfdata (intf);
490
491 usb_set_intfdata (intf, NULL);
492 if (rio) {
493 usb_deregister_dev(intf, &usb_rio_class);
494
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100495 mutex_lock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496 if (rio->isopen) {
497 rio->isopen = 0;
498 /* better let it finish - the release will do whats needed */
499 rio->rio_dev = NULL;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100500 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700501 return;
502 }
503 kfree(rio->ibuf);
504 kfree(rio->obuf);
505
Greg Kroah-Hartman1b29a372008-08-18 13:21:04 -0700506 dev_info(&intf->dev, "USB Rio disconnected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507
508 rio->present = 0;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100509 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510 }
511}
512
513static struct usb_device_id rio_table [] = {
514 { USB_DEVICE(0x0841, 1) }, /* Rio 500 */
515 { } /* Terminating entry */
516};
517
518MODULE_DEVICE_TABLE (usb, rio_table);
519
520static struct usb_driver rio_driver = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521 .name = "rio500",
522 .probe = probe_rio,
523 .disconnect = disconnect_rio,
524 .id_table = rio_table,
525};
526
527static int __init usb_rio_init(void)
528{
529 int retval;
530 retval = usb_register(&rio_driver);
531 if (retval)
532 goto out;
533
Greg Kroah-Hartman1b29a372008-08-18 13:21:04 -0700534 printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
535 DRIVER_DESC "\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536
537out:
538 return retval;
539}
540
541
542static void __exit usb_rio_cleanup(void)
543{
544 struct rio_usb_data *rio = &rio_instance;
545
546 rio->present = 0;
547 usb_deregister(&rio_driver);
548
549
550}
551
552module_init(usb_rio_init);
553module_exit(usb_rio_cleanup);
554
555MODULE_AUTHOR( DRIVER_AUTHOR );
556MODULE_DESCRIPTION( DRIVER_DESC );
557MODULE_LICENSE("GPL");
558