mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
scsi: sd: Use combined sense codes
Refactor the SCSI disk driver to use as much as possible the 16-bit 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> Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Reviewed-by: Hannes Reinecke <hare@kernel.org> Link: https://patch.msgid.link/20260908090308.1085097-9-dlemoal@kernel.org Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
This commit is contained in:
parent
85952eaa68
commit
b9d5da78ff
|
|
@ -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) {
|
||||
scsi_sense_asc(sshdr) == ASC_INVALID_FIELD_IN_CDB) {
|
||||
/*
|
||||
* INVALID FIELD IN CDB error: a zone management command was
|
||||
* attempted on a conventional zone. Nothing to worry about,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user