Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Oliver Neukum and committed by
Greg Kroah-Hartman
8e695cdb abb02fdf

+24 -47
+24 -47
drivers/usb/class/usblp.c
··· 7 7 * Copyright (c) 2000 Vojtech Pavlik <vojtech@suse.cz> 8 8 # Copyright (c) 2001 Pete Zaitcev <zaitcev@redhat.com> 9 9 # Copyright (c) 2001 David Paschal <paschal@rcsis.com> 10 + * Copyright (c) 2006 Oliver Neukum <oliver@neukum.name> 10 11 * 11 12 * USB Printer Device Class driver for USB printers and printer cables 12 13 * ··· 274 273 { 275 274 struct usblp *usblp = urb->context; 276 275 277 - if (!usblp || !usblp->dev || !usblp->used || !usblp->present) 276 + if (unlikely(!usblp || !usblp->dev || !usblp->used)) 278 277 return; 279 278 279 + if (unlikely(!usblp->present)) 280 + goto unplug; 280 281 if (unlikely(urb->status)) 281 282 warn("usblp%d: nonzero read/write bulk status received: %d", 282 283 usblp->minor, urb->status); 283 284 usblp->rcomplete = 1; 285 + unplug: 284 286 wake_up_interruptible(&usblp->wait); 285 287 } 286 288 ··· 291 287 { 292 288 struct usblp *usblp = urb->context; 293 289 294 - if (!usblp || !usblp->dev || !usblp->used || !usblp->present) 290 + if (unlikely(!usblp || !usblp->dev || !usblp->used)) 295 291 return; 296 - 292 + if (unlikely(!usblp->present)) 293 + goto unplug; 297 294 if (unlikely(urb->status)) 298 295 warn("usblp%d: nonzero read/write bulk status received: %d", 299 296 usblp->minor, urb->status); 300 297 usblp->wcomplete = 1; 298 + unplug: 301 299 wake_up_interruptible(&usblp->wait); 302 300 } 303 301 ··· 633 627 634 628 static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) 635 629 { 636 - DECLARE_WAITQUEUE(wait, current); 637 630 struct usblp *usblp = file->private_data; 638 - int timeout, err = 0, transfer_length = 0; 631 + int timeout, rv, err = 0, transfer_length = 0; 639 632 size_t writecount = 0; 640 633 641 634 while (writecount < count) { ··· 646 641 } 647 642 648 643 timeout = USBLP_WRITE_TIMEOUT; 649 - add_wait_queue(&usblp->wait, &wait); 650 - while ( 1==1 ) { 651 644 652 - if (signal_pending(current)) { 653 - remove_wait_queue(&usblp->wait, &wait); 654 - return writecount ? writecount : -EINTR; 655 - } 656 - set_current_state(TASK_INTERRUPTIBLE); 657 - if (timeout && !usblp->wcomplete) { 658 - timeout = schedule_timeout(timeout); 659 - } else { 660 - set_current_state(TASK_RUNNING); 661 - break; 662 - } 663 - } 664 - remove_wait_queue(&usblp->wait, &wait); 645 + rv = wait_event_interruptible_timeout(usblp->wait, usblp->wcomplete || !usblp->present , timeout); 646 + if (rv < 0) 647 + return writecount ? writecount : -EINTR; 665 648 } 666 - 667 649 down (&usblp->sem); 668 650 if (!usblp->present) { 669 651 up (&usblp->sem); ··· 716 724 static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) 717 725 { 718 726 struct usblp *usblp = file->private_data; 719 - DECLARE_WAITQUEUE(wait, current); 727 + int rv; 720 728 721 729 if (!usblp->bidir) 722 730 return -EINVAL; ··· 734 742 count = -EAGAIN; 735 743 goto done; 736 744 } 737 - 738 - add_wait_queue(&usblp->wait, &wait); 739 - while (1==1) { 740 - if (signal_pending(current)) { 741 - count = -EINTR; 742 - remove_wait_queue(&usblp->wait, &wait); 743 - goto done; 744 - } 745 - up (&usblp->sem); 746 - set_current_state(TASK_INTERRUPTIBLE); 747 - if (!usblp->rcomplete) { 748 - schedule(); 749 - } else { 750 - set_current_state(TASK_RUNNING); 751 - down(&usblp->sem); 752 - break; 753 - } 754 - down (&usblp->sem); 745 + up(&usblp->sem); 746 + rv = wait_event_interruptible(usblp->wait, usblp->rcomplete || !usblp->present); 747 + down(&usblp->sem); 748 + if (rv < 0) { 749 + count = -EINTR; 750 + goto done; 755 751 } 756 - remove_wait_queue(&usblp->wait, &wait); 757 752 } 758 753 759 754 if (!usblp->present) { ··· 853 874 854 875 /* Malloc and start initializing usblp structure so we can use it 855 876 * directly. */ 856 - if (!(usblp = kmalloc(sizeof(struct usblp), GFP_KERNEL))) { 877 + if (!(usblp = kzalloc(sizeof(struct usblp), GFP_KERNEL))) { 857 878 err("out of memory for usblp"); 858 879 goto abort; 859 880 } 860 - memset(usblp, 0, sizeof(struct usblp)); 861 881 usblp->dev = dev; 862 882 init_MUTEX (&usblp->sem); 863 883 init_waitqueue_head(&usblp->wait); ··· 1192 1214 { 1193 1215 int retval; 1194 1216 retval = usb_register(&usblp_driver); 1195 - if (retval) 1196 - goto out; 1197 - info(DRIVER_VERSION ": " DRIVER_DESC); 1198 - out: 1217 + if (!retval) 1218 + info(DRIVER_VERSION ": " DRIVER_DESC); 1219 + 1199 1220 return retval; 1200 1221 } 1201 1222