diff options
Diffstat (limited to 'drivers/usb/class')
| -rw-r--r-- | drivers/usb/class/cdc-acm.c | 9 | ||||
| -rw-r--r-- | drivers/usb/class/usblp.c | 71 |
2 files changed, 31 insertions, 49 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index b9fd39fd1b5b..97bdeb1c2181 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
| @@ -1014,8 +1014,13 @@ static void acm_disconnect(struct usb_interface *intf) | |||
| 1014 | } | 1014 | } |
| 1015 | 1015 | ||
| 1016 | down(&open_sem); | 1016 | down(&open_sem); |
| 1017 | if (!usb_get_intfdata(intf)) { | ||
| 1018 | up(&open_sem); | ||
| 1019 | return; | ||
| 1020 | } | ||
| 1017 | acm->dev = NULL; | 1021 | acm->dev = NULL; |
| 1018 | usb_set_intfdata (intf, NULL); | 1022 | usb_set_intfdata(acm->control, NULL); |
| 1023 | usb_set_intfdata(acm->data, NULL); | ||
| 1019 | 1024 | ||
| 1020 | tasklet_disable(&acm->urb_task); | 1025 | tasklet_disable(&acm->urb_task); |
| 1021 | 1026 | ||
| @@ -1036,7 +1041,7 @@ static void acm_disconnect(struct usb_interface *intf) | |||
| 1036 | for (i = 0; i < ACM_NRB; i++) | 1041 | for (i = 0; i < ACM_NRB; i++) |
| 1037 | usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma); | 1042 | usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma); |
| 1038 | 1043 | ||
| 1039 | usb_driver_release_interface(&acm_driver, acm->data); | 1044 | usb_driver_release_interface(&acm_driver, intf == acm->control ? acm->data : intf); |
| 1040 | 1045 | ||
| 1041 | if (!acm->used) { | 1046 | if (!acm->used) { |
| 1042 | acm_tty_unregister(acm); | 1047 | acm_tty_unregister(acm); |
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index dba4cc026077..d34848ac30b0 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | * Copyright (c) 2000 Vojtech Pavlik <vojtech@suse.cz> | 7 | * Copyright (c) 2000 Vojtech Pavlik <vojtech@suse.cz> |
| 8 | # Copyright (c) 2001 Pete Zaitcev <zaitcev@redhat.com> | 8 | # Copyright (c) 2001 Pete Zaitcev <zaitcev@redhat.com> |
| 9 | # Copyright (c) 2001 David Paschal <paschal@rcsis.com> | 9 | # Copyright (c) 2001 David Paschal <paschal@rcsis.com> |
| 10 | * Copyright (c) 2006 Oliver Neukum <oliver@neukum.name> | ||
| 10 | * | 11 | * |
| 11 | * USB Printer Device Class driver for USB printers and printer cables | 12 | * USB Printer Device Class driver for USB printers and printer cables |
| 12 | * | 13 | * |
| @@ -273,13 +274,16 @@ static void usblp_bulk_read(struct urb *urb, struct pt_regs *regs) | |||
| 273 | { | 274 | { |
| 274 | struct usblp *usblp = urb->context; | 275 | struct usblp *usblp = urb->context; |
| 275 | 276 | ||
| 276 | if (!usblp || !usblp->dev || !usblp->used || !usblp->present) | 277 | if (unlikely(!usblp || !usblp->dev || !usblp->used)) |
| 277 | return; | 278 | return; |
| 278 | 279 | ||
| 280 | if (unlikely(!usblp->present)) | ||
| 281 | goto unplug; | ||
| 279 | if (unlikely(urb->status)) | 282 | if (unlikely(urb->status)) |
| 280 | warn("usblp%d: nonzero read/write bulk status received: %d", | 283 | warn("usblp%d: nonzero read/write bulk status received: %d", |
| 281 | usblp->minor, urb->status); | 284 | usblp->minor, urb->status); |
| 282 | usblp->rcomplete = 1; | 285 | usblp->rcomplete = 1; |
| 286 | unplug: | ||
| 283 | wake_up_interruptible(&usblp->wait); | 287 | wake_up_interruptible(&usblp->wait); |
| 284 | } | 288 | } |
| 285 | 289 | ||
| @@ -287,13 +291,15 @@ static void usblp_bulk_write(struct urb *urb, struct pt_regs *regs) | |||
| 287 | { | 291 | { |
| 288 | struct usblp *usblp = urb->context; | 292 | struct usblp *usblp = urb->context; |
| 289 | 293 | ||
| 290 | if (!usblp || !usblp->dev || !usblp->used || !usblp->present) | 294 | if (unlikely(!usblp || !usblp->dev || !usblp->used)) |
| 291 | return; | 295 | return; |
| 292 | 296 | if (unlikely(!usblp->present)) | |
| 297 | goto unplug; | ||
| 293 | if (unlikely(urb->status)) | 298 | if (unlikely(urb->status)) |
| 294 | warn("usblp%d: nonzero read/write bulk status received: %d", | 299 | warn("usblp%d: nonzero read/write bulk status received: %d", |
| 295 | usblp->minor, urb->status); | 300 | usblp->minor, urb->status); |
| 296 | usblp->wcomplete = 1; | 301 | usblp->wcomplete = 1; |
| 302 | unplug: | ||
| 297 | wake_up_interruptible(&usblp->wait); | 303 | wake_up_interruptible(&usblp->wait); |
| 298 | } | 304 | } |
| 299 | 305 | ||
| @@ -627,9 +633,8 @@ done: | |||
| 627 | 633 | ||
| 628 | static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) | 634 | static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) |
| 629 | { | 635 | { |
| 630 | DECLARE_WAITQUEUE(wait, current); | ||
| 631 | struct usblp *usblp = file->private_data; | 636 | struct usblp *usblp = file->private_data; |
| 632 | int timeout, err = 0, transfer_length = 0; | 637 | int timeout, rv, err = 0, transfer_length = 0; |
| 633 | size_t writecount = 0; | 638 | size_t writecount = 0; |
| 634 | 639 | ||
| 635 | while (writecount < count) { | 640 | while (writecount < count) { |
| @@ -641,24 +646,11 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t | |||
| 641 | } | 646 | } |
| 642 | 647 | ||
| 643 | timeout = USBLP_WRITE_TIMEOUT; | 648 | timeout = USBLP_WRITE_TIMEOUT; |
| 644 | add_wait_queue(&usblp->wait, &wait); | ||
| 645 | while ( 1==1 ) { | ||
| 646 | 649 | ||
| 647 | if (signal_pending(current)) { | 650 | rv = wait_event_interruptible_timeout(usblp->wait, usblp->wcomplete || !usblp->present , timeout); |
| 648 | remove_wait_queue(&usblp->wait, &wait); | 651 | if (rv < 0) |
| 649 | return writecount ? writecount : -EINTR; | 652 | return writecount ? writecount : -EINTR; |
| 650 | } | ||
| 651 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 652 | if (timeout && !usblp->wcomplete) { | ||
| 653 | timeout = schedule_timeout(timeout); | ||
| 654 | } else { | ||
| 655 | set_current_state(TASK_RUNNING); | ||
| 656 | break; | ||
| 657 | } | ||
| 658 | } | ||
| 659 | remove_wait_queue(&usblp->wait, &wait); | ||
| 660 | } | 653 | } |
| 661 | |||
| 662 | down (&usblp->sem); | 654 | down (&usblp->sem); |
| 663 | if (!usblp->present) { | 655 | if (!usblp->present) { |
| 664 | up (&usblp->sem); | 656 | up (&usblp->sem); |
| @@ -724,7 +716,7 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t | |||
| 724 | static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) | 716 | static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) |
| 725 | { | 717 | { |
| 726 | struct usblp *usblp = file->private_data; | 718 | struct usblp *usblp = file->private_data; |
| 727 | DECLARE_WAITQUEUE(wait, current); | 719 | int rv; |
| 728 | 720 | ||
| 729 | if (!usblp->bidir) | 721 | if (!usblp->bidir) |
| 730 | return -EINVAL; | 722 | return -EINVAL; |
| @@ -742,26 +734,13 @@ static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count, | |||
| 742 | count = -EAGAIN; | 734 | count = -EAGAIN; |
| 743 | goto done; | 735 | goto done; |
| 744 | } | 736 | } |
| 745 | 737 | up(&usblp->sem); | |
| 746 | add_wait_queue(&usblp->wait, &wait); | 738 | rv = wait_event_interruptible(usblp->wait, usblp->rcomplete || !usblp->present); |
| 747 | while (1==1) { | 739 | down(&usblp->sem); |
| 748 | if (signal_pending(current)) { | 740 | if (rv < 0) { |
| 749 | count = -EINTR; | 741 | count = -EINTR; |
| 750 | remove_wait_queue(&usblp->wait, &wait); | 742 | goto done; |
| 751 | goto done; | ||
| 752 | } | ||
| 753 | up (&usblp->sem); | ||
| 754 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 755 | if (!usblp->rcomplete) { | ||
| 756 | schedule(); | ||
| 757 | } else { | ||
| 758 | set_current_state(TASK_RUNNING); | ||
| 759 | down(&usblp->sem); | ||
| 760 | break; | ||
| 761 | } | ||
| 762 | down (&usblp->sem); | ||
| 763 | } | 743 | } |
| 764 | remove_wait_queue(&usblp->wait, &wait); | ||
| 765 | } | 744 | } |
| 766 | 745 | ||
| 767 | if (!usblp->present) { | 746 | if (!usblp->present) { |
| @@ -874,11 +853,10 @@ static int usblp_probe(struct usb_interface *intf, | |||
| 874 | 853 | ||
| 875 | /* Malloc and start initializing usblp structure so we can use it | 854 | /* Malloc and start initializing usblp structure so we can use it |
| 876 | * directly. */ | 855 | * directly. */ |
| 877 | if (!(usblp = kmalloc(sizeof(struct usblp), GFP_KERNEL))) { | 856 | if (!(usblp = kzalloc(sizeof(struct usblp), GFP_KERNEL))) { |
| 878 | err("out of memory for usblp"); | 857 | err("out of memory for usblp"); |
| 879 | goto abort; | 858 | goto abort; |
| 880 | } | 859 | } |
| 881 | memset(usblp, 0, sizeof(struct usblp)); | ||
| 882 | usblp->dev = dev; | 860 | usblp->dev = dev; |
| 883 | init_MUTEX (&usblp->sem); | 861 | init_MUTEX (&usblp->sem); |
| 884 | init_waitqueue_head(&usblp->wait); | 862 | init_waitqueue_head(&usblp->wait); |
| @@ -1214,10 +1192,9 @@ static int __init usblp_init(void) | |||
| 1214 | { | 1192 | { |
| 1215 | int retval; | 1193 | int retval; |
| 1216 | retval = usb_register(&usblp_driver); | 1194 | retval = usb_register(&usblp_driver); |
| 1217 | if (retval) | 1195 | if (!retval) |
| 1218 | goto out; | 1196 | info(DRIVER_VERSION ": " DRIVER_DESC); |
| 1219 | info(DRIVER_VERSION ": " DRIVER_DESC); | 1197 | |
| 1220 | out: | ||
| 1221 | return retval; | 1198 | return retval; |
| 1222 | } | 1199 | } |
| 1223 | 1200 | ||
