diff options
Diffstat (limited to 'drivers/scsi/scsi_error.c')
-rw-r--r-- | drivers/scsi/scsi_error.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 815e7d63f3e2..746ff6a1f309 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -547,6 +547,18 @@ enum scsi_disposition scsi_check_sense(struct scsi_cmnd *scmd) scsi_report_sense(sdev, &sshdr); + if (sshdr.sense_key == UNIT_ATTENTION) { + /* + * Increment the counters for Power on/Reset or New Media so + * that all ULDs interested in these can see that those have + * happened, even if someone else gets the sense data. + */ + if (sshdr.asc == 0x28) + scmd->device->ua_new_media_ctr++; + else if (sshdr.asc == 0x29) + scmd->device->ua_por_ctr++; + } + if (scsi_sense_is_deferred(&sshdr)) return NEEDS_RETRY; @@ -653,7 +665,8 @@ enum scsi_disposition scsi_check_sense(struct scsi_cmnd *scmd) * if the device is in the process of becoming ready, we * should retry. */ - if ((sshdr.asc == 0x04) && (sshdr.ascq == 0x01)) + if ((sshdr.asc == 0x04) && + (sshdr.ascq == 0x01 || sshdr.ascq == 0x0a)) return NEEDS_RETRY; /* * if the device is not started, we need to wake @@ -711,6 +724,13 @@ enum scsi_disposition scsi_check_sense(struct scsi_cmnd *scmd) return SUCCESS; case COMPLETED: + /* + * A command using command duration limits (CDL) with a + * descriptor set with policy 0xD may be completed with success + * and the sense data DATA CURRENTLY UNAVAILABLE, indicating + * that the command was in fact aborted because it exceeded its + * duration limit. Never retry these commands. + */ if (sshdr.asc == 0x55 && sshdr.ascq == 0x0a) { set_scsi_ml_byte(scmd, SCSIML_STAT_DL_TIMEOUT); req->cmd_flags |= REQ_FAILFAST_DEV; |