blob: 88f6abe7362480223f250c514f6868288c029965 [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
92 info("Rio opened.");
93
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
103 info("Rio closed.");
104 return 0;
105}
106
107static int
108ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd,
109 unsigned long arg)
110{
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
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 */
121 if ( rio == NULL ||
122 rio->present == 0 ||
123 rio->rio_dev == NULL )
124 {
125 retval = -ENODEV;
126 goto err_out;
127 }
128
129 switch (cmd) {
130 case RIO_RECV_COMMAND:
131 data = (void __user *) arg;
132 if (data == NULL)
133 break;
134 if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand))) {
135 retval = -EFAULT;
136 goto err_out;
137 }
138 if (rio_cmd.length < 0 || rio_cmd.length > PAGE_SIZE) {
139 retval = -EINVAL;
140 goto err_out;
141 }
142 buffer = (unsigned char *) __get_free_page(GFP_KERNEL);
143 if (buffer == NULL) {
144 retval = -ENOMEM;
145 goto err_out;
146 }
147 if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length)) {
148 retval = -EFAULT;
149 free_page((unsigned long) buffer);
150 goto err_out;
151 }
152
153 requesttype = rio_cmd.requesttype | USB_DIR_IN |
154 USB_TYPE_VENDOR | USB_RECIP_DEVICE;
155 dbg
156 ("sending command:reqtype=%0x req=%0x value=%0x index=%0x len=%0x",
157 requesttype, rio_cmd.request, rio_cmd.value,
158 rio_cmd.index, rio_cmd.length);
159 /* Send rio control message */
160 retries = 3;
161 while (retries) {
162 result = usb_control_msg(rio->rio_dev,
163 usb_rcvctrlpipe(rio-> rio_dev, 0),
164 rio_cmd.request,
165 requesttype,
166 rio_cmd.value,
167 rio_cmd.index, buffer,
168 rio_cmd.length,
169 jiffies_to_msecs(rio_cmd.timeout));
170 if (result == -ETIMEDOUT)
171 retries--;
172 else if (result < 0) {
173 err("Error executing ioctrl. code = %d", result);
174 retries = 0;
175 } else {
176 dbg("Executed ioctl. Result = %d (data=%02x)",
177 result, buffer[0]);
178 if (copy_to_user(rio_cmd.buffer, buffer,
179 rio_cmd.length)) {
180 free_page((unsigned long) buffer);
181 retval = -EFAULT;
182 goto err_out;
183 }
184 retries = 0;
185 }
186
187 /* rio_cmd.buffer contains a raw stream of single byte
188 data which has been returned from rio. Data is
189 interpreted at application level. For data that
190 will be cast to data types longer than 1 byte, data
191 will be little_endian and will potentially need to
192 be swapped at the app level */
193
194 }
195 free_page((unsigned long) buffer);
196 break;
197
198 case RIO_SEND_COMMAND:
199 data = (void __user *) arg;
200 if (data == NULL)
201 break;
202 if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand))) {
203 retval = -EFAULT;
204 goto err_out;
205 }
206 if (rio_cmd.length < 0 || rio_cmd.length > PAGE_SIZE) {
207 retval = -EINVAL;
208 goto err_out;
209 }
210 buffer = (unsigned char *) __get_free_page(GFP_KERNEL);
211 if (buffer == NULL) {
212 retval = -ENOMEM;
213 goto err_out;
214 }
215 if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length)) {
216 free_page((unsigned long)buffer);
217 retval = -EFAULT;
218 goto err_out;
219 }
220
221 requesttype = rio_cmd.requesttype | USB_DIR_OUT |
222 USB_TYPE_VENDOR | USB_RECIP_DEVICE;
223 dbg("sending command: reqtype=%0x req=%0x value=%0x index=%0x len=%0x",
224 requesttype, rio_cmd.request, rio_cmd.value,
225 rio_cmd.index, rio_cmd.length);
226 /* Send rio control message */
227 retries = 3;
228 while (retries) {
229 result = usb_control_msg(rio->rio_dev,
230 usb_sndctrlpipe(rio-> rio_dev, 0),
231 rio_cmd.request,
232 requesttype,
233 rio_cmd.value,
234 rio_cmd.index, buffer,
235 rio_cmd.length,
236 jiffies_to_msecs(rio_cmd.timeout));
237 if (result == -ETIMEDOUT)
238 retries--;
239 else if (result < 0) {
240 err("Error executing ioctrl. code = %d", result);
241 retries = 0;
242 } else {
243 dbg("Executed ioctl. Result = %d", result);
244 retries = 0;
245
246 }
247
248 }
249 free_page((unsigned long) buffer);
250 break;
251
252 default:
253 retval = -ENOTTY;
254 break;
255 }
256
257
258err_out:
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100259 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260 return retval;
261}
262
263static ssize_t
264write_rio(struct file *file, const char __user *buffer,
265 size_t count, loff_t * ppos)
266{
267 DEFINE_WAIT(wait);
268 struct rio_usb_data *rio = &rio_instance;
269
270 unsigned long copy_size;
271 unsigned long bytes_written = 0;
272 unsigned int partial;
273
274 int result = 0;
275 int maxretry;
276 int errn = 0;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100277 int intr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100279 intr = mutex_lock_interruptible(&(rio->lock));
280 if (intr)
281 return -EINTR;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282 /* Sanity check to make sure rio is connected, powered, etc */
283 if ( rio == NULL ||
284 rio->present == 0 ||
285 rio->rio_dev == NULL )
286 {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100287 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288 return -ENODEV;
289 }
290
291
292
293 do {
294 unsigned long thistime;
295 char *obuf = rio->obuf;
296
297 thistime = copy_size =
298 (count >= OBUF_SIZE) ? OBUF_SIZE : count;
299 if (copy_from_user(rio->obuf, buffer, copy_size)) {
300 errn = -EFAULT;
301 goto error;
302 }
303 maxretry = 5;
304 while (thistime) {
305 if (!rio->rio_dev) {
306 errn = -ENODEV;
307 goto error;
308 }
309 if (signal_pending(current)) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100310 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700311 return bytes_written ? bytes_written : -EINTR;
312 }
313
314 result = usb_bulk_msg(rio->rio_dev,
315 usb_sndbulkpipe(rio->rio_dev, 2),
316 obuf, thistime, &partial, 5000);
317
318 dbg("write stats: result:%d thistime:%lu partial:%u",
319 result, thistime, partial);
320
321 if (result == -ETIMEDOUT) { /* NAK - so hold for a while */
322 if (!maxretry--) {
323 errn = -ETIME;
324 goto error;
325 }
326 prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE);
327 schedule_timeout(NAK_TIMEOUT);
328 finish_wait(&rio->wait_q, &wait);
329 continue;
330 } else if (!result && partial) {
331 obuf += partial;
332 thistime -= partial;
333 } else
334 break;
335 };
336 if (result) {
337 err("Write Whoops - %x", result);
338 errn = -EIO;
339 goto error;
340 }
341 bytes_written += copy_size;
342 count -= copy_size;
343 buffer += copy_size;
344 } while (count > 0);
345
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100346 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347
348 return bytes_written ? bytes_written : -EIO;
349
350error:
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100351 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700352 return errn;
353}
354
355static ssize_t
356read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
357{
358 DEFINE_WAIT(wait);
359 struct rio_usb_data *rio = &rio_instance;
360 ssize_t read_count;
361 unsigned int partial;
362 int this_read;
363 int result;
364 int maxretry = 10;
365 char *ibuf;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100366 int intr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100368 intr = mutex_lock_interruptible(&(rio->lock));
369 if (intr)
370 return -EINTR;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 /* Sanity check to make sure rio is connected, powered, etc */
372 if ( rio == NULL ||
373 rio->present == 0 ||
374 rio->rio_dev == NULL )
375 {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100376 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377 return -ENODEV;
378 }
379
380 ibuf = rio->ibuf;
381
382 read_count = 0;
383
384
385 while (count > 0) {
386 if (signal_pending(current)) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100387 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388 return read_count ? read_count : -EINTR;
389 }
390 if (!rio->rio_dev) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100391 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392 return -ENODEV;
393 }
394 this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count;
395
396 result = usb_bulk_msg(rio->rio_dev,
397 usb_rcvbulkpipe(rio->rio_dev, 1),
398 ibuf, this_read, &partial,
399 8000);
400
Greg Kroah-Hartman654f3112005-11-17 09:48:09 -0800401 dbg("read stats: result:%d this_read:%u partial:%u",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402 result, this_read, partial);
403
404 if (partial) {
405 count = this_read = partial;
406 } else if (result == -ETIMEDOUT || result == 15) { /* FIXME: 15 ??? */
407 if (!maxretry--) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100408 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409 err("read_rio: maxretry timeout");
410 return -ETIME;
411 }
412 prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE);
413 schedule_timeout(NAK_TIMEOUT);
414 finish_wait(&rio->wait_q, &wait);
415 continue;
416 } else if (result != -EREMOTEIO) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100417 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418 err("Read Whoops - result:%u partial:%u this_read:%u",
419 result, partial, this_read);
420 return -EIO;
421 } else {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100422 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423 return (0);
424 }
425
426 if (this_read) {
427 if (copy_to_user(buffer, ibuf, this_read)) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100428 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429 return -EFAULT;
430 }
431 count -= this_read;
432 read_count += this_read;
433 buffer += this_read;
434 }
435 }
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100436 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437 return read_count;
438}
439
440static struct
441file_operations usb_rio_fops = {
442 .owner = THIS_MODULE,
443 .read = read_rio,
444 .write = write_rio,
445 .ioctl = ioctl_rio,
446 .open = open_rio,
447 .release = close_rio,
448};
449
450static struct usb_class_driver usb_rio_class = {
Greg Kroah-Hartmand6e5bcf2005-06-20 21:15:16 -0700451 .name = "rio500%d",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452 .fops = &usb_rio_fops,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453 .minor_base = RIO_MINOR,
454};
455
456static int probe_rio(struct usb_interface *intf,
457 const struct usb_device_id *id)
458{
459 struct usb_device *dev = interface_to_usbdev(intf);
460 struct rio_usb_data *rio = &rio_instance;
461 int retval;
462
463 info("USB Rio found at address %d", dev->devnum);
464
465 retval = usb_register_dev(intf, &usb_rio_class);
466 if (retval) {
467 err("Not able to get a minor for this device.");
468 return -ENOMEM;
469 }
470
471 rio->rio_dev = dev;
472
Jesper Juhl0e8eb0f2005-12-11 20:34:02 +0100473 if (!(rio->obuf = kmalloc(OBUF_SIZE, GFP_KERNEL))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474 err("probe_rio: Not enough memory for the output buffer");
475 usb_deregister_dev(intf, &usb_rio_class);
476 return -ENOMEM;
477 }
478 dbg("probe_rio: obuf address:%p", rio->obuf);
479
Jesper Juhl0e8eb0f2005-12-11 20:34:02 +0100480 if (!(rio->ibuf = kmalloc(IBUF_SIZE, GFP_KERNEL))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481 err("probe_rio: Not enough memory for the input buffer");
482 usb_deregister_dev(intf, &usb_rio_class);
483 kfree(rio->obuf);
484 return -ENOMEM;
485 }
486 dbg("probe_rio: ibuf address:%p", rio->ibuf);
487
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100488 mutex_init(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489
490 usb_set_intfdata (intf, rio);
491 rio->present = 1;
492
493 return 0;
494}
495
496static void disconnect_rio(struct usb_interface *intf)
497{
498 struct rio_usb_data *rio = usb_get_intfdata (intf);
499
500 usb_set_intfdata (intf, NULL);
501 if (rio) {
502 usb_deregister_dev(intf, &usb_rio_class);
503
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100504 mutex_lock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505 if (rio->isopen) {
506 rio->isopen = 0;
507 /* better let it finish - the release will do whats needed */
508 rio->rio_dev = NULL;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100509 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510 return;
511 }
512 kfree(rio->ibuf);
513 kfree(rio->obuf);
514
515 info("USB Rio disconnected.");
516
517 rio->present = 0;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100518 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519 }
520}
521
522static struct usb_device_id rio_table [] = {
523 { USB_DEVICE(0x0841, 1) }, /* Rio 500 */
524 { } /* Terminating entry */
525};
526
527MODULE_DEVICE_TABLE (usb, rio_table);
528
529static struct usb_driver rio_driver = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530 .name = "rio500",
531 .probe = probe_rio,
532 .disconnect = disconnect_rio,
533 .id_table = rio_table,
534};
535
536static int __init usb_rio_init(void)
537{
538 int retval;
539 retval = usb_register(&rio_driver);
540 if (retval)
541 goto out;
542
543 info(DRIVER_VERSION ":" DRIVER_DESC);
544
545out:
546 return retval;
547}
548
549
550static void __exit usb_rio_cleanup(void)
551{
552 struct rio_usb_data *rio = &rio_instance;
553
554 rio->present = 0;
555 usb_deregister(&rio_driver);
556
557
558}
559
560module_init(usb_rio_init);
561module_exit(usb_rio_cleanup);
562
563MODULE_AUTHOR( DRIVER_AUTHOR );
564MODULE_DESCRIPTION( DRIVER_DESC );
565MODULE_LICENSE("GPL");
566