blob: cb55dc5330dfaa201f9f50f804807a13ba9a5b2d [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;
156 dbg
157 ("sending command:reqtype=%0x req=%0x value=%0x index=%0x len=%0x",
158 requesttype, rio_cmd.request, rio_cmd.value,
159 rio_cmd.index, rio_cmd.length);
160 /* 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 {
179 dbg("Executed ioctl. Result = %d (data=%02x)",
180 result, buffer[0]);
181 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;
226 dbg("sending command: reqtype=%0x req=%0x value=%0x index=%0x len=%0x",
227 requesttype, rio_cmd.request, rio_cmd.value,
228 rio_cmd.index, rio_cmd.length);
229 /* Send rio control message */
230 retries = 3;
231 while (retries) {
232 result = usb_control_msg(rio->rio_dev,
233 usb_sndctrlpipe(rio-> rio_dev, 0),
234 rio_cmd.request,
235 requesttype,
236 rio_cmd.value,
237 rio_cmd.index, buffer,
238 rio_cmd.length,
239 jiffies_to_msecs(rio_cmd.timeout));
240 if (result == -ETIMEDOUT)
241 retries--;
242 else if (result < 0) {
Greg Kroah-Hartmanc41fba12012-04-20 16:53:48 -0700243 dev_err(&rio->rio_dev->dev,
244 "Error executing ioctrl. code = %d\n",
245 result);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246 retries = 0;
247 } else {
248 dbg("Executed ioctl. Result = %d", result);
249 retries = 0;
250
251 }
252
253 }
254 free_page((unsigned long) buffer);
255 break;
256
257 default:
258 retval = -ENOTTY;
259 break;
260 }
261
262
263err_out:
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100264 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700265 return retval;
266}
267
268static ssize_t
269write_rio(struct file *file, const char __user *buffer,
270 size_t count, loff_t * ppos)
271{
272 DEFINE_WAIT(wait);
273 struct rio_usb_data *rio = &rio_instance;
274
275 unsigned long copy_size;
276 unsigned long bytes_written = 0;
277 unsigned int partial;
278
279 int result = 0;
280 int maxretry;
281 int errn = 0;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100282 int intr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100284 intr = mutex_lock_interruptible(&(rio->lock));
285 if (intr)
286 return -EINTR;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700287 /* Sanity check to make sure rio is connected, powered, etc */
Adrian Bunk3328d972007-10-18 12:53:07 +0200288 if (rio->present == 0 || rio->rio_dev == NULL) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100289 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290 return -ENODEV;
291 }
292
293
294
295 do {
296 unsigned long thistime;
297 char *obuf = rio->obuf;
298
299 thistime = copy_size =
300 (count >= OBUF_SIZE) ? OBUF_SIZE : count;
301 if (copy_from_user(rio->obuf, buffer, copy_size)) {
302 errn = -EFAULT;
303 goto error;
304 }
305 maxretry = 5;
306 while (thistime) {
307 if (!rio->rio_dev) {
308 errn = -ENODEV;
309 goto error;
310 }
311 if (signal_pending(current)) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100312 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700313 return bytes_written ? bytes_written : -EINTR;
314 }
315
316 result = usb_bulk_msg(rio->rio_dev,
317 usb_sndbulkpipe(rio->rio_dev, 2),
318 obuf, thistime, &partial, 5000);
319
320 dbg("write stats: result:%d thistime:%lu partial:%u",
321 result, thistime, partial);
322
323 if (result == -ETIMEDOUT) { /* NAK - so hold for a while */
324 if (!maxretry--) {
325 errn = -ETIME;
326 goto error;
327 }
328 prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE);
329 schedule_timeout(NAK_TIMEOUT);
330 finish_wait(&rio->wait_q, &wait);
331 continue;
332 } else if (!result && partial) {
333 obuf += partial;
334 thistime -= partial;
335 } else
336 break;
337 };
338 if (result) {
Greg Kroah-Hartmanc41fba12012-04-20 16:53:48 -0700339 dev_err(&rio->rio_dev->dev, "Write Whoops - %x\n",
340 result);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341 errn = -EIO;
342 goto error;
343 }
344 bytes_written += copy_size;
345 count -= copy_size;
346 buffer += copy_size;
347 } while (count > 0);
348
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100349 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700350
351 return bytes_written ? bytes_written : -EIO;
352
353error:
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100354 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700355 return errn;
356}
357
358static ssize_t
359read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
360{
361 DEFINE_WAIT(wait);
362 struct rio_usb_data *rio = &rio_instance;
363 ssize_t read_count;
364 unsigned int partial;
365 int this_read;
366 int result;
367 int maxretry = 10;
368 char *ibuf;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100369 int intr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100371 intr = mutex_lock_interruptible(&(rio->lock));
372 if (intr)
373 return -EINTR;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374 /* Sanity check to make sure rio is connected, powered, etc */
Adrian Bunk3328d972007-10-18 12:53:07 +0200375 if (rio->present == 0 || rio->rio_dev == NULL) {
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));
Greg Kroah-Hartmanc41fba12012-04-20 16:53:48 -0700409 dev_err(&rio->rio_dev->dev,
410 "read_rio: maxretry timeout\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411 return -ETIME;
412 }
413 prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE);
414 schedule_timeout(NAK_TIMEOUT);
415 finish_wait(&rio->wait_q, &wait);
416 continue;
417 } else if (result != -EREMOTEIO) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100418 mutex_unlock(&(rio->lock));
Greg Kroah-Hartmanc41fba12012-04-20 16:53:48 -0700419 dev_err(&rio->rio_dev->dev,
420 "Read Whoops - result:%u partial:%u this_read:%u\n",
421 result, partial, this_read);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422 return -EIO;
423 } else {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100424 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425 return (0);
426 }
427
428 if (this_read) {
429 if (copy_to_user(buffer, ibuf, this_read)) {
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100430 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700431 return -EFAULT;
432 }
433 count -= this_read;
434 read_count += this_read;
435 buffer += this_read;
436 }
437 }
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100438 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439 return read_count;
440}
441
Alexey Dobriyan828c0952009-10-01 15:43:56 -0700442static const struct file_operations usb_rio_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443 .owner = THIS_MODULE,
444 .read = read_rio,
445 .write = write_rio,
Alan Cox54592152008-05-22 22:47:31 +0100446 .unlocked_ioctl = ioctl_rio,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447 .open = open_rio,
448 .release = close_rio,
Arnd Bergmann6038f372010-08-15 18:52:59 +0200449 .llseek = noop_llseek,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700450};
451
452static struct usb_class_driver usb_rio_class = {
Greg Kroah-Hartmand6e5bcf2005-06-20 21:15:16 -0700453 .name = "rio500%d",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700454 .fops = &usb_rio_fops,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455 .minor_base = RIO_MINOR,
456};
457
458static int probe_rio(struct usb_interface *intf,
459 const struct usb_device_id *id)
460{
461 struct usb_device *dev = interface_to_usbdev(intf);
462 struct rio_usb_data *rio = &rio_instance;
463 int retval;
464
Greg Kroah-Hartman1b29a372008-08-18 13:21:04 -0700465 dev_info(&intf->dev, "USB Rio found at address %d\n", dev->devnum);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466
467 retval = usb_register_dev(intf, &usb_rio_class);
468 if (retval) {
Greg Kroah-Hartmanc41fba12012-04-20 16:53:48 -0700469 dev_err(&dev->dev,
470 "Not able to get a minor for this device.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700471 return -ENOMEM;
472 }
473
474 rio->rio_dev = dev;
475
Jesper Juhl0e8eb0f2005-12-11 20:34:02 +0100476 if (!(rio->obuf = kmalloc(OBUF_SIZE, GFP_KERNEL))) {
Greg Kroah-Hartmanc41fba12012-04-20 16:53:48 -0700477 dev_err(&dev->dev,
478 "probe_rio: Not enough memory for the output buffer\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479 usb_deregister_dev(intf, &usb_rio_class);
480 return -ENOMEM;
481 }
482 dbg("probe_rio: obuf address:%p", rio->obuf);
483
Jesper Juhl0e8eb0f2005-12-11 20:34:02 +0100484 if (!(rio->ibuf = kmalloc(IBUF_SIZE, GFP_KERNEL))) {
Greg Kroah-Hartmanc41fba12012-04-20 16:53:48 -0700485 dev_err(&dev->dev,
486 "probe_rio: Not enough memory for the input buffer\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487 usb_deregister_dev(intf, &usb_rio_class);
488 kfree(rio->obuf);
489 return -ENOMEM;
490 }
491 dbg("probe_rio: ibuf address:%p", rio->ibuf);
492
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100493 mutex_init(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700494
495 usb_set_intfdata (intf, rio);
496 rio->present = 1;
497
498 return 0;
499}
500
501static void disconnect_rio(struct usb_interface *intf)
502{
503 struct rio_usb_data *rio = usb_get_intfdata (intf);
504
505 usb_set_intfdata (intf, NULL);
Arnd Bergmann925ce682010-07-11 23:18:56 +0200506 mutex_lock(&rio500_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507 if (rio) {
508 usb_deregister_dev(intf, &usb_rio_class);
509
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100510 mutex_lock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511 if (rio->isopen) {
512 rio->isopen = 0;
513 /* better let it finish - the release will do whats needed */
514 rio->rio_dev = NULL;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100515 mutex_unlock(&(rio->lock));
Arnd Bergmann925ce682010-07-11 23:18:56 +0200516 mutex_unlock(&rio500_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517 return;
518 }
519 kfree(rio->ibuf);
520 kfree(rio->obuf);
521
Greg Kroah-Hartman1b29a372008-08-18 13:21:04 -0700522 dev_info(&intf->dev, "USB Rio disconnected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523
524 rio->present = 0;
Oliver Neukum2cba72f2006-12-15 23:48:56 +0100525 mutex_unlock(&(rio->lock));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526 }
Arnd Bergmann925ce682010-07-11 23:18:56 +0200527 mutex_unlock(&rio500_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528}
529
Németh Márton33b9e162010-01-10 15:34:45 +0100530static const struct usb_device_id rio_table[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531 { USB_DEVICE(0x0841, 1) }, /* Rio 500 */
532 { } /* Terminating entry */
533};
534
535MODULE_DEVICE_TABLE (usb, rio_table);
536
537static struct usb_driver rio_driver = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700538 .name = "rio500",
539 .probe = probe_rio,
540 .disconnect = disconnect_rio,
541 .id_table = rio_table,
542};
543
Greg Kroah-Hartman65db4302011-11-18 09:34:02 -0800544module_usb_driver(rio_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545
546MODULE_AUTHOR( DRIVER_AUTHOR );
547MODULE_DESCRIPTION( DRIVER_DESC );
548MODULE_LICENSE("GPL");
549