diff options
author | Oliver Neukum <oliver@neukum.name> | 2006-12-03 03:46:35 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-12-20 13:13:23 -0500 |
commit | 8e42266965b9db03a86d2cf55400cd3afb67a114 (patch) | |
tree | aacd80bf9337be749046bb1612438e54a51779da /drivers/usb/class | |
parent | b1cff285ae8d21012ad3717e412b0f50066dc061 (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')
-rw-r--r-- | drivers/usb/class/usblp.c | 54 |
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 | ||
131 | struct usblp { | 131 | struct 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 | ||
646 | done: | 646 | done: |
647 | up (&usblp->sem); | 647 | mutex_unlock (&usblp->mut); |
648 | return retval; | 648 | return retval; |
649 | } | 649 | } |
650 | 650 | ||
651 | static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) | 651 | static 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 | |||
739 | static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) | 741 | static 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 | ||
809 | done: | 813 | done: |
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; |