aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/class/usblp.c
diff options
context:
space:
mode:
authorOliver Neukum <neukum@fachschaft.cup.uni-muenchen.de>2006-01-07 15:35:20 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-01-31 20:23:37 -0500
commit8e695cdbffe66f5d3142a363f47053be9f83a90d (patch)
tree5bca03e23ce1a6ba89ac90da202958fb19881095 /drivers/usb/class/usblp.c
parentabb02fdf83f981f2511b3772db6e106845c70ad9 (diff)
[PATCH] USB: cleanup of usblp
this fixes -potential hang by disconnecting through usbfs -kzalloc -general cleanup -micro optimisation in interrupt handlers It compiles and I am printing. Signed-off-by: Oliver Neukum <oliver@neukum.name> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/class/usblp.c')
-rw-r--r--drivers/usb/class/usblp.c71
1 files changed, 24 insertions, 47 deletions
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;
286unplug:
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;
302unplug:
297 wake_up_interruptible(&usblp->wait); 303 wake_up_interruptible(&usblp->wait);
298} 304}
299 305
@@ -627,9 +633,8 @@ done:
627 633
628static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) 634static 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
724static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) 716static 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
1220out:
1221 return retval; 1198 return retval;
1222} 1199}
1223 1200