aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/cciss.c77
-rw-r--r--drivers/block/cciss.h1
2 files changed, 46 insertions, 32 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 2d128831d3ca..700170711061 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -2292,26 +2292,12 @@ static int check_target_status(ctlr_info_t *h, CommandList_struct *c)
2292 return IO_ERROR; 2292 return IO_ERROR;
2293} 2293}
2294 2294
2295static int sendcmd_withirq_core(ctlr_info_t *h, CommandList_struct *c) 2295static int process_sendcmd_error(ctlr_info_t *h, CommandList_struct *c)
2296{ 2296{
2297 DECLARE_COMPLETION_ONSTACK(wait);
2298 u64bit buff_dma_handle;
2299 unsigned long flags;
2300 int return_status = IO_OK; 2297 int return_status = IO_OK;
2301 2298
2302resend_cmd2: 2299 if (c->err_info->CommandStatus == CMD_SUCCESS)
2303 c->waiting = &wait; 2300 return IO_OK;
2304 /* Put the request on the tail of the queue and send it */
2305 spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
2306 addQ(&h->reqQ, c);
2307 h->Qdepth++;
2308 start_io(h);
2309 spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
2310
2311 wait_for_completion(&wait);
2312
2313 if (c->err_info->CommandStatus == 0)
2314 goto command_done;
2315 2301
2316 switch (c->err_info->CommandStatus) { 2302 switch (c->err_info->CommandStatus) {
2317 case CMD_TARGET_STATUS: 2303 case CMD_TARGET_STATUS:
@@ -2322,7 +2308,7 @@ resend_cmd2:
2322 /* expected for inquiry and report lun commands */ 2308 /* expected for inquiry and report lun commands */
2323 break; 2309 break;
2324 case CMD_INVALID: 2310 case CMD_INVALID:
2325 printk(KERN_WARNING "cciss: Cmd 0x%02x is " 2311 printk(KERN_WARNING "cciss: cmd 0x%02x is "
2326 "reported invalid\n", c->Request.CDB[0]); 2312 "reported invalid\n", c->Request.CDB[0]);
2327 return_status = IO_ERROR; 2313 return_status = IO_ERROR;
2328 break; 2314 break;
@@ -2355,19 +2341,7 @@ resend_cmd2:
2355 printk(KERN_WARNING 2341 printk(KERN_WARNING
2356 "cciss%d: unsolicited abort 0x%02x\n", h->ctlr, 2342 "cciss%d: unsolicited abort 0x%02x\n", h->ctlr,
2357 c->Request.CDB[0]); 2343 c->Request.CDB[0]);
2358 if (c->retry_count < MAX_CMD_RETRIES) { 2344 return_status = IO_NEEDS_RETRY;
2359 printk(KERN_WARNING
2360 "cciss%d: retrying 0x%02x\n", h->ctlr,
2361 c->Request.CDB[0]);
2362 c->retry_count++;
2363 /* erase the old error information */
2364 memset(c->err_info, 0,
2365 sizeof(ErrorInfo_struct));
2366 return_status = IO_OK;
2367 INIT_COMPLETION(wait);
2368 goto resend_cmd2;
2369 }
2370 return_status = IO_ERROR;
2371 break; 2345 break;
2372 default: 2346 default:
2373 printk(KERN_WARNING "cciss: cmd 0x%02x returned " 2347 printk(KERN_WARNING "cciss: cmd 0x%02x returned "
@@ -2375,6 +2349,44 @@ resend_cmd2:
2375 c->err_info->CommandStatus); 2349 c->err_info->CommandStatus);
2376 return_status = IO_ERROR; 2350 return_status = IO_ERROR;
2377 } 2351 }
2352 return return_status;
2353}
2354
2355static int sendcmd_withirq_core(ctlr_info_t *h, CommandList_struct *c,
2356 int attempt_retry)
2357{
2358 DECLARE_COMPLETION_ONSTACK(wait);
2359 u64bit buff_dma_handle;
2360 unsigned long flags;
2361 int return_status = IO_OK;
2362
2363resend_cmd2:
2364 c->waiting = &wait;
2365 /* Put the request on the tail of the queue and send it */
2366 spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
2367 addQ(&h->reqQ, c);
2368 h->Qdepth++;
2369 start_io(h);
2370 spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
2371
2372 wait_for_completion(&wait);
2373
2374 if (c->err_info->CommandStatus == 0 || !attempt_retry)
2375 goto command_done;
2376
2377 return_status = process_sendcmd_error(h, c);
2378
2379 if (return_status == IO_NEEDS_RETRY &&
2380 c->retry_count < MAX_CMD_RETRIES) {
2381 printk(KERN_WARNING "cciss%d: retrying 0x%02x\n", h->ctlr,
2382 c->Request.CDB[0]);
2383 c->retry_count++;
2384 /* erase the old error information */
2385 memset(c->err_info, 0, sizeof(ErrorInfo_struct));
2386 return_status = IO_OK;
2387 INIT_COMPLETION(wait);
2388 goto resend_cmd2;
2389 }
2378 2390
2379command_done: 2391command_done:
2380 /* unlock the buffers from DMA */ 2392 /* unlock the buffers from DMA */
@@ -2399,7 +2411,8 @@ static int sendcmd_withirq(__u8 cmd, int ctlr, void *buff, size_t size,
2399 return_status = fill_cmd(c, cmd, ctlr, buff, size, page_code, 2411 return_status = fill_cmd(c, cmd, ctlr, buff, size, page_code,
2400 scsi3addr, cmd_type); 2412 scsi3addr, cmd_type);
2401 if (return_status == IO_OK) 2413 if (return_status == IO_OK)
2402 return_status = sendcmd_withirq_core(h, c); 2414 return_status = sendcmd_withirq_core(h, c, 1);
2415
2403 cmd_free(h, c, 0); 2416 cmd_free(h, c, 0);
2404 return return_status; 2417 return return_status;
2405} 2418}
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h
index dd1926d8cd97..25cd58e25021 100644
--- a/drivers/block/cciss.h
+++ b/drivers/block/cciss.h
@@ -11,6 +11,7 @@
11 11
12#define IO_OK 0 12#define IO_OK 0
13#define IO_ERROR 1 13#define IO_ERROR 1
14#define IO_NEEDS_RETRY 3
14 15
15#define VENDOR_LEN 8 16#define VENDOR_LEN 8
16#define MODEL_LEN 16 17#define MODEL_LEN 16