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

[PATCH] USB storage: cleanups

Some minor cleanups.  First, some locking in the bus-reset.  Next, we move
current_sg into struct us_data (why make more memory allocation issues for
ourselves?).  Next, we change sm_state into a normal variable, since it
shouldn't require atomic_t anytmore.  Finally, we remove some references to
a couple of flags that don't do anything anymore.

# Fix device locking during the bus-reset routine.
#
# Embed current_sg in struct us_data.
#
# Make us->sm_state a regular int instead of an atomic_t.
#
# Remove a couple of references to the START_STOP and IGNORE_SER
# flag bits.
parent 4eef80b0
...@@ -548,10 +548,9 @@ void isd200_invoke_transport( struct us_data *us, ...@@ -548,10 +548,9 @@ void isd200_invoke_transport( struct us_data *us,
/* if the command gets aborted by the higher layers, we need to /* if the command gets aborted by the higher layers, we need to
* short-circuit all other processing * short-circuit all other processing
*/ */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) { if (us->sm_state == US_STATE_ABORTING) {
US_DEBUGP("-- transport indicates command was aborted\n"); US_DEBUGP("-- command was aborted\n");
srb->result = DID_ABORT << 16; goto Handle_Abort;
return;
} }
switch (transferStatus) { switch (transferStatus) {
...@@ -561,6 +560,11 @@ void isd200_invoke_transport( struct us_data *us, ...@@ -561,6 +560,11 @@ void isd200_invoke_transport( struct us_data *us,
srb->result = SAM_STAT_GOOD; srb->result = SAM_STAT_GOOD;
break; break;
case USB_STOR_TRANSPORT_NO_SENSE:
US_DEBUGP("-- transport indicates protocol failure\n");
srb->result = SAM_STAT_CHECK_CONDITION;
return;
case USB_STOR_TRANSPORT_FAILED: case USB_STOR_TRANSPORT_FAILED:
US_DEBUGP("-- transport indicates command failure\n"); US_DEBUGP("-- transport indicates command failure\n");
need_auto_sense = 1; need_auto_sense = 1;
...@@ -591,10 +595,9 @@ void isd200_invoke_transport( struct us_data *us, ...@@ -591,10 +595,9 @@ void isd200_invoke_transport( struct us_data *us,
if (need_auto_sense) { if (need_auto_sense) {
result = isd200_read_regs(us); result = isd200_read_regs(us);
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) { if (us->sm_state == US_STATE_ABORTING) {
US_DEBUGP("-- auto-sense aborted\n"); US_DEBUGP("-- auto-sense aborted\n");
srb->result = DID_ABORT << 16; goto Handle_Abort;
return;
} }
if (result == ISD200_GOOD) { if (result == ISD200_GOOD) {
isd200_build_sense(us, srb); isd200_build_sense(us, srb);
...@@ -603,8 +606,10 @@ void isd200_invoke_transport( struct us_data *us, ...@@ -603,8 +606,10 @@ void isd200_invoke_transport( struct us_data *us,
/* If things are really okay, then let's show that */ /* If things are really okay, then let's show that */
if ((srb->sense_buffer[2] & 0xf) == 0x0) if ((srb->sense_buffer[2] & 0xf) == 0x0)
srb->result = SAM_STAT_GOOD; srb->result = SAM_STAT_GOOD;
} else } else {
srb->result = DID_ERROR << 16; srb->result = DID_ERROR << 16;
/* Need reset here */
}
} }
/* Regardless of auto-sense, if we _know_ we have an error /* Regardless of auto-sense, if we _know_ we have an error
...@@ -612,6 +617,16 @@ void isd200_invoke_transport( struct us_data *us, ...@@ -612,6 +617,16 @@ void isd200_invoke_transport( struct us_data *us,
*/ */
if (transferStatus == USB_STOR_TRANSPORT_FAILED) if (transferStatus == USB_STOR_TRANSPORT_FAILED)
srb->result = SAM_STAT_CHECK_CONDITION; srb->result = SAM_STAT_CHECK_CONDITION;
return;
/* abort processing: the bulk-only transport requires a reset
* following an abort */
Handle_Abort:
srb->result = DID_ABORT << 16;
/* permit the reset transfer to take place */
clear_bit(US_FLIDX_ABORTING, &us->flags);
/* Need reset here */
} }
#ifdef CONFIG_USB_STORAGE_DEBUG #ifdef CONFIG_USB_STORAGE_DEBUG
......
...@@ -141,16 +141,15 @@ static int usb_storage_release(struct Scsi_Host *psh) ...@@ -141,16 +141,15 @@ static int usb_storage_release(struct Scsi_Host *psh)
static int usb_storage_queuecommand( Scsi_Cmnd *srb , void (*done)(Scsi_Cmnd *)) static int usb_storage_queuecommand( Scsi_Cmnd *srb , void (*done)(Scsi_Cmnd *))
{ {
struct us_data *us = (struct us_data *)srb->device->host->hostdata[0]; struct us_data *us = (struct us_data *)srb->device->host->hostdata[0];
int state = atomic_read(&us->sm_state);
US_DEBUGP("queuecommand() called\n"); US_DEBUGP("queuecommand() called\n");
srb->host_scribble = (unsigned char *)us; srb->host_scribble = (unsigned char *)us;
/* enqueue the command */ /* enqueue the command */
if (state != US_STATE_IDLE || us->srb != NULL) { if (us->sm_state != US_STATE_IDLE || us->srb != NULL) {
printk(KERN_ERR USB_STORAGE "Error in %s: " printk(KERN_ERR USB_STORAGE "Error in %s: "
"state = %d, us->srb = %p\n", "state = %d, us->srb = %p\n",
__FUNCTION__, state, us->srb); __FUNCTION__, us->sm_state, us->srb);
return SCSI_MLQUEUE_HOST_BUSY; return SCSI_MLQUEUE_HOST_BUSY;
} }
...@@ -173,7 +172,6 @@ static int usb_storage_command_abort( Scsi_Cmnd *srb ) ...@@ -173,7 +172,6 @@ static int usb_storage_command_abort( Scsi_Cmnd *srb )
{ {
struct Scsi_Host *host = srb->device->host; struct Scsi_Host *host = srb->device->host;
struct us_data *us = (struct us_data *) host->hostdata[0]; struct us_data *us = (struct us_data *) host->hostdata[0];
int state = atomic_read(&us->sm_state);
US_DEBUGP("%s called\n", __FUNCTION__); US_DEBUGP("%s called\n", __FUNCTION__);
...@@ -186,19 +184,19 @@ static int usb_storage_command_abort( Scsi_Cmnd *srb ) ...@@ -186,19 +184,19 @@ static int usb_storage_command_abort( Scsi_Cmnd *srb )
/* Normally the current state is RUNNING. If the control thread /* Normally the current state is RUNNING. If the control thread
* hasn't even started processing this command, the state will be * hasn't even started processing this command, the state will be
* IDLE. Anything else is a bug. */ * IDLE. Anything else is a bug. */
if (state != US_STATE_RUNNING && state != US_STATE_IDLE) { if (us->sm_state != US_STATE_RUNNING
&& us->sm_state != US_STATE_IDLE) {
printk(KERN_ERR USB_STORAGE "Error in %s: " printk(KERN_ERR USB_STORAGE "Error in %s: "
"invalid state %d\n", __FUNCTION__, state); "invalid state %d\n", __FUNCTION__, us->sm_state);
return FAILED; return FAILED;
} }
/* Set state to ABORTING, set the ABORTING bit, and release the lock */ /* Set state to ABORTING, set the ABORTING bit, and release the lock */
atomic_set(&us->sm_state, US_STATE_ABORTING); us->sm_state = US_STATE_ABORTING;
set_bit(US_FLIDX_ABORTING, &us->flags); set_bit(US_FLIDX_ABORTING, &us->flags);
scsi_unlock(host); scsi_unlock(host);
/* If the state was RUNNING, stop an ongoing USB transfer */ /* Stop an ongoing USB transfer */
if (state == US_STATE_RUNNING)
usb_stor_stop_transport(us); usb_stor_stop_transport(us);
/* Wait for the aborted command to finish */ /* Wait for the aborted command to finish */
...@@ -216,32 +214,27 @@ static int usb_storage_command_abort( Scsi_Cmnd *srb ) ...@@ -216,32 +214,27 @@ static int usb_storage_command_abort( Scsi_Cmnd *srb )
static int usb_storage_device_reset( Scsi_Cmnd *srb ) static int usb_storage_device_reset( Scsi_Cmnd *srb )
{ {
struct us_data *us = (struct us_data *)srb->device->host->hostdata[0]; struct us_data *us = (struct us_data *)srb->device->host->hostdata[0];
int state = atomic_read(&us->sm_state);
int result; int result;
US_DEBUGP("%s called\n", __FUNCTION__); US_DEBUGP("%s called\n", __FUNCTION__);
if (state != US_STATE_IDLE) { if (us->sm_state != US_STATE_IDLE) {
printk(KERN_ERR USB_STORAGE "Error in %s: " printk(KERN_ERR USB_STORAGE "Error in %s: "
"invalid state %d\n", __FUNCTION__, state); "invalid state %d\n", __FUNCTION__, us->sm_state);
return FAILED; return FAILED;
} }
/* set the state and release the lock */ /* set the state and release the lock */
atomic_set(&us->sm_state, US_STATE_RESETTING); us->sm_state = US_STATE_RESETTING;
scsi_unlock(srb->device->host); scsi_unlock(srb->device->host);
/* lock the device pointers */ /* lock the device pointers and do the reset */
down(&(us->dev_semaphore)); down(&(us->dev_semaphore));
/* do the reset */
result = us->transport_reset(us); result = us->transport_reset(us);
/* unlock */
up(&(us->dev_semaphore)); up(&(us->dev_semaphore));
/* lock access to the state and clear it */ /* lock access to the state and clear it */
scsi_lock(srb->device->host); scsi_lock(srb->device->host);
atomic_set(&us->sm_state, US_STATE_IDLE); us->sm_state = US_STATE_IDLE;
return result; return result;
} }
...@@ -252,42 +245,39 @@ static int usb_storage_device_reset( Scsi_Cmnd *srb ) ...@@ -252,42 +245,39 @@ static int usb_storage_device_reset( Scsi_Cmnd *srb )
static int usb_storage_bus_reset( Scsi_Cmnd *srb ) static int usb_storage_bus_reset( Scsi_Cmnd *srb )
{ {
struct us_data *us = (struct us_data *)srb->device->host->hostdata[0]; struct us_data *us = (struct us_data *)srb->device->host->hostdata[0];
int state = atomic_read(&us->sm_state);
int result; int result;
US_DEBUGP("%s called\n", __FUNCTION__); US_DEBUGP("%s called\n", __FUNCTION__);
if (state != US_STATE_IDLE) { if (us->sm_state != US_STATE_IDLE) {
printk(KERN_ERR USB_STORAGE "Error in %s: " printk(KERN_ERR USB_STORAGE "Error in %s: "
"invalid state %d\n", __FUNCTION__, state); "invalid state %d\n", __FUNCTION__, us->sm_state);
return FAILED; return FAILED;
} }
/* set the state and release the lock */ /* set the state and release the lock */
atomic_set(&us->sm_state, US_STATE_RESETTING); us->sm_state = US_STATE_RESETTING;
scsi_unlock(srb->device->host); scsi_unlock(srb->device->host);
/* The USB subsystem doesn't handle synchronisation between /* The USB subsystem doesn't handle synchronisation between
a device's several drivers. Therefore we reset only devices * a device's several drivers. Therefore we reset only devices
with just one interface, which we of course own. * with just one interface, which we of course own. */
*/
//FIXME: needs locking against config changes
if (us->pusb_dev->actconfig->desc.bNumInterfaces == 1) {
/* lock the device and attempt to reset the port */
down(&(us->dev_semaphore)); down(&(us->dev_semaphore));
result = usb_reset_device(us->pusb_dev); if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
up(&(us->dev_semaphore)); result = -EIO;
US_DEBUGP("usb_reset_device returns %d\n", result); US_DEBUGP("Attempt to reset during disconnect\n");
} else { } else if (us->pusb_dev->actconfig->desc.bNumInterfaces != 1) {
result = -EBUSY; result = -EBUSY;
US_DEBUGP("Refusing to reset a multi-interface device\n"); US_DEBUGP("Refusing to reset a multi-interface device\n");
} else {
result = usb_reset_device(us->pusb_dev);
US_DEBUGP("usb_reset_device returns %d\n", result);
} }
up(&(us->dev_semaphore));
/* lock access to the state and clear it */ /* lock access to the state and clear it */
scsi_lock(srb->device->host); scsi_lock(srb->device->host);
atomic_set(&us->sm_state, US_STATE_IDLE); us->sm_state = US_STATE_IDLE;
return result < 0 ? FAILED : SUCCESS; return result < 0 ? FAILED : SUCCESS;
} }
...@@ -333,8 +323,6 @@ static int usb_storage_proc_info (struct Scsi_Host *hostptr, char *buffer, char ...@@ -333,8 +323,6 @@ static int usb_storage_proc_info (struct Scsi_Host *hostptr, char *buffer, char
#define DO_FLAG(a) if (f & US_FL_##a) pos += sprintf(pos, " " #a) #define DO_FLAG(a) if (f & US_FL_##a) pos += sprintf(pos, " " #a)
DO_FLAG(SINGLE_LUN); DO_FLAG(SINGLE_LUN);
DO_FLAG(MODE_XLATE); DO_FLAG(MODE_XLATE);
DO_FLAG(START_STOP);
DO_FLAG(IGNORE_SER);
DO_FLAG(SCM_MULT_TARG); DO_FLAG(SCM_MULT_TARG);
DO_FLAG(FIX_INQUIRY); DO_FLAG(FIX_INQUIRY);
DO_FLAG(FIX_CAPACITY); DO_FLAG(FIX_CAPACITY);
......
...@@ -136,9 +136,9 @@ static int usb_stor_msg_common(struct us_data *us, int timeout) ...@@ -136,9 +136,9 @@ static int usb_stor_msg_common(struct us_data *us, int timeout)
struct timer_list to_timer; struct timer_list to_timer;
int status; int status;
/* don't submit URBS during abort/disconnect processing */ /* don't submit URBs during abort/disconnect processing */
if (us->flags & DONT_SUBMIT) if (us->flags & DONT_SUBMIT)
return -ECONNRESET; return -EIO;
/* set up data structures for the wakeup system */ /* set up data structures for the wakeup system */
init_completion(&urb_done); init_completion(&urb_done);
...@@ -299,17 +299,17 @@ static int interpret_urb_result(struct us_data *us, unsigned int pipe, ...@@ -299,17 +299,17 @@ static int interpret_urb_result(struct us_data *us, unsigned int pipe,
return USB_STOR_XFER_ERROR; return USB_STOR_XFER_ERROR;
return USB_STOR_XFER_STALLED; return USB_STOR_XFER_STALLED;
/* NAK - that means we've retried this a few times already */ /* timeout or excessively long NAK */
case -ETIMEDOUT: case -ETIMEDOUT:
US_DEBUGP("-- device NAKed\n"); US_DEBUGP("-- timeout or NAK\n");
return USB_STOR_XFER_ERROR; return USB_STOR_XFER_ERROR;
/* babble - the device tried to send more than we wanted to read */ /* babble - the device tried to send more than we wanted to read */
case -EOVERFLOW: case -EOVERFLOW:
US_DEBUGP("-- Babble\n"); US_DEBUGP("-- babble\n");
return USB_STOR_XFER_LONG; return USB_STOR_XFER_LONG;
/* the transfer was cancelled, presumably by an abort */ /* the transfer was cancelled by abort, disconnect, or timeout */
case -ECONNRESET: case -ECONNRESET:
US_DEBUGP("-- transfer cancelled\n"); US_DEBUGP("-- transfer cancelled\n");
return USB_STOR_XFER_ERROR; return USB_STOR_XFER_ERROR;
...@@ -319,6 +319,11 @@ static int interpret_urb_result(struct us_data *us, unsigned int pipe, ...@@ -319,6 +319,11 @@ static int interpret_urb_result(struct us_data *us, unsigned int pipe,
US_DEBUGP("-- short read transfer\n"); US_DEBUGP("-- short read transfer\n");
return USB_STOR_XFER_SHORT; return USB_STOR_XFER_SHORT;
/* abort or disconnect in progress */
case -EIO:
US_DEBUGP("-- abort or disconnect in progress\n");
return USB_STOR_XFER_ERROR;
/* the catch-all error case */ /* the catch-all error case */
default: default:
US_DEBUGP("-- unknown error\n"); US_DEBUGP("-- unknown error\n");
...@@ -430,7 +435,7 @@ int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe, ...@@ -430,7 +435,7 @@ int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
/* initialize the scatter-gather request block */ /* initialize the scatter-gather request block */
US_DEBUGP("%s: xfer %u bytes, %d entries\n", __FUNCTION__, US_DEBUGP("%s: xfer %u bytes, %d entries\n", __FUNCTION__,
length, num_sg); length, num_sg);
result = usb_sg_init(us->current_sg, us->pusb_dev, pipe, 0, result = usb_sg_init(&us->current_sg, us->pusb_dev, pipe, 0,
sg, num_sg, length, SLAB_NOIO); sg, num_sg, length, SLAB_NOIO);
if (result) { if (result) {
US_DEBUGP("usb_sg_init returned %d\n", result); US_DEBUGP("usb_sg_init returned %d\n", result);
...@@ -447,19 +452,19 @@ int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe, ...@@ -447,19 +452,19 @@ int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
/* cancel the request, if it hasn't been cancelled already */ /* cancel the request, if it hasn't been cancelled already */
if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->flags)) { if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->flags)) {
US_DEBUGP("-- cancelling sg request\n"); US_DEBUGP("-- cancelling sg request\n");
usb_sg_cancel(us->current_sg); usb_sg_cancel(&us->current_sg);
} }
} }
/* wait for the completion of the transfer */ /* wait for the completion of the transfer */
usb_sg_wait(us->current_sg); usb_sg_wait(&us->current_sg);
clear_bit(US_FLIDX_SG_ACTIVE, &us->flags); clear_bit(US_FLIDX_SG_ACTIVE, &us->flags);
result = us->current_sg->status; result = us->current_sg.status;
if (act_len) if (act_len)
*act_len = us->current_sg->bytes; *act_len = us->current_sg.bytes;
return interpret_urb_result(us, pipe, length, result, return interpret_urb_result(us, pipe, length, result,
us->current_sg->bytes); us->current_sg.bytes);
} }
/* /*
...@@ -518,7 +523,7 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -518,7 +523,7 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
/* if the command gets aborted by the higher layers, we need to /* if the command gets aborted by the higher layers, we need to
* short-circuit all other processing * short-circuit all other processing
*/ */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) { if (us->sm_state == US_STATE_ABORTING) {
US_DEBUGP("-- command was aborted\n"); US_DEBUGP("-- command was aborted\n");
goto Handle_Abort; goto Handle_Abort;
} }
...@@ -650,7 +655,7 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -650,7 +655,7 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
srb->cmd_len = old_cmd_len; srb->cmd_len = old_cmd_len;
memcpy(srb->cmnd, old_cmnd, MAX_COMMAND_SIZE); memcpy(srb->cmnd, old_cmnd, MAX_COMMAND_SIZE);
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) { if (us->sm_state == US_STATE_ABORTING) {
US_DEBUGP("-- auto-sense aborted\n"); US_DEBUGP("-- auto-sense aborted\n");
goto Handle_Abort; goto Handle_Abort;
} }
...@@ -734,7 +739,7 @@ void usb_stor_stop_transport(struct us_data *us) ...@@ -734,7 +739,7 @@ void usb_stor_stop_transport(struct us_data *us)
/* If we are waiting for a scatter-gather operation, cancel it. */ /* If we are waiting for a scatter-gather operation, cancel it. */
if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->flags)) { if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->flags)) {
US_DEBUGP("-- cancelling sg request\n"); US_DEBUGP("-- cancelling sg request\n");
usb_sg_cancel(us->current_sg); usb_sg_cancel(&us->current_sg);
} }
} }
......
...@@ -328,13 +328,13 @@ static int usb_stor_control_thread(void * __us) ...@@ -328,13 +328,13 @@ static int usb_stor_control_thread(void * __us)
scsi_lock(host); scsi_lock(host);
/* has the command been aborted *already* ? */ /* has the command been aborted *already* ? */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) { if (us->sm_state == US_STATE_ABORTING) {
us->srb->result = DID_ABORT << 16; us->srb->result = DID_ABORT << 16;
goto SkipForAbort; goto SkipForAbort;
} }
/* set the state and release the lock */ /* set the state and release the lock */
atomic_set(&us->sm_state, US_STATE_RUNNING); us->sm_state = US_STATE_RUNNING;
scsi_unlock(host); scsi_unlock(host);
/* lock the device pointers */ /* lock the device pointers */
...@@ -404,12 +404,12 @@ static int usb_stor_control_thread(void * __us) ...@@ -404,12 +404,12 @@ static int usb_stor_control_thread(void * __us)
* sm_state == US_STATE_ABORTING, not srb->result == DID_ABORT, * sm_state == US_STATE_ABORTING, not srb->result == DID_ABORT,
* because an abort request might be received after all the * because an abort request might be received after all the
* USB processing was complete. */ * USB processing was complete. */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) if (us->sm_state == US_STATE_ABORTING)
complete(&(us->notify)); complete(&(us->notify));
/* empty the queue, reset the state, and release the lock */ /* empty the queue, reset the state, and release the lock */
us->srb = NULL; us->srb = NULL;
atomic_set(&us->sm_state, US_STATE_IDLE); us->sm_state = US_STATE_IDLE;
scsi_unlock(host); scsi_unlock(host);
} /* for (;;) */ } /* for (;;) */
...@@ -447,7 +447,7 @@ static void get_device_info(struct us_data *us, ...@@ -447,7 +447,7 @@ static void get_device_info(struct us_data *us,
if (dev->descriptor.iProduct) if (dev->descriptor.iProduct)
usb_string(dev, dev->descriptor.iProduct, usb_string(dev, dev->descriptor.iProduct,
us->product, sizeof(us->product)); us->product, sizeof(us->product));
if (dev->descriptor.iSerialNumber && !(us->flags & US_FL_IGNORE_SER)) if (dev->descriptor.iSerialNumber)
usb_string(dev, dev->descriptor.iSerialNumber, usb_string(dev, dev->descriptor.iSerialNumber,
us->serial, sizeof(us->serial)); us->serial, sizeof(us->serial));
...@@ -698,13 +698,6 @@ static int usb_stor_acquire_resources(struct us_data *us) ...@@ -698,13 +698,6 @@ static int usb_stor_acquire_resources(struct us_data *us)
return -ENOMEM; return -ENOMEM;
} }
US_DEBUGP("Allocating scatter-gather request block\n");
us->current_sg = kmalloc(sizeof(*us->current_sg), GFP_KERNEL);
if (!us->current_sg) {
US_DEBUGP("allocation failed\n");
return -ENOMEM;
}
/* Lock the device while we carry out the next two operations */ /* Lock the device while we carry out the next two operations */
down(&us->dev_semaphore); down(&us->dev_semaphore);
...@@ -720,7 +713,7 @@ static int usb_stor_acquire_resources(struct us_data *us) ...@@ -720,7 +713,7 @@ static int usb_stor_acquire_resources(struct us_data *us)
up(&us->dev_semaphore); up(&us->dev_semaphore);
/* Start up our control thread */ /* Start up our control thread */
atomic_set(&us->sm_state, US_STATE_IDLE); us->sm_state = US_STATE_IDLE;
p = kernel_thread(usb_stor_control_thread, us, CLONE_VM); p = kernel_thread(usb_stor_control_thread, us, CLONE_VM);
if (p < 0) { if (p < 0) {
printk(KERN_WARNING USB_STORAGE printk(KERN_WARNING USB_STORAGE
...@@ -782,7 +775,7 @@ void usb_stor_release_resources(struct us_data *us) ...@@ -782,7 +775,7 @@ void usb_stor_release_resources(struct us_data *us)
*/ */
if (us->pid) { if (us->pid) {
US_DEBUGP("-- sending exit command to thread\n"); US_DEBUGP("-- sending exit command to thread\n");
BUG_ON(atomic_read(&us->sm_state) != US_STATE_IDLE); BUG_ON(us->sm_state != US_STATE_IDLE);
us->srb = NULL; us->srb = NULL;
up(&(us->sema)); up(&(us->sema));
wait_for_completion(&(us->notify)); wait_for_completion(&(us->notify));
...@@ -800,8 +793,6 @@ void usb_stor_release_resources(struct us_data *us) ...@@ -800,8 +793,6 @@ void usb_stor_release_resources(struct us_data *us)
} }
/* Free the USB control blocks */ /* Free the USB control blocks */
if (us->current_sg)
kfree(us->current_sg);
if (us->current_urb) if (us->current_urb)
usb_free_urb(us->current_urb); usb_free_urb(us->current_urb);
if (us->dr) if (us->dr)
......
...@@ -139,7 +139,7 @@ struct us_data { ...@@ -139,7 +139,7 @@ struct us_data {
/* thread information */ /* thread information */
int pid; /* control thread */ int pid; /* control thread */
atomic_t sm_state; /* what we are doing */ int sm_state; /* what we are doing */
/* interrupt communications data */ /* interrupt communications data */
unsigned char irqdata[2]; /* data from USB IRQ */ unsigned char irqdata[2]; /* data from USB IRQ */
...@@ -147,7 +147,7 @@ struct us_data { ...@@ -147,7 +147,7 @@ struct us_data {
/* control and bulk communications data */ /* control and bulk communications data */
struct urb *current_urb; /* non-int USB requests */ struct urb *current_urb; /* non-int USB requests */
struct usb_ctrlrequest *dr; /* control requests */ struct usb_ctrlrequest *dr; /* control requests */
struct usb_sg_request *current_sg; /* scatter-gather USB */ struct usb_sg_request current_sg; /* scatter-gather USB */
/* 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