]> err.no Git - linux-2.6/blobdiff - drivers/usb/misc/iowarrior.c
Merge branch 'master' of git://git.infradead.org/~dedekind/ubi-2.6
[linux-2.6] / drivers / usb / misc / iowarrior.c
index 3bb33f7bfa3626ee027218832d409e9dbc2cdb2a..46d9f27ec17380122d0f3db1ef198b04d3fa2696 100644 (file)
@@ -100,8 +100,6 @@ struct iowarrior {
 /*--------------*/
 /*    globals   */
 /*--------------*/
-/* prevent races between open() and disconnect() */
-static DECLARE_MUTEX(disconnect_sem);
 
 /*
  *  USB spec identifies 5 second timeouts.
@@ -160,9 +158,10 @@ static void iowarrior_callback(struct urb *urb)
        int read_idx;
        int aux_idx;
        int offset;
-       int status;
+       int status = urb->status;
+       int retval;
 
-       switch (urb->status) {
+       switch (status) {
        case 0:
                /* success */
                break;
@@ -215,10 +214,10 @@ static void iowarrior_callback(struct urb *urb)
        wake_up_interruptible(&dev->read_wait);
 
 exit:
-       status = usb_submit_urb(urb, GFP_ATOMIC);
-       if (status)
+       retval = usb_submit_urb(urb, GFP_ATOMIC);
+       if (retval)
                dev_err(&dev->interface->dev, "%s - usb_submit_urb failed with result %d",
-                       __FUNCTION__, status);
+                       __FUNCTION__, retval);
 
 }
 
@@ -228,13 +227,15 @@ exit:
 static void iowarrior_write_callback(struct urb *urb)
 {
        struct iowarrior *dev;
+       int status = urb->status;
+
        dev = (struct iowarrior *)urb->context;
        /* sync/async unlink faults aren't errors */
-       if (urb->status &&
-           !(urb->status == -ENOENT ||
-             urb->status == -ECONNRESET || urb->status == -ESHUTDOWN)) {
+       if (status &&
+           !(status == -ENOENT ||
+             status == -ECONNRESET || status == -ESHUTDOWN)) {
                dbg("%s - nonzero write bulk status received: %d",
-                   __func__, urb->status);
+                   __func__, status);
        }
        /* free up our allocated buffer */
        usb_buffer_free(urb->dev, urb->transfer_buffer_length,
@@ -600,22 +601,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) {
@@ -636,7 +633,7 @@ static int iowarrior_open(struct inode *inode, struct file *file)
        retval = 0;
 
 out:
-       up(&disconnect_sem);
+       mutex_unlock(&dev->mutex);
        return retval;
 }
 
@@ -868,19 +865,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;
 
@@ -898,7 +892,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);