diff options
Diffstat (limited to 'drivers/usb/misc/iowarrior.c')
-rw-r--r-- | drivers/usb/misc/iowarrior.c | 33 |
1 files changed, 12 insertions, 21 deletions
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index fc51207b71b..28548d18671 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c @@ -100,8 +100,6 @@ struct iowarrior { /*--------------*/ /* globals */ /*--------------*/ -/* prevent races between open() and disconnect() */ -static DECLARE_MUTEX(disconnect_sem); /* * USB spec identifies 5 second timeouts. @@ -495,8 +493,8 @@ static int iowarrior_ioctl(struct inode *inode, struct file *file, /* verify that the device wasn't unplugged */ if (!dev->present) { - mutex_unlock(&dev->mutex); - return -ENODEV; + retval = -ENODEV; + goto error_out; } dbg("%s - minor %d, cmd 0x%.4x, arg %ld", __func__, dev->minor, cmd, @@ -579,9 +577,10 @@ static int iowarrior_ioctl(struct inode *inode, struct file *file, retval = -ENOTTY; break; } - +error_out: /* unlock the device */ mutex_unlock(&dev->mutex); + kfree(buffer); return retval; } @@ -599,22 +598,18 @@ static int iowarrior_open(struct inode *inode, struct file *file) subminor = iminor(inode); - /* prevent disconnects */ - down(&disconnect_sem); - interface = usb_find_interface(&iowarrior_driver, subminor); if (!interface) { err("%s - error, can't find device for minor %d", __FUNCTION__, subminor); - retval = -ENODEV; - goto out; + return -ENODEV; } dev = usb_get_intfdata(interface); - if (!dev) { - retval = -ENODEV; - goto out; - } + if (!dev) + return -ENODEV; + + mutex_lock(&dev->mutex); /* Only one process can open each device, no sharing. */ if (dev->opened) { @@ -635,7 +630,7 @@ static int iowarrior_open(struct inode *inode, struct file *file) retval = 0; out: - up(&disconnect_sem); + mutex_unlock(&dev->mutex); return retval; } @@ -867,19 +862,16 @@ static void iowarrior_disconnect(struct usb_interface *interface) struct iowarrior *dev; int minor; - /* prevent races with open() */ - down(&disconnect_sem); - dev = usb_get_intfdata(interface); usb_set_intfdata(interface, NULL); - mutex_lock(&dev->mutex); - minor = dev->minor; /* give back our minor */ usb_deregister_dev(interface, &iowarrior_class); + mutex_lock(&dev->mutex); + /* prevent device read, write and ioctl */ dev->present = 0; @@ -897,7 +889,6 @@ static void iowarrior_disconnect(struct usb_interface *interface) /* no process is using the device, cleanup now */ iowarrior_delete(dev); } - up(&disconnect_sem); dev_info(&interface->dev, "I/O-Warror #%d now disconnected\n", minor - IOWARRIOR_MINOR_BASE); |