aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/class/usblp.c
diff options
context:
space:
mode:
authorOliver Neukum <oliver@neukum.name>2006-12-03 03:46:35 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-12-20 13:13:23 -0500
commit8e42266965b9db03a86d2cf55400cd3afb67a114 (patch)
treeaacd80bf9337be749046bb1612438e54a51779da /drivers/usb/class/usblp.c
parentb1cff285ae8d21012ad3717e412b0f50066dc061 (diff)
USB: mutexification of usblp
this patch: - converts usblp fully to mutex - makes sleeping interruptible where EINTR can be returned anyway 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.c54
1 files changed, 29 insertions, 25 deletions
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index 6303970e93c1..24ee8be359f5 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -130,7 +130,7 @@ MFG:HEWLETT-PACKARD;MDL:DESKJET 970C;CMD:MLC,PCL,PML;CLASS:PRINTER;DESCRIPTION:H
130 130
131struct usblp { 131struct usblp {
132 struct usb_device *dev; /* USB device */ 132 struct usb_device *dev; /* USB device */
133 struct semaphore sem; /* locks this struct, especially "dev" */ 133 struct mutex mut; /* locks this struct, especially "dev" */
134 char *writebuf; /* write transfer_buffer */ 134 char *writebuf; /* write transfer_buffer */
135 char *readbuf; /* read transfer_buffer */ 135 char *readbuf; /* read transfer_buffer */
136 char *statusbuf; /* status transfer_buffer */ 136 char *statusbuf; /* status transfer_buffer */
@@ -465,7 +465,7 @@ static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
465 int twoints[2]; 465 int twoints[2];
466 int retval = 0; 466 int retval = 0;
467 467
468 down (&usblp->sem); 468 mutex_lock (&usblp->mut);
469 if (!usblp->present) { 469 if (!usblp->present) {
470 retval = -ENODEV; 470 retval = -ENODEV;
471 goto done; 471 goto done;
@@ -644,14 +644,14 @@ static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
644 } 644 }
645 645
646done: 646done:
647 up (&usblp->sem); 647 mutex_unlock (&usblp->mut);
648 return retval; 648 return retval;
649} 649}
650 650
651static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) 651static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
652{ 652{
653 struct usblp *usblp = file->private_data; 653 struct usblp *usblp = file->private_data;
654 int timeout, rv, err = 0, transfer_length = 0; 654 int timeout, intr, rv, err = 0, transfer_length = 0;
655 size_t writecount = 0; 655 size_t writecount = 0;
656 656
657 while (writecount < count) { 657 while (writecount < count) {
@@ -668,14 +668,16 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t
668 if (rv < 0) 668 if (rv < 0)
669 return writecount ? writecount : -EINTR; 669 return writecount ? writecount : -EINTR;
670 } 670 }
671 down (&usblp->sem); 671 intr = mutex_lock_interruptible (&usblp->mut);
672 if (intr)
673 return writecount ? writecount : -EINTR;
672 if (!usblp->present) { 674 if (!usblp->present) {
673 up (&usblp->sem); 675 mutex_unlock (&usblp->mut);
674 return -ENODEV; 676 return -ENODEV;
675 } 677 }
676 678
677 if (usblp->sleeping) { 679 if (usblp->sleeping) {
678 up (&usblp->sem); 680 mutex_unlock (&usblp->mut);
679 return writecount ? writecount : -ENODEV; 681 return writecount ? writecount : -ENODEV;
680 } 682 }
681 683
@@ -687,10 +689,10 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t
687 err = usblp->writeurb->status; 689 err = usblp->writeurb->status;
688 } else 690 } else
689 err = usblp_check_status(usblp, err); 691 err = usblp_check_status(usblp, err);
690 up (&usblp->sem); 692 mutex_unlock (&usblp->mut);
691 693
692 /* if the fault was due to disconnect, let khubd's 694 /* if the fault was due to disconnect, let khubd's
693 * call to usblp_disconnect() grab usblp->sem ... 695 * call to usblp_disconnect() grab usblp->mut ...
694 */ 696 */
695 schedule (); 697 schedule ();
696 continue; 698 continue;
@@ -702,7 +704,7 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t
702 */ 704 */
703 writecount += transfer_length; 705 writecount += transfer_length;
704 if (writecount == count) { 706 if (writecount == count) {
705 up(&usblp->sem); 707 mutex_unlock(&usblp->mut);
706 break; 708 break;
707 } 709 }
708 710
@@ -714,7 +716,7 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t
714 716
715 if (copy_from_user(usblp->writeurb->transfer_buffer, 717 if (copy_from_user(usblp->writeurb->transfer_buffer,
716 buffer + writecount, transfer_length)) { 718 buffer + writecount, transfer_length)) {
717 up(&usblp->sem); 719 mutex_unlock(&usblp->mut);
718 return writecount ? writecount : -EFAULT; 720 return writecount ? writecount : -EFAULT;
719 } 721 }
720 722
@@ -727,10 +729,10 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t
727 count = -EIO; 729 count = -EIO;
728 else 730 else
729 count = writecount ? writecount : -ENOMEM; 731 count = writecount ? writecount : -ENOMEM;
730 up (&usblp->sem); 732 mutex_unlock (&usblp->mut);
731 break; 733 break;
732 } 734 }
733 up (&usblp->sem); 735 mutex_unlock (&usblp->mut);
734 } 736 }
735 737
736 return count; 738 return count;
@@ -739,12 +741,14 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t
739static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) 741static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
740{ 742{
741 struct usblp *usblp = file->private_data; 743 struct usblp *usblp = file->private_data;
742 int rv; 744 int rv, intr;
743 745
744 if (!usblp->bidir) 746 if (!usblp->bidir)
745 return -EINVAL; 747 return -EINVAL;
746 748
747 down (&usblp->sem); 749 intr = mutex_lock_interruptible (&usblp->mut);
750 if (intr)
751 return -EINTR;
748 if (!usblp->present) { 752 if (!usblp->present) {
749 count = -ENODEV; 753 count = -ENODEV;
750 goto done; 754 goto done;
@@ -757,9 +761,9 @@ static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count,
757 count = -EAGAIN; 761 count = -EAGAIN;
758 goto done; 762 goto done;
759 } 763 }
760 up(&usblp->sem); 764 mutex_unlock(&usblp->mut);
761 rv = wait_event_interruptible(usblp->wait, usblp->rcomplete || !usblp->present); 765 rv = wait_event_interruptible(usblp->wait, usblp->rcomplete || !usblp->present);
762 down(&usblp->sem); 766 mutex_lock(&usblp->mut);
763 if (rv < 0) { 767 if (rv < 0) {
764 count = -EINTR; 768 count = -EINTR;
765 goto done; 769 goto done;
@@ -807,7 +811,7 @@ static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count,
807 } 811 }
808 812
809done: 813done:
810 up (&usblp->sem); 814 mutex_unlock (&usblp->mut);
811 return count; 815 return count;
812} 816}
813 817
@@ -886,7 +890,7 @@ static int usblp_probe(struct usb_interface *intf,
886 goto abort; 890 goto abort;
887 } 891 }
888 usblp->dev = dev; 892 usblp->dev = dev;
889 init_MUTEX (&usblp->sem); 893 mutex_init (&usblp->mut);
890 init_waitqueue_head(&usblp->wait); 894 init_waitqueue_head(&usblp->wait);
891 usblp->ifnum = intf->cur_altsetting->desc.bInterfaceNumber; 895 usblp->ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
892 usblp->intf = intf; 896 usblp->intf = intf;
@@ -1178,7 +1182,7 @@ static void usblp_disconnect(struct usb_interface *intf)
1178 device_remove_file(&intf->dev, &dev_attr_ieee1284_id); 1182 device_remove_file(&intf->dev, &dev_attr_ieee1284_id);
1179 1183
1180 mutex_lock (&usblp_mutex); 1184 mutex_lock (&usblp_mutex);
1181 down (&usblp->sem); 1185 mutex_lock (&usblp->mut);
1182 usblp->present = 0; 1186 usblp->present = 0;
1183 usb_set_intfdata (intf, NULL); 1187 usb_set_intfdata (intf, NULL);
1184 1188
@@ -1187,7 +1191,7 @@ static void usblp_disconnect(struct usb_interface *intf)
1187 usblp->writebuf, usblp->writeurb->transfer_dma); 1191 usblp->writebuf, usblp->writeurb->transfer_dma);
1188 usb_buffer_free (usblp->dev, USBLP_BUF_SIZE, 1192 usb_buffer_free (usblp->dev, USBLP_BUF_SIZE,
1189 usblp->readbuf, usblp->readurb->transfer_dma); 1193 usblp->readbuf, usblp->readurb->transfer_dma);
1190 up (&usblp->sem); 1194 mutex_unlock (&usblp->mut);
1191 1195
1192 if (!usblp->used) 1196 if (!usblp->used)
1193 usblp_cleanup (usblp); 1197 usblp_cleanup (usblp);
@@ -1200,11 +1204,11 @@ static int usblp_suspend (struct usb_interface *intf, pm_message_t message)
1200 1204
1201 /* this races against normal access and open */ 1205 /* this races against normal access and open */
1202 mutex_lock (&usblp_mutex); 1206 mutex_lock (&usblp_mutex);
1203 down (&usblp->sem); 1207 mutex_lock (&usblp->mut);
1204 /* we take no more IO */ 1208 /* we take no more IO */
1205 usblp->sleeping = 1; 1209 usblp->sleeping = 1;
1206 usblp_unlink_urbs(usblp); 1210 usblp_unlink_urbs(usblp);
1207 up (&usblp->sem); 1211 mutex_unlock (&usblp->mut);
1208 mutex_unlock (&usblp_mutex); 1212 mutex_unlock (&usblp_mutex);
1209 1213
1210 return 0; 1214 return 0;
@@ -1216,12 +1220,12 @@ static int usblp_resume (struct usb_interface *intf)
1216 int r; 1220 int r;
1217 1221
1218 mutex_lock (&usblp_mutex); 1222 mutex_lock (&usblp_mutex);
1219 down (&usblp->sem); 1223 mutex_lock (&usblp->mut);
1220 1224
1221 usblp->sleeping = 0; 1225 usblp->sleeping = 0;
1222 r = handle_bidir (usblp); 1226 r = handle_bidir (usblp);
1223 1227
1224 up (&usblp->sem); 1228 mutex_unlock (&usblp->mut);
1225 mutex_unlock (&usblp_mutex); 1229 mutex_unlock (&usblp_mutex);
1226 1230
1227 return r; 1231 return r;