blob: 13731d5126248b280a60471cd5348a36e5802c05 [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>
Linus Torvalds1da177e2005-04-16 15:20:36 -070039#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
Arnd Bergmann925ce682010-07-11 23:18:56 +020074static DEFINE_MUTEX(rio500_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -070075static 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() */
Arnd Bergmann925ce682010-07-11 23:18:56 +020082 mutex_lock(&rio500_mutex);
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));
Arnd Bergmann925ce682010-07-11 23:18:56 +020087 mutex_unlock(&rio500_mutex);
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");
Arnd Bergmann925ce682010-07-11 23:18:56 +020097 mutex_unlock(&rio500_mutex);
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;
Greg Kroah-Hartmane1a344d2012-05-01 21:33:59 -0700155 dev_dbg(&rio->rio_dev->dev,
156 "sending command:reqtype=%0x req=%0x value=%0x index=%0x len=%0x\n",
157 requesttype, rio_cmd.request, rio_cmd.value,
158 rio_cmd.index, rio_cmd.length);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700159 /* 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) {
Greg Kroah-Hartmanc41fba12012-04-20 16:53:48 -0700173 dev_err(&rio->rio_dev->dev,
174 "Error executing ioctrl. code = %d\n",
175 result);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700176 retries = 0;
177 } else {
Greg Kroah-Hartmane1a344d2012-05-01 21:33:59 -0700178 dev_dbg(&rio->rio_dev->dev,
179 "Executed ioctl. Result = %d (data=%02x)\n",
180 result, buffer[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181 if (copy_to_user(rio_cmd.buffer, buffer,
182 rio_cmd.length)) {
183 free_page((unsigned long) buffer);
184 retval = -EFAULT;
185 goto err_out;
186 }
187 retries = 0;
188 }
189
190 /* rio_cmd.buffer contains a raw stream of single byte
191 data which has been returned from rio. Data is
192 interpreted at application level. For data that
193 will be cast to data types longer than 1 byte, data
194 will be little_endian and will potentially need to
195 be swapped at the app level */
196
197 }
198 free_page((unsigned long) buffer);
199 break;
200
201 case RIO_SEND_COMMAND:
202 data = (void __user *) arg;
203 if (data == NULL)
204 break;
205 if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand))) {
206 retval = -EFAULT;
207 goto err_out;
208 }
209 if (rio_cmd.length < 0 || rio_cmd.length > PAGE_SIZE) {
210 retval = -EINVAL;
211 goto err_out;
212 }
213 buffer = (unsigned char *) __get_free_page(GFP_KERNEL);
214 if (buffer == NULL) {
215 retval = -ENOMEM;
216 goto err_out;
217 }
218 if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length)) {
219 free_page((unsigned long)buffer);
220 retval = -EFAULT;
221 goto err_out;
222 }
223
224 requesttype = rio_cmd.requesttype | USB_DIR_OUT |
225 USB_TYPE_VENDOR | USB_RECIP_DEVICE;
Greg Kroah-Hartmane1a344d2012-05-01 21:33:59 -0700226 dev_dbg(&rio->rio_dev->dev,
227 "sending command: reqtype=%0x req=%0x value=%0x index=%0x len=%0x\n",
228 requesttype, rio_cmd.request, rio_cmd.value,
229 rio_cmd.index, rio_cmd.length);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230 /* Send rio control message */
231 retries = 3;
232 while (retries) {
233 result = usb_control_msg(rio->rio_dev,
234 usb_sndctrlpipe(rio-> rio_dev, 0),
235 rio_cmd.request,
236 requesttype,
237 rio_cmd.value,
238 rio_cmd.index, buffer,
239 rio_cmd.length,
240 jiffies_to_msecs(rio_cmd.timeout));
241 if (result == -ETIMEDOUT)
242 retries--;
243 else if (result < 0) {
Greg Kroah-Hartmanc41fba12012-04-20 16:53:48 -0700244 dev_err(&rio->rio_dev->dev,
245 "Error executing ioctrl. code = %d\n",
246 result);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247 retries = 0;
248 } else {
Greg Kroah-Hartmane1a344d2012-05-01 21:33:59 -0700249 dev_dbg(&rio->rio_dev->dev,
250 "Executed ioctl. Result = %d\n", result);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251 retries = 0;
252
253 }
254
255 }
256 free_page((unsigned long) buffer);
257 break;
258
259 default:
260 retval = -ENOTTY;
261 break;
262 }
263
264
265err_out:
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100266 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267 return retval;
268}
269
270static ssize_t
271write_rio(struct file *file, const char __user *buffer,
272 size_t count, loff_t * ppos)
273{
274 DEFINE_WAIT(wait);
275 struct rio_usb_data *rio = &rio_instance;
276
277 unsigned long copy_size;
278 unsigned long bytes_written = 0;
279 unsigned int partial;
280
281 int result = 0;
282 int maxretry;
283 int errn = 0;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100284 int intr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100286 intr = mutex_lock_interruptible(&(rio->lock));
287 if (intr)
288 return -EINTR;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700289 /* Sanity check to make sure rio is connected, powered, etc */
Adrian Bunk3328d972007-10-18 12:53:07 +0200290 if (rio->present == 0 || rio->rio_dev == NULL) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100291 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292 return -ENODEV;
293 }
294
295
296
297 do {
298 unsigned long thistime;
299 char *obuf = rio->obuf;
300
301 thistime = copy_size =
302 (count >= OBUF_SIZE) ? OBUF_SIZE : count;
303 if (copy_from_user(rio->obuf, buffer, copy_size)) {
304 errn = -EFAULT;
305 goto error;
306 }
307 maxretry = 5;
308 while (thistime) {
309 if (!rio->rio_dev) {
310 errn = -ENODEV;
311 goto error;
312 }
313 if (signal_pending(current)) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100314 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700315 return bytes_written ? bytes_written : -EINTR;
316 }
317
318 result = usb_bulk_msg(rio->rio_dev,
319 usb_sndbulkpipe(rio->rio_dev, 2),
320 obuf, thistime, &partial, 5000);
321
Greg Kroah-Hartmane1a344d2012-05-01 21:33:59 -0700322 dev_dbg(&rio->rio_dev->dev,
323 "write stats: result:%d thistime:%lu partial:%u\n",
324 result, thistime, partial);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325
326 if (result == -ETIMEDOUT) { /* NAK - so hold for a while */
327 if (!maxretry--) {
328 errn = -ETIME;
329 goto error;
330 }
331 prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE);
332 schedule_timeout(NAK_TIMEOUT);
333 finish_wait(&rio->wait_q, &wait);
334 continue;
335 } else if (!result && partial) {
336 obuf += partial;
337 thistime -= partial;
338 } else
339 break;
Peter Senna Tschudin17e67912012-09-12 19:03:20 +0200340 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341 if (result) {
Greg Kroah-Hartmanc41fba12012-04-20 16:53:48 -0700342 dev_err(&rio->rio_dev->dev, "Write Whoops - %x\n",
343 result);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344 errn = -EIO;
345 goto error;
346 }
347 bytes_written += copy_size;
348 count -= copy_size;
349 buffer += copy_size;
350 } while (count > 0);
351
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100352 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353
354 return bytes_written ? bytes_written : -EIO;
355
356error:
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100357 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700358 return errn;
359}
360
361static ssize_t
362read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
363{
364 DEFINE_WAIT(wait);
365 struct rio_usb_data *rio = &rio_instance;
366 ssize_t read_count;
367 unsigned int partial;
368 int this_read;
369 int result;
370 int maxretry = 10;
371 char *ibuf;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100372 int intr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100374 intr = mutex_lock_interruptible(&(rio->lock));
375 if (intr)
376 return -EINTR;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377 /* Sanity check to make sure rio is connected, powered, etc */
Adrian Bunk3328d972007-10-18 12:53:07 +0200378 if (rio->present == 0 || rio->rio_dev == NULL) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100379 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380 return -ENODEV;
381 }
382
383 ibuf = rio->ibuf;
384
385 read_count = 0;
386
387
388 while (count > 0) {
389 if (signal_pending(current)) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100390 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391 return read_count ? read_count : -EINTR;
392 }
393 if (!rio->rio_dev) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100394 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395 return -ENODEV;
396 }
397 this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count;
398
399 result = usb_bulk_msg(rio->rio_dev,
400 usb_rcvbulkpipe(rio->rio_dev, 1),
401 ibuf, this_read, &partial,
402 8000);
403
Greg Kroah-Hartmane1a344d2012-05-01 21:33:59 -0700404 dev_dbg(&rio->rio_dev->dev,
405 "read stats: result:%d this_read:%u partial:%u\n",
406 result, this_read, partial);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407
408 if (partial) {
409 count = this_read = partial;
410 } else if (result == -ETIMEDOUT || result == 15) { /* FIXME: 15 ??? */
411 if (!maxretry--) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100412 mutex_unlock(&(rio->lock));
Greg Kroah-Hartmanc41fba12012-04-20 16:53:48 -0700413 dev_err(&rio->rio_dev->dev,
414 "read_rio: maxretry timeout\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415 return -ETIME;
416 }
417 prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE);
418 schedule_timeout(NAK_TIMEOUT);
419 finish_wait(&rio->wait_q, &wait);
420 continue;
421 } else if (result != -EREMOTEIO) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100422 mutex_unlock(&(rio->lock));
Greg Kroah-Hartmanc41fba12012-04-20 16:53:48 -0700423 dev_err(&rio->rio_dev->dev,
424 "Read Whoops - result:%u partial:%u this_read:%u\n",
425 result, partial, this_read);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426 return -EIO;
427 } else {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100428 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429 return (0);
430 }
431
432 if (this_read) {
433 if (copy_to_user(buffer, ibuf, this_read)) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100434 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435 return -EFAULT;
436 }
437 count -= this_read;
438 read_count += this_read;
439 buffer += this_read;
440 }
441 }
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100442 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443 return read_count;
444}
445
Alexey Dobriyan828c0952009-10-01 15:43:56 -0700446static const struct file_operations usb_rio_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447 .owner = THIS_MODULE,
448 .read = read_rio,
449 .write = write_rio,
Alan Cox54592152008-05-22 22:47:31 +0100450 .unlocked_ioctl = ioctl_rio,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451 .open = open_rio,
452 .release = close_rio,
Arnd Bergmann6038f372010-08-15 18:52:59 +0200453 .llseek = noop_llseek,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700454};
455
456static struct usb_class_driver usb_rio_class = {
Greg Kroah-Hartmand6e5bcf2005-06-20 21:15:16 -0700457 .name = "rio500%d",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458 .fops = &usb_rio_fops,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459 .minor_base = RIO_MINOR,
460};
461
462static int probe_rio(struct usb_interface *intf,
463 const struct usb_device_id *id)
464{
465 struct usb_device *dev = interface_to_usbdev(intf);
466 struct rio_usb_data *rio = &rio_instance;
467 int retval;
468
Greg Kroah-Hartman1b29a372008-08-18 13:21:04 -0700469 dev_info(&intf->dev, "USB Rio found at address %d\n", dev->devnum);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470
471 retval = usb_register_dev(intf, &usb_rio_class);
472 if (retval) {
Greg Kroah-Hartmanc41fba12012-04-20 16:53:48 -0700473 dev_err(&dev->dev,
474 "Not able to get a minor for this device.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700475 return -ENOMEM;
476 }
477
478 rio->rio_dev = dev;
479
Jesper Juhl0e8eb0f2005-12-11 20:34:02 +0100480 if (!(rio->obuf = kmalloc(OBUF_SIZE, GFP_KERNEL))) {
Greg Kroah-Hartmanc41fba12012-04-20 16:53:48 -0700481 dev_err(&dev->dev,
482 "probe_rio: Not enough memory for the output buffer\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483 usb_deregister_dev(intf, &usb_rio_class);
484 return -ENOMEM;
485 }
Greg Kroah-Hartmane1a344d2012-05-01 21:33:59 -0700486 dev_dbg(&intf->dev, "obuf address:%p\n", rio->obuf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487
Jesper Juhl0e8eb0f2005-12-11 20:34:02 +0100488 if (!(rio->ibuf = kmalloc(IBUF_SIZE, GFP_KERNEL))) {
Greg Kroah-Hartmanc41fba12012-04-20 16:53:48 -0700489 dev_err(&dev->dev,
490 "probe_rio: Not enough memory for the input buffer\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700491 usb_deregister_dev(intf, &usb_rio_class);
492 kfree(rio->obuf);
493 return -ENOMEM;
494 }
Greg Kroah-Hartmane1a344d2012-05-01 21:33:59 -0700495 dev_dbg(&intf->dev, "ibuf address:%p\n", rio->ibuf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100497 mutex_init(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498
499 usb_set_intfdata (intf, rio);
500 rio->present = 1;
501
502 return 0;
503}
504
505static void disconnect_rio(struct usb_interface *intf)
506{
507 struct rio_usb_data *rio = usb_get_intfdata (intf);
508
509 usb_set_intfdata (intf, NULL);
Arnd Bergmann925ce682010-07-11 23:18:56 +0200510 mutex_lock(&rio500_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511 if (rio) {
512 usb_deregister_dev(intf, &usb_rio_class);
513
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100514 mutex_lock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700515 if (rio->isopen) {
516 rio->isopen = 0;
517 /* better let it finish - the release will do whats needed */
518 rio->rio_dev = NULL;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100519 mutex_unlock(&(rio->lock));
Arnd Bergmann925ce682010-07-11 23:18:56 +0200520 mutex_unlock(&rio500_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521 return;
522 }
523 kfree(rio->ibuf);
524 kfree(rio->obuf);
525
Greg Kroah-Hartman1b29a372008-08-18 13:21:04 -0700526 dev_info(&intf->dev, "USB Rio disconnected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527
528 rio->present = 0;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100529 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530 }
Arnd Bergmann925ce682010-07-11 23:18:56 +0200531 mutex_unlock(&rio500_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700532}
533
Németh Márton33b9e162010-01-10 15:34:45 +0100534static const struct usb_device_id rio_table[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535 { USB_DEVICE(0x0841, 1) }, /* Rio 500 */
536 { } /* Terminating entry */
537};
538
539MODULE_DEVICE_TABLE (usb, rio_table);
540
541static struct usb_driver rio_driver = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542 .name = "rio500",
543 .probe = probe_rio,
544 .disconnect = disconnect_rio,
545 .id_table = rio_table,
546};
547
Greg Kroah-Hartman65db4302011-11-18 09:34:02 -0800548module_usb_driver(rio_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549
550MODULE_AUTHOR( DRIVER_AUTHOR );
551MODULE_DESCRIPTION( DRIVER_DESC );
552MODULE_LICENSE("GPL");
553