Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 47796
b: refs/heads/master
c: 292148f
h: refs/heads/master
v: v3
  • Loading branch information
Brian King authored and James Bottomley committed Feb 3, 2007
1 parent 40476a7 commit d043c1c
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 117 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: 214fbb75075efa677b614be79a2d62dd79785b4f
refs/heads/master: 292148f8bb2b5d120440e046d24de07a739461aa
239 changes: 123 additions & 116 deletions trunk/drivers/scsi/scsi_error.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,128 @@ static void scsi_eh_done(struct scsi_cmnd *scmd)
complete(eh_action);
}

/**
* scsi_try_host_reset - ask host adapter to reset itself
* @scmd: SCSI cmd to send hsot reset.
**/
static int scsi_try_host_reset(struct scsi_cmnd *scmd)
{
unsigned long flags;
int rtn;

SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Host RST\n",
__FUNCTION__));

if (!scmd->device->host->hostt->eh_host_reset_handler)
return FAILED;

rtn = scmd->device->host->hostt->eh_host_reset_handler(scmd);

if (rtn == SUCCESS) {
if (!scmd->device->host->hostt->skip_settle_delay)
ssleep(HOST_RESET_SETTLE_TIME);
spin_lock_irqsave(scmd->device->host->host_lock, flags);
scsi_report_bus_reset(scmd->device->host,
scmd_channel(scmd));
spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
}

return rtn;
}

/**
* scsi_try_bus_reset - ask host to perform a bus reset
* @scmd: SCSI cmd to send bus reset.
**/
static int scsi_try_bus_reset(struct scsi_cmnd *scmd)
{
unsigned long flags;
int rtn;

SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Bus RST\n",
__FUNCTION__));

if (!scmd->device->host->hostt->eh_bus_reset_handler)
return FAILED;

rtn = scmd->device->host->hostt->eh_bus_reset_handler(scmd);

if (rtn == SUCCESS) {
if (!scmd->device->host->hostt->skip_settle_delay)
ssleep(BUS_RESET_SETTLE_TIME);
spin_lock_irqsave(scmd->device->host->host_lock, flags);
scsi_report_bus_reset(scmd->device->host,
scmd_channel(scmd));
spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
}

return rtn;
}

/**
* scsi_try_bus_device_reset - Ask host to perform a BDR on a dev
* @scmd: SCSI cmd used to send BDR
*
* Notes:
* There is no timeout for this operation. if this operation is
* unreliable for a given host, then the host itself needs to put a
* timer on it, and set the host back to a consistent state prior to
* returning.
**/
static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd)
{
int rtn;

if (!scmd->device->host->hostt->eh_device_reset_handler)
return FAILED;

rtn = scmd->device->host->hostt->eh_device_reset_handler(scmd);
if (rtn == SUCCESS) {
scmd->device->was_reset = 1;
scmd->device->expecting_cc_ua = 1;
}

return rtn;
}

static int __scsi_try_to_abort_cmd(struct scsi_cmnd *scmd)
{
if (!scmd->device->host->hostt->eh_abort_handler)
return FAILED;

return scmd->device->host->hostt->eh_abort_handler(scmd);
}

/**
* scsi_try_to_abort_cmd - Ask host to abort a running command.
* @scmd: SCSI cmd to abort from Lower Level.
*
* Notes:
* This function will not return until the user's completion function
* has been called. there is no timeout on this operation. if the
* author of the low-level driver wishes this operation to be timed,
* they can provide this facility themselves. helper functions in
* scsi_error.c can be supplied to make this easier to do.
**/
static int scsi_try_to_abort_cmd(struct scsi_cmnd *scmd)
{
/*
* scsi_done was called just after the command timed out and before
* we had a chance to process it. (db)
*/
if (scmd->serial_number == 0)
return SUCCESS;
return __scsi_try_to_abort_cmd(scmd);
}

static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd)
{
if (__scsi_try_to_abort_cmd(scmd) != SUCCESS)
if (scsi_try_bus_device_reset(scmd) != SUCCESS)
if (scsi_try_bus_reset(scmd) != SUCCESS)
scsi_try_host_reset(scmd);
}

/**
* scsi_send_eh_cmnd - submit a scsi command as part of error recory
* @scmd: SCSI command structure to hijack
Expand Down Expand Up @@ -584,13 +706,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
break;
}
} else {
/*
* FIXME(eric) - we are not tracking whether we could
* abort a timed out command or not. not sure how
* we should treat them differently anyways.
*/
if (shost->hostt->eh_abort_handler)
shost->hostt->eh_abort_handler(scmd);
scsi_abort_eh_cmnd(scmd);
rtn = FAILED;
}

Expand Down Expand Up @@ -722,31 +838,6 @@ int scsi_eh_get_sense(struct list_head *work_q,
}
EXPORT_SYMBOL_GPL(scsi_eh_get_sense);

/**
* scsi_try_to_abort_cmd - Ask host to abort a running command.
* @scmd: SCSI cmd to abort from Lower Level.
*
* Notes:
* This function will not return until the user's completion function
* has been called. there is no timeout on this operation. if the
* author of the low-level driver wishes this operation to be timed,
* they can provide this facility themselves. helper functions in
* scsi_error.c can be supplied to make this easier to do.
**/
static int scsi_try_to_abort_cmd(struct scsi_cmnd *scmd)
{
if (!scmd->device->host->hostt->eh_abort_handler)
return FAILED;

/*
* scsi_done was called just after the command timed out and before
* we had a chance to process it. (db)
*/
if (scmd->serial_number == 0)
return SUCCESS;
return scmd->device->host->hostt->eh_abort_handler(scmd);
}

/**
* scsi_eh_tur - Send TUR to device.
* @scmd: Scsi cmd to send TUR
Expand Down Expand Up @@ -820,32 +911,6 @@ static int scsi_eh_abort_cmds(struct list_head *work_q,
return list_empty(work_q);
}

/**
* scsi_try_bus_device_reset - Ask host to perform a BDR on a dev
* @scmd: SCSI cmd used to send BDR
*
* Notes:
* There is no timeout for this operation. if this operation is
* unreliable for a given host, then the host itself needs to put a
* timer on it, and set the host back to a consistent state prior to
* returning.
**/
static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd)
{
int rtn;

if (!scmd->device->host->hostt->eh_device_reset_handler)
return FAILED;

rtn = scmd->device->host->hostt->eh_device_reset_handler(scmd);
if (rtn == SUCCESS) {
scmd->device->was_reset = 1;
scmd->device->expecting_cc_ua = 1;
}

return rtn;
}

/**
* scsi_eh_try_stu - Send START_UNIT to device.
* @scmd: Scsi cmd to send START_UNIT
Expand Down Expand Up @@ -976,64 +1041,6 @@ static int scsi_eh_bus_device_reset(struct Scsi_Host *shost,
return list_empty(work_q);
}

/**
* scsi_try_bus_reset - ask host to perform a bus reset
* @scmd: SCSI cmd to send bus reset.
**/
static int scsi_try_bus_reset(struct scsi_cmnd *scmd)
{
unsigned long flags;
int rtn;

SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Bus RST\n",
__FUNCTION__));

if (!scmd->device->host->hostt->eh_bus_reset_handler)
return FAILED;

rtn = scmd->device->host->hostt->eh_bus_reset_handler(scmd);

if (rtn == SUCCESS) {
if (!scmd->device->host->hostt->skip_settle_delay)
ssleep(BUS_RESET_SETTLE_TIME);
spin_lock_irqsave(scmd->device->host->host_lock, flags);
scsi_report_bus_reset(scmd->device->host,
scmd_channel(scmd));
spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
}

return rtn;
}

/**
* scsi_try_host_reset - ask host adapter to reset itself
* @scmd: SCSI cmd to send hsot reset.
**/
static int scsi_try_host_reset(struct scsi_cmnd *scmd)
{
unsigned long flags;
int rtn;

SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Host RST\n",
__FUNCTION__));

if (!scmd->device->host->hostt->eh_host_reset_handler)
return FAILED;

rtn = scmd->device->host->hostt->eh_host_reset_handler(scmd);

if (rtn == SUCCESS) {
if (!scmd->device->host->hostt->skip_settle_delay)
ssleep(HOST_RESET_SETTLE_TIME);
spin_lock_irqsave(scmd->device->host->host_lock, flags);
scsi_report_bus_reset(scmd->device->host,
scmd_channel(scmd));
spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
}

return rtn;
}

/**
* scsi_eh_bus_reset - send a bus reset
* @shost: scsi host being recovered.
Expand Down

0 comments on commit d043c1c

Please sign in to comment.