aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_error.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi_error.c')
-rw-r--r--drivers/scsi/scsi_error.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 45c75649b9e0..991de3c15cfc 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -223,7 +223,7 @@ static inline void scsi_eh_prt_fail_stats(struct Scsi_Host *shost,
223 * @scmd: Cmd to have sense checked. 223 * @scmd: Cmd to have sense checked.
224 * 224 *
225 * Return value: 225 * Return value:
226 * SUCCESS or FAILED or NEEDS_RETRY 226 * SUCCESS or FAILED or NEEDS_RETRY or TARGET_ERROR
227 * 227 *
228 * Notes: 228 * Notes:
229 * When a deferred error is detected the current command has 229 * When a deferred error is detected the current command has
@@ -326,17 +326,19 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
326 */ 326 */
327 return SUCCESS; 327 return SUCCESS;
328 328
329 /* these three are not supported */ 329 /* these are not supported */
330 case COPY_ABORTED: 330 case COPY_ABORTED:
331 case VOLUME_OVERFLOW: 331 case VOLUME_OVERFLOW:
332 case MISCOMPARE: 332 case MISCOMPARE:
333 return SUCCESS; 333 case BLANK_CHECK:
334 case DATA_PROTECT:
335 return TARGET_ERROR;
334 336
335 case MEDIUM_ERROR: 337 case MEDIUM_ERROR:
336 if (sshdr.asc == 0x11 || /* UNRECOVERED READ ERR */ 338 if (sshdr.asc == 0x11 || /* UNRECOVERED READ ERR */
337 sshdr.asc == 0x13 || /* AMNF DATA FIELD */ 339 sshdr.asc == 0x13 || /* AMNF DATA FIELD */
338 sshdr.asc == 0x14) { /* RECORD NOT FOUND */ 340 sshdr.asc == 0x14) { /* RECORD NOT FOUND */
339 return SUCCESS; 341 return TARGET_ERROR;
340 } 342 }
341 return NEEDS_RETRY; 343 return NEEDS_RETRY;
342 344
@@ -344,11 +346,9 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
344 if (scmd->device->retry_hwerror) 346 if (scmd->device->retry_hwerror)
345 return ADD_TO_MLQUEUE; 347 return ADD_TO_MLQUEUE;
346 else 348 else
347 return SUCCESS; 349 return TARGET_ERROR;
348 350
349 case ILLEGAL_REQUEST: 351 case ILLEGAL_REQUEST:
350 case BLANK_CHECK:
351 case DATA_PROTECT:
352 default: 352 default:
353 return SUCCESS; 353 return SUCCESS;
354 } 354 }
@@ -787,6 +787,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
787 case SUCCESS: 787 case SUCCESS:
788 case NEEDS_RETRY: 788 case NEEDS_RETRY:
789 case FAILED: 789 case FAILED:
790 case TARGET_ERROR:
790 break; 791 break;
791 case ADD_TO_MLQUEUE: 792 case ADD_TO_MLQUEUE:
792 rtn = NEEDS_RETRY; 793 rtn = NEEDS_RETRY;
@@ -1469,6 +1470,14 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)
1469 rtn = scsi_check_sense(scmd); 1470 rtn = scsi_check_sense(scmd);
1470 if (rtn == NEEDS_RETRY) 1471 if (rtn == NEEDS_RETRY)
1471 goto maybe_retry; 1472 goto maybe_retry;
1473 else if (rtn == TARGET_ERROR) {
1474 /*
1475 * Need to modify host byte to signal a
1476 * permanent target failure
1477 */
1478 scmd->result |= (DID_TARGET_FAILURE << 16);
1479 rtn = SUCCESS;
1480 }
1472 /* if rtn == FAILED, we have no sense information; 1481 /* if rtn == FAILED, we have no sense information;
1473 * returning FAILED will wake the error handler thread 1482 * returning FAILED will wake the error handler thread
1474 * to collect the sense and redo the decide 1483 * to collect the sense and redo the decide
@@ -1486,6 +1495,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)
1486 case RESERVATION_CONFLICT: 1495 case RESERVATION_CONFLICT:
1487 sdev_printk(KERN_INFO, scmd->device, 1496 sdev_printk(KERN_INFO, scmd->device,
1488 "reservation conflict\n"); 1497 "reservation conflict\n");
1498 scmd->result |= (DID_NEXUS_FAILURE << 16);
1489 return SUCCESS; /* causes immediate i/o error */ 1499 return SUCCESS; /* causes immediate i/o error */
1490 default: 1500 default:
1491 return FAILED; 1501 return FAILED;