Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 8672
b: refs/heads/master
c: 226173e
h: refs/heads/master
v: v3
  • Loading branch information
Matthew Dharm authored and Greg Kroah-Hartman committed Sep 12, 2005
1 parent 6fbbaa4 commit 89cd2c2
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 15 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b789696af8b4102b7cc26dec30c2c51ce51ee18b
refs/heads/master: 226173edae1c49c68ebb723771a02302c85e3475
20 changes: 9 additions & 11 deletions trunk/drivers/usb/storage/scsiglue.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,42 +227,42 @@ static int queuecommand(struct scsi_cmnd *srb,
***********************************************************************/

/* Command timeout and abort */
/* This is always called with scsi_lock(host) held */
static int command_abort(struct scsi_cmnd *srb)
{
struct us_data *us = host_to_us(srb->device->host);

US_DEBUGP("%s called\n", __FUNCTION__);

/* us->srb together with the TIMED_OUT, RESETTING, and ABORTING
* bits are protected by the host lock. */
scsi_lock(us_to_host(us));

/* Is this command still active? */
if (us->srb != srb) {
scsi_unlock(us_to_host(us));
US_DEBUGP ("-- nothing to abort\n");
return FAILED;
}

/* Set the TIMED_OUT bit. Also set the ABORTING bit, but only if
* a device reset isn't already in progress (to avoid interfering
* with the reset). To prevent races with auto-reset, we must
* stop any ongoing USB transfers while still holding the host
* lock. */
* with the reset). Note that we must retain the host lock while
* calling usb_stor_stop_transport(); otherwise it might interfere
* with an auto-reset that begins as soon as we release the lock. */
set_bit(US_FLIDX_TIMED_OUT, &us->flags);
if (!test_bit(US_FLIDX_RESETTING, &us->flags)) {
set_bit(US_FLIDX_ABORTING, &us->flags);
usb_stor_stop_transport(us);
}
scsi_unlock(us_to_host(us));

/* Wait for the aborted command to finish */
wait_for_completion(&us->notify);

/* Reacquire the lock and allow USB transfers to resume */
clear_bit(US_FLIDX_ABORTING, &us->flags);
clear_bit(US_FLIDX_TIMED_OUT, &us->flags);
return SUCCESS;
}

/* This invokes the transport reset mechanism to reset the state of the
* device */
/* This is always called with scsi_lock(host) held */
static int device_reset(struct scsi_cmnd *srb)
{
struct us_data *us = host_to_us(srb->device->host);
Expand All @@ -279,7 +279,6 @@ static int device_reset(struct scsi_cmnd *srb)
}

/* Simulate a SCSI bus reset by resetting the device's USB port. */
/* This is always called with scsi_lock(host) held */
static int bus_reset(struct scsi_cmnd *srb)
{
struct us_data *us = host_to_us(srb->device->host);
Expand All @@ -291,7 +290,6 @@ static int bus_reset(struct scsi_cmnd *srb)
result = usb_stor_port_reset(us);
up(&(us->dev_semaphore));

/* lock the host for the return */
return result < 0 ? FAILED : SUCCESS;
}

Expand Down
11 changes: 8 additions & 3 deletions trunk/drivers/usb/storage/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -392,11 +392,16 @@ static int usb_stor_control_thread(void * __us)
/* If an abort request was received we need to signal that
* the abort has finished. The proper test for this is
* the TIMED_OUT flag, not srb->result == DID_ABORT, because
* a timeout/abort request might be received after all the
* USB processing was complete. */
if (test_bit(US_FLIDX_TIMED_OUT, &us->flags))
* the timeout might have occurred after the command had
* already completed with a different result code. */
if (test_bit(US_FLIDX_TIMED_OUT, &us->flags)) {
complete(&(us->notify));

/* Allow USB transfers to resume */
clear_bit(US_FLIDX_ABORTING, &us->flags);
clear_bit(US_FLIDX_TIMED_OUT, &us->flags);
}

/* finished working on this command */
us->srb = NULL;
scsi_unlock(host);
Expand Down

0 comments on commit 89cd2c2

Please sign in to comment.