mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-06 10:57:46 +00:00
cciss: separate error processing and command retrying code in sendcmd_withirq_core()
Separate the error processing from sendcmd_withirq_core from the code which retries commands. The rationale for this is that the SCSI error handling code can then be made to use sendcmd_withirq_core, but avoid retrying commands. Signed-off-by: Stephen M. Cameron <scameron@beardog.cca.cpqcorp.net> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
This commit is contained in:
parent
3c2ab40296
commit
789a424ad1
2 changed files with 46 additions and 32 deletions
|
@ -2292,26 +2292,12 @@ static int check_target_status(ctlr_info_t *h, CommandList_struct *c)
|
||||||
return IO_ERROR;
|
return IO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sendcmd_withirq_core(ctlr_info_t *h, CommandList_struct *c)
|
static int process_sendcmd_error(ctlr_info_t *h, CommandList_struct *c)
|
||||||
{
|
{
|
||||||
DECLARE_COMPLETION_ONSTACK(wait);
|
|
||||||
u64bit buff_dma_handle;
|
|
||||||
unsigned long flags;
|
|
||||||
int return_status = IO_OK;
|
int return_status = IO_OK;
|
||||||
|
|
||||||
resend_cmd2:
|
if (c->err_info->CommandStatus == CMD_SUCCESS)
|
||||||
c->waiting = &wait;
|
return IO_OK;
|
||||||
/* Put the request on the tail of the queue and send it */
|
|
||||||
spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
|
|
||||||
addQ(&h->reqQ, c);
|
|
||||||
h->Qdepth++;
|
|
||||||
start_io(h);
|
|
||||||
spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
|
|
||||||
|
|
||||||
wait_for_completion(&wait);
|
|
||||||
|
|
||||||
if (c->err_info->CommandStatus == 0)
|
|
||||||
goto command_done;
|
|
||||||
|
|
||||||
switch (c->err_info->CommandStatus) {
|
switch (c->err_info->CommandStatus) {
|
||||||
case CMD_TARGET_STATUS:
|
case CMD_TARGET_STATUS:
|
||||||
|
@ -2322,7 +2308,7 @@ static int sendcmd_withirq_core(ctlr_info_t *h, CommandList_struct *c)
|
||||||
/* expected for inquiry and report lun commands */
|
/* expected for inquiry and report lun commands */
|
||||||
break;
|
break;
|
||||||
case CMD_INVALID:
|
case CMD_INVALID:
|
||||||
printk(KERN_WARNING "cciss: Cmd 0x%02x is "
|
printk(KERN_WARNING "cciss: cmd 0x%02x is "
|
||||||
"reported invalid\n", c->Request.CDB[0]);
|
"reported invalid\n", c->Request.CDB[0]);
|
||||||
return_status = IO_ERROR;
|
return_status = IO_ERROR;
|
||||||
break;
|
break;
|
||||||
|
@ -2355,19 +2341,7 @@ static int sendcmd_withirq_core(ctlr_info_t *h, CommandList_struct *c)
|
||||||
printk(KERN_WARNING
|
printk(KERN_WARNING
|
||||||
"cciss%d: unsolicited abort 0x%02x\n", h->ctlr,
|
"cciss%d: unsolicited abort 0x%02x\n", h->ctlr,
|
||||||
c->Request.CDB[0]);
|
c->Request.CDB[0]);
|
||||||
if (c->retry_count < MAX_CMD_RETRIES) {
|
return_status = IO_NEEDS_RETRY;
|
||||||
printk(KERN_WARNING
|
|
||||||
"cciss%d: retrying 0x%02x\n", h->ctlr,
|
|
||||||
c->Request.CDB[0]);
|
|
||||||
c->retry_count++;
|
|
||||||
/* erase the old error information */
|
|
||||||
memset(c->err_info, 0,
|
|
||||||
sizeof(ErrorInfo_struct));
|
|
||||||
return_status = IO_OK;
|
|
||||||
INIT_COMPLETION(wait);
|
|
||||||
goto resend_cmd2;
|
|
||||||
}
|
|
||||||
return_status = IO_ERROR;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printk(KERN_WARNING "cciss: cmd 0x%02x returned "
|
printk(KERN_WARNING "cciss: cmd 0x%02x returned "
|
||||||
|
@ -2375,6 +2349,44 @@ static int sendcmd_withirq_core(ctlr_info_t *h, CommandList_struct *c)
|
||||||
c->err_info->CommandStatus);
|
c->err_info->CommandStatus);
|
||||||
return_status = IO_ERROR;
|
return_status = IO_ERROR;
|
||||||
}
|
}
|
||||||
|
return return_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sendcmd_withirq_core(ctlr_info_t *h, CommandList_struct *c,
|
||||||
|
int attempt_retry)
|
||||||
|
{
|
||||||
|
DECLARE_COMPLETION_ONSTACK(wait);
|
||||||
|
u64bit buff_dma_handle;
|
||||||
|
unsigned long flags;
|
||||||
|
int return_status = IO_OK;
|
||||||
|
|
||||||
|
resend_cmd2:
|
||||||
|
c->waiting = &wait;
|
||||||
|
/* Put the request on the tail of the queue and send it */
|
||||||
|
spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
|
||||||
|
addQ(&h->reqQ, c);
|
||||||
|
h->Qdepth++;
|
||||||
|
start_io(h);
|
||||||
|
spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
|
||||||
|
|
||||||
|
wait_for_completion(&wait);
|
||||||
|
|
||||||
|
if (c->err_info->CommandStatus == 0 || !attempt_retry)
|
||||||
|
goto command_done;
|
||||||
|
|
||||||
|
return_status = process_sendcmd_error(h, c);
|
||||||
|
|
||||||
|
if (return_status == IO_NEEDS_RETRY &&
|
||||||
|
c->retry_count < MAX_CMD_RETRIES) {
|
||||||
|
printk(KERN_WARNING "cciss%d: retrying 0x%02x\n", h->ctlr,
|
||||||
|
c->Request.CDB[0]);
|
||||||
|
c->retry_count++;
|
||||||
|
/* erase the old error information */
|
||||||
|
memset(c->err_info, 0, sizeof(ErrorInfo_struct));
|
||||||
|
return_status = IO_OK;
|
||||||
|
INIT_COMPLETION(wait);
|
||||||
|
goto resend_cmd2;
|
||||||
|
}
|
||||||
|
|
||||||
command_done:
|
command_done:
|
||||||
/* unlock the buffers from DMA */
|
/* unlock the buffers from DMA */
|
||||||
|
@ -2399,7 +2411,8 @@ static int sendcmd_withirq(__u8 cmd, int ctlr, void *buff, size_t size,
|
||||||
return_status = fill_cmd(c, cmd, ctlr, buff, size, page_code,
|
return_status = fill_cmd(c, cmd, ctlr, buff, size, page_code,
|
||||||
scsi3addr, cmd_type);
|
scsi3addr, cmd_type);
|
||||||
if (return_status == IO_OK)
|
if (return_status == IO_OK)
|
||||||
return_status = sendcmd_withirq_core(h, c);
|
return_status = sendcmd_withirq_core(h, c, 1);
|
||||||
|
|
||||||
cmd_free(h, c, 0);
|
cmd_free(h, c, 0);
|
||||||
return return_status;
|
return return_status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#define IO_OK 0
|
#define IO_OK 0
|
||||||
#define IO_ERROR 1
|
#define IO_ERROR 1
|
||||||
|
#define IO_NEEDS_RETRY 3
|
||||||
|
|
||||||
#define VENDOR_LEN 8
|
#define VENDOR_LEN 8
|
||||||
#define MODEL_LEN 16
|
#define MODEL_LEN 16
|
||||||
|
|
Loading…
Reference in a new issue