diff options
author | Jarod Wilson <jarod@redhat.com> | 2010-10-18 10:57:06 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-10-22 18:05:36 -0400 |
commit | 917167e9a34f7577086ccfcbf07f6fb96a209a31 (patch) | |
tree | bdf9bbd22b00df0a355353741c225a7e220005e8 | |
parent | a36e83c94ca9bfae8dae8a7ab98f18931f70612d (diff) |
[media] lirc_igorplugusb: assorted fixups
Tighten up error checking, rename some functions to less generic names,
remove unnecessary cruft, add missing debug modparam wiring, and fix up
some printk output.
Signed-off-by: Jarod Wilson <jarod@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/staging/lirc/lirc_igorplugusb.c | 123 |
1 files changed, 65 insertions, 58 deletions
diff --git a/drivers/staging/lirc/lirc_igorplugusb.c b/drivers/staging/lirc/lirc_igorplugusb.c index e680d8897106..b9a4ffd9c7a4 100644 --- a/drivers/staging/lirc/lirc_igorplugusb.c +++ b/drivers/staging/lirc/lirc_igorplugusb.c | |||
@@ -57,7 +57,7 @@ | |||
57 | #define DRIVER_VERSION "0.1" | 57 | #define DRIVER_VERSION "0.1" |
58 | #define DRIVER_AUTHOR \ | 58 | #define DRIVER_AUTHOR \ |
59 | "Jan M. Hochstein <hochstein@algo.informatik.tu-darmstadt.de>" | 59 | "Jan M. Hochstein <hochstein@algo.informatik.tu-darmstadt.de>" |
60 | #define DRIVER_DESC "USB remote driver for LIRC" | 60 | #define DRIVER_DESC "Igorplug USB remote driver for LIRC" |
61 | #define DRIVER_NAME "lirc_igorplugusb" | 61 | #define DRIVER_NAME "lirc_igorplugusb" |
62 | 62 | ||
63 | /* debugging support */ | 63 | /* debugging support */ |
@@ -201,7 +201,6 @@ struct igorplug { | |||
201 | 201 | ||
202 | /* usb */ | 202 | /* usb */ |
203 | struct usb_device *usbdev; | 203 | struct usb_device *usbdev; |
204 | struct urb *urb_in; | ||
205 | int devnum; | 204 | int devnum; |
206 | 205 | ||
207 | unsigned char *buf_in; | 206 | unsigned char *buf_in; |
@@ -216,28 +215,36 @@ struct igorplug { | |||
216 | 215 | ||
217 | /* handle sending (init strings) */ | 216 | /* handle sending (init strings) */ |
218 | int send_flags; | 217 | int send_flags; |
219 | wait_queue_head_t wait_out; | ||
220 | }; | 218 | }; |
221 | 219 | ||
222 | static int unregister_from_lirc(struct igorplug *ir) | 220 | static int unregister_from_lirc(struct igorplug *ir) |
223 | { | 221 | { |
224 | struct lirc_driver *d = ir->d; | 222 | struct lirc_driver *d; |
225 | int devnum; | 223 | int devnum; |
226 | 224 | ||
227 | if (!ir->d) | 225 | if (!ir) { |
226 | printk(KERN_ERR "%s: called with NULL device struct!\n", | ||
227 | __func__); | ||
228 | return -EINVAL; | 228 | return -EINVAL; |
229 | } | ||
229 | 230 | ||
230 | devnum = ir->devnum; | 231 | devnum = ir->devnum; |
231 | dprintk(DRIVER_NAME "[%d]: unregister from lirc called\n", devnum); | 232 | d = ir->d; |
232 | 233 | ||
233 | lirc_unregister_driver(d->minor); | 234 | if (!d) { |
235 | printk(KERN_ERR "%s: called with NULL lirc driver struct!\n", | ||
236 | __func__); | ||
237 | return -EINVAL; | ||
238 | } | ||
234 | 239 | ||
235 | printk(DRIVER_NAME "[%d]: usb remote disconnected\n", devnum); | 240 | dprintk(DRIVER_NAME "[%d]: calling lirc_unregister_driver\n", devnum); |
241 | lirc_unregister_driver(d->minor); | ||
236 | 242 | ||
237 | kfree(d); | 243 | kfree(d); |
238 | ir->d = NULL; | 244 | ir->d = NULL; |
239 | kfree(ir); | 245 | kfree(ir); |
240 | return 0; | 246 | |
247 | return devnum; | ||
241 | } | 248 | } |
242 | 249 | ||
243 | static int set_use_inc(void *data) | 250 | static int set_use_inc(void *data) |
@@ -248,6 +255,7 @@ static int set_use_inc(void *data) | |||
248 | printk(DRIVER_NAME "[?]: set_use_inc called with no context\n"); | 255 | printk(DRIVER_NAME "[?]: set_use_inc called with no context\n"); |
249 | return -EIO; | 256 | return -EIO; |
250 | } | 257 | } |
258 | |||
251 | dprintk(DRIVER_NAME "[%d]: set use inc\n", ir->devnum); | 259 | dprintk(DRIVER_NAME "[%d]: set use inc\n", ir->devnum); |
252 | 260 | ||
253 | if (!ir->usbdev) | 261 | if (!ir->usbdev) |
@@ -264,6 +272,7 @@ static void set_use_dec(void *data) | |||
264 | printk(DRIVER_NAME "[?]: set_use_dec called with no context\n"); | 272 | printk(DRIVER_NAME "[?]: set_use_dec called with no context\n"); |
265 | return; | 273 | return; |
266 | } | 274 | } |
275 | |||
267 | dprintk(DRIVER_NAME "[%d]: set use dec\n", ir->devnum); | 276 | dprintk(DRIVER_NAME "[%d]: set use dec\n", ir->devnum); |
268 | } | 277 | } |
269 | 278 | ||
@@ -274,22 +283,21 @@ static void set_use_dec(void *data) | |||
274 | * -ENODATA if none was available. This should add some number of bits | 283 | * -ENODATA if none was available. This should add some number of bits |
275 | * evenly divisible by code_length to the buffer | 284 | * evenly divisible by code_length to the buffer |
276 | */ | 285 | */ |
277 | static int usb_remote_poll(void *data, struct lirc_buffer *buf) | 286 | static int igorplugusb_remote_poll(void *data, struct lirc_buffer *buf) |
278 | { | 287 | { |
279 | int ret; | 288 | int ret; |
280 | struct igorplug *ir = (struct igorplug *)data; | 289 | struct igorplug *ir = (struct igorplug *)data; |
281 | 290 | ||
282 | if (!ir->usbdev) /* Has the device been removed? */ | 291 | if (!ir || !ir->usbdev) /* Has the device been removed? */ |
283 | return -ENODEV; | 292 | return -ENODEV; |
284 | 293 | ||
285 | memset(ir->buf_in, 0, ir->len_in); | 294 | memset(ir->buf_in, 0, ir->len_in); |
286 | 295 | ||
287 | ret = usb_control_msg( | 296 | ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), |
288 | ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), | 297 | GET_INFRACODE, USB_TYPE_VENDOR | USB_DIR_IN, |
289 | GET_INFRACODE, USB_TYPE_VENDOR|USB_DIR_IN, | 298 | 0/* offset */, /*unused*/0, |
290 | 0/* offset */, /*unused*/0, | 299 | ir->buf_in, ir->len_in, |
291 | ir->buf_in, ir->len_in, | 300 | /*timeout*/HZ * USB_CTRL_GET_TIMEOUT); |
292 | /*timeout*/HZ * USB_CTRL_GET_TIMEOUT); | ||
293 | if (ret > 0) { | 301 | if (ret > 0) { |
294 | int i = DEVICE_HEADERLEN; | 302 | int i = DEVICE_HEADERLEN; |
295 | int code, timediff; | 303 | int code, timediff; |
@@ -358,12 +366,12 @@ static int usb_remote_poll(void *data, struct lirc_buffer *buf) | |||
358 | 366 | ||
359 | 367 | ||
360 | 368 | ||
361 | static int usb_remote_probe(struct usb_interface *intf, | 369 | static int igorplugusb_remote_probe(struct usb_interface *intf, |
362 | const struct usb_device_id *id) | 370 | const struct usb_device_id *id) |
363 | { | 371 | { |
364 | struct usb_device *dev = NULL; | 372 | struct usb_device *dev = NULL; |
365 | struct usb_host_interface *idesc = NULL; | 373 | struct usb_host_interface *idesc = NULL; |
366 | struct usb_host_endpoint *ep_ctl2; | 374 | struct usb_endpoint_descriptor *ep; |
367 | struct igorplug *ir = NULL; | 375 | struct igorplug *ir = NULL; |
368 | struct lirc_driver *driver = NULL; | 376 | struct lirc_driver *driver = NULL; |
369 | int devnum, pipe, maxp; | 377 | int devnum, pipe, maxp; |
@@ -380,20 +388,21 @@ static int usb_remote_probe(struct usb_interface *intf, | |||
380 | 388 | ||
381 | if (idesc->desc.bNumEndpoints != 1) | 389 | if (idesc->desc.bNumEndpoints != 1) |
382 | return -ENODEV; | 390 | return -ENODEV; |
383 | ep_ctl2 = idesc->endpoint; | 391 | |
384 | if (((ep_ctl2->desc.bEndpointAddress & USB_ENDPOINT_DIR_MASK) | 392 | ep = &idesc->endpoint->desc; |
393 | if (((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) | ||
385 | != USB_DIR_IN) | 394 | != USB_DIR_IN) |
386 | || (ep_ctl2->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | 395 | || (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) |
387 | != USB_ENDPOINT_XFER_CONTROL) | 396 | != USB_ENDPOINT_XFER_CONTROL) |
388 | return -ENODEV; | 397 | return -ENODEV; |
389 | pipe = usb_rcvctrlpipe(dev, ep_ctl2->desc.bEndpointAddress); | 398 | |
399 | pipe = usb_rcvctrlpipe(dev, ep->bEndpointAddress); | ||
390 | devnum = dev->devnum; | 400 | devnum = dev->devnum; |
391 | maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); | 401 | maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); |
392 | 402 | ||
393 | dprintk(DRIVER_NAME "[%d]: bytes_in_key=%zu maxp=%d\n", | 403 | dprintk(DRIVER_NAME "[%d]: bytes_in_key=%zu maxp=%d\n", |
394 | devnum, CODE_LENGTH, maxp); | 404 | devnum, CODE_LENGTH, maxp); |
395 | 405 | ||
396 | |||
397 | mem_failure = 0; | 406 | mem_failure = 0; |
398 | ir = kzalloc(sizeof(struct igorplug), GFP_KERNEL); | 407 | ir = kzalloc(sizeof(struct igorplug), GFP_KERNEL); |
399 | if (!ir) { | 408 | if (!ir) { |
@@ -406,9 +415,8 @@ static int usb_remote_probe(struct usb_interface *intf, | |||
406 | goto mem_failure_switch; | 415 | goto mem_failure_switch; |
407 | } | 416 | } |
408 | 417 | ||
409 | ir->buf_in = usb_alloc_coherent(dev, | 418 | ir->buf_in = usb_alloc_coherent(dev, DEVICE_BUFLEN + DEVICE_HEADERLEN, |
410 | DEVICE_BUFLEN+DEVICE_HEADERLEN, | 419 | GFP_ATOMIC, &ir->dma_in); |
411 | GFP_ATOMIC, &ir->dma_in); | ||
412 | if (!ir->buf_in) { | 420 | if (!ir->buf_in) { |
413 | mem_failure = 3; | 421 | mem_failure = 3; |
414 | goto mem_failure_switch; | 422 | goto mem_failure_switch; |
@@ -424,12 +432,10 @@ static int usb_remote_probe(struct usb_interface *intf, | |||
424 | driver->set_use_inc = &set_use_inc; | 432 | driver->set_use_inc = &set_use_inc; |
425 | driver->set_use_dec = &set_use_dec; | 433 | driver->set_use_dec = &set_use_dec; |
426 | driver->sample_rate = sample_rate; /* per second */ | 434 | driver->sample_rate = sample_rate; /* per second */ |
427 | driver->add_to_buf = &usb_remote_poll; | 435 | driver->add_to_buf = &igorplugusb_remote_poll; |
428 | driver->dev = &intf->dev; | 436 | driver->dev = &intf->dev; |
429 | driver->owner = THIS_MODULE; | 437 | driver->owner = THIS_MODULE; |
430 | 438 | ||
431 | init_waitqueue_head(&ir->wait_out); | ||
432 | |||
433 | minor = lirc_register_driver(driver); | 439 | minor = lirc_register_driver(driver); |
434 | if (minor < 0) | 440 | if (minor < 0) |
435 | mem_failure = 9; | 441 | mem_failure = 9; |
@@ -484,24 +490,28 @@ mem_failure_switch: | |||
484 | } | 490 | } |
485 | 491 | ||
486 | 492 | ||
487 | static void usb_remote_disconnect(struct usb_interface *intf) | 493 | static void igorplugusb_remote_disconnect(struct usb_interface *intf) |
488 | { | 494 | { |
489 | struct usb_device *dev = interface_to_usbdev(intf); | 495 | struct usb_device *usbdev = interface_to_usbdev(intf); |
490 | struct igorplug *ir = usb_get_intfdata(intf); | 496 | struct igorplug *ir = usb_get_intfdata(intf); |
497 | struct device *dev = &intf->dev; | ||
498 | int devnum; | ||
499 | |||
491 | usb_set_intfdata(intf, NULL); | 500 | usb_set_intfdata(intf, NULL); |
492 | 501 | ||
493 | if (!ir || !ir->d) | 502 | if (!ir || !ir->d) |
494 | return; | 503 | return; |
495 | 504 | ||
496 | ir->usbdev = NULL; | 505 | ir->usbdev = NULL; |
497 | wake_up_all(&ir->wait_out); | ||
498 | 506 | ||
499 | usb_free_coherent(dev, ir->len_in, ir->buf_in, ir->dma_in); | 507 | usb_free_coherent(usbdev, ir->len_in, ir->buf_in, ir->dma_in); |
508 | |||
509 | devnum = unregister_from_lirc(ir); | ||
500 | 510 | ||
501 | unregister_from_lirc(ir); | 511 | dev_info(dev, DRIVER_NAME "[%d]: %s done\n", devnum, __func__); |
502 | } | 512 | } |
503 | 513 | ||
504 | static struct usb_device_id usb_remote_id_table[] = { | 514 | static struct usb_device_id igorplugusb_remote_id_table[] = { |
505 | /* Igor Plug USB (Atmel's Manufact. ID) */ | 515 | /* Igor Plug USB (Atmel's Manufact. ID) */ |
506 | { USB_DEVICE(0x03eb, 0x0002) }, | 516 | { USB_DEVICE(0x03eb, 0x0002) }, |
507 | 517 | ||
@@ -509,38 +519,33 @@ static struct usb_device_id usb_remote_id_table[] = { | |||
509 | { } | 519 | { } |
510 | }; | 520 | }; |
511 | 521 | ||
512 | static struct usb_driver usb_remote_driver = { | 522 | static struct usb_driver igorplugusb_remote_driver = { |
513 | .name = DRIVER_NAME, | 523 | .name = DRIVER_NAME, |
514 | .probe = usb_remote_probe, | 524 | .probe = igorplugusb_remote_probe, |
515 | .disconnect = usb_remote_disconnect, | 525 | .disconnect = igorplugusb_remote_disconnect, |
516 | .id_table = usb_remote_id_table | 526 | .id_table = igorplugusb_remote_id_table |
517 | }; | 527 | }; |
518 | 528 | ||
519 | static int __init usb_remote_init(void) | 529 | static int __init igorplugusb_remote_init(void) |
520 | { | 530 | { |
521 | int i; | 531 | int ret = 0; |
522 | 532 | ||
523 | printk(KERN_INFO "\n" | 533 | dprintk(DRIVER_NAME ": loaded, debug mode enabled\n"); |
524 | DRIVER_NAME ": " DRIVER_DESC " v" DRIVER_VERSION "\n"); | ||
525 | printk(DRIVER_NAME ": " DRIVER_AUTHOR "\n"); | ||
526 | dprintk(DRIVER_NAME ": debug mode enabled\n"); | ||
527 | 534 | ||
528 | i = usb_register(&usb_remote_driver); | 535 | ret = usb_register(&igorplugusb_remote_driver); |
529 | if (i < 0) { | 536 | if (ret) |
530 | printk(DRIVER_NAME ": usb register failed, result = %d\n", i); | 537 | printk(KERN_ERR DRIVER_NAME ": usb register failed!\n"); |
531 | return -ENODEV; | ||
532 | } | ||
533 | 538 | ||
534 | return 0; | 539 | return ret; |
535 | } | 540 | } |
536 | 541 | ||
537 | static void __exit usb_remote_exit(void) | 542 | static void __exit igorplugusb_remote_exit(void) |
538 | { | 543 | { |
539 | usb_deregister(&usb_remote_driver); | 544 | usb_deregister(&igorplugusb_remote_driver); |
540 | } | 545 | } |
541 | 546 | ||
542 | module_init(usb_remote_init); | 547 | module_init(igorplugusb_remote_init); |
543 | module_exit(usb_remote_exit); | 548 | module_exit(igorplugusb_remote_exit); |
544 | 549 | ||
545 | #include <linux/vermagic.h> | 550 | #include <linux/vermagic.h> |
546 | MODULE_INFO(vermagic, VERMAGIC_STRING); | 551 | MODULE_INFO(vermagic, VERMAGIC_STRING); |
@@ -548,8 +553,10 @@ MODULE_INFO(vermagic, VERMAGIC_STRING); | |||
548 | MODULE_DESCRIPTION(DRIVER_DESC); | 553 | MODULE_DESCRIPTION(DRIVER_DESC); |
549 | MODULE_AUTHOR(DRIVER_AUTHOR); | 554 | MODULE_AUTHOR(DRIVER_AUTHOR); |
550 | MODULE_LICENSE("GPL"); | 555 | MODULE_LICENSE("GPL"); |
551 | MODULE_DEVICE_TABLE(usb, usb_remote_id_table); | 556 | MODULE_DEVICE_TABLE(usb, igorplugusb_remote_id_table); |
552 | 557 | ||
553 | module_param(sample_rate, int, S_IRUGO | S_IWUSR); | 558 | module_param(sample_rate, int, S_IRUGO | S_IWUSR); |
554 | MODULE_PARM_DESC(sample_rate, "Sampling rate in Hz (default: 100)"); | 559 | MODULE_PARM_DESC(sample_rate, "Sampling rate in Hz (default: 100)"); |
555 | 560 | ||
561 | module_param(debug, bool, S_IRUGO | S_IWUSR); | ||
562 | MODULE_PARM_DESC(debug, "Debug enabled or not"); | ||