Commit 56465344 authored by Matthew Dharm's avatar Matthew Dharm Committed by Greg Kroah-Hartman

[PATCH] usb-storage: code cleanup, small fixes

This patch consolidates quite a bit of code for allocation/deallocation of
URBs, and removes a kmalloc() from a command path.
parent 29a1059a
...@@ -428,18 +428,13 @@ int usb_stor_control_msg(struct us_data *us, unsigned int pipe, ...@@ -428,18 +428,13 @@ int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
void *data, u16 size) void *data, u16 size)
{ {
int status; int status;
struct usb_ctrlrequest *dr;
dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO);
if (!dr)
return -ENOMEM;
/* fill in the devrequest structure */ /* fill in the devrequest structure */
dr->bRequestType = requesttype; us->dr->bRequestType = requesttype;
dr->bRequest = request; us->dr->bRequest = request;
dr->wValue = cpu_to_le16(value); us->dr->wValue = cpu_to_le16(value);
dr->wIndex = cpu_to_le16(index); us->dr->wIndex = cpu_to_le16(index);
dr->wLength = cpu_to_le16(size); us->dr->wLength = cpu_to_le16(size);
/* lock the URB */ /* lock the URB */
down(&(us->current_urb_sem)); down(&(us->current_urb_sem));
...@@ -452,7 +447,7 @@ int usb_stor_control_msg(struct us_data *us, unsigned int pipe, ...@@ -452,7 +447,7 @@ int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
/* fill the URB */ /* fill the URB */
FILL_CONTROL_URB(us->current_urb, us->pusb_dev, pipe, 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); usb_stor_blocking_completion, NULL);
/* submit the URB */ /* submit the URB */
......
...@@ -487,18 +487,37 @@ static int usb_stor_control_thread(void * __us) ...@@ -487,18 +487,37 @@ static int usb_stor_control_thread(void * __us)
return 0; 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 * 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 * strucuture is current. This includes the ep_int field, which gives us
* the endpoint for the interrupt. * the endpoint for the interrupt.
* Returns non-zero on failure, zero on success * 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; unsigned int pipe;
int maxp; int maxp;
int result; int result;
/* 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;
}
/* 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;
}
/* allocate the IRQ URB, if it is needed */
if (ss->protocol == US_PR_CBI) {
US_DEBUGP("Allocating IRQ for CBI transport\n"); US_DEBUGP("Allocating IRQ for CBI transport\n");
/* lock access to the data structure */ /* lock access to the data structure */
...@@ -509,32 +528,73 @@ static int usb_stor_allocate_irq(struct us_data *ss) ...@@ -509,32 +528,73 @@ static int usb_stor_allocate_irq(struct us_data *ss)
if (!ss->irq_urb) { if (!ss->irq_urb) {
up(&(ss->irq_urb_sem)); up(&(ss->irq_urb_sem));
US_DEBUGP("couldn't allocate interrupt URB"); US_DEBUGP("couldn't allocate interrupt URB");
return 1; return 3;
} }
/* calculate the pipe and max packet size */ /* calculate the pipe and max packet size */
pipe = usb_rcvintpipe(ss->pusb_dev, ss->ep_int->bEndpointAddress & pipe = usb_rcvintpipe(ss->pusb_dev,
USB_ENDPOINT_NUMBER_MASK); ss->ep_int->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
maxp = usb_maxpacket(ss->pusb_dev, pipe, usb_pipeout(pipe)); maxp = usb_maxpacket(ss->pusb_dev, pipe, usb_pipeout(pipe));
if (maxp > sizeof(ss->irqbuf)) if (maxp > sizeof(ss->irqbuf))
maxp = sizeof(ss->irqbuf); maxp = sizeof(ss->irqbuf);
/* fill in the URB with our data */ /* fill in the URB with our data */
FILL_INT_URB(ss->irq_urb, ss->pusb_dev, pipe, ss->irqbuf, maxp, FILL_INT_URB(ss->irq_urb, ss->pusb_dev, pipe, ss->irqbuf,
usb_stor_CBI_irq, ss, ss->ep_int->bInterval); maxp, usb_stor_CBI_irq, ss, ss->ep_int->bInterval);
/* submit the URB for processing */ /* submit the URB for processing */
result = usb_submit_urb(ss->irq_urb, GFP_KERNEL); result = usb_submit_urb(ss->irq_urb, GFP_KERNEL);
US_DEBUGP("usb_submit_urb() returns %d\n", result); US_DEBUGP("usb_submit_urb() returns %d\n", result);
if (result) { if (result) {
usb_free_urb(ss->irq_urb);
up(&(ss->irq_urb_sem)); up(&(ss->irq_urb_sem));
return 2; return 4;
} }
/* unlock the data structure and return success */ /* unlock the data structure */
up(&(ss->irq_urb_sem)); up(&(ss->irq_urb_sem));
return 0;
} /* 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));
/* 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 */ /* 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, ...@@ -712,13 +772,8 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum,
USB_ENDPOINT_NUMBER_MASK; USB_ENDPOINT_NUMBER_MASK;
ss->ep_int = ep_int; ss->ep_int = ep_int;
/* allocate an IRQ callback if one is needed */ /* allocate the URB, the usb_ctrlrequest, and the IRQ URB */
if ((ss->protocol == US_PR_CBI) && usb_stor_allocate_irq(ss)) if (usb_stor_allocate_urbs(ss))
goto BadDevice;
/* allocate the URB we're going to use */
ss->current_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!ss->current_urb)
goto BadDevice; goto BadDevice;
/* Re-Initialize the device if it needs it */ /* Re-Initialize the device if it needs it */
...@@ -741,11 +796,6 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum, ...@@ -741,11 +796,6 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum,
memset(ss, 0, sizeof(struct us_data)); memset(ss, 0, sizeof(struct us_data));
new_device = 1; 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 */ /* Initialize the mutexes only when the struct is new */
init_completion(&(ss->notify)); init_completion(&(ss->notify));
init_MUTEX_LOCKED(&(ss->ip_waitq)); init_MUTEX_LOCKED(&(ss->ip_waitq));
...@@ -943,8 +993,8 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum, ...@@ -943,8 +993,8 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum,
} }
US_DEBUGP("Protocol: %s\n", ss->protocol_name); US_DEBUGP("Protocol: %s\n", ss->protocol_name);
/* allocate an IRQ callback if one is needed */ /* allocate the URB, the usb_ctrlrequest, and the IRQ URB */
if ((ss->protocol == US_PR_CBI) && usb_stor_allocate_irq(ss)) if (usb_stor_allocate_urbs(ss))
goto BadDevice; goto BadDevice;
/* /*
...@@ -1020,26 +1070,11 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum, ...@@ -1020,26 +1070,11 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum,
/* we come here if there are any problems */ /* we come here if there are any problems */
BadDevice: BadDevice:
US_DEBUGP("storage_probe() failed\n"); US_DEBUGP("storage_probe() failed\n");
down(&ss->irq_urb_sem); usb_stor_deallocate_urbs(ss);
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;
if (new_device) if (new_device)
kfree(ss); kfree(ss);
else else
up(&ss->dev_semaphore); up(&ss->dev_semaphore);
usb_put_dev(dev);
return NULL; return NULL;
} }
...@@ -1047,7 +1082,6 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum, ...@@ -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) static void storage_disconnect(struct usb_device *dev, void *ptr)
{ {
struct us_data *ss = ptr; struct us_data *ss = ptr;
int result;
US_DEBUGP("storage_disconnect() called\n"); US_DEBUGP("storage_disconnect() called\n");
...@@ -1057,33 +1091,8 @@ static void storage_disconnect(struct usb_device *dev, void *ptr) ...@@ -1057,33 +1091,8 @@ static void storage_disconnect(struct usb_device *dev, void *ptr)
return; return;
} }
/* lock access to the device data structure */
down(&(ss->dev_semaphore)); down(&(ss->dev_semaphore));
usb_stor_deallocate_urbs(ss);
/* 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 */
up(&(ss->dev_semaphore)); up(&(ss->dev_semaphore));
} }
......
...@@ -185,6 +185,7 @@ struct us_data { ...@@ -185,6 +185,7 @@ struct us_data {
/* control and bulk communications data */ /* control and bulk communications data */
struct semaphore current_urb_sem; /* to protect irq_urb */ struct semaphore current_urb_sem; /* to protect irq_urb */
struct urb *current_urb; /* non-int USB requests */ struct urb *current_urb; /* non-int USB requests */
struct usb_ctrlrequest *dr; /* control requests */
/* the semaphore for sleeping the control thread */ /* the semaphore for sleeping the control thread */
struct semaphore sema; /* to sleep thread on */ struct semaphore sema; /* to sleep thread on */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment