blob: 6e761fabffca064a965c487703e930e0b29055cf [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
Oliver Neukumb07c7a32019-05-09 11:30:59 +0200106 /* against disconnect() */
107 mutex_lock(&rio500_mutex);
108 mutex_lock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109
Oliver Neukumb07c7a32019-05-09 11:30:59 +0200110 rio->isopen = 0;
111 if (!rio->present) {
112 /* cleanup has been delayed */
113 kfree(rio->ibuf);
114 kfree(rio->obuf);
115 rio->ibuf = NULL;
116 rio->obuf = NULL;
117 } else {
118 dev_info(&rio->rio_dev->dev, "Rio closed.\n");
119 }
120 mutex_unlock(&(rio->lock));
121 mutex_unlock(&rio500_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122 return 0;
123}
124
Alan Cox54592152008-05-22 22:47:31 +0100125static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126{
127 struct RioCommand rio_cmd;
128 struct rio_usb_data *rio = &rio_instance;
129 void __user *data;
130 unsigned char *buffer;
131 int result, requesttype;
132 int retries;
133 int retval=0;
134
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100135 mutex_lock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136 /* Sanity check to make sure rio is connected, powered, etc */
Adrian Bunk3328d972007-10-18 12:53:07 +0200137 if (rio->present == 0 || rio->rio_dev == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138 retval = -ENODEV;
139 goto err_out;
140 }
141
142 switch (cmd) {
143 case RIO_RECV_COMMAND:
144 data = (void __user *) arg;
145 if (data == NULL)
146 break;
147 if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand))) {
148 retval = -EFAULT;
149 goto err_out;
150 }
151 if (rio_cmd.length < 0 || rio_cmd.length > PAGE_SIZE) {
152 retval = -EINVAL;
153 goto err_out;
154 }
155 buffer = (unsigned char *) __get_free_page(GFP_KERNEL);
156 if (buffer == NULL) {
157 retval = -ENOMEM;
158 goto err_out;
159 }
160 if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length)) {
161 retval = -EFAULT;
162 free_page((unsigned long) buffer);
163 goto err_out;
164 }
165
166 requesttype = rio_cmd.requesttype | USB_DIR_IN |
167 USB_TYPE_VENDOR | USB_RECIP_DEVICE;
Greg Kroah-Hartmane1a344d2012-05-01 21:33:59 -0700168 dev_dbg(&rio->rio_dev->dev,
169 "sending command:reqtype=%0x req=%0x value=%0x index=%0x len=%0x\n",
170 requesttype, rio_cmd.request, rio_cmd.value,
171 rio_cmd.index, rio_cmd.length);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172 /* Send rio control message */
173 retries = 3;
174 while (retries) {
175 result = usb_control_msg(rio->rio_dev,
176 usb_rcvctrlpipe(rio-> rio_dev, 0),
177 rio_cmd.request,
178 requesttype,
179 rio_cmd.value,
180 rio_cmd.index, buffer,
181 rio_cmd.length,
182 jiffies_to_msecs(rio_cmd.timeout));
183 if (result == -ETIMEDOUT)
184 retries--;
185 else if (result < 0) {
Greg Kroah-Hartmanc41fba12012-04-20 16:53:48 -0700186 dev_err(&rio->rio_dev->dev,
187 "Error executing ioctrl. code = %d\n",
188 result);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189 retries = 0;
190 } else {
Greg Kroah-Hartmane1a344d2012-05-01 21:33:59 -0700191 dev_dbg(&rio->rio_dev->dev,
192 "Executed ioctl. Result = %d (data=%02x)\n",
193 result, buffer[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700194 if (copy_to_user(rio_cmd.buffer, buffer,
195 rio_cmd.length)) {
196 free_page((unsigned long) buffer);
197 retval = -EFAULT;
198 goto err_out;
199 }
200 retries = 0;
201 }
202
203 /* rio_cmd.buffer contains a raw stream of single byte
204 data which has been returned from rio. Data is
205 interpreted at application level. For data that
206 will be cast to data types longer than 1 byte, data
207 will be little_endian and will potentially need to
208 be swapped at the app level */
209
210 }
211 free_page((unsigned long) buffer);
212 break;
213
214 case RIO_SEND_COMMAND:
215 data = (void __user *) arg;
216 if (data == NULL)
217 break;
218 if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand))) {
219 retval = -EFAULT;
220 goto err_out;
221 }
222 if (rio_cmd.length < 0 || rio_cmd.length > PAGE_SIZE) {
223 retval = -EINVAL;
224 goto err_out;
225 }
226 buffer = (unsigned char *) __get_free_page(GFP_KERNEL);
227 if (buffer == NULL) {
228 retval = -ENOMEM;
229 goto err_out;
230 }
231 if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length)) {
232 free_page((unsigned long)buffer);
233 retval = -EFAULT;
234 goto err_out;
235 }
236
237 requesttype = rio_cmd.requesttype | USB_DIR_OUT |
238 USB_TYPE_VENDOR | USB_RECIP_DEVICE;
Greg Kroah-Hartmane1a344d2012-05-01 21:33:59 -0700239 dev_dbg(&rio->rio_dev->dev,
240 "sending command: reqtype=%0x req=%0x value=%0x index=%0x len=%0x\n",
241 requesttype, rio_cmd.request, rio_cmd.value,
242 rio_cmd.index, rio_cmd.length);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700243 /* Send rio control message */
244 retries = 3;
245 while (retries) {
246 result = usb_control_msg(rio->rio_dev,
247 usb_sndctrlpipe(rio-> rio_dev, 0),
248 rio_cmd.request,
249 requesttype,
250 rio_cmd.value,
251 rio_cmd.index, buffer,
252 rio_cmd.length,
253 jiffies_to_msecs(rio_cmd.timeout));
254 if (result == -ETIMEDOUT)
255 retries--;
256 else if (result < 0) {
Greg Kroah-Hartmanc41fba12012-04-20 16:53:48 -0700257 dev_err(&rio->rio_dev->dev,
258 "Error executing ioctrl. code = %d\n",
259 result);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260 retries = 0;
261 } else {
Greg Kroah-Hartmane1a344d2012-05-01 21:33:59 -0700262 dev_dbg(&rio->rio_dev->dev,
263 "Executed ioctl. Result = %d\n", result);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700264 retries = 0;
265
266 }
267
268 }
269 free_page((unsigned long) buffer);
270 break;
271
272 default:
273 retval = -ENOTTY;
274 break;
275 }
276
277
278err_out:
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100279 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280 return retval;
281}
282
283static ssize_t
284write_rio(struct file *file, const char __user *buffer,
285 size_t count, loff_t * ppos)
286{
287 DEFINE_WAIT(wait);
288 struct rio_usb_data *rio = &rio_instance;
289
290 unsigned long copy_size;
291 unsigned long bytes_written = 0;
292 unsigned int partial;
293
294 int result = 0;
295 int maxretry;
296 int errn = 0;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100297 int intr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100299 intr = mutex_lock_interruptible(&(rio->lock));
300 if (intr)
301 return -EINTR;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302 /* Sanity check to make sure rio is connected, powered, etc */
Adrian Bunk3328d972007-10-18 12:53:07 +0200303 if (rio->present == 0 || rio->rio_dev == NULL) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100304 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305 return -ENODEV;
306 }
307
308
309
310 do {
311 unsigned long thistime;
312 char *obuf = rio->obuf;
313
314 thistime = copy_size =
315 (count >= OBUF_SIZE) ? OBUF_SIZE : count;
316 if (copy_from_user(rio->obuf, buffer, copy_size)) {
317 errn = -EFAULT;
318 goto error;
319 }
320 maxretry = 5;
321 while (thistime) {
322 if (!rio->rio_dev) {
323 errn = -ENODEV;
324 goto error;
325 }
326 if (signal_pending(current)) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100327 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700328 return bytes_written ? bytes_written : -EINTR;
329 }
330
331 result = usb_bulk_msg(rio->rio_dev,
332 usb_sndbulkpipe(rio->rio_dev, 2),
333 obuf, thistime, &partial, 5000);
334
Greg Kroah-Hartmane1a344d2012-05-01 21:33:59 -0700335 dev_dbg(&rio->rio_dev->dev,
336 "write stats: result:%d thistime:%lu partial:%u\n",
337 result, thistime, partial);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700338
339 if (result == -ETIMEDOUT) { /* NAK - so hold for a while */
340 if (!maxretry--) {
341 errn = -ETIME;
342 goto error;
343 }
344 prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE);
345 schedule_timeout(NAK_TIMEOUT);
346 finish_wait(&rio->wait_q, &wait);
347 continue;
348 } else if (!result && partial) {
349 obuf += partial;
350 thistime -= partial;
351 } else
352 break;
Peter Senna Tschudin17e67912012-09-12 19:03:20 +0200353 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354 if (result) {
Greg Kroah-Hartmanc41fba12012-04-20 16:53:48 -0700355 dev_err(&rio->rio_dev->dev, "Write Whoops - %x\n",
356 result);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357 errn = -EIO;
358 goto error;
359 }
360 bytes_written += copy_size;
361 count -= copy_size;
362 buffer += copy_size;
363 } while (count > 0);
364
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100365 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366
367 return bytes_written ? bytes_written : -EIO;
368
369error:
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100370 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 return errn;
372}
373
374static ssize_t
375read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
376{
377 DEFINE_WAIT(wait);
378 struct rio_usb_data *rio = &rio_instance;
379 ssize_t read_count;
380 unsigned int partial;
381 int this_read;
382 int result;
383 int maxretry = 10;
384 char *ibuf;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100385 int intr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100387 intr = mutex_lock_interruptible(&(rio->lock));
388 if (intr)
389 return -EINTR;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390 /* Sanity check to make sure rio is connected, powered, etc */
Adrian Bunk3328d972007-10-18 12:53:07 +0200391 if (rio->present == 0 || rio->rio_dev == NULL) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100392 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393 return -ENODEV;
394 }
395
396 ibuf = rio->ibuf;
397
398 read_count = 0;
399
400
401 while (count > 0) {
402 if (signal_pending(current)) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100403 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404 return read_count ? read_count : -EINTR;
405 }
406 if (!rio->rio_dev) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100407 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408 return -ENODEV;
409 }
410 this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count;
411
412 result = usb_bulk_msg(rio->rio_dev,
413 usb_rcvbulkpipe(rio->rio_dev, 1),
414 ibuf, this_read, &partial,
415 8000);
416
Greg Kroah-Hartmane1a344d2012-05-01 21:33:59 -0700417 dev_dbg(&rio->rio_dev->dev,
418 "read stats: result:%d this_read:%u partial:%u\n",
419 result, this_read, partial);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420
421 if (partial) {
422 count = this_read = partial;
423 } else if (result == -ETIMEDOUT || result == 15) { /* FIXME: 15 ??? */
424 if (!maxretry--) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100425 mutex_unlock(&(rio->lock));
Greg Kroah-Hartmanc41fba12012-04-20 16:53:48 -0700426 dev_err(&rio->rio_dev->dev,
427 "read_rio: maxretry timeout\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428 return -ETIME;
429 }
430 prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE);
431 schedule_timeout(NAK_TIMEOUT);
432 finish_wait(&rio->wait_q, &wait);
433 continue;
434 } else if (result != -EREMOTEIO) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100435 mutex_unlock(&(rio->lock));
Greg Kroah-Hartmanc41fba12012-04-20 16:53:48 -0700436 dev_err(&rio->rio_dev->dev,
437 "Read Whoops - result:%u partial:%u this_read:%u\n",
438 result, partial, this_read);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439 return -EIO;
440 } else {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100441 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442 return (0);
443 }
444
445 if (this_read) {
446 if (copy_to_user(buffer, ibuf, this_read)) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100447 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448 return -EFAULT;
449 }
450 count -= this_read;
451 read_count += this_read;
452 buffer += this_read;
453 }
454 }
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100455 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700456 return read_count;
457}
458
Alexey Dobriyan828c0952009-10-01 15:43:56 -0700459static const struct file_operations usb_rio_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700460 .owner = THIS_MODULE,
461 .read = read_rio,
462 .write = write_rio,
Alan Cox54592152008-05-22 22:47:31 +0100463 .unlocked_ioctl = ioctl_rio,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700464 .open = open_rio,
465 .release = close_rio,
Arnd Bergmann6038f372010-08-15 18:52:59 +0200466 .llseek = noop_llseek,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700467};
468
469static struct usb_class_driver usb_rio_class = {
Greg Kroah-Hartmand6e5bcf2005-06-20 21:15:16 -0700470 .name = "rio500%d",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700471 .fops = &usb_rio_fops,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472 .minor_base = RIO_MINOR,
473};
474
475static int probe_rio(struct usb_interface *intf,
476 const struct usb_device_id *id)
477{
478 struct usb_device *dev = interface_to_usbdev(intf);
479 struct rio_usb_data *rio = &rio_instance;
Oliver Neukum6496f8e2019-05-09 11:30:58 +0200480 int retval = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481
Oliver Neukum6496f8e2019-05-09 11:30:58 +0200482 mutex_lock(&rio500_mutex);
483 if (rio->present) {
484 dev_info(&intf->dev, "Second USB Rio at address %d refused\n", dev->devnum);
485 retval = -EBUSY;
486 goto bail_out;
487 } else {
488 dev_info(&intf->dev, "USB Rio found at address %d\n", dev->devnum);
489 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700490
491 retval = usb_register_dev(intf, &usb_rio_class);
492 if (retval) {
Greg Kroah-Hartmanc41fba12012-04-20 16:53:48 -0700493 dev_err(&dev->dev,
494 "Not able to get a minor for this device.\n");
Oliver Neukum6496f8e2019-05-09 11:30:58 +0200495 retval = -ENOMEM;
496 goto bail_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700497 }
498
499 rio->rio_dev = dev;
500
Jesper Juhl0e8eb0f2005-12-11 20:34:02 +0100501 if (!(rio->obuf = kmalloc(OBUF_SIZE, GFP_KERNEL))) {
Greg Kroah-Hartmanc41fba12012-04-20 16:53:48 -0700502 dev_err(&dev->dev,
503 "probe_rio: Not enough memory for the output buffer\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700504 usb_deregister_dev(intf, &usb_rio_class);
Oliver Neukum6496f8e2019-05-09 11:30:58 +0200505 retval = -ENOMEM;
506 goto bail_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507 }
Greg Kroah-Hartmane1a344d2012-05-01 21:33:59 -0700508 dev_dbg(&intf->dev, "obuf address:%p\n", rio->obuf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509
Jesper Juhl0e8eb0f2005-12-11 20:34:02 +0100510 if (!(rio->ibuf = kmalloc(IBUF_SIZE, GFP_KERNEL))) {
Greg Kroah-Hartmanc41fba12012-04-20 16:53:48 -0700511 dev_err(&dev->dev,
512 "probe_rio: Not enough memory for the input buffer\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700513 usb_deregister_dev(intf, &usb_rio_class);
514 kfree(rio->obuf);
Oliver Neukum6496f8e2019-05-09 11:30:58 +0200515 retval = -ENOMEM;
516 goto bail_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517 }
Greg Kroah-Hartmane1a344d2012-05-01 21:33:59 -0700518 dev_dbg(&intf->dev, "ibuf address:%p\n", rio->ibuf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100520 mutex_init(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521
522 usb_set_intfdata (intf, rio);
523 rio->present = 1;
Oliver Neukum6496f8e2019-05-09 11:30:58 +0200524bail_out:
525 mutex_unlock(&rio500_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526
Oliver Neukum6496f8e2019-05-09 11:30:58 +0200527 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528}
529
530static void disconnect_rio(struct usb_interface *intf)
531{
532 struct rio_usb_data *rio = usb_get_intfdata (intf);
533
534 usb_set_intfdata (intf, NULL);
Arnd Bergmann925ce682010-07-11 23:18:56 +0200535 mutex_lock(&rio500_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536 if (rio) {
537 usb_deregister_dev(intf, &usb_rio_class);
538
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100539 mutex_lock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540 if (rio->isopen) {
541 rio->isopen = 0;
542 /* better let it finish - the release will do whats needed */
543 rio->rio_dev = NULL;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100544 mutex_unlock(&(rio->lock));
Arnd Bergmann925ce682010-07-11 23:18:56 +0200545 mutex_unlock(&rio500_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546 return;
547 }
548 kfree(rio->ibuf);
549 kfree(rio->obuf);
550
Greg Kroah-Hartman1b29a372008-08-18 13:21:04 -0700551 dev_info(&intf->dev, "USB Rio disconnected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700552
553 rio->present = 0;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100554 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555 }
Arnd Bergmann925ce682010-07-11 23:18:56 +0200556 mutex_unlock(&rio500_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557}
558
Németh Márton33b9e162010-01-10 15:34:45 +0100559static const struct usb_device_id rio_table[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560 { USB_DEVICE(0x0841, 1) }, /* Rio 500 */
561 { } /* Terminating entry */
562};
563
564MODULE_DEVICE_TABLE (usb, rio_table);
565
566static struct usb_driver rio_driver = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 .name = "rio500",
568 .probe = probe_rio,
569 .disconnect = disconnect_rio,
570 .id_table = rio_table,
571};
572
Greg Kroah-Hartman65db4302011-11-18 09:34:02 -0800573module_usb_driver(rio_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574
575MODULE_AUTHOR( DRIVER_AUTHOR );
576MODULE_DESCRIPTION( DRIVER_DESC );
577MODULE_LICENSE("GPL");
578