# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.604.1.4 -> 1.604.1.5 # drivers/usb/storage/usb.c 1.25 -> 1.26 # drivers/usb/storage/transport.c 1.20 -> 1.21 # drivers/usb/storage/usb.h 1.11 -> 1.12 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 02/07/04 mdharm-usb@one-eyed-alien.net 1.604.1.5 # [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. # -------------------------------------------- # diff -Nru a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c --- a/drivers/usb/storage/transport.c Fri Jul 5 14:51:18 2002 +++ b/drivers/usb/storage/transport.c Fri Jul 5 14:51:18 2002 @@ -428,18 +428,13 @@ 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 @@ /* 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 */ diff -Nru a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c --- a/drivers/usb/storage/usb.c Fri Jul 5 14:51:18 2002 +++ b/drivers/usb/storage/usb.c Fri Jul 5 14:51:18 2002 @@ -487,54 +487,114 @@ 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 @@ 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 @@ 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 @@ } 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 @@ /* 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_disconnect(struct usb_device *dev, void *ptr) { struct us_data *ss = ptr; - int result; US_DEBUGP("storage_disconnect() called\n"); @@ -1057,33 +1091,8 @@ 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)); } diff -Nru a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h --- a/drivers/usb/storage/usb.h Fri Jul 5 14:51:18 2002 +++ b/drivers/usb/storage/usb.h Fri Jul 5 14:51:18 2002 @@ -185,6 +185,7 @@ /* 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 */