diff options
author | Mike Miller (OS Dev) <mikem@beardog.cca.cpqcorp.net> | 2007-05-08 03:29:34 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-08 14:15:09 -0400 |
commit | 198b766013e680a9e367aeb0d62f402029868a09 (patch) | |
tree | 911b4269e4335361ea8be2809b203d4d38002b38 /drivers/block/cciss.c | |
parent | 03bbfee58d440f5dc2e880944ab75fc644534794 (diff) |
cciss: set rq->errors more correctly in driver
Set rq->errors more correctly in cciss driver. Previously we had set it
synonymously with the meaning of the last parameter of end_that_last_request
and complete_buffers (the "uptodate" parameter) and had gotten away with it
for all this time because nobody ever looked at rq->errors.
SCSI_IOCTL_SEND_COMMAND looks at rq->errors, so now it matters that it be
right.
Signed-off-by: Stephen M. Cameron <steve.cameron@hp.com>
Signed-off-by: Mike Miller <mike.miller@hp.com>
Cc: James Bottomley <James.Bottomley@steeleye.com>
Cc: Jens Axboe <jens.axboe@oracle.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/block/cciss.c')
-rw-r--r-- | drivers/block/cciss.c | 43 |
1 files changed, 22 insertions, 21 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index efcc908490df..4ec3e75ba474 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -1261,7 +1261,7 @@ static void cciss_softirq_done(struct request *rq) | |||
1261 | pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir); | 1261 | pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir); |
1262 | } | 1262 | } |
1263 | 1263 | ||
1264 | complete_buffers(rq->bio, rq->errors); | 1264 | complete_buffers(rq->bio, (rq->errors == 0)); |
1265 | 1265 | ||
1266 | if (blk_fs_request(rq)) { | 1266 | if (blk_fs_request(rq)) { |
1267 | const int rw = rq_data_dir(rq); | 1267 | const int rw = rq_data_dir(rq); |
@@ -1275,7 +1275,7 @@ static void cciss_softirq_done(struct request *rq) | |||
1275 | 1275 | ||
1276 | add_disk_randomness(rq->rq_disk); | 1276 | add_disk_randomness(rq->rq_disk); |
1277 | spin_lock_irqsave(&h->lock, flags); | 1277 | spin_lock_irqsave(&h->lock, flags); |
1278 | end_that_request_last(rq, rq->errors); | 1278 | end_that_request_last(rq, (rq->errors == 0)); |
1279 | cmd_free(h, cmd, 1); | 1279 | cmd_free(h, cmd, 1); |
1280 | cciss_check_queues(h); | 1280 | cciss_check_queues(h); |
1281 | spin_unlock_irqrestore(&h->lock, flags); | 1281 | spin_unlock_irqrestore(&h->lock, flags); |
@@ -2366,27 +2366,27 @@ static inline void resend_cciss_cmd(ctlr_info_t *h, CommandList_struct *c) | |||
2366 | static inline int evaluate_target_status(CommandList_struct *cmd) | 2366 | static inline int evaluate_target_status(CommandList_struct *cmd) |
2367 | { | 2367 | { |
2368 | unsigned char sense_key; | 2368 | unsigned char sense_key; |
2369 | int status = 0; /* 0 means bad, 1 means good. */ | 2369 | int error_count = 1; |
2370 | 2370 | ||
2371 | if (cmd->err_info->ScsiStatus != 0x02) { /* not check condition? */ | 2371 | if (cmd->err_info->ScsiStatus != 0x02) { /* not check condition? */ |
2372 | if (!blk_pc_request(cmd->rq)) | 2372 | if (!blk_pc_request(cmd->rq)) |
2373 | printk(KERN_WARNING "cciss: cmd %p " | 2373 | printk(KERN_WARNING "cciss: cmd %p " |
2374 | "has SCSI Status 0x%x\n", | 2374 | "has SCSI Status 0x%x\n", |
2375 | cmd, cmd->err_info->ScsiStatus); | 2375 | cmd, cmd->err_info->ScsiStatus); |
2376 | return status; | 2376 | return error_count; |
2377 | } | 2377 | } |
2378 | 2378 | ||
2379 | /* check the sense key */ | 2379 | /* check the sense key */ |
2380 | sense_key = 0xf & cmd->err_info->SenseInfo[2]; | 2380 | sense_key = 0xf & cmd->err_info->SenseInfo[2]; |
2381 | /* no status or recovered error */ | 2381 | /* no status or recovered error */ |
2382 | if ((sense_key == 0x0) || (sense_key == 0x1)) | 2382 | if ((sense_key == 0x0) || (sense_key == 0x1)) |
2383 | status = 1; | 2383 | error_count = 0; |
2384 | 2384 | ||
2385 | if (!blk_pc_request(cmd->rq)) { /* Not SG_IO or similar? */ | 2385 | if (!blk_pc_request(cmd->rq)) { /* Not SG_IO or similar? */ |
2386 | if (status == 0) | 2386 | if (error_count != 0) |
2387 | printk(KERN_WARNING "cciss: cmd %p has CHECK CONDITION" | 2387 | printk(KERN_WARNING "cciss: cmd %p has CHECK CONDITION" |
2388 | " sense key = 0x%x\n", cmd, sense_key); | 2388 | " sense key = 0x%x\n", cmd, sense_key); |
2389 | return status; | 2389 | return error_count; |
2390 | } | 2390 | } |
2391 | 2391 | ||
2392 | /* SG_IO or similar, copy sense data back */ | 2392 | /* SG_IO or similar, copy sense data back */ |
@@ -2398,7 +2398,7 @@ static inline int evaluate_target_status(CommandList_struct *cmd) | |||
2398 | } else | 2398 | } else |
2399 | cmd->rq->sense_len = 0; | 2399 | cmd->rq->sense_len = 0; |
2400 | 2400 | ||
2401 | return status; | 2401 | return error_count; |
2402 | } | 2402 | } |
2403 | 2403 | ||
2404 | /* checks the status of the job and calls complete buffers to mark all | 2404 | /* checks the status of the job and calls complete buffers to mark all |
@@ -2408,18 +2408,20 @@ static inline int evaluate_target_status(CommandList_struct *cmd) | |||
2408 | static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd, | 2408 | static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd, |
2409 | int timeout) | 2409 | int timeout) |
2410 | { | 2410 | { |
2411 | int status = 1; | ||
2412 | int retry_cmd = 0; | 2411 | int retry_cmd = 0; |
2412 | struct request *rq = cmd->rq; | ||
2413 | |||
2414 | rq->errors = 0; | ||
2413 | 2415 | ||
2414 | if (timeout) | 2416 | if (timeout) |
2415 | status = 0; | 2417 | rq->errors = 1; |
2416 | 2418 | ||
2417 | if (cmd->err_info->CommandStatus == 0) /* no error has occurred */ | 2419 | if (cmd->err_info->CommandStatus == 0) /* no error has occurred */ |
2418 | goto after_error_processing; | 2420 | goto after_error_processing; |
2419 | 2421 | ||
2420 | switch (cmd->err_info->CommandStatus) { | 2422 | switch (cmd->err_info->CommandStatus) { |
2421 | case CMD_TARGET_STATUS: | 2423 | case CMD_TARGET_STATUS: |
2422 | status = evaluate_target_status(cmd); | 2424 | rq->errors = evaluate_target_status(cmd); |
2423 | break; | 2425 | break; |
2424 | case CMD_DATA_UNDERRUN: | 2426 | case CMD_DATA_UNDERRUN: |
2425 | if (blk_fs_request(cmd->rq)) { | 2427 | if (blk_fs_request(cmd->rq)) { |
@@ -2438,32 +2440,32 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd, | |||
2438 | case CMD_INVALID: | 2440 | case CMD_INVALID: |
2439 | printk(KERN_WARNING "cciss: cmd %p is " | 2441 | printk(KERN_WARNING "cciss: cmd %p is " |
2440 | "reported invalid\n", cmd); | 2442 | "reported invalid\n", cmd); |
2441 | status = 0; | 2443 | rq->errors = 1; |
2442 | break; | 2444 | break; |
2443 | case CMD_PROTOCOL_ERR: | 2445 | case CMD_PROTOCOL_ERR: |
2444 | printk(KERN_WARNING "cciss: cmd %p has " | 2446 | printk(KERN_WARNING "cciss: cmd %p has " |
2445 | "protocol error \n", cmd); | 2447 | "protocol error \n", cmd); |
2446 | status = 0; | 2448 | rq->errors = 1; |
2447 | break; | 2449 | break; |
2448 | case CMD_HARDWARE_ERR: | 2450 | case CMD_HARDWARE_ERR: |
2449 | printk(KERN_WARNING "cciss: cmd %p had " | 2451 | printk(KERN_WARNING "cciss: cmd %p had " |
2450 | " hardware error\n", cmd); | 2452 | " hardware error\n", cmd); |
2451 | status = 0; | 2453 | rq->errors = 1; |
2452 | break; | 2454 | break; |
2453 | case CMD_CONNECTION_LOST: | 2455 | case CMD_CONNECTION_LOST: |
2454 | printk(KERN_WARNING "cciss: cmd %p had " | 2456 | printk(KERN_WARNING "cciss: cmd %p had " |
2455 | "connection lost\n", cmd); | 2457 | "connection lost\n", cmd); |
2456 | status = 0; | 2458 | rq->errors = 1; |
2457 | break; | 2459 | break; |
2458 | case CMD_ABORTED: | 2460 | case CMD_ABORTED: |
2459 | printk(KERN_WARNING "cciss: cmd %p was " | 2461 | printk(KERN_WARNING "cciss: cmd %p was " |
2460 | "aborted\n", cmd); | 2462 | "aborted\n", cmd); |
2461 | status = 0; | 2463 | rq->errors = 1; |
2462 | break; | 2464 | break; |
2463 | case CMD_ABORT_FAILED: | 2465 | case CMD_ABORT_FAILED: |
2464 | printk(KERN_WARNING "cciss: cmd %p reports " | 2466 | printk(KERN_WARNING "cciss: cmd %p reports " |
2465 | "abort failed\n", cmd); | 2467 | "abort failed\n", cmd); |
2466 | status = 0; | 2468 | rq->errors = 1; |
2467 | break; | 2469 | break; |
2468 | case CMD_UNSOLICITED_ABORT: | 2470 | case CMD_UNSOLICITED_ABORT: |
2469 | printk(KERN_WARNING "cciss%d: unsolicited " | 2471 | printk(KERN_WARNING "cciss%d: unsolicited " |
@@ -2477,17 +2479,17 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd, | |||
2477 | printk(KERN_WARNING | 2479 | printk(KERN_WARNING |
2478 | "cciss%d: %p retried too " | 2480 | "cciss%d: %p retried too " |
2479 | "many times\n", h->ctlr, cmd); | 2481 | "many times\n", h->ctlr, cmd); |
2480 | status = 0; | 2482 | rq->errors = 1; |
2481 | break; | 2483 | break; |
2482 | case CMD_TIMEOUT: | 2484 | case CMD_TIMEOUT: |
2483 | printk(KERN_WARNING "cciss: cmd %p timedout\n", cmd); | 2485 | printk(KERN_WARNING "cciss: cmd %p timedout\n", cmd); |
2484 | status = 0; | 2486 | rq->errors = 1; |
2485 | break; | 2487 | break; |
2486 | default: | 2488 | default: |
2487 | printk(KERN_WARNING "cciss: cmd %p returned " | 2489 | printk(KERN_WARNING "cciss: cmd %p returned " |
2488 | "unknown status %x\n", cmd, | 2490 | "unknown status %x\n", cmd, |
2489 | cmd->err_info->CommandStatus); | 2491 | cmd->err_info->CommandStatus); |
2490 | status = 0; | 2492 | rq->errors = 1; |
2491 | } | 2493 | } |
2492 | 2494 | ||
2493 | after_error_processing: | 2495 | after_error_processing: |
@@ -2498,7 +2500,6 @@ after_error_processing: | |||
2498 | return; | 2500 | return; |
2499 | } | 2501 | } |
2500 | cmd->rq->data_len = 0; | 2502 | cmd->rq->data_len = 0; |
2501 | cmd->rq->errors = status; | ||
2502 | cmd->rq->completion_data = cmd; | 2503 | cmd->rq->completion_data = cmd; |
2503 | blk_add_trace_rq(cmd->rq->q, cmd->rq, BLK_TA_COMPLETE); | 2504 | blk_add_trace_rq(cmd->rq->q, cmd->rq, BLK_TA_COMPLETE); |
2504 | blk_complete_request(cmd->rq); | 2505 | blk_complete_request(cmd->rq); |