]>
Commit | Line | Data |
---|---|---|
5fd54ace | 1 | // SPDX-License-Identifier: GPL-2.0+ |
1da177e4 LT |
2 | /* -*- linux-c -*- */ |
3 | ||
4 | /* | |
5 | * Driver for USB Rio 500 | |
6 | * | |
7 | * Cesar Miquel ([email protected]) | |
8 | * | |
9 | * based on hp_scanner.c by David E. Nelson ([email protected]) | |
1da177e4 LT |
10 | * |
11 | * Based upon mouse.c (Brad Keryan) and printer.c (Michael Gee). | |
12 | * | |
13 | * Changelog: | |
14 | * 30/05/2003 replaced lock/unlock kernel with up/down | |
15 | * Daniele Bellucci [email protected] | |
16 | * */ | |
17 | ||
18 | #include <linux/module.h> | |
19 | #include <linux/kernel.h> | |
20 | #include <linux/signal.h> | |
174cd4b1 | 21 | #include <linux/sched/signal.h> |
925ce689 | 22 | #include <linux/mutex.h> |
1da177e4 LT |
23 | #include <linux/errno.h> |
24 | #include <linux/random.h> | |
25 | #include <linux/poll.h> | |
1da177e4 LT |
26 | #include <linux/slab.h> |
27 | #include <linux/spinlock.h> | |
28 | #include <linux/usb.h> | |
1da177e4 LT |
29 | #include <linux/wait.h> |
30 | ||
31 | #include "rio500_usb.h" | |
32 | ||
1da177e4 LT |
33 | #define DRIVER_AUTHOR "Cesar Miquel <[email protected]>" |
34 | #define DRIVER_DESC "USB Rio 500 driver" | |
35 | ||
36 | #define RIO_MINOR 64 | |
37 | ||
38 | /* stall/wait timeout for rio */ | |
39 | #define NAK_TIMEOUT (HZ) | |
40 | ||
41 | #define IBUF_SIZE 0x1000 | |
42 | ||
43 | /* Size of the rio buffer */ | |
44 | #define OBUF_SIZE 0x10000 | |
45 | ||
46 | struct rio_usb_data { | |
47 | struct usb_device *rio_dev; /* init: probe_rio */ | |
48 | unsigned int ifnum; /* Interface number of the USB device */ | |
49 | int isopen; /* nz if open */ | |
50 | int present; /* Device is present on the bus */ | |
51 | char *obuf, *ibuf; /* transfer buffers */ | |
52 | char bulk_in_ep, bulk_out_ep; /* Endpoint assignments */ | |
53 | wait_queue_head_t wait_q; /* for timeouts */ | |
2cba72f0 | 54 | struct mutex lock; /* general race avoidance */ |
1da177e4 LT |
55 | }; |
56 | ||
925ce689 | 57 | static DEFINE_MUTEX(rio500_mutex); |
1da177e4 LT |
58 | static struct rio_usb_data rio_instance; |
59 | ||
60 | static int open_rio(struct inode *inode, struct file *file) | |
61 | { | |
62 | struct rio_usb_data *rio = &rio_instance; | |
511e2d02 ON |
63 | |
64 | /* against disconnect() */ | |
925ce689 | 65 | mutex_lock(&rio500_mutex); |
2cba72f0 | 66 | mutex_lock(&(rio->lock)); |
1da177e4 LT |
67 | |
68 | if (rio->isopen || !rio->present) { | |
2cba72f0 | 69 | mutex_unlock(&(rio->lock)); |
925ce689 | 70 | mutex_unlock(&rio500_mutex); |
1da177e4 LT |
71 | return -EBUSY; |
72 | } | |
73 | rio->isopen = 1; | |
74 | ||
75 | init_waitqueue_head(&rio->wait_q); | |
76 | ||
2cba72f0 | 77 | mutex_unlock(&(rio->lock)); |
1da177e4 | 78 | |
1b29a375 | 79 | dev_info(&rio->rio_dev->dev, "Rio opened.\n"); |
925ce689 | 80 | mutex_unlock(&rio500_mutex); |
1da177e4 LT |
81 | |
82 | return 0; | |
83 | } | |
84 | ||
85 | static int close_rio(struct inode *inode, struct file *file) | |
86 | { | |
87 | struct rio_usb_data *rio = &rio_instance; | |
88 | ||
89 | rio->isopen = 0; | |
90 | ||
1b29a375 | 91 | dev_info(&rio->rio_dev->dev, "Rio closed.\n"); |
1da177e4 LT |
92 | return 0; |
93 | } | |
94 | ||
54592157 | 95 | static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg) |
1da177e4 LT |
96 | { |
97 | struct RioCommand rio_cmd; | |
98 | struct rio_usb_data *rio = &rio_instance; | |
99 | void __user *data; | |
100 | unsigned char *buffer; | |
101 | int result, requesttype; | |
102 | int retries; | |
103 | int retval=0; | |
104 | ||
2cba72f0 | 105 | mutex_lock(&(rio->lock)); |
1da177e4 | 106 | /* Sanity check to make sure rio is connected, powered, etc */ |
3328d975 | 107 | if (rio->present == 0 || rio->rio_dev == NULL) { |
1da177e4 LT |
108 | retval = -ENODEV; |
109 | goto err_out; | |
110 | } | |
111 | ||
112 | switch (cmd) { | |
113 | case RIO_RECV_COMMAND: | |
114 | data = (void __user *) arg; | |
115 | if (data == NULL) | |
116 | break; | |
117 | if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand))) { | |
118 | retval = -EFAULT; | |
119 | goto err_out; | |
120 | } | |
121 | if (rio_cmd.length < 0 || rio_cmd.length > PAGE_SIZE) { | |
122 | retval = -EINVAL; | |
123 | goto err_out; | |
124 | } | |
125 | buffer = (unsigned char *) __get_free_page(GFP_KERNEL); | |
126 | if (buffer == NULL) { | |
127 | retval = -ENOMEM; | |
128 | goto err_out; | |
129 | } | |
130 | if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length)) { | |
131 | retval = -EFAULT; | |
132 | free_page((unsigned long) buffer); | |
133 | goto err_out; | |
134 | } | |
135 | ||
136 | requesttype = rio_cmd.requesttype | USB_DIR_IN | | |
137 | USB_TYPE_VENDOR | USB_RECIP_DEVICE; | |
e1a344d3 GKH |
138 | dev_dbg(&rio->rio_dev->dev, |
139 | "sending command:reqtype=%0x req=%0x value=%0x index=%0x len=%0x\n", | |
140 | requesttype, rio_cmd.request, rio_cmd.value, | |
141 | rio_cmd.index, rio_cmd.length); | |
1da177e4 LT |
142 | /* Send rio control message */ |
143 | retries = 3; | |
144 | while (retries) { | |
145 | result = usb_control_msg(rio->rio_dev, | |
146 | usb_rcvctrlpipe(rio-> rio_dev, 0), | |
147 | rio_cmd.request, | |
148 | requesttype, | |
149 | rio_cmd.value, | |
150 | rio_cmd.index, buffer, | |
151 | rio_cmd.length, | |
152 | jiffies_to_msecs(rio_cmd.timeout)); | |
153 | if (result == -ETIMEDOUT) | |
154 | retries--; | |
155 | else if (result < 0) { | |
c41fba13 GKH |
156 | dev_err(&rio->rio_dev->dev, |
157 | "Error executing ioctrl. code = %d\n", | |
158 | result); | |
1da177e4 LT |
159 | retries = 0; |
160 | } else { | |
e1a344d3 GKH |
161 | dev_dbg(&rio->rio_dev->dev, |
162 | "Executed ioctl. Result = %d (data=%02x)\n", | |
163 | result, buffer[0]); | |
1da177e4 LT |
164 | if (copy_to_user(rio_cmd.buffer, buffer, |
165 | rio_cmd.length)) { | |
166 | free_page((unsigned long) buffer); | |
167 | retval = -EFAULT; | |
168 | goto err_out; | |
169 | } | |
170 | retries = 0; | |
171 | } | |
172 | ||
173 | /* rio_cmd.buffer contains a raw stream of single byte | |
174 | data which has been returned from rio. Data is | |
175 | interpreted at application level. For data that | |
176 | will be cast to data types longer than 1 byte, data | |
177 | will be little_endian and will potentially need to | |
178 | be swapped at the app level */ | |
179 | ||
180 | } | |
181 | free_page((unsigned long) buffer); | |
182 | break; | |
183 | ||
184 | case RIO_SEND_COMMAND: | |
185 | data = (void __user *) arg; | |
186 | if (data == NULL) | |
187 | break; | |
188 | if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand))) { | |
189 | retval = -EFAULT; | |
190 | goto err_out; | |
191 | } | |
192 | if (rio_cmd.length < 0 || rio_cmd.length > PAGE_SIZE) { | |
193 | retval = -EINVAL; | |
194 | goto err_out; | |
195 | } | |
196 | buffer = (unsigned char *) __get_free_page(GFP_KERNEL); | |
197 | if (buffer == NULL) { | |
198 | retval = -ENOMEM; | |
199 | goto err_out; | |
200 | } | |
201 | if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length)) { | |
202 | free_page((unsigned long)buffer); | |
203 | retval = -EFAULT; | |
204 | goto err_out; | |
205 | } | |
206 | ||
207 | requesttype = rio_cmd.requesttype | USB_DIR_OUT | | |
208 | USB_TYPE_VENDOR | USB_RECIP_DEVICE; | |
e1a344d3 GKH |
209 | dev_dbg(&rio->rio_dev->dev, |
210 | "sending command: reqtype=%0x req=%0x value=%0x index=%0x len=%0x\n", | |
211 | requesttype, rio_cmd.request, rio_cmd.value, | |
212 | rio_cmd.index, rio_cmd.length); | |
1da177e4 LT |
213 | /* Send rio control message */ |
214 | retries = 3; | |
215 | while (retries) { | |
216 | result = usb_control_msg(rio->rio_dev, | |
217 | usb_sndctrlpipe(rio-> rio_dev, 0), | |
218 | rio_cmd.request, | |
219 | requesttype, | |
220 | rio_cmd.value, | |
221 | rio_cmd.index, buffer, | |
222 | rio_cmd.length, | |
223 | jiffies_to_msecs(rio_cmd.timeout)); | |
224 | if (result == -ETIMEDOUT) | |
225 | retries--; | |
226 | else if (result < 0) { | |
c41fba13 GKH |
227 | dev_err(&rio->rio_dev->dev, |
228 | "Error executing ioctrl. code = %d\n", | |
229 | result); | |
1da177e4 LT |
230 | retries = 0; |
231 | } else { | |
e1a344d3 GKH |
232 | dev_dbg(&rio->rio_dev->dev, |
233 | "Executed ioctl. Result = %d\n", result); | |
1da177e4 LT |
234 | retries = 0; |
235 | ||
236 | } | |
237 | ||
238 | } | |
239 | free_page((unsigned long) buffer); | |
240 | break; | |
241 | ||
242 | default: | |
243 | retval = -ENOTTY; | |
244 | break; | |
245 | } | |
246 | ||
247 | ||
248 | err_out: | |
2cba72f0 | 249 | mutex_unlock(&(rio->lock)); |
1da177e4 LT |
250 | return retval; |
251 | } | |
252 | ||
253 | static ssize_t | |
254 | write_rio(struct file *file, const char __user *buffer, | |
255 | size_t count, loff_t * ppos) | |
256 | { | |
257 | DEFINE_WAIT(wait); | |
258 | struct rio_usb_data *rio = &rio_instance; | |
259 | ||
260 | unsigned long copy_size; | |
261 | unsigned long bytes_written = 0; | |
262 | unsigned int partial; | |
263 | ||
264 | int result = 0; | |
265 | int maxretry; | |
266 | int errn = 0; | |
2cba72f0 | 267 | int intr; |
1da177e4 | 268 | |
2cba72f0 ON |
269 | intr = mutex_lock_interruptible(&(rio->lock)); |
270 | if (intr) | |
271 | return -EINTR; | |
1da177e4 | 272 | /* Sanity check to make sure rio is connected, powered, etc */ |
3328d975 | 273 | if (rio->present == 0 || rio->rio_dev == NULL) { |
2cba72f0 | 274 | mutex_unlock(&(rio->lock)); |
1da177e4 LT |
275 | return -ENODEV; |
276 | } | |
277 | ||
278 | ||
279 | ||
280 | do { | |
281 | unsigned long thistime; | |
282 | char *obuf = rio->obuf; | |
283 | ||
284 | thistime = copy_size = | |
285 | (count >= OBUF_SIZE) ? OBUF_SIZE : count; | |
286 | if (copy_from_user(rio->obuf, buffer, copy_size)) { | |
287 | errn = -EFAULT; | |
288 | goto error; | |
289 | } | |
290 | maxretry = 5; | |
291 | while (thistime) { | |
292 | if (!rio->rio_dev) { | |
293 | errn = -ENODEV; | |
294 | goto error; | |
295 | } | |
296 | if (signal_pending(current)) { | |
2cba72f0 | 297 | mutex_unlock(&(rio->lock)); |
1da177e4 LT |
298 | return bytes_written ? bytes_written : -EINTR; |
299 | } | |
300 | ||
301 | result = usb_bulk_msg(rio->rio_dev, | |
302 | usb_sndbulkpipe(rio->rio_dev, 2), | |
303 | obuf, thistime, &partial, 5000); | |
304 | ||
e1a344d3 GKH |
305 | dev_dbg(&rio->rio_dev->dev, |
306 | "write stats: result:%d thistime:%lu partial:%u\n", | |
307 | result, thistime, partial); | |
1da177e4 LT |
308 | |
309 | if (result == -ETIMEDOUT) { /* NAK - so hold for a while */ | |
310 | if (!maxretry--) { | |
311 | errn = -ETIME; | |
312 | goto error; | |
313 | } | |
314 | prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE); | |
315 | schedule_timeout(NAK_TIMEOUT); | |
316 | finish_wait(&rio->wait_q, &wait); | |
317 | continue; | |
318 | } else if (!result && partial) { | |
319 | obuf += partial; | |
320 | thistime -= partial; | |
321 | } else | |
322 | break; | |
17e67910 | 323 | } |
1da177e4 | 324 | if (result) { |
c41fba13 GKH |
325 | dev_err(&rio->rio_dev->dev, "Write Whoops - %x\n", |
326 | result); | |
1da177e4 LT |
327 | errn = -EIO; |
328 | goto error; | |
329 | } | |
330 | bytes_written += copy_size; | |
331 | count -= copy_size; | |
332 | buffer += copy_size; | |
333 | } while (count > 0); | |
334 | ||
2cba72f0 | 335 | mutex_unlock(&(rio->lock)); |
1da177e4 LT |
336 | |
337 | return bytes_written ? bytes_written : -EIO; | |
338 | ||
339 | error: | |
2cba72f0 | 340 | mutex_unlock(&(rio->lock)); |
1da177e4 LT |
341 | return errn; |
342 | } | |
343 | ||
344 | static ssize_t | |
345 | read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos) | |
346 | { | |
347 | DEFINE_WAIT(wait); | |
348 | struct rio_usb_data *rio = &rio_instance; | |
349 | ssize_t read_count; | |
350 | unsigned int partial; | |
351 | int this_read; | |
352 | int result; | |
353 | int maxretry = 10; | |
354 | char *ibuf; | |
2cba72f0 | 355 | int intr; |
1da177e4 | 356 | |
2cba72f0 ON |
357 | intr = mutex_lock_interruptible(&(rio->lock)); |
358 | if (intr) | |
359 | return -EINTR; | |
1da177e4 | 360 | /* Sanity check to make sure rio is connected, powered, etc */ |
3328d975 | 361 | if (rio->present == 0 || rio->rio_dev == NULL) { |
2cba72f0 | 362 | mutex_unlock(&(rio->lock)); |
1da177e4 LT |
363 | return -ENODEV; |
364 | } | |
365 | ||
366 | ibuf = rio->ibuf; | |
367 | ||
368 | read_count = 0; | |
369 | ||
370 | ||
371 | while (count > 0) { | |
372 | if (signal_pending(current)) { | |
2cba72f0 | 373 | mutex_unlock(&(rio->lock)); |
1da177e4 LT |
374 | return read_count ? read_count : -EINTR; |
375 | } | |
376 | if (!rio->rio_dev) { | |
2cba72f0 | 377 | mutex_unlock(&(rio->lock)); |
1da177e4 LT |
378 | return -ENODEV; |
379 | } | |
380 | this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count; | |
381 | ||
382 | result = usb_bulk_msg(rio->rio_dev, | |
383 | usb_rcvbulkpipe(rio->rio_dev, 1), | |
384 | ibuf, this_read, &partial, | |
385 | 8000); | |
386 | ||
e1a344d3 GKH |
387 | dev_dbg(&rio->rio_dev->dev, |
388 | "read stats: result:%d this_read:%u partial:%u\n", | |
389 | result, this_read, partial); | |
1da177e4 LT |
390 | |
391 | if (partial) { | |
392 | count = this_read = partial; | |
393 | } else if (result == -ETIMEDOUT || result == 15) { /* FIXME: 15 ??? */ | |
394 | if (!maxretry--) { | |
2cba72f0 | 395 | mutex_unlock(&(rio->lock)); |
c41fba13 GKH |
396 | dev_err(&rio->rio_dev->dev, |
397 | "read_rio: maxretry timeout\n"); | |
1da177e4 LT |
398 | return -ETIME; |
399 | } | |
400 | prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE); | |
401 | schedule_timeout(NAK_TIMEOUT); | |
402 | finish_wait(&rio->wait_q, &wait); | |
403 | continue; | |
404 | } else if (result != -EREMOTEIO) { | |
2cba72f0 | 405 | mutex_unlock(&(rio->lock)); |
c41fba13 | 406 | dev_err(&rio->rio_dev->dev, |
651b297c | 407 | "Read Whoops - result:%d partial:%u this_read:%u\n", |
c41fba13 | 408 | result, partial, this_read); |
1da177e4 LT |
409 | return -EIO; |
410 | } else { | |
2cba72f0 | 411 | mutex_unlock(&(rio->lock)); |
1da177e4 LT |
412 | return (0); |
413 | } | |
414 | ||
415 | if (this_read) { | |
416 | if (copy_to_user(buffer, ibuf, this_read)) { | |
2cba72f0 | 417 | mutex_unlock(&(rio->lock)); |
1da177e4 LT |
418 | return -EFAULT; |
419 | } | |
420 | count -= this_read; | |
421 | read_count += this_read; | |
422 | buffer += this_read; | |
423 | } | |
424 | } | |
2cba72f0 | 425 | mutex_unlock(&(rio->lock)); |
1da177e4 LT |
426 | return read_count; |
427 | } | |
428 | ||
828c0950 | 429 | static const struct file_operations usb_rio_fops = { |
1da177e4 LT |
430 | .owner = THIS_MODULE, |
431 | .read = read_rio, | |
432 | .write = write_rio, | |
54592157 | 433 | .unlocked_ioctl = ioctl_rio, |
1da177e4 LT |
434 | .open = open_rio, |
435 | .release = close_rio, | |
6038f373 | 436 | .llseek = noop_llseek, |
1da177e4 LT |
437 | }; |
438 | ||
439 | static struct usb_class_driver usb_rio_class = { | |
d6e5bcf4 | 440 | .name = "rio500%d", |
1da177e4 | 441 | .fops = &usb_rio_fops, |
1da177e4 LT |
442 | .minor_base = RIO_MINOR, |
443 | }; | |
444 | ||
445 | static int probe_rio(struct usb_interface *intf, | |
446 | const struct usb_device_id *id) | |
447 | { | |
448 | struct usb_device *dev = interface_to_usbdev(intf); | |
449 | struct rio_usb_data *rio = &rio_instance; | |
450 | int retval; | |
451 | ||
1b29a375 | 452 | dev_info(&intf->dev, "USB Rio found at address %d\n", dev->devnum); |
1da177e4 LT |
453 | |
454 | retval = usb_register_dev(intf, &usb_rio_class); | |
455 | if (retval) { | |
c41fba13 GKH |
456 | dev_err(&dev->dev, |
457 | "Not able to get a minor for this device.\n"); | |
1da177e4 LT |
458 | return -ENOMEM; |
459 | } | |
460 | ||
461 | rio->rio_dev = dev; | |
462 | ||
0e8eb0f0 | 463 | if (!(rio->obuf = kmalloc(OBUF_SIZE, GFP_KERNEL))) { |
c41fba13 GKH |
464 | dev_err(&dev->dev, |
465 | "probe_rio: Not enough memory for the output buffer\n"); | |
1da177e4 LT |
466 | usb_deregister_dev(intf, &usb_rio_class); |
467 | return -ENOMEM; | |
468 | } | |
e1a344d3 | 469 | dev_dbg(&intf->dev, "obuf address:%p\n", rio->obuf); |
1da177e4 | 470 | |
0e8eb0f0 | 471 | if (!(rio->ibuf = kmalloc(IBUF_SIZE, GFP_KERNEL))) { |
c41fba13 GKH |
472 | dev_err(&dev->dev, |
473 | "probe_rio: Not enough memory for the input buffer\n"); | |
1da177e4 LT |
474 | usb_deregister_dev(intf, &usb_rio_class); |
475 | kfree(rio->obuf); | |
476 | return -ENOMEM; | |
477 | } | |
e1a344d3 | 478 | dev_dbg(&intf->dev, "ibuf address:%p\n", rio->ibuf); |
1da177e4 | 479 | |
2cba72f0 | 480 | mutex_init(&(rio->lock)); |
1da177e4 LT |
481 | |
482 | usb_set_intfdata (intf, rio); | |
483 | rio->present = 1; | |
484 | ||
485 | return 0; | |
486 | } | |
487 | ||
488 | static void disconnect_rio(struct usb_interface *intf) | |
489 | { | |
490 | struct rio_usb_data *rio = usb_get_intfdata (intf); | |
491 | ||
492 | usb_set_intfdata (intf, NULL); | |
925ce689 | 493 | mutex_lock(&rio500_mutex); |
1da177e4 LT |
494 | if (rio) { |
495 | usb_deregister_dev(intf, &usb_rio_class); | |
496 | ||
2cba72f0 | 497 | mutex_lock(&(rio->lock)); |
1da177e4 LT |
498 | if (rio->isopen) { |
499 | rio->isopen = 0; | |
500 | /* better let it finish - the release will do whats needed */ | |
501 | rio->rio_dev = NULL; | |
2cba72f0 | 502 | mutex_unlock(&(rio->lock)); |
925ce689 | 503 | mutex_unlock(&rio500_mutex); |
1da177e4 LT |
504 | return; |
505 | } | |
506 | kfree(rio->ibuf); | |
507 | kfree(rio->obuf); | |
508 | ||
1b29a375 | 509 | dev_info(&intf->dev, "USB Rio disconnected.\n"); |
1da177e4 LT |
510 | |
511 | rio->present = 0; | |
2cba72f0 | 512 | mutex_unlock(&(rio->lock)); |
1da177e4 | 513 | } |
925ce689 | 514 | mutex_unlock(&rio500_mutex); |
1da177e4 LT |
515 | } |
516 | ||
33b9e162 | 517 | static const struct usb_device_id rio_table[] = { |
1da177e4 LT |
518 | { USB_DEVICE(0x0841, 1) }, /* Rio 500 */ |
519 | { } /* Terminating entry */ | |
520 | }; | |
521 | ||
522 | MODULE_DEVICE_TABLE (usb, rio_table); | |
523 | ||
524 | static struct usb_driver rio_driver = { | |
1da177e4 LT |
525 | .name = "rio500", |
526 | .probe = probe_rio, | |
527 | .disconnect = disconnect_rio, | |
528 | .id_table = rio_table, | |
529 | }; | |
530 | ||
65db4305 | 531 | module_usb_driver(rio_driver); |
1da177e4 LT |
532 | |
533 | MODULE_AUTHOR( DRIVER_AUTHOR ); | |
534 | MODULE_DESCRIPTION( DRIVER_DESC ); | |
535 | MODULE_LICENSE("GPL"); | |
536 |