blob: 17e4eecaee734f12dccff1c54cee282ec12862f1 [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;
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
Greg Kroah-Hartman1b29a372008-08-18 13:21:04 -070093 dev_info(&rio->rio_dev->dev, "Rio opened.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -070094
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
Greg Kroah-Hartman1b29a372008-08-18 13:21:04 -0700104 dev_info(&rio->rio_dev->dev, "Rio closed.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105 return 0;
106}
107
Alan Cox54592152008-05-22 22:47:31 +0100108static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109{
110 struct RioCommand rio_cmd;
111 struct rio_usb_data *rio = &rio_instance;
112 void __user *data;
113 unsigned char *buffer;
114 int result, requesttype;
115 int retries;
116 int retval=0;
117
Alan Cox54592152008-05-22 22:47:31 +0100118 lock_kernel();
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100119 mutex_lock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120 /* Sanity check to make sure rio is connected, powered, etc */
Adrian Bunk3328d972007-10-18 12:53:07 +0200121 if (rio->present == 0 || rio->rio_dev == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122 retval = -ENODEV;
123 goto err_out;
124 }
125
126 switch (cmd) {
127 case RIO_RECV_COMMAND:
128 data = (void __user *) arg;
129 if (data == NULL)
130 break;
131 if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand))) {
132 retval = -EFAULT;
133 goto err_out;
134 }
135 if (rio_cmd.length < 0 || rio_cmd.length > PAGE_SIZE) {
136 retval = -EINVAL;
137 goto err_out;
138 }
139 buffer = (unsigned char *) __get_free_page(GFP_KERNEL);
140 if (buffer == NULL) {
141 retval = -ENOMEM;
142 goto err_out;
143 }
144 if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length)) {
145 retval = -EFAULT;
146 free_page((unsigned long) buffer);
147 goto err_out;
148 }
149
150 requesttype = rio_cmd.requesttype | USB_DIR_IN |
151 USB_TYPE_VENDOR | USB_RECIP_DEVICE;
152 dbg
153 ("sending command:reqtype=%0x req=%0x value=%0x index=%0x len=%0x",
154 requesttype, rio_cmd.request, rio_cmd.value,
155 rio_cmd.index, rio_cmd.length);
156 /* Send rio control message */
157 retries = 3;
158 while (retries) {
159 result = usb_control_msg(rio->rio_dev,
160 usb_rcvctrlpipe(rio-> rio_dev, 0),
161 rio_cmd.request,
162 requesttype,
163 rio_cmd.value,
164 rio_cmd.index, buffer,
165 rio_cmd.length,
166 jiffies_to_msecs(rio_cmd.timeout));
167 if (result == -ETIMEDOUT)
168 retries--;
169 else if (result < 0) {
170 err("Error executing ioctrl. code = %d", result);
171 retries = 0;
172 } else {
173 dbg("Executed ioctl. Result = %d (data=%02x)",
174 result, buffer[0]);
175 if (copy_to_user(rio_cmd.buffer, buffer,
176 rio_cmd.length)) {
177 free_page((unsigned long) buffer);
178 retval = -EFAULT;
179 goto err_out;
180 }
181 retries = 0;
182 }
183
184 /* rio_cmd.buffer contains a raw stream of single byte
185 data which has been returned from rio. Data is
186 interpreted at application level. For data that
187 will be cast to data types longer than 1 byte, data
188 will be little_endian and will potentially need to
189 be swapped at the app level */
190
191 }
192 free_page((unsigned long) buffer);
193 break;
194
195 case RIO_SEND_COMMAND:
196 data = (void __user *) arg;
197 if (data == NULL)
198 break;
199 if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand))) {
200 retval = -EFAULT;
201 goto err_out;
202 }
203 if (rio_cmd.length < 0 || rio_cmd.length > PAGE_SIZE) {
204 retval = -EINVAL;
205 goto err_out;
206 }
207 buffer = (unsigned char *) __get_free_page(GFP_KERNEL);
208 if (buffer == NULL) {
209 retval = -ENOMEM;
210 goto err_out;
211 }
212 if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length)) {
213 free_page((unsigned long)buffer);
214 retval = -EFAULT;
215 goto err_out;
216 }
217
218 requesttype = rio_cmd.requesttype | USB_DIR_OUT |
219 USB_TYPE_VENDOR | USB_RECIP_DEVICE;
220 dbg("sending command: reqtype=%0x req=%0x value=%0x index=%0x len=%0x",
221 requesttype, rio_cmd.request, rio_cmd.value,
222 rio_cmd.index, rio_cmd.length);
223 /* Send rio control message */
224 retries = 3;
225 while (retries) {
226 result = usb_control_msg(rio->rio_dev,
227 usb_sndctrlpipe(rio-> rio_dev, 0),
228 rio_cmd.request,
229 requesttype,
230 rio_cmd.value,
231 rio_cmd.index, buffer,
232 rio_cmd.length,
233 jiffies_to_msecs(rio_cmd.timeout));
234 if (result == -ETIMEDOUT)
235 retries--;
236 else if (result < 0) {
237 err("Error executing ioctrl. code = %d", result);
238 retries = 0;
239 } else {
240 dbg("Executed ioctl. Result = %d", result);
241 retries = 0;
242
243 }
244
245 }
246 free_page((unsigned long) buffer);
247 break;
248
249 default:
250 retval = -ENOTTY;
251 break;
252 }
253
254
255err_out:
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100256 mutex_unlock(&(rio->lock));
Alan Cox54592152008-05-22 22:47:31 +0100257 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258 return retval;
259}
260
261static ssize_t
262write_rio(struct file *file, const char __user *buffer,
263 size_t count, loff_t * ppos)
264{
265 DEFINE_WAIT(wait);
266 struct rio_usb_data *rio = &rio_instance;
267
268 unsigned long copy_size;
269 unsigned long bytes_written = 0;
270 unsigned int partial;
271
272 int result = 0;
273 int maxretry;
274 int errn = 0;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100275 int intr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100277 intr = mutex_lock_interruptible(&(rio->lock));
278 if (intr)
279 return -EINTR;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280 /* Sanity check to make sure rio is connected, powered, etc */
Adrian Bunk3328d972007-10-18 12:53:07 +0200281 if (rio->present == 0 || rio->rio_dev == NULL) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100282 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283 return -ENODEV;
284 }
285
286
287
288 do {
289 unsigned long thistime;
290 char *obuf = rio->obuf;
291
292 thistime = copy_size =
293 (count >= OBUF_SIZE) ? OBUF_SIZE : count;
294 if (copy_from_user(rio->obuf, buffer, copy_size)) {
295 errn = -EFAULT;
296 goto error;
297 }
298 maxretry = 5;
299 while (thistime) {
300 if (!rio->rio_dev) {
301 errn = -ENODEV;
302 goto error;
303 }
304 if (signal_pending(current)) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100305 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700306 return bytes_written ? bytes_written : -EINTR;
307 }
308
309 result = usb_bulk_msg(rio->rio_dev,
310 usb_sndbulkpipe(rio->rio_dev, 2),
311 obuf, thistime, &partial, 5000);
312
313 dbg("write stats: result:%d thistime:%lu partial:%u",
314 result, thistime, partial);
315
316 if (result == -ETIMEDOUT) { /* NAK - so hold for a while */
317 if (!maxretry--) {
318 errn = -ETIME;
319 goto error;
320 }
321 prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE);
322 schedule_timeout(NAK_TIMEOUT);
323 finish_wait(&rio->wait_q, &wait);
324 continue;
325 } else if (!result && partial) {
326 obuf += partial;
327 thistime -= partial;
328 } else
329 break;
330 };
331 if (result) {
332 err("Write Whoops - %x", result);
333 errn = -EIO;
334 goto error;
335 }
336 bytes_written += copy_size;
337 count -= copy_size;
338 buffer += copy_size;
339 } while (count > 0);
340
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100341 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342
343 return bytes_written ? bytes_written : -EIO;
344
345error:
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100346 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347 return errn;
348}
349
350static ssize_t
351read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
352{
353 DEFINE_WAIT(wait);
354 struct rio_usb_data *rio = &rio_instance;
355 ssize_t read_count;
356 unsigned int partial;
357 int this_read;
358 int result;
359 int maxretry = 10;
360 char *ibuf;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100361 int intr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700362
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100363 intr = mutex_lock_interruptible(&(rio->lock));
364 if (intr)
365 return -EINTR;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366 /* Sanity check to make sure rio is connected, powered, etc */
Adrian Bunk3328d972007-10-18 12:53:07 +0200367 if (rio->present == 0 || rio->rio_dev == NULL) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100368 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369 return -ENODEV;
370 }
371
372 ibuf = rio->ibuf;
373
374 read_count = 0;
375
376
377 while (count > 0) {
378 if (signal_pending(current)) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100379 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380 return read_count ? read_count : -EINTR;
381 }
382 if (!rio->rio_dev) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100383 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384 return -ENODEV;
385 }
386 this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count;
387
388 result = usb_bulk_msg(rio->rio_dev,
389 usb_rcvbulkpipe(rio->rio_dev, 1),
390 ibuf, this_read, &partial,
391 8000);
392
Greg Kroah-Hartman654f3112005-11-17 09:48:09 -0800393 dbg("read stats: result:%d this_read:%u partial:%u",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394 result, this_read, partial);
395
396 if (partial) {
397 count = this_read = partial;
398 } else if (result == -ETIMEDOUT || result == 15) { /* FIXME: 15 ??? */
399 if (!maxretry--) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100400 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401 err("read_rio: maxretry timeout");
402 return -ETIME;
403 }
404 prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE);
405 schedule_timeout(NAK_TIMEOUT);
406 finish_wait(&rio->wait_q, &wait);
407 continue;
408 } else if (result != -EREMOTEIO) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100409 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410 err("Read Whoops - result:%u partial:%u this_read:%u",
411 result, partial, this_read);
412 return -EIO;
413 } else {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100414 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415 return (0);
416 }
417
418 if (this_read) {
419 if (copy_to_user(buffer, ibuf, this_read)) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100420 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421 return -EFAULT;
422 }
423 count -= this_read;
424 read_count += this_read;
425 buffer += this_read;
426 }
427 }
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100428 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429 return read_count;
430}
431
Alexey Dobriyan828c0952009-10-01 15:43:56 -0700432static const struct file_operations usb_rio_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433 .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
Németh Márton33b9e162010-01-10 15:34:45 +0100513static const struct usb_device_id rio_table[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514 { 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