blob: 47ce46bb5b014a2866bccc3c6e75b5939b3b272f [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>
Alexey Dobriyan405f5572009-07-11 22:08:37 +040035#include <linux/smp_lock.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070036#include <linux/errno.h>
37#include <linux/random.h>
38#include <linux/poll.h>
39#include <linux/init.h>
40#include <linux/slab.h>
41#include <linux/spinlock.h>
42#include <linux/usb.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070043#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;
Oliver Neukum86266452010-01-13 15:33:15 +010080 lock_kernel();
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
Greg Kroah-Hartman1b29a372008-08-18 13:21:04 -070093 dev_info(&rio->rio_dev->dev, "Rio opened.\n");
Oliver Neukum86266452010-01-13 15:33:15 +010094 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -070095
96 return 0;
97}
98
99static int close_rio(struct inode *inode, struct file *file)
100{
101 struct rio_usb_data *rio = &rio_instance;
102
103 rio->isopen = 0;
104
Greg Kroah-Hartman1b29a372008-08-18 13:21:04 -0700105 dev_info(&rio->rio_dev->dev, "Rio closed.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106 return 0;
107}
108
Alan Cox54592152008-05-22 22:47:31 +0100109static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110{
111 struct RioCommand rio_cmd;
112 struct rio_usb_data *rio = &rio_instance;
113 void __user *data;
114 unsigned char *buffer;
115 int result, requesttype;
116 int retries;
117 int retval=0;
118
Alan Cox54592152008-05-22 22:47:31 +0100119 lock_kernel();
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 */
Adrian Bunk3328d972007-10-18 12:53:07 +0200122 if (rio->present == 0 || rio->rio_dev == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123 retval = -ENODEV;
124 goto err_out;
125 }
126
127 switch (cmd) {
128 case RIO_RECV_COMMAND:
129 data = (void __user *) arg;
130 if (data == NULL)
131 break;
132 if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand))) {
133 retval = -EFAULT;
134 goto err_out;
135 }
136 if (rio_cmd.length < 0 || rio_cmd.length > PAGE_SIZE) {
137 retval = -EINVAL;
138 goto err_out;
139 }
140 buffer = (unsigned char *) __get_free_page(GFP_KERNEL);
141 if (buffer == NULL) {
142 retval = -ENOMEM;
143 goto err_out;
144 }
145 if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length)) {
146 retval = -EFAULT;
147 free_page((unsigned long) buffer);
148 goto err_out;
149 }
150
151 requesttype = rio_cmd.requesttype | USB_DIR_IN |
152 USB_TYPE_VENDOR | USB_RECIP_DEVICE;
153 dbg
154 ("sending command:reqtype=%0x req=%0x value=%0x index=%0x len=%0x",
155 requesttype, rio_cmd.request, rio_cmd.value,
156 rio_cmd.index, rio_cmd.length);
157 /* Send rio control message */
158 retries = 3;
159 while (retries) {
160 result = usb_control_msg(rio->rio_dev,
161 usb_rcvctrlpipe(rio-> rio_dev, 0),
162 rio_cmd.request,
163 requesttype,
164 rio_cmd.value,
165 rio_cmd.index, buffer,
166 rio_cmd.length,
167 jiffies_to_msecs(rio_cmd.timeout));
168 if (result == -ETIMEDOUT)
169 retries--;
170 else if (result < 0) {
171 err("Error executing ioctrl. code = %d", result);
172 retries = 0;
173 } else {
174 dbg("Executed ioctl. Result = %d (data=%02x)",
175 result, buffer[0]);
176 if (copy_to_user(rio_cmd.buffer, buffer,
177 rio_cmd.length)) {
178 free_page((unsigned long) buffer);
179 retval = -EFAULT;
180 goto err_out;
181 }
182 retries = 0;
183 }
184
185 /* rio_cmd.buffer contains a raw stream of single byte
186 data which has been returned from rio. Data is
187 interpreted at application level. For data that
188 will be cast to data types longer than 1 byte, data
189 will be little_endian and will potentially need to
190 be swapped at the app level */
191
192 }
193 free_page((unsigned long) buffer);
194 break;
195
196 case RIO_SEND_COMMAND:
197 data = (void __user *) arg;
198 if (data == NULL)
199 break;
200 if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand))) {
201 retval = -EFAULT;
202 goto err_out;
203 }
204 if (rio_cmd.length < 0 || rio_cmd.length > PAGE_SIZE) {
205 retval = -EINVAL;
206 goto err_out;
207 }
208 buffer = (unsigned char *) __get_free_page(GFP_KERNEL);
209 if (buffer == NULL) {
210 retval = -ENOMEM;
211 goto err_out;
212 }
213 if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length)) {
214 free_page((unsigned long)buffer);
215 retval = -EFAULT;
216 goto err_out;
217 }
218
219 requesttype = rio_cmd.requesttype | USB_DIR_OUT |
220 USB_TYPE_VENDOR | USB_RECIP_DEVICE;
221 dbg("sending command: reqtype=%0x req=%0x value=%0x index=%0x len=%0x",
222 requesttype, rio_cmd.request, rio_cmd.value,
223 rio_cmd.index, rio_cmd.length);
224 /* Send rio control message */
225 retries = 3;
226 while (retries) {
227 result = usb_control_msg(rio->rio_dev,
228 usb_sndctrlpipe(rio-> rio_dev, 0),
229 rio_cmd.request,
230 requesttype,
231 rio_cmd.value,
232 rio_cmd.index, buffer,
233 rio_cmd.length,
234 jiffies_to_msecs(rio_cmd.timeout));
235 if (result == -ETIMEDOUT)
236 retries--;
237 else if (result < 0) {
238 err("Error executing ioctrl. code = %d", result);
239 retries = 0;
240 } else {
241 dbg("Executed ioctl. Result = %d", result);
242 retries = 0;
243
244 }
245
246 }
247 free_page((unsigned long) buffer);
248 break;
249
250 default:
251 retval = -ENOTTY;
252 break;
253 }
254
255
256err_out:
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100257 mutex_unlock(&(rio->lock));
Alan Cox54592152008-05-22 22:47:31 +0100258 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259 return retval;
260}
261
262static ssize_t
263write_rio(struct file *file, const char __user *buffer,
264 size_t count, loff_t * ppos)
265{
266 DEFINE_WAIT(wait);
267 struct rio_usb_data *rio = &rio_instance;
268
269 unsigned long copy_size;
270 unsigned long bytes_written = 0;
271 unsigned int partial;
272
273 int result = 0;
274 int maxretry;
275 int errn = 0;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100276 int intr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100278 intr = mutex_lock_interruptible(&(rio->lock));
279 if (intr)
280 return -EINTR;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700281 /* Sanity check to make sure rio is connected, powered, etc */
Adrian Bunk3328d972007-10-18 12:53:07 +0200282 if (rio->present == 0 || rio->rio_dev == NULL) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100283 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700284 return -ENODEV;
285 }
286
287
288
289 do {
290 unsigned long thistime;
291 char *obuf = rio->obuf;
292
293 thistime = copy_size =
294 (count >= OBUF_SIZE) ? OBUF_SIZE : count;
295 if (copy_from_user(rio->obuf, buffer, copy_size)) {
296 errn = -EFAULT;
297 goto error;
298 }
299 maxretry = 5;
300 while (thistime) {
301 if (!rio->rio_dev) {
302 errn = -ENODEV;
303 goto error;
304 }
305 if (signal_pending(current)) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100306 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700307 return bytes_written ? bytes_written : -EINTR;
308 }
309
310 result = usb_bulk_msg(rio->rio_dev,
311 usb_sndbulkpipe(rio->rio_dev, 2),
312 obuf, thistime, &partial, 5000);
313
314 dbg("write stats: result:%d thistime:%lu partial:%u",
315 result, thistime, partial);
316
317 if (result == -ETIMEDOUT) { /* NAK - so hold for a while */
318 if (!maxretry--) {
319 errn = -ETIME;
320 goto error;
321 }
322 prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE);
323 schedule_timeout(NAK_TIMEOUT);
324 finish_wait(&rio->wait_q, &wait);
325 continue;
326 } else if (!result && partial) {
327 obuf += partial;
328 thistime -= partial;
329 } else
330 break;
331 };
332 if (result) {
333 err("Write Whoops - %x", result);
334 errn = -EIO;
335 goto error;
336 }
337 bytes_written += copy_size;
338 count -= copy_size;
339 buffer += copy_size;
340 } while (count > 0);
341
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100342 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700343
344 return bytes_written ? bytes_written : -EIO;
345
346error:
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100347 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348 return errn;
349}
350
351static ssize_t
352read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
353{
354 DEFINE_WAIT(wait);
355 struct rio_usb_data *rio = &rio_instance;
356 ssize_t read_count;
357 unsigned int partial;
358 int this_read;
359 int result;
360 int maxretry = 10;
361 char *ibuf;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100362 int intr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100364 intr = mutex_lock_interruptible(&(rio->lock));
365 if (intr)
366 return -EINTR;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367 /* Sanity check to make sure rio is connected, powered, etc */
Adrian Bunk3328d972007-10-18 12:53:07 +0200368 if (rio->present == 0 || rio->rio_dev == NULL) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100369 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370 return -ENODEV;
371 }
372
373 ibuf = rio->ibuf;
374
375 read_count = 0;
376
377
378 while (count > 0) {
379 if (signal_pending(current)) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100380 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381 return read_count ? read_count : -EINTR;
382 }
383 if (!rio->rio_dev) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100384 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385 return -ENODEV;
386 }
387 this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count;
388
389 result = usb_bulk_msg(rio->rio_dev,
390 usb_rcvbulkpipe(rio->rio_dev, 1),
391 ibuf, this_read, &partial,
392 8000);
393
Greg Kroah-Hartman654f3112005-11-17 09:48:09 -0800394 dbg("read stats: result:%d this_read:%u partial:%u",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395 result, this_read, partial);
396
397 if (partial) {
398 count = this_read = partial;
399 } else if (result == -ETIMEDOUT || result == 15) { /* FIXME: 15 ??? */
400 if (!maxretry--) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100401 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402 err("read_rio: maxretry timeout");
403 return -ETIME;
404 }
405 prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE);
406 schedule_timeout(NAK_TIMEOUT);
407 finish_wait(&rio->wait_q, &wait);
408 continue;
409 } else if (result != -EREMOTEIO) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100410 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411 err("Read Whoops - result:%u partial:%u this_read:%u",
412 result, partial, this_read);
413 return -EIO;
414 } else {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100415 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416 return (0);
417 }
418
419 if (this_read) {
420 if (copy_to_user(buffer, ibuf, this_read)) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100421 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422 return -EFAULT;
423 }
424 count -= this_read;
425 read_count += this_read;
426 buffer += this_read;
427 }
428 }
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100429 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430 return read_count;
431}
432
Alexey Dobriyan828c0952009-10-01 15:43:56 -0700433static const struct file_operations usb_rio_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434 .owner = THIS_MODULE,
435 .read = read_rio,
436 .write = write_rio,
Alan Cox54592152008-05-22 22:47:31 +0100437 .unlocked_ioctl = ioctl_rio,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438 .open = open_rio,
439 .release = close_rio,
440};
441
442static struct usb_class_driver usb_rio_class = {
Greg Kroah-Hartmand6e5bcf2005-06-20 21:15:16 -0700443 .name = "rio500%d",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444 .fops = &usb_rio_fops,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445 .minor_base = RIO_MINOR,
446};
447
448static int probe_rio(struct usb_interface *intf,
449 const struct usb_device_id *id)
450{
451 struct usb_device *dev = interface_to_usbdev(intf);
452 struct rio_usb_data *rio = &rio_instance;
453 int retval;
454
Greg Kroah-Hartman1b29a372008-08-18 13:21:04 -0700455 dev_info(&intf->dev, "USB Rio found at address %d\n", dev->devnum);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700456
457 retval = usb_register_dev(intf, &usb_rio_class);
458 if (retval) {
459 err("Not able to get a minor for this device.");
460 return -ENOMEM;
461 }
462
463 rio->rio_dev = dev;
464
Jesper Juhl0e8eb0f2005-12-11 20:34:02 +0100465 if (!(rio->obuf = kmalloc(OBUF_SIZE, GFP_KERNEL))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466 err("probe_rio: Not enough memory for the output buffer");
467 usb_deregister_dev(intf, &usb_rio_class);
468 return -ENOMEM;
469 }
470 dbg("probe_rio: obuf address:%p", rio->obuf);
471
Jesper Juhl0e8eb0f2005-12-11 20:34:02 +0100472 if (!(rio->ibuf = kmalloc(IBUF_SIZE, GFP_KERNEL))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473 err("probe_rio: Not enough memory for the input buffer");
474 usb_deregister_dev(intf, &usb_rio_class);
475 kfree(rio->obuf);
476 return -ENOMEM;
477 }
478 dbg("probe_rio: ibuf address:%p", rio->ibuf);
479
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100480 mutex_init(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481
482 usb_set_intfdata (intf, rio);
483 rio->present = 1;
484
485 return 0;
486}
487
488static void disconnect_rio(struct usb_interface *intf)
489{
490 struct rio_usb_data *rio = usb_get_intfdata (intf);
491
492 usb_set_intfdata (intf, NULL);
493 if (rio) {
494 usb_deregister_dev(intf, &usb_rio_class);
495
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100496 mutex_lock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700497 if (rio->isopen) {
498 rio->isopen = 0;
499 /* better let it finish - the release will do whats needed */
500 rio->rio_dev = NULL;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100501 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502 return;
503 }
504 kfree(rio->ibuf);
505 kfree(rio->obuf);
506
Greg Kroah-Hartman1b29a372008-08-18 13:21:04 -0700507 dev_info(&intf->dev, "USB Rio disconnected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508
509 rio->present = 0;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100510 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511 }
512}
513
Németh Márton33b9e162010-01-10 15:34:45 +0100514static const struct usb_device_id rio_table[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700515 { USB_DEVICE(0x0841, 1) }, /* Rio 500 */
516 { } /* Terminating entry */
517};
518
519MODULE_DEVICE_TABLE (usb, rio_table);
520
521static struct usb_driver rio_driver = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522 .name = "rio500",
523 .probe = probe_rio,
524 .disconnect = disconnect_rio,
525 .id_table = rio_table,
526};
527
528static int __init usb_rio_init(void)
529{
530 int retval;
531 retval = usb_register(&rio_driver);
532 if (retval)
533 goto out;
534
Greg Kroah-Hartman1b29a372008-08-18 13:21:04 -0700535 printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
536 DRIVER_DESC "\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537
538out:
539 return retval;
540}
541
542
543static void __exit usb_rio_cleanup(void)
544{
545 struct rio_usb_data *rio = &rio_instance;
546
547 rio->present = 0;
548 usb_deregister(&rio_driver);
549
550
551}
552
553module_init(usb_rio_init);
554module_exit(usb_rio_cleanup);
555
556MODULE_AUTHOR( DRIVER_AUTHOR );
557MODULE_DESCRIPTION( DRIVER_DESC );
558MODULE_LICENSE("GPL");
559