blob: b9b356a9dd11bd1c99353e28f0e3d2a1a151316f [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>
Arnd Bergmann925ce682010-07-11 23:18:56 +020035#include <linux/mutex.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
Arnd Bergmann925ce682010-07-11 23:18:56 +020075static DEFINE_MUTEX(rio500_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -070076static struct rio_usb_data rio_instance;
77
78static int open_rio(struct inode *inode, struct file *file)
79{
80 struct rio_usb_data *rio = &rio_instance;
Oliver Neukum511e2d02010-01-14 16:10:38 +010081
82 /* against disconnect() */
Arnd Bergmann925ce682010-07-11 23:18:56 +020083 mutex_lock(&rio500_mutex);
Oliver Neukum2cba72f2006-12-15 23:48:56 +010084 mutex_lock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -070085
86 if (rio->isopen || !rio->present) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +010087 mutex_unlock(&(rio->lock));
Arnd Bergmann925ce682010-07-11 23:18:56 +020088 mutex_unlock(&rio500_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -070089 return -EBUSY;
90 }
91 rio->isopen = 1;
92
93 init_waitqueue_head(&rio->wait_q);
94
Oliver Neukum2cba72f2006-12-15 23:48:56 +010095 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -070096
Greg Kroah-Hartman1b29a372008-08-18 13:21:04 -070097 dev_info(&rio->rio_dev->dev, "Rio opened.\n");
Arnd Bergmann925ce682010-07-11 23:18:56 +020098 mutex_unlock(&rio500_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -070099
100 return 0;
101}
102
103static int close_rio(struct inode *inode, struct file *file)
104{
105 struct rio_usb_data *rio = &rio_instance;
106
107 rio->isopen = 0;
108
Greg Kroah-Hartman1b29a372008-08-18 13:21:04 -0700109 dev_info(&rio->rio_dev->dev, "Rio closed.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110 return 0;
111}
112
Alan Cox54592152008-05-22 22:47:31 +0100113static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114{
115 struct RioCommand rio_cmd;
116 struct rio_usb_data *rio = &rio_instance;
117 void __user *data;
118 unsigned char *buffer;
119 int result, requesttype;
120 int retries;
121 int retval=0;
122
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100123 mutex_lock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124 /* Sanity check to make sure rio is connected, powered, etc */
Adrian Bunk3328d972007-10-18 12:53:07 +0200125 if (rio->present == 0 || rio->rio_dev == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126 retval = -ENODEV;
127 goto err_out;
128 }
129
130 switch (cmd) {
131 case RIO_RECV_COMMAND:
132 data = (void __user *) arg;
133 if (data == NULL)
134 break;
135 if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand))) {
136 retval = -EFAULT;
137 goto err_out;
138 }
139 if (rio_cmd.length < 0 || rio_cmd.length > PAGE_SIZE) {
140 retval = -EINVAL;
141 goto err_out;
142 }
143 buffer = (unsigned char *) __get_free_page(GFP_KERNEL);
144 if (buffer == NULL) {
145 retval = -ENOMEM;
146 goto err_out;
147 }
148 if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length)) {
149 retval = -EFAULT;
150 free_page((unsigned long) buffer);
151 goto err_out;
152 }
153
154 requesttype = rio_cmd.requesttype | USB_DIR_IN |
155 USB_TYPE_VENDOR | USB_RECIP_DEVICE;
Greg Kroah-Hartmane1a344d2012-05-01 21:33:59 -0700156 dev_dbg(&rio->rio_dev->dev,
157 "sending command:reqtype=%0x req=%0x value=%0x index=%0x len=%0x\n",
158 requesttype, rio_cmd.request, rio_cmd.value,
159 rio_cmd.index, rio_cmd.length);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700160 /* Send rio control message */
161 retries = 3;
162 while (retries) {
163 result = usb_control_msg(rio->rio_dev,
164 usb_rcvctrlpipe(rio-> rio_dev, 0),
165 rio_cmd.request,
166 requesttype,
167 rio_cmd.value,
168 rio_cmd.index, buffer,
169 rio_cmd.length,
170 jiffies_to_msecs(rio_cmd.timeout));
171 if (result == -ETIMEDOUT)
172 retries--;
173 else if (result < 0) {
Greg Kroah-Hartmanc41fba12012-04-20 16:53:48 -0700174 dev_err(&rio->rio_dev->dev,
175 "Error executing ioctrl. code = %d\n",
176 result);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700177 retries = 0;
178 } else {
Greg Kroah-Hartmane1a344d2012-05-01 21:33:59 -0700179 dev_dbg(&rio->rio_dev->dev,
180 "Executed ioctl. Result = %d (data=%02x)\n",
181 result, buffer[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182 if (copy_to_user(rio_cmd.buffer, buffer,
183 rio_cmd.length)) {
184 free_page((unsigned long) buffer);
185 retval = -EFAULT;
186 goto err_out;
187 }
188 retries = 0;
189 }
190
191 /* rio_cmd.buffer contains a raw stream of single byte
192 data which has been returned from rio. Data is
193 interpreted at application level. For data that
194 will be cast to data types longer than 1 byte, data
195 will be little_endian and will potentially need to
196 be swapped at the app level */
197
198 }
199 free_page((unsigned long) buffer);
200 break;
201
202 case RIO_SEND_COMMAND:
203 data = (void __user *) arg;
204 if (data == NULL)
205 break;
206 if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand))) {
207 retval = -EFAULT;
208 goto err_out;
209 }
210 if (rio_cmd.length < 0 || rio_cmd.length > PAGE_SIZE) {
211 retval = -EINVAL;
212 goto err_out;
213 }
214 buffer = (unsigned char *) __get_free_page(GFP_KERNEL);
215 if (buffer == NULL) {
216 retval = -ENOMEM;
217 goto err_out;
218 }
219 if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length)) {
220 free_page((unsigned long)buffer);
221 retval = -EFAULT;
222 goto err_out;
223 }
224
225 requesttype = rio_cmd.requesttype | USB_DIR_OUT |
226 USB_TYPE_VENDOR | USB_RECIP_DEVICE;
Greg Kroah-Hartmane1a344d2012-05-01 21:33:59 -0700227 dev_dbg(&rio->rio_dev->dev,
228 "sending command: reqtype=%0x req=%0x value=%0x index=%0x len=%0x\n",
229 requesttype, rio_cmd.request, rio_cmd.value,
230 rio_cmd.index, rio_cmd.length);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700231 /* Send rio control message */
232 retries = 3;
233 while (retries) {
234 result = usb_control_msg(rio->rio_dev,
235 usb_sndctrlpipe(rio-> rio_dev, 0),
236 rio_cmd.request,
237 requesttype,
238 rio_cmd.value,
239 rio_cmd.index, buffer,
240 rio_cmd.length,
241 jiffies_to_msecs(rio_cmd.timeout));
242 if (result == -ETIMEDOUT)
243 retries--;
244 else if (result < 0) {
Greg Kroah-Hartmanc41fba12012-04-20 16:53:48 -0700245 dev_err(&rio->rio_dev->dev,
246 "Error executing ioctrl. code = %d\n",
247 result);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700248 retries = 0;
249 } else {
Greg Kroah-Hartmane1a344d2012-05-01 21:33:59 -0700250 dev_dbg(&rio->rio_dev->dev,
251 "Executed ioctl. Result = %d\n", result);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252 retries = 0;
253
254 }
255
256 }
257 free_page((unsigned long) buffer);
258 break;
259
260 default:
261 retval = -ENOTTY;
262 break;
263 }
264
265
266err_out:
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100267 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268 return retval;
269}
270
271static ssize_t
272write_rio(struct file *file, const char __user *buffer,
273 size_t count, loff_t * ppos)
274{
275 DEFINE_WAIT(wait);
276 struct rio_usb_data *rio = &rio_instance;
277
278 unsigned long copy_size;
279 unsigned long bytes_written = 0;
280 unsigned int partial;
281
282 int result = 0;
283 int maxretry;
284 int errn = 0;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100285 int intr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100287 intr = mutex_lock_interruptible(&(rio->lock));
288 if (intr)
289 return -EINTR;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290 /* Sanity check to make sure rio is connected, powered, etc */
Adrian Bunk3328d972007-10-18 12:53:07 +0200291 if (rio->present == 0 || rio->rio_dev == NULL) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100292 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293 return -ENODEV;
294 }
295
296
297
298 do {
299 unsigned long thistime;
300 char *obuf = rio->obuf;
301
302 thistime = copy_size =
303 (count >= OBUF_SIZE) ? OBUF_SIZE : count;
304 if (copy_from_user(rio->obuf, buffer, copy_size)) {
305 errn = -EFAULT;
306 goto error;
307 }
308 maxretry = 5;
309 while (thistime) {
310 if (!rio->rio_dev) {
311 errn = -ENODEV;
312 goto error;
313 }
314 if (signal_pending(current)) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100315 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700316 return bytes_written ? bytes_written : -EINTR;
317 }
318
319 result = usb_bulk_msg(rio->rio_dev,
320 usb_sndbulkpipe(rio->rio_dev, 2),
321 obuf, thistime, &partial, 5000);
322
Greg Kroah-Hartmane1a344d2012-05-01 21:33:59 -0700323 dev_dbg(&rio->rio_dev->dev,
324 "write stats: result:%d thistime:%lu partial:%u\n",
325 result, thistime, partial);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326
327 if (result == -ETIMEDOUT) { /* NAK - so hold for a while */
328 if (!maxretry--) {
329 errn = -ETIME;
330 goto error;
331 }
332 prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE);
333 schedule_timeout(NAK_TIMEOUT);
334 finish_wait(&rio->wait_q, &wait);
335 continue;
336 } else if (!result && partial) {
337 obuf += partial;
338 thistime -= partial;
339 } else
340 break;
Peter Senna Tschudin17e67912012-09-12 19:03:20 +0200341 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342 if (result) {
Greg Kroah-Hartmanc41fba12012-04-20 16:53:48 -0700343 dev_err(&rio->rio_dev->dev, "Write Whoops - %x\n",
344 result);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700345 errn = -EIO;
346 goto error;
347 }
348 bytes_written += copy_size;
349 count -= copy_size;
350 buffer += copy_size;
351 } while (count > 0);
352
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100353 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354
355 return bytes_written ? bytes_written : -EIO;
356
357error:
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100358 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359 return errn;
360}
361
362static ssize_t
363read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
364{
365 DEFINE_WAIT(wait);
366 struct rio_usb_data *rio = &rio_instance;
367 ssize_t read_count;
368 unsigned int partial;
369 int this_read;
370 int result;
371 int maxretry = 10;
372 char *ibuf;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100373 int intr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100375 intr = mutex_lock_interruptible(&(rio->lock));
376 if (intr)
377 return -EINTR;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378 /* Sanity check to make sure rio is connected, powered, etc */
Adrian Bunk3328d972007-10-18 12:53:07 +0200379 if (rio->present == 0 || rio->rio_dev == NULL) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100380 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381 return -ENODEV;
382 }
383
384 ibuf = rio->ibuf;
385
386 read_count = 0;
387
388
389 while (count > 0) {
390 if (signal_pending(current)) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100391 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392 return read_count ? read_count : -EINTR;
393 }
394 if (!rio->rio_dev) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100395 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396 return -ENODEV;
397 }
398 this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count;
399
400 result = usb_bulk_msg(rio->rio_dev,
401 usb_rcvbulkpipe(rio->rio_dev, 1),
402 ibuf, this_read, &partial,
403 8000);
404
Greg Kroah-Hartmane1a344d2012-05-01 21:33:59 -0700405 dev_dbg(&rio->rio_dev->dev,
406 "read stats: result:%d this_read:%u partial:%u\n",
407 result, this_read, partial);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408
409 if (partial) {
410 count = this_read = partial;
411 } else if (result == -ETIMEDOUT || result == 15) { /* FIXME: 15 ??? */
412 if (!maxretry--) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100413 mutex_unlock(&(rio->lock));
Greg Kroah-Hartmanc41fba12012-04-20 16:53:48 -0700414 dev_err(&rio->rio_dev->dev,
415 "read_rio: maxretry timeout\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416 return -ETIME;
417 }
418 prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE);
419 schedule_timeout(NAK_TIMEOUT);
420 finish_wait(&rio->wait_q, &wait);
421 continue;
422 } else if (result != -EREMOTEIO) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100423 mutex_unlock(&(rio->lock));
Greg Kroah-Hartmanc41fba12012-04-20 16:53:48 -0700424 dev_err(&rio->rio_dev->dev,
425 "Read Whoops - result:%u partial:%u this_read:%u\n",
426 result, partial, this_read);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427 return -EIO;
428 } else {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100429 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430 return (0);
431 }
432
433 if (this_read) {
434 if (copy_to_user(buffer, ibuf, this_read)) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100435 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700436 return -EFAULT;
437 }
438 count -= this_read;
439 read_count += this_read;
440 buffer += this_read;
441 }
442 }
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100443 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444 return read_count;
445}
446
Alexey Dobriyan828c0952009-10-01 15:43:56 -0700447static const struct file_operations usb_rio_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448 .owner = THIS_MODULE,
449 .read = read_rio,
450 .write = write_rio,
Alan Cox54592152008-05-22 22:47:31 +0100451 .unlocked_ioctl = ioctl_rio,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452 .open = open_rio,
453 .release = close_rio,
Arnd Bergmann6038f372010-08-15 18:52:59 +0200454 .llseek = noop_llseek,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455};
456
457static struct usb_class_driver usb_rio_class = {
Greg Kroah-Hartmand6e5bcf2005-06-20 21:15:16 -0700458 .name = "rio500%d",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459 .fops = &usb_rio_fops,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700460 .minor_base = RIO_MINOR,
461};
462
463static int probe_rio(struct usb_interface *intf,
464 const struct usb_device_id *id)
465{
466 struct usb_device *dev = interface_to_usbdev(intf);
467 struct rio_usb_data *rio = &rio_instance;
468 int retval;
469
Greg Kroah-Hartman1b29a372008-08-18 13:21:04 -0700470 dev_info(&intf->dev, "USB Rio found at address %d\n", dev->devnum);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700471
472 retval = usb_register_dev(intf, &usb_rio_class);
473 if (retval) {
Greg Kroah-Hartmanc41fba12012-04-20 16:53:48 -0700474 dev_err(&dev->dev,
475 "Not able to get a minor for this device.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476 return -ENOMEM;
477 }
478
479 rio->rio_dev = dev;
480
Jesper Juhl0e8eb0f2005-12-11 20:34:02 +0100481 if (!(rio->obuf = kmalloc(OBUF_SIZE, GFP_KERNEL))) {
Greg Kroah-Hartmanc41fba12012-04-20 16:53:48 -0700482 dev_err(&dev->dev,
483 "probe_rio: Not enough memory for the output buffer\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700484 usb_deregister_dev(intf, &usb_rio_class);
485 return -ENOMEM;
486 }
Greg Kroah-Hartmane1a344d2012-05-01 21:33:59 -0700487 dev_dbg(&intf->dev, "obuf address:%p\n", rio->obuf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700488
Jesper Juhl0e8eb0f2005-12-11 20:34:02 +0100489 if (!(rio->ibuf = kmalloc(IBUF_SIZE, GFP_KERNEL))) {
Greg Kroah-Hartmanc41fba12012-04-20 16:53:48 -0700490 dev_err(&dev->dev,
491 "probe_rio: Not enough memory for the input buffer\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700492 usb_deregister_dev(intf, &usb_rio_class);
493 kfree(rio->obuf);
494 return -ENOMEM;
495 }
Greg Kroah-Hartmane1a344d2012-05-01 21:33:59 -0700496 dev_dbg(&intf->dev, "ibuf address:%p\n", rio->ibuf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700497
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100498 mutex_init(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499
500 usb_set_intfdata (intf, rio);
501 rio->present = 1;
502
503 return 0;
504}
505
506static void disconnect_rio(struct usb_interface *intf)
507{
508 struct rio_usb_data *rio = usb_get_intfdata (intf);
509
510 usb_set_intfdata (intf, NULL);
Arnd Bergmann925ce682010-07-11 23:18:56 +0200511 mutex_lock(&rio500_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700512 if (rio) {
513 usb_deregister_dev(intf, &usb_rio_class);
514
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100515 mutex_lock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516 if (rio->isopen) {
517 rio->isopen = 0;
518 /* better let it finish - the release will do whats needed */
519 rio->rio_dev = NULL;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100520 mutex_unlock(&(rio->lock));
Arnd Bergmann925ce682010-07-11 23:18:56 +0200521 mutex_unlock(&rio500_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522 return;
523 }
524 kfree(rio->ibuf);
525 kfree(rio->obuf);
526
Greg Kroah-Hartman1b29a372008-08-18 13:21:04 -0700527 dev_info(&intf->dev, "USB Rio disconnected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528
529 rio->present = 0;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100530 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531 }
Arnd Bergmann925ce682010-07-11 23:18:56 +0200532 mutex_unlock(&rio500_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533}
534
Németh Márton33b9e162010-01-10 15:34:45 +0100535static const struct usb_device_id rio_table[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536 { USB_DEVICE(0x0841, 1) }, /* Rio 500 */
537 { } /* Terminating entry */
538};
539
540MODULE_DEVICE_TABLE (usb, rio_table);
541
542static struct usb_driver rio_driver = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543 .name = "rio500",
544 .probe = probe_rio,
545 .disconnect = disconnect_rio,
546 .id_table = rio_table,
547};
548
Greg Kroah-Hartman65db4302011-11-18 09:34:02 -0800549module_usb_driver(rio_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700550
551MODULE_AUTHOR( DRIVER_AUTHOR );
552MODULE_DESCRIPTION( DRIVER_DESC );
553MODULE_LICENSE("GPL");
554