]> git.hungrycats.org Git - linux/commitdiff
[PATCH] usb-storage: code cleanup, small fixes
authorMatthew Dharm <mdharm-usb@one-eyed-alien.net>
Thu, 4 Jul 2002 11:21:08 +0000 (04:21 -0700)
committerGreg Kroah-Hartman <greg@kroah.com>
Thu, 4 Jul 2002 11:21:08 +0000 (04:21 -0700)
This patch consolidates quite a bit of code for allocation/deallocation of
URBs, and removes a kmalloc() from a command path.

drivers/usb/storage/transport.c
drivers/usb/storage/usb.c
drivers/usb/storage/usb.h

index bcf22f6c2d9f2c162cf1bf63b94b749ef52f70e6..28eeb8be4b9a7021403e26d2cc089e6165b1202e 100644 (file)
@@ -428,18 +428,13 @@ int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
                         void *data, u16 size)
 {
        int status;
-       struct usb_ctrlrequest *dr;
-
-       dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO);
-       if (!dr)
-               return -ENOMEM;
 
        /* fill in the devrequest structure */
-       dr->bRequestType = requesttype;
-       dr->bRequest = request;
-       dr->wValue = cpu_to_le16(value);
-       dr->wIndex = cpu_to_le16(index);
-       dr->wLength = cpu_to_le16(size);
+       us->dr->bRequestType = requesttype;
+       us->dr->bRequest = request;
+       us->dr->wValue = cpu_to_le16(value);
+       us->dr->wIndex = cpu_to_le16(index);
+       us->dr->wLength = cpu_to_le16(size);
 
        /* lock the URB */
        down(&(us->current_urb_sem));
@@ -452,7 +447,7 @@ int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
 
        /* fill the URB */
        FILL_CONTROL_URB(us->current_urb, us->pusb_dev, pipe, 
-                        (unsigned char*) dr, data, size, 
+                        (unsigned char*) us->dr, data, size, 
                         usb_stor_blocking_completion, NULL);
 
        /* submit the URB */
index 76d70eb5a9bf3ad574b76de7918c59ae94c19d09..5b586c94866f0adac7fb68cd048d9d005613857c 100644 (file)
@@ -487,54 +487,114 @@ static int usb_stor_control_thread(void * __us)
        return 0;
 }      
 
-/* Set up the IRQ pipe and handler
+/* Set up the URB, the usb_ctrlrequest, and the IRQ pipe and handler.
+ * ss->dev_semaphore should already be locked.
  * Note that this function assumes that all the data in the us_data
  * strucuture is current.  This includes the ep_int field, which gives us
  * the endpoint for the interrupt.
  * Returns non-zero on failure, zero on success
  */ 
-static int usb_stor_allocate_irq(struct us_data *ss)
+static int usb_stor_allocate_urbs(struct us_data *ss)
 {
        unsigned int pipe;
        int maxp;
        int result;
 
-       US_DEBUGP("Allocating IRQ for CBI transport\n");
-
-       /* lock access to the data structure */
-       down(&(ss->irq_urb_sem));
-
-       /* allocate the URB */
-       ss->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
-       if (!ss->irq_urb) {
-               up(&(ss->irq_urb_sem));
-               US_DEBUGP("couldn't allocate interrupt URB");
+       /* allocate the URB we're going to use */
+       US_DEBUGP("Allocating URB\n");
+       ss->current_urb = usb_alloc_urb(0, GFP_KERNEL);
+       if (!ss->current_urb) {
+               US_DEBUGP("allocation failed\n");
                return 1;
        }
 
-       /* calculate the pipe and max packet size */
-       pipe = usb_rcvintpipe(ss->pusb_dev, ss->ep_int->bEndpointAddress & 
-                             USB_ENDPOINT_NUMBER_MASK);
-       maxp = usb_maxpacket(ss->pusb_dev, pipe, usb_pipeout(pipe));
-       if (maxp > sizeof(ss->irqbuf))
-               maxp = sizeof(ss->irqbuf);
-
-       /* fill in the URB with our data */
-       FILL_INT_URB(ss->irq_urb, ss->pusb_dev, pipe, ss->irqbuf, maxp, 
-                    usb_stor_CBI_irq, ss, ss->ep_int->bInterval); 
-
-       /* submit the URB for processing */
-       result = usb_submit_urb(ss->irq_urb, GFP_KERNEL);
-       US_DEBUGP("usb_submit_urb() returns %d\n", result);
-       if (result) {
-               usb_free_urb(ss->irq_urb);
-               up(&(ss->irq_urb_sem));
+       /* allocate the usb_ctrlrequest for control packets */
+       US_DEBUGP("Allocating usb_ctrlrequest\n");
+       ss->dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO);
+       if (!ss->dr) {
+               US_DEBUGP("allocation failed\n");
                return 2;
        }
 
-       /* unlock the data structure and return success */
+       /* allocate the IRQ URB, if it is needed */
+       if (ss->protocol == US_PR_CBI) {
+               US_DEBUGP("Allocating IRQ for CBI transport\n");
+
+               /* lock access to the data structure */
+               down(&(ss->irq_urb_sem));
+
+               /* allocate the URB */
+               ss->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
+               if (!ss->irq_urb) {
+                       up(&(ss->irq_urb_sem));
+                       US_DEBUGP("couldn't allocate interrupt URB");
+                       return 3;
+               }
+
+               /* calculate the pipe and max packet size */
+               pipe = usb_rcvintpipe(ss->pusb_dev,
+                   ss->ep_int->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+               maxp = usb_maxpacket(ss->pusb_dev, pipe, usb_pipeout(pipe));
+               if (maxp > sizeof(ss->irqbuf))
+                       maxp = sizeof(ss->irqbuf);
+
+               /* fill in the URB with our data */
+               FILL_INT_URB(ss->irq_urb, ss->pusb_dev, pipe, ss->irqbuf,
+                       maxp, usb_stor_CBI_irq, ss, ss->ep_int->bInterval); 
+
+               /* submit the URB for processing */
+               result = usb_submit_urb(ss->irq_urb, GFP_KERNEL);
+               US_DEBUGP("usb_submit_urb() returns %d\n", result);
+               if (result) {
+                       up(&(ss->irq_urb_sem));
+                       return 4;
+               }
+
+               /* unlock the data structure */
+               up(&(ss->irq_urb_sem));
+
+       } /* ss->protocol == US_PR_CBI */
+
+       return 0;       /* success */
+}
+
+/* Deallocate the URB, the usb_ctrlrequest, and the IRQ pipe.
+ * ss->dev_semaphore must already be locked.
+ */
+static void usb_stor_deallocate_urbs(struct us_data *ss)
+{
+       int result;
+
+       /* release the IRQ, if we have one */
+       down(&(ss->irq_urb_sem));
+       if (ss->irq_urb) {
+               US_DEBUGP("-- releasing irq URB\n");
+               result = usb_unlink_urb(ss->irq_urb);
+               US_DEBUGP("-- usb_unlink_urb() returned %d\n", result);
+               usb_free_urb(ss->irq_urb);
+               ss->irq_urb = NULL;
+       }
        up(&(ss->irq_urb_sem));
-       return 0;
+
+       /* free the usb_ctrlrequest buffer */
+       if (ss->dr) {
+               kfree(ss->dr);
+               ss->dr = NULL;
+       }
+
+       /* free up the main URB for this device */
+       if (ss->current_urb) {
+               US_DEBUGP("-- releasing main URB\n");
+               result = usb_unlink_urb(ss->current_urb);
+               US_DEBUGP("-- usb_unlink_urb() returned %d\n", result);
+               usb_free_urb(ss->current_urb);
+               ss->current_urb = NULL;
+       }
+
+       /* mark the device as gone */
+       clear_bit(DEV_ATTACHED, &ss->bitflags);
+       usb_put_dev(ss->pusb_dev);
+       ss->pusb_dev = NULL;
 }
 
 /* Probe to see if a new device is actually a SCSI device */
@@ -712,13 +772,8 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum,
                        USB_ENDPOINT_NUMBER_MASK;
                ss->ep_int = ep_int;
 
-               /* allocate an IRQ callback if one is needed */
-               if ((ss->protocol == US_PR_CBI) && usb_stor_allocate_irq(ss))
-                       goto BadDevice;
-
-               /* allocate the URB we're going to use */
-               ss->current_urb = usb_alloc_urb(0, GFP_KERNEL);
-               if (!ss->current_urb)
+               /* allocate the URB, the usb_ctrlrequest, and the IRQ URB */
+               if (usb_stor_allocate_urbs(ss))
                        goto BadDevice;
 
                 /* Re-Initialize the device if it needs it */
@@ -741,11 +796,6 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum,
                memset(ss, 0, sizeof(struct us_data));
                new_device = 1;
 
-               /* allocate the URB we're going to use */
-               ss->current_urb = usb_alloc_urb(0, GFP_KERNEL);
-               if (!ss->current_urb)
-                       goto BadDevice;
-
                /* Initialize the mutexes only when the struct is new */
                init_completion(&(ss->notify));
                init_MUTEX_LOCKED(&(ss->ip_waitq));
@@ -943,8 +993,8 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum,
                }
                US_DEBUGP("Protocol: %s\n", ss->protocol_name);
 
-               /* allocate an IRQ callback if one is needed */
-               if ((ss->protocol == US_PR_CBI) && usb_stor_allocate_irq(ss))
+               /* allocate the URB, the usb_ctrlrequest, and the IRQ URB */
+               if (usb_stor_allocate_urbs(ss))
                        goto BadDevice;
 
                /*
@@ -1020,26 +1070,11 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum,
        /* we come here if there are any problems */
        BadDevice:
        US_DEBUGP("storage_probe() failed\n");
-       down(&ss->irq_urb_sem);
-       if (ss->irq_urb) {
-               usb_unlink_urb(ss->irq_urb);
-               usb_free_urb(ss->irq_urb);
-               ss->irq_urb = NULL;
-       }
-       up(&ss->irq_urb_sem);
-       if (ss->current_urb) {
-               usb_unlink_urb(ss->current_urb);
-               usb_free_urb(ss->current_urb);
-               ss->current_urb = NULL;
-       }
-
-       clear_bit(DEV_ATTACHED, &ss->bitflags);
-       ss->pusb_dev = NULL;
+       usb_stor_deallocate_urbs(ss);
        if (new_device)
                kfree(ss);
        else
                up(&ss->dev_semaphore);
-       usb_put_dev(dev);
        return NULL;
 }
 
@@ -1047,7 +1082,6 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum,
 static void storage_disconnect(struct usb_device *dev, void *ptr)
 {
        struct us_data *ss = ptr;
-       int result;
 
        US_DEBUGP("storage_disconnect() called\n");
 
@@ -1057,33 +1091,8 @@ static void storage_disconnect(struct usb_device *dev, void *ptr)
                return;
        }
 
-       /* lock access to the device data structure */
        down(&(ss->dev_semaphore));
-
-       /* release the IRQ, if we have one */
-       down(&(ss->irq_urb_sem));
-       if (ss->irq_urb) {
-               US_DEBUGP("-- releasing irq URB\n");
-               result = usb_unlink_urb(ss->irq_urb);
-               US_DEBUGP("-- usb_unlink_urb() returned %d\n", result);
-               usb_free_urb(ss->irq_urb);
-               ss->irq_urb = NULL;
-       }
-       up(&(ss->irq_urb_sem));
-
-       /* free up the main URB for this device */
-       US_DEBUGP("-- releasing main URB\n");
-       result = usb_unlink_urb(ss->current_urb);
-       US_DEBUGP("-- usb_unlink_urb() returned %d\n", result);
-       usb_free_urb(ss->current_urb);
-       ss->current_urb = NULL;
-
-       /* mark the device as gone */
-       usb_put_dev(ss->pusb_dev);
-       ss->pusb_dev = NULL;
-       clear_bit(DEV_ATTACHED, &ss->bitflags);
-
-       /* unlock access to the device data structure */
+       usb_stor_deallocate_urbs(ss);
        up(&(ss->dev_semaphore));
 }
 
index d0f1f24ded28638b952c958ee59d07969e2d7290..57f175ec28663e958185268f36f9106584e606b1 100644 (file)
@@ -185,6 +185,7 @@ struct us_data {
        /* control and bulk communications data */
        struct semaphore        current_urb_sem; /* to protect irq_urb   */
        struct urb              *current_urb;    /* non-int USB requests */
+       struct usb_ctrlrequest  *dr;             /* control requests     */
 
        /* the semaphore for sleeping the control thread */
        struct semaphore        sema;            /* to sleep thread on   */