diff options
author | scameron@beardog.cca.cpqcorp.net <scameron@beardog.cca.cpqcorp.net> | 2009-06-08 17:04:35 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2009-06-08 23:47:43 -0400 |
commit | 3c2ab40296894d1f7ad9714550fdf9b96d4e9ee6 (patch) | |
tree | d83a8cfceddeae1c7a2bc102250c0482ffd6fb36 /drivers/block | |
parent | b57695fe131b13d3f2460cfeb9175cff673ed337 (diff) |
cciss: factor out fix target status processing code from sendcmd functions
Factor out code to process target status of completed commands in sendcmd()
and sendcmd_withirq_core(), and fix problem that bad target status was ignored in
sendcmd_withirq_core.
Signed-off-by: Stephen M. Cameron <scameron@beardog.cca.cpqcorp.net>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/cciss.c | 56 |
1 files changed, 34 insertions, 22 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 885ea1e38e42..2d128831d3ca 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -2267,6 +2267,31 @@ static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff, | |||
2267 | return status; | 2267 | return status; |
2268 | } | 2268 | } |
2269 | 2269 | ||
2270 | static int check_target_status(ctlr_info_t *h, CommandList_struct *c) | ||
2271 | { | ||
2272 | switch (c->err_info->ScsiStatus) { | ||
2273 | case SAM_STAT_GOOD: | ||
2274 | return IO_OK; | ||
2275 | case SAM_STAT_CHECK_CONDITION: | ||
2276 | switch (0xf & c->err_info->SenseInfo[2]) { | ||
2277 | case 0: return IO_OK; /* no sense */ | ||
2278 | case 1: return IO_OK; /* recovered error */ | ||
2279 | default: | ||
2280 | printk(KERN_WARNING "cciss%d: cmd 0x%02x " | ||
2281 | "check condition, sense key = 0x%02x\n", | ||
2282 | h->ctlr, c->Request.CDB[0], | ||
2283 | c->err_info->SenseInfo[2]); | ||
2284 | } | ||
2285 | break; | ||
2286 | default: | ||
2287 | printk(KERN_WARNING "cciss%d: cmd 0x%02x" | ||
2288 | "scsi status = 0x%02x\n", h->ctlr, | ||
2289 | c->Request.CDB[0], c->err_info->ScsiStatus); | ||
2290 | break; | ||
2291 | } | ||
2292 | return IO_ERROR; | ||
2293 | } | ||
2294 | |||
2270 | static int sendcmd_withirq_core(ctlr_info_t *h, CommandList_struct *c) | 2295 | static int sendcmd_withirq_core(ctlr_info_t *h, CommandList_struct *c) |
2271 | { | 2296 | { |
2272 | DECLARE_COMPLETION_ONSTACK(wait); | 2297 | DECLARE_COMPLETION_ONSTACK(wait); |
@@ -2290,16 +2315,7 @@ resend_cmd2: | |||
2290 | 2315 | ||
2291 | switch (c->err_info->CommandStatus) { | 2316 | switch (c->err_info->CommandStatus) { |
2292 | case CMD_TARGET_STATUS: | 2317 | case CMD_TARGET_STATUS: |
2293 | printk(KERN_WARNING "cciss: cmd 0x%02x " | 2318 | return_status = check_target_status(h, c); |
2294 | "has completed with errors\n", c->Request.CDB[0]); | ||
2295 | if (c->err_info->ScsiStatus) { | ||
2296 | printk(KERN_WARNING "cciss: cmd 0x%02x " | ||
2297 | "has SCSI Status = %x\n", | ||
2298 | c->Request.CDB[0], c->err_info->ScsiStatus); | ||
2299 | if (c->err_info->ScsiStatus == SAM_STAT_CHECK_CONDITION) | ||
2300 | printk(KERN_WARNING "sense key = 0x%02x\n", | ||
2301 | 0xf & c->err_info->SenseInfo[2]); | ||
2302 | } | ||
2303 | break; | 2319 | break; |
2304 | case CMD_DATA_UNDERRUN: | 2320 | case CMD_DATA_UNDERRUN: |
2305 | case CMD_DATA_OVERRUN: | 2321 | case CMD_DATA_OVERRUN: |
@@ -2710,33 +2726,29 @@ resend_cmd1: | |||
2710 | printk(KERN_WARNING "cciss%d: retried %p too many " | 2726 | printk(KERN_WARNING "cciss%d: retried %p too many " |
2711 | "times\n", h->ctlr, c); | 2727 | "times\n", h->ctlr, c); |
2712 | status = IO_ERROR; | 2728 | status = IO_ERROR; |
2713 | goto cleanup1; | 2729 | break; |
2714 | } | 2730 | } |
2715 | 2731 | ||
2716 | if (c->err_info->CommandStatus == CMD_UNABORTABLE) { | 2732 | if (c->err_info->CommandStatus == CMD_UNABORTABLE) { |
2717 | printk(KERN_WARNING "cciss%d: command could not be " | 2733 | printk(KERN_WARNING "cciss%d: command could not be " |
2718 | "aborted.\n", h->ctlr); | 2734 | "aborted.\n", h->ctlr); |
2719 | status = IO_ERROR; | 2735 | status = IO_ERROR; |
2720 | goto cleanup1; | 2736 | break; |
2721 | } | 2737 | } |
2722 | 2738 | ||
2723 | printk(KERN_WARNING "cciss%d: sendcmd error\n", h->ctlr); | ||
2724 | printk(KERN_WARNING "cmd = 0x%02x, CommandStatus = 0x%02x\n", | ||
2725 | c->Request.CDB[0], c->err_info->CommandStatus); | ||
2726 | if (c->err_info->CommandStatus == CMD_TARGET_STATUS) { | 2739 | if (c->err_info->CommandStatus == CMD_TARGET_STATUS) { |
2727 | printk(KERN_WARNING "Target status = 0x%02x\n", | 2740 | status = check_target_status(h, c); |
2728 | c->err_info->ScsiStatus); | 2741 | break; |
2729 | if (c->err_info->ScsiStatus == 2) /* chk cond */ | ||
2730 | printk(KERN_WARNING "Sense key = 0x%02x\n", | ||
2731 | 0xf & c->err_info->SenseInfo[2]); | ||
2732 | } | 2742 | } |
2733 | 2743 | ||
2744 | printk(KERN_WARNING "cciss%d: sendcmd error\n", h->ctlr); | ||
2745 | printk(KERN_WARNING "cmd = 0x%02x, CommandStatus = 0x%02x\n", | ||
2746 | c->Request.CDB[0], c->err_info->CommandStatus); | ||
2734 | status = IO_ERROR; | 2747 | status = IO_ERROR; |
2735 | goto cleanup1; | 2748 | break; |
2736 | 2749 | ||
2737 | } while (1); | 2750 | } while (1); |
2738 | 2751 | ||
2739 | cleanup1: | ||
2740 | /* unlock the data buffer from DMA */ | 2752 | /* unlock the data buffer from DMA */ |
2741 | buff_dma_handle.val32.lower = c->SG[0].Addr.lower; | 2753 | buff_dma_handle.val32.lower = c->SG[0].Addr.lower; |
2742 | buff_dma_handle.val32.upper = c->SG[0].Addr.upper; | 2754 | buff_dma_handle.val32.upper = c->SG[0].Addr.upper; |