blob: a85771b1563d2c6151340b16da2319064da57cb4 [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 Neukum511e2d02010-01-14 16:10:38 +010080
81 /* against disconnect() */
Oliver Neukum86266452010-01-13 15:33:15 +010082 lock_kernel();
Oliver Neukum2cba72f2006-12-15 23:48:56 +010083 mutex_lock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -070084
85 if (rio->isopen || !rio->present) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +010086 mutex_unlock(&(rio->lock));
Oliver Neukum511e2d02010-01-14 16:10:38 +010087 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -070088 return -EBUSY;
89 }
90 rio->isopen = 1;
91
92 init_waitqueue_head(&rio->wait_q);
93
Oliver Neukum2cba72f2006-12-15 23:48:56 +010094 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -070095
Greg Kroah-Hartman1b29a372008-08-18 13:21:04 -070096 dev_info(&rio->rio_dev->dev, "Rio opened.\n");
Oliver Neukum86266452010-01-13 15:33:15 +010097 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -070098
99 return 0;
100}
101
102static int close_rio(struct inode *inode, struct file *file)
103{
104 struct rio_usb_data *rio = &rio_instance;
105
106 rio->isopen = 0;
107
Greg Kroah-Hartman1b29a372008-08-18 13:21:04 -0700108 dev_info(&rio->rio_dev->dev, "Rio closed.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109 return 0;
110}
111
Alan Cox54592152008-05-22 22:47:31 +0100112static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113{
114 struct RioCommand rio_cmd;
115 struct rio_usb_data *rio = &rio_instance;
116 void __user *data;
117 unsigned char *buffer;
118 int result, requesttype;
119 int retries;
120 int retval=0;
121
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100122 mutex_lock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123 /* Sanity check to make sure rio is connected, powered, etc */
Adrian Bunk3328d972007-10-18 12:53:07 +0200124 if (rio->present == 0 || rio->rio_dev == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125 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 */
Adrian Bunk3328d972007-10-18 12:53:07 +0200283 if (rio->present == 0 || rio->rio_dev == NULL) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100284 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285 return -ENODEV;
286 }
287
288
289
290 do {
291 unsigned long thistime;
292 char *obuf = rio->obuf;
293
294 thistime = copy_size =
295 (count >= OBUF_SIZE) ? OBUF_SIZE : count;
296 if (copy_from_user(rio->obuf, buffer, copy_size)) {
297 errn = -EFAULT;
298 goto error;
299 }
300 maxretry = 5;
301 while (thistime) {
302 if (!rio->rio_dev) {
303 errn = -ENODEV;
304 goto error;
305 }
306 if (signal_pending(current)) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100307 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700308 return bytes_written ? bytes_written : -EINTR;
309 }
310
311 result = usb_bulk_msg(rio->rio_dev,
312 usb_sndbulkpipe(rio->rio_dev, 2),
313 obuf, thistime, &partial, 5000);
314
315 dbg("write stats: result:%d thistime:%lu partial:%u",
316 result, thistime, partial);
317
318 if (result == -ETIMEDOUT) { /* NAK - so hold for a while */
319 if (!maxretry--) {
320 errn = -ETIME;
321 goto error;
322 }
323 prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE);
324 schedule_timeout(NAK_TIMEOUT);
325 finish_wait(&rio->wait_q, &wait);
326 continue;
327 } else if (!result && partial) {
328 obuf += partial;
329 thistime -= partial;
330 } else
331 break;
332 };
333 if (result) {
334 err("Write Whoops - %x", result);
335 errn = -EIO;
336 goto error;
337 }
338 bytes_written += copy_size;
339 count -= copy_size;
340 buffer += copy_size;
341 } while (count > 0);
342
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100343 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344
345 return bytes_written ? bytes_written : -EIO;
346
347error:
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100348 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349 return errn;
350}
351
352static ssize_t
353read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
354{
355 DEFINE_WAIT(wait);
356 struct rio_usb_data *rio = &rio_instance;
357 ssize_t read_count;
358 unsigned int partial;
359 int this_read;
360 int result;
361 int maxretry = 10;
362 char *ibuf;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100363 int intr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700364
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100365 intr = mutex_lock_interruptible(&(rio->lock));
366 if (intr)
367 return -EINTR;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368 /* Sanity check to make sure rio is connected, powered, etc */
Adrian Bunk3328d972007-10-18 12:53:07 +0200369 if (rio->present == 0 || rio->rio_dev == NULL) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100370 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 return -ENODEV;
372 }
373
374 ibuf = rio->ibuf;
375
376 read_count = 0;
377
378
379 while (count > 0) {
380 if (signal_pending(current)) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100381 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382 return read_count ? read_count : -EINTR;
383 }
384 if (!rio->rio_dev) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100385 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386 return -ENODEV;
387 }
388 this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count;
389
390 result = usb_bulk_msg(rio->rio_dev,
391 usb_rcvbulkpipe(rio->rio_dev, 1),
392 ibuf, this_read, &partial,
393 8000);
394
Greg Kroah-Hartman654f3112005-11-17 09:48:09 -0800395 dbg("read stats: result:%d this_read:%u partial:%u",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396 result, this_read, partial);
397
398 if (partial) {
399 count = this_read = partial;
400 } else if (result == -ETIMEDOUT || result == 15) { /* FIXME: 15 ??? */
401 if (!maxretry--) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100402 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403 err("read_rio: maxretry timeout");
404 return -ETIME;
405 }
406 prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE);
407 schedule_timeout(NAK_TIMEOUT);
408 finish_wait(&rio->wait_q, &wait);
409 continue;
410 } else if (result != -EREMOTEIO) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100411 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412 err("Read Whoops - result:%u partial:%u this_read:%u",
413 result, partial, this_read);
414 return -EIO;
415 } else {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100416 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417 return (0);
418 }
419
420 if (this_read) {
421 if (copy_to_user(buffer, ibuf, this_read)) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100422 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423 return -EFAULT;
424 }
425 count -= this_read;
426 read_count += this_read;
427 buffer += this_read;
428 }
429 }
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100430 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700431 return read_count;
432}
433
Alexey Dobriyan828c0952009-10-01 15:43:56 -0700434static const struct file_operations usb_rio_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435 .owner = THIS_MODULE,
436 .read = read_rio,
437 .write = write_rio,
Alan Cox54592152008-05-22 22:47:31 +0100438 .unlocked_ioctl = ioctl_rio,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439 .open = open_rio,
440 .release = close_rio,
441};
442
443static struct usb_class_driver usb_rio_class = {
Greg Kroah-Hartmand6e5bcf2005-06-20 21:15:16 -0700444 .name = "rio500%d",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445 .fops = &usb_rio_fops,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446 .minor_base = RIO_MINOR,
447};
448
449static int probe_rio(struct usb_interface *intf,
450 const struct usb_device_id *id)
451{
452 struct usb_device *dev = interface_to_usbdev(intf);
453 struct rio_usb_data *rio = &rio_instance;
454 int retval;
455
Greg Kroah-Hartman1b29a372008-08-18 13:21:04 -0700456 dev_info(&intf->dev, "USB Rio found at address %d\n", dev->devnum);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700457
458 retval = usb_register_dev(intf, &usb_rio_class);
459 if (retval) {
460 err("Not able to get a minor for this device.");
461 return -ENOMEM;
462 }
463
464 rio->rio_dev = dev;
465
Jesper Juhl0e8eb0f2005-12-11 20:34:02 +0100466 if (!(rio->obuf = kmalloc(OBUF_SIZE, GFP_KERNEL))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700467 err("probe_rio: Not enough memory for the output buffer");
468 usb_deregister_dev(intf, &usb_rio_class);
469 return -ENOMEM;
470 }
471 dbg("probe_rio: obuf address:%p", rio->obuf);
472
Jesper Juhl0e8eb0f2005-12-11 20:34:02 +0100473 if (!(rio->ibuf = kmalloc(IBUF_SIZE, GFP_KERNEL))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474 err("probe_rio: Not enough memory for the input buffer");
475 usb_deregister_dev(intf, &usb_rio_class);
476 kfree(rio->obuf);
477 return -ENOMEM;
478 }
479 dbg("probe_rio: ibuf address:%p", rio->ibuf);
480
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100481 mutex_init(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700482
483 usb_set_intfdata (intf, rio);
484 rio->present = 1;
485
486 return 0;
487}
488
489static void disconnect_rio(struct usb_interface *intf)
490{
491 struct rio_usb_data *rio = usb_get_intfdata (intf);
492
493 usb_set_intfdata (intf, NULL);
Oliver Neukum511e2d02010-01-14 16:10:38 +0100494 lock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700495 if (rio) {
496 usb_deregister_dev(intf, &usb_rio_class);
497
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100498 mutex_lock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499 if (rio->isopen) {
500 rio->isopen = 0;
501 /* better let it finish - the release will do whats needed */
502 rio->rio_dev = NULL;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100503 mutex_unlock(&(rio->lock));
Oliver Neukum511e2d02010-01-14 16:10:38 +0100504 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505 return;
506 }
507 kfree(rio->ibuf);
508 kfree(rio->obuf);
509
Greg Kroah-Hartman1b29a372008-08-18 13:21:04 -0700510 dev_info(&intf->dev, "USB Rio disconnected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511
512 rio->present = 0;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100513 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514 }
Oliver Neukum511e2d02010-01-14 16:10:38 +0100515 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516}
517
Németh Márton33b9e162010-01-10 15:34:45 +0100518static const struct usb_device_id rio_table[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519 { USB_DEVICE(0x0841, 1) }, /* Rio 500 */
520 { } /* Terminating entry */
521};
522
523MODULE_DEVICE_TABLE (usb, rio_table);
524
525static struct usb_driver rio_driver = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526 .name = "rio500",
527 .probe = probe_rio,
528 .disconnect = disconnect_rio,
529 .id_table = rio_table,
530};
531
532static int __init usb_rio_init(void)
533{
534 int retval;
535 retval = usb_register(&rio_driver);
536 if (retval)
537 goto out;
538
Greg Kroah-Hartman1b29a372008-08-18 13:21:04 -0700539 printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
540 DRIVER_DESC "\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541
542out:
543 return retval;
544}
545
546
547static void __exit usb_rio_cleanup(void)
548{
549 struct rio_usb_data *rio = &rio_instance;
550
551 rio->present = 0;
552 usb_deregister(&rio_driver);
553
554
555}
556
557module_init(usb_rio_init);
558module_exit(usb_rio_cleanup);
559
560MODULE_AUTHOR( DRIVER_AUTHOR );
561MODULE_DESCRIPTION( DRIVER_DESC );
562MODULE_LICENSE("GPL");
563