@@ -1786,8 +1786,7 @@ static int media_not_present(struct scsi_disk *sdkp,
switch (sshdr->sense_key) {
case UNIT_ATTENTION:
case NOT_READY:
- /* medium not present */
- if (sshdr->asc == 0x3A) {
+ if (scsi_sense_asc(sshdr) == ASC_MEDIUM_NOT_PRESENT) {
set_media_not_present(sdkp);
return 1;
}
@@ -1911,12 +1910,14 @@ static int sd_sync_cache(struct scsi_disk *sdkp)
if (scsi_status_is_check_condition(res) &&
scsi_sense_valid(&sshdr)) {
+ u8 asc = scsi_sense_asc(&sshdr);
+
sd_print_sense_hdr(sdkp, &sshdr);
/* we need to evaluate the error return */
- if (sshdr.asc == 0x3a || /* medium not present */
- sshdr.asc == 0x20 || /* invalid command */
- (sshdr.asc == 0x74 && sshdr.ascq == 0x71)) /* drive is password locked */
+ if (asc == ASC_MEDIUM_NOT_PRESENT ||
+ asc == ASC_INVALID_COMMAND_OP_CODE ||
+ sshdr.sense_code == LU_ACCESS_NOT_AUTHORIZED)
/* this is no error here */
return 0;
@@ -1926,8 +1927,8 @@ static int sd_sync_cache(struct scsi_disk *sdkp)
* this is called during shutdown or suspend so just
* return success so those operations can proceed.
*/
- if ((sshdr.asc == 0x04 && sshdr.ascq == 0x04) ||
- sshdr.sense_key == ILLEGAL_REQUEST)
+ if (sshdr.sense_key == ILLEGAL_REQUEST ||
+ sshdr.sense_code == LU_NOT_READY_FORMAT_IN_PROGRESS)
return 0;
}
@@ -2015,7 +2016,9 @@ static int sd_scsi_to_pr_err(struct scsi_sense_hdr *sshdr, int result)
return PR_STS_IOERR;
if (sshdr->sense_key == ILLEGAL_REQUEST &&
- (sshdr->asc == 0x26 || sshdr->asc == 0x24))
+ (scsi_sense_asc(sshdr) ==
+ ASC_INVALID_FIELD_IN_PARAMETER_LIST ||
+ scsi_sense_asc(sshdr) == ASC_INVALID_FIELD_IN_CDB))
return -EINVAL;
fallthrough;
@@ -2034,8 +2037,7 @@ static int sd_pr_in_command(struct block_device *bdev, u8 sa,
struct scsi_failure failure_defs[] = {
{
.sense_key = UNIT_ATTENTION,
- .asc = SCMD_FAILURE_ASC_ANY,
- .ascq = SCMD_FAILURE_ASCQ_ANY,
+ .sense_code = SCMD_FAILURE_SENSE_CODE_ANY,
.allowed = 5,
.result = SAM_STAT_CHECK_CONDITION,
},
@@ -2146,8 +2148,7 @@ static int sd_pr_out_command(struct block_device *bdev, u8 sa, u64 key,
struct scsi_failure failure_defs[] = {
{
.sense_key = UNIT_ATTENTION,
- .asc = SCMD_FAILURE_ASC_ANY,
- .ascq = SCMD_FAILURE_ASCQ_ANY,
+ .sense_code = SCMD_FAILURE_SENSE_CODE_ANY,
.allowed = 5,
.result = SAM_STAT_CHECK_CONDITION,
},
@@ -2440,16 +2441,17 @@ static int sd_done(struct scsi_cmnd *SCpnt)
memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
break;
case ABORTED_COMMAND:
- if (sshdr.asc == 0x10) /* DIF: Target detected corruption */
+ if (scsi_sense_asc(&sshdr) == ASC_ID_CRC_OR_ECC_ERROR) /* DIF */
good_bytes = sd_completed_bytes(SCpnt);
break;
case ILLEGAL_REQUEST:
- switch (sshdr.asc) {
- case 0x10: /* DIX: Host detected corruption */
+ switch (scsi_sense_asc(&sshdr)) {
+ case ASC_ID_CRC_OR_ECC_ERROR:
+ /* DIX */
good_bytes = sd_completed_bytes(SCpnt);
break;
- case 0x20: /* INVALID COMMAND OPCODE */
- case 0x24: /* INVALID FIELD IN CDB */
+ case ASC_INVALID_COMMAND_OP_CODE:
+ case ASC_INVALID_FIELD_IN_CDB:
switch (SCpnt->cmnd[0]) {
case UNMAP:
sd_disable_discard(sdkp);
@@ -2495,14 +2497,14 @@ sd_spinup_disk(struct scsi_disk *sdkp)
/* Do not retry Medium Not Present */
{
.sense_key = UNIT_ATTENTION,
- .asc = 0x3A,
- .ascq = SCMD_FAILURE_ASCQ_ANY,
+ .sense_code =
+ MEDIUM_NOT_PRESENT | SCMD_FAILURE_ASCQ_ANY,
.result = SAM_STAT_CHECK_CONDITION,
},
{
.sense_key = NOT_READY,
- .asc = 0x3A,
- .ascq = SCMD_FAILURE_ASCQ_ANY,
+ .sense_code =
+ MEDIUM_NOT_PRESENT | SCMD_FAILURE_ASCQ_ANY,
.result = SAM_STAT_CHECK_CONDITION,
},
/* Retry when scsi_status_is_good would return false 3 times */
@@ -2566,18 +2568,18 @@ sd_spinup_disk(struct scsi_disk *sdkp)
break;
if (sense_valid && sshdr.sense_key == NOT_READY) {
- if (sshdr.asc == 4 && sshdr.ascq == 3)
- break; /* manual intervention required */
- if (sshdr.asc == 4 && sshdr.ascq == 0xb)
- break; /* standby */
- if (sshdr.asc == 4 && sshdr.ascq == 0xc)
- break; /* unavailable */
- if (sshdr.asc == 4 && sshdr.ascq == 0x1b)
- break; /* sanitize in progress */
- if (sshdr.asc == 4 && sshdr.ascq == 0x24)
- break; /* depopulation in progress */
- if (sshdr.asc == 4 && sshdr.ascq == 0x25)
- break; /* depopulation restoration in progress */
+ switch (sshdr.sense_code) {
+ case LU_NOT_READY_MANUAL_INTERVENTION_REQUIRED:
+ case LU_NOT_ACCESSIBLE_TARGET_PORT_IN_STANDBY_STATE:
+ case LU_NOT_ACCESSIBLE_TARGET_PORT_IN_UNAVAILABLE_STATE:
+ case LU_NOT_READY_SANITIZE_IN_PROGRESS:
+ case DEPOPULATION_IN_PROGRESS:
+ case DEPOPULATION_RESTORATION_IN_PROGRESS:
+ goto out;
+ default:
+ break;
+ }
+
/*
* Issue command to spin up drive when not ready
*/
@@ -2608,8 +2610,9 @@ sd_spinup_disk(struct scsi_disk *sdkp)
* occur here. It's characteristic of these devices.
*/
} else if (sense_valid &&
- sshdr.sense_key == UNIT_ATTENTION &&
- sshdr.asc == 0x28) {
+ sshdr.sense_key == UNIT_ATTENTION &&
+ scsi_sense_asc(&sshdr) ==
+ ASC_NOT_READY_TO_READY_CHANGE_MEDIUM_MAY_HAVE_CHANGED) {
if (!spintime) {
spintime_expire = jiffies + 5 * HZ;
spintime = 1;
@@ -2628,6 +2631,7 @@ sd_spinup_disk(struct scsi_disk *sdkp)
} while (spintime && time_before_eq(jiffies, spintime_expire));
+out:
if (spintime) {
if (scsi_status_is_good(the_result))
printk(KERN_CONT "ready\n");
@@ -2753,15 +2757,14 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
sense_valid = scsi_sense_valid(&sshdr);
if (sense_valid &&
sshdr.sense_key == ILLEGAL_REQUEST &&
- (sshdr.asc == 0x20 || sshdr.asc == 0x24) &&
- sshdr.ascq == 0x00)
- /* Invalid Command Operation Code or
- * Invalid Field in CDB, just retry
- * silently with RC10 */
+ (sshdr.sense_code == INVALID_COMMAND_OP_CODE ||
+ sshdr.sense_code == INVALID_FIELD_IN_CDB))
+ /* Just retry silently with RC10 */
return -EINVAL;
if (sense_valid &&
sshdr.sense_key == UNIT_ATTENTION &&
- sshdr.asc == 0x29 && sshdr.ascq == 0x00)
+ sshdr.sense_code ==
+ POWER_ON_RESET_OR_BUS_DEVICE_RESET_OCCURRED)
/* Device reset might occur several times,
* give it one more chance */
if (--reset_retries > 0)
@@ -2818,18 +2821,18 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp,
/* Do not retry Medium Not Present */
{
.sense_key = UNIT_ATTENTION,
- .asc = 0x3A,
+ .sense_code = MEDIUM_NOT_PRESENT,
.result = SAM_STAT_CHECK_CONDITION,
},
{
.sense_key = NOT_READY,
- .asc = 0x3A,
+ .sense_code = MEDIUM_NOT_PRESENT,
.result = SAM_STAT_CHECK_CONDITION,
},
/* Device reset might occur several times so retry a lot */
{
.sense_key = UNIT_ATTENTION,
- .asc = 0x29,
+ .sense_code = POWER_ON_RESET_OR_BUS_DEVICE_RESET_OCCURRED,
.allowed = READ_CAPACITY_RETRIES_ON_RESET,
.result = SAM_STAT_CHECK_CONDITION,
},
@@ -3258,8 +3261,7 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer)
bad_sense:
if (res == -EIO && scsi_sense_valid(&sshdr) &&
sshdr.sense_key == ILLEGAL_REQUEST &&
- sshdr.asc == 0x24 && sshdr.ascq == 0x0)
- /* Invalid field in CDB */
+ sshdr.sense_code == INVALID_FIELD_IN_CDB)
sd_first_printk(KERN_NOTICE, sdkp, "Cache data unavailable\n");
else
sd_first_printk(KERN_ERR, sdkp,
@@ -4160,22 +4162,19 @@ static int sd_start_stop_device(struct scsi_disk *sdkp, int start)
{
/* Power on, reset, or bus device reset occurred */
.sense_key = UNIT_ATTENTION,
- .asc = 0x29,
- .ascq = 0,
+ .sense_code = POWER_ON_RESET_OR_BUS_DEVICE_RESET_OCCURRED,
.result = SAM_STAT_CHECK_CONDITION,
},
{
/* Power on occurred */
.sense_key = UNIT_ATTENTION,
- .asc = 0x29,
- .ascq = 1,
+ .sense_code = POWER_ON_OCCURRED,
.result = SAM_STAT_CHECK_CONDITION,
},
{
/* SCSI bus reset */
.sense_key = UNIT_ATTENTION,
- .asc = 0x29,
- .ascq = 2,
+ .sense_code = SCSI_BUS_RESET_OCCURRED,
.result = SAM_STAT_CHECK_CONDITION,
},
{}
@@ -4207,8 +4206,7 @@ static int sd_start_stop_device(struct scsi_disk *sdkp, int start)
sd_print_result(sdkp, "Start/Stop Unit failed", res);
if (res > 0 && scsi_sense_valid(&sshdr)) {
sd_print_sense_hdr(sdkp, &sshdr);
- /* 0x3a is medium not present */
- if (sshdr.asc == 0x3a)
+ if (scsi_sense_asc(&sshdr) == ASC_MEDIUM_NOT_PRESENT)
res = 0;
}
}
@@ -369,7 +369,7 @@ unsigned int sd_zbc_complete(struct scsi_cmnd *cmd, unsigned int good_bytes,
if (op_is_zone_mgmt(req_op(rq)) &&
result &&
sshdr->sense_key == ILLEGAL_REQUEST &&
- sshdr->asc == 0x24) {
+ sshdr->sense_code == INVALID_FIELD_IN_CDB) {
/*
* INVALID FIELD IN CDB error: a zone management command was
* attempted on a conventional zone. Nothing to worry about,
Refactor the SCSI disk driver to use as much as possible the 16-bits sense_code field of struct scsi_sense_hdr and struct scsi_failure and replace all hard-coded additional sense codes and additional sense code qualifiers with the enum values defined in include/scsi/scsi_sense.h. This helps with code clarity as the sense codes being processed are easier to test and self-documented. No functional change intended. Signed-off-by: Damien Le Moal <dlemoal@kernel.org> --- drivers/scsi/sd.c | 106 +++++++++++++++++++++--------------------- drivers/scsi/sd_zbc.c | 2 +- 2 files changed, 53 insertions(+), 55 deletions(-)