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,
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 */
......
......@@ -487,18 +487,37 @@ 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;
/* 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");
/* lock access to the data structure */
......@@ -509,32 +528,73 @@ static int usb_stor_allocate_irq(struct us_data *ss)
if (!ss->irq_urb) {
up(&(ss->irq_urb_sem));
US_DEBUGP("couldn't allocate interrupt URB");
return 1;
return 3;
}
/* calculate the pipe and max packet size */
pipe = usb_rcvintpipe(ss->pusb_dev, ss->ep_int->bEndpointAddress &
USB_ENDPOINT_NUMBER_MASK);
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);
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));
return 2;
return 4;
}
/* unlock the data structure and return success */
/* unlock the data structure */
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 */
......@@ -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));
}
......
......@@ -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 */
......
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