Skip to content

Commit

Permalink
scsi: core: Kill DRIVER_SENSE
Browse files Browse the repository at this point in the history
Replace the check for DRIVER_SENSE with a check for
scsi_status_is_check_condition().

Audit all callsites to ensure the SAM status is set correctly. For
backwards compability move the DRIVER_SENSE definition to sg.h, and update
sg, bsg, and scsi_ioctl to set the DRIVER_SENSE driver_status whenever
SAM_STAT_CHECK_CONDITION is present.

[mkp: fix zeroday srp warning]

Link: https://lore.kernel.org/r/20210427083046.31620-10-hare@suse.de
Signed-off-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

fix
  • Loading branch information
hreinecke authored and martinkpetersen committed Jun 1, 2021
1 parent d0672a0 commit 464a00c
Show file tree
Hide file tree
Showing 35 changed files with 76 additions and 115 deletions.
2 changes: 2 additions & 0 deletions block/bsg.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ static int bsg_scsi_complete_rq(struct request *rq, struct sg_io_v4 *hdr)
hdr->device_status = sreq->result & 0xff;
hdr->transport_status = host_byte(sreq->result);
hdr->driver_status = driver_byte(sreq->result);
if (scsi_status_is_check_condition(sreq->result))
hdr->driver_status = DRIVER_SENSE;
hdr->info = 0;
if (hdr->device_status || hdr->transport_status || hdr->driver_status)
hdr->info |= SG_INFO_CHECK;
Expand Down
2 changes: 2 additions & 0 deletions block/scsi_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,8 @@ static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
hdr->msg_status = msg_byte(req->result);
hdr->host_status = host_byte(req->result);
hdr->driver_status = driver_byte(req->result);
if (scsi_status_is_check_condition(hdr->status))
hdr->driver_status = DRIVER_SENSE;
hdr->info = 0;
if (hdr->masked_status || hdr->host_status || hdr->driver_status)
hdr->info |= SG_INFO_CHECK;
Expand Down
13 changes: 3 additions & 10 deletions drivers/ata/libata-scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -411,13 +411,12 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
rc = cmd_result;
goto error;
}
if (driver_byte(cmd_result) == DRIVER_SENSE) {/* sense data available */
if (scsi_sense_valid(&sshdr)) {/* sense data available */
u8 *desc = sensebuf + 8;
cmd_result &= ~(0xFF<<24); /* DRIVER_SENSE is not an error */

/* If we set cc then ATA pass-through will cause a
* check condition even if no error. Filter that. */
if (cmd_result & SAM_STAT_CHECK_CONDITION) {
if (scsi_status_is_check_condition(cmd_result)) {
if (sshdr.sense_key == RECOVERED_ERROR &&
sshdr.asc == 0 && sshdr.ascq == 0x1d)
cmd_result &= ~SAM_STAT_CHECK_CONDITION;
Expand Down Expand Up @@ -496,9 +495,8 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
rc = cmd_result;
goto error;
}
if (driver_byte(cmd_result) == DRIVER_SENSE) {/* sense data available */
if (scsi_sense_valid(&sshdr)) {/* sense data available */
u8 *desc = sensebuf + 8;
cmd_result &= ~(0xFF<<24); /* DRIVER_SENSE is not an error */

/* If we set cc then ATA pass-through will cause a
* check condition even if no error. Filter that. */
Expand Down Expand Up @@ -864,8 +862,6 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc)

memset(sb, 0, SCSI_SENSE_BUFFERSIZE);

cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;

/*
* Use ata_to_sense_error() to map status register bits
* onto sense key, asc & ascq.
Expand Down Expand Up @@ -962,8 +958,6 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc)

memset(sb, 0, SCSI_SENSE_BUFFERSIZE);

cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;

if (ata_dev_disabled(dev)) {
/* Device disabled after error recovery */
/* LOGICAL UNIT NOT READY, HARD RESET REQUIRED */
Expand Down Expand Up @@ -4201,7 +4195,6 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd)

case REQUEST_SENSE:
ata_scsi_set_sense(dev, cmd, 0, 0, 0);
cmd->result = (DRIVER_SENSE << 24);
break;

/* if we reach this, then writeback caching is disabled,
Expand Down
2 changes: 1 addition & 1 deletion drivers/scsi/NCR5380.c
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,7 @@ static void complete_cmd(struct Scsi_Host *instance,
scsi_eh_restore_cmnd(cmd, &hostdata->ses);
} else {
scsi_eh_restore_cmnd(cmd, &hostdata->ses);
set_driver_byte(cmd, DRIVER_SENSE);
set_status_byte(cmd, SAM_STAT_CHECK_CONDITION);
}
hostdata->sensing = NULL;
}
Expand Down
2 changes: 0 additions & 2 deletions drivers/scsi/advansys.c
Original file line number Diff line number Diff line change
Expand Up @@ -5964,7 +5964,6 @@ static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n");
ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
SCSI_SENSE_BUFFERSIZE);
set_driver_byte(scp, DRIVER_SENSE);
}
break;

Expand Down Expand Up @@ -6715,7 +6714,6 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n");
ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
SCSI_SENSE_BUFFERSIZE);
set_driver_byte(scp, DRIVER_SENSE);
}
break;

Expand Down
19 changes: 7 additions & 12 deletions drivers/scsi/aic7xxx/aic79xx_osm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1928,7 +1928,7 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd,
memcpy(cmd->sense_buffer,
ahd_get_sense_buf(ahd, scb)
+ sense_offset, sense_size);
cmd->result |= (DRIVER_SENSE << 24);
set_status_byte(cmd, SAM_STAT_CHECK_CONDITION);

#ifdef AHD_DEBUG
if (ahd_debug & AHD_SHOW_SENSE) {
Expand Down Expand Up @@ -2018,6 +2018,7 @@ ahd_linux_queue_cmd_complete(struct ahd_softc *ahd, struct scsi_cmnd *cmd)
int new_status = DID_OK;
int do_fallback = 0;
int scsi_status;
struct scsi_sense_data *sense;

/*
* Map CAM error codes into Linux Error codes. We
Expand All @@ -2041,18 +2042,12 @@ ahd_linux_queue_cmd_complete(struct ahd_softc *ahd, struct scsi_cmnd *cmd)
switch(scsi_status) {
case SAM_STAT_COMMAND_TERMINATED:
case SAM_STAT_CHECK_CONDITION:
if ((cmd->result >> 24) != DRIVER_SENSE) {
sense = (struct scsi_sense_data *)
cmd->sense_buffer;
if (sense->extra_len >= 5 &&
(sense->add_sense_code == 0x47
|| sense->add_sense_code == 0x48))
do_fallback = 1;
} else {
struct scsi_sense_data *sense;

sense = (struct scsi_sense_data *)
cmd->sense_buffer;
if (sense->extra_len >= 5 &&
(sense->add_sense_code == 0x47
|| sense->add_sense_code == 0x48))
do_fallback = 1;
}
break;
default:
break;
Expand Down
1 change: 0 additions & 1 deletion drivers/scsi/aic7xxx/aic7xxx_osm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1838,7 +1838,6 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc,
if (sense_size < SCSI_SENSE_BUFFERSIZE)
memset(&cmd->sense_buffer[sense_size], 0,
SCSI_SENSE_BUFFERSIZE - sense_size);
cmd->result |= (DRIVER_SENSE << 24);
#ifdef AHC_DEBUG
if (ahc_debug & AHC_SHOW_SENSE) {
int i;
Expand Down
1 change: 0 additions & 1 deletion drivers/scsi/arcmsr/arcmsr_hba.c
Original file line number Diff line number Diff line change
Expand Up @@ -1335,7 +1335,6 @@ static void arcmsr_report_sense_info(struct CommandControlBlock *ccb)
memcpy(sensebuffer, ccb->arcmsr_cdb.SenseData, sense_data_length);
sensebuffer->ErrorCode = SCSI_SENSE_CURRENT_ERRORS;
sensebuffer->Valid = 1;
pcmd->result |= (DRIVER_SENSE << 24);
}
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/scsi/ch.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ ch_do_scsi(scsi_changer *ch, unsigned char *cmd, int cmd_len,
MAX_RETRIES, NULL);
if (result < 0)
return result;
if (driver_byte(result) == DRIVER_SENSE) {
if (scsi_sense_valid(&sshdr)) {
if (debug)
scsi_print_sense_hdr(ch->device, ch->name, &sshdr);
errno = ch_find_errno(&sshdr);
Expand Down
3 changes: 1 addition & 2 deletions drivers/scsi/cxlflash/superpipe.c
Original file line number Diff line number Diff line change
Expand Up @@ -369,8 +369,7 @@ static int read_cap16(struct scsi_device *sdev, struct llun_info *lli)
goto out;
}

if (result > 0 && driver_byte(result) == DRIVER_SENSE) {
result &= ~(0xFF<<24); /* DRIVER_SENSE is not an error */
if (result > 0 && scsi_sense_valid(&sshdr)) {
if (result & SAM_STAT_CHECK_CONDITION) {
switch (sshdr.sense_key) {
case NO_SENSE:
Expand Down
13 changes: 3 additions & 10 deletions drivers/scsi/dc395x.c
Original file line number Diff line number Diff line change
Expand Up @@ -3239,16 +3239,9 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
}
dprintkdbg(DBG_0, "srb_done: AUTO_REQSENSE2\n");

if (srb->total_xfer_length
&& srb->total_xfer_length >= cmd->underflow)
cmd->result =
MK_RES_LNX(DRIVER_SENSE, DID_OK,
srb->end_message, CHECK_CONDITION);
/*SET_RES_DID(cmd->result,DID_OK) */
else
cmd->result =
MK_RES_LNX(DRIVER_SENSE, DID_OK,
srb->end_message, CHECK_CONDITION);
cmd->result =
MK_RES(0, DID_OK,
srb->end_message, SAM_STAT_CHECK_CONDITION);

goto ckc_e;
}
Expand Down
4 changes: 1 addition & 3 deletions drivers/scsi/esp_scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -922,9 +922,7 @@ static void esp_cmd_is_done(struct esp *esp, struct esp_cmd_entry *ent,
* saw originally. Also, report that we are providing
* the sense data.
*/
cmd->result = ((DRIVER_SENSE << 24) |
(DID_OK << 16) |
(SAM_STAT_CHECK_CONDITION << 0));
cmd->result = SAM_STAT_CHECK_CONDITION;

ent->flags &= ~ESP_CMD_FLAG_AUTOSENSE;
if (esp_debug & ESP_DEBUG_AUTOSENSE) {
Expand Down
8 changes: 2 additions & 6 deletions drivers/scsi/megaraid.c
Original file line number Diff line number Diff line change
Expand Up @@ -1583,19 +1583,15 @@ mega_cmd_done(adapter_t *adapter, u8 completed[], int nstatus, int status)
memcpy(cmd->sense_buffer, pthru->reqsensearea,
14);

cmd->result = (DRIVER_SENSE << 24) |
(DID_OK << 16) |
(CHECK_CONDITION << 1);
cmd->result = SAM_STAT_CHECK_CONDITION;
}
else {
if (mbox->m_out.cmd == MEGA_MBOXCMD_EXTPTHRU) {

memcpy(cmd->sense_buffer,
epthru->reqsensearea, 14);

cmd->result = (DRIVER_SENSE << 24) |
(DID_OK << 16) |
(CHECK_CONDITION << 1);
cmd->result = SAM_STAT_CHECK_CONDITION;
} else
scsi_build_sense(cmd, 0,
ABORTED_COMMAND, 0, 0);
Expand Down
7 changes: 2 additions & 5 deletions drivers/scsi/megaraid/megaraid_mbox.c
Original file line number Diff line number Diff line change
Expand Up @@ -2299,18 +2299,15 @@ megaraid_mbox_dpc(unsigned long devp)
memcpy(scp->sense_buffer, pthru->reqsensearea,
14);

scp->result = DRIVER_SENSE << 24 |
DID_OK << 16 | CHECK_CONDITION << 1;
scp->result = SAM_STAT_CHECK_CONDITION;
}
else {
if (mbox->cmd == MBOXCMD_EXTPTHRU) {

memcpy(scp->sense_buffer,
epthru->reqsensearea, 14);

scp->result = DRIVER_SENSE << 24 |
DID_OK << 16 |
CHECK_CONDITION << 1;
scp->result = SAM_STAT_CHECK_CONDITION;
} else
scsi_build_sense(scp, 0,
ABORTED_COMMAND, 0, 0);
Expand Down
2 changes: 0 additions & 2 deletions drivers/scsi/megaraid/megaraid_sas_base.c
Original file line number Diff line number Diff line change
Expand Up @@ -3617,8 +3617,6 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
SCSI_SENSE_BUFFERSIZE);
memcpy(cmd->scmd->sense_buffer, cmd->sense,
hdr->sense_len);

cmd->scmd->result |= DRIVER_SENSE << 24;
}

break;
Expand Down
1 change: 0 additions & 1 deletion drivers/scsi/megaraid/megaraid_sas_fusion.c
Original file line number Diff line number Diff line change
Expand Up @@ -2051,7 +2051,6 @@ map_cmd_status(struct fusion_context *fusion,
SCSI_SENSE_BUFFERSIZE);
memcpy(scmd->sense_buffer, sense,
SCSI_SENSE_BUFFERSIZE);
scmd->result |= DRIVER_SENSE << 24;
}

/*
Expand Down
1 change: 0 additions & 1 deletion drivers/scsi/mvumi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1317,7 +1317,6 @@ static void mvumi_complete_cmd(struct mvumi_hba *mhba, struct mvumi_cmd *cmd,
if (ob_frame->rsp_flag & CL_RSP_FLAG_SENSEDATA) {
memcpy(cmd->scmd->sense_buffer, ob_frame->payload,
sizeof(struct mvumi_sense_data));
scmd->result |= (DRIVER_SENSE << 24);
}
break;
default:
Expand Down
7 changes: 0 additions & 7 deletions drivers/scsi/scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,13 +185,6 @@ void scsi_finish_command(struct scsi_cmnd *cmd)
if (atomic_read(&sdev->device_blocked))
atomic_set(&sdev->device_blocked, 0);

/*
* If we have valid sense information, then some kind of recovery
* must have taken place. Make a note of this.
*/
if (SCSI_SENSE_VALID(cmd))
cmd->result |= (DRIVER_SENSE << 24);

SCSI_LOG_MLCOMPLETE(4, sdev_printk(KERN_INFO, sdev,
"Notifying upper driver of completion "
"(result %x)\n", cmd->result));
Expand Down
4 changes: 2 additions & 2 deletions drivers/scsi/scsi_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -851,10 +851,10 @@ static struct device_driver sdebug_driverfs_driver = {
};

static const int check_condition_result =
(DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
SAM_STAT_CHECK_CONDITION;

static const int illegal_condition_result =
(DRIVER_SENSE << 24) | (DID_ABORT << 16) | SAM_STAT_CHECK_CONDITION;
(DID_ABORT << 16) | SAM_STAT_CHECK_CONDITION;

static const int device_qfull_result =
(DID_OK << 16) | SAM_STAT_TASK_SET_FULL;
Expand Down
3 changes: 1 addition & 2 deletions drivers/scsi/scsi_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,7 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,

if (result < 0)
goto out;
if (driver_byte(result) == DRIVER_SENSE &&
scsi_sense_valid(&sshdr)) {
if (scsi_sense_valid(&sshdr)) {
switch (sshdr.sense_key) {
case ILLEGAL_REQUEST:
if (cmd[0] == ALLOW_MEDIUM_REMOVAL)
Expand Down
10 changes: 3 additions & 7 deletions drivers/scsi/scsi_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -593,8 +593,6 @@ static blk_status_t scsi_result_to_blk_status(struct scsi_cmnd *cmd, int result)
case DID_OK:
/*
* Also check the other bytes than the status byte in result
* to handle the case when a SCSI LLD sets result to
* DRIVER_SENSE << 24 without setting SAM_STAT_CHECK_CONDITION.
*/
if (scsi_status_is_good(result) && (result & ~0xff) == 0)
return BLK_STS_OK;
Expand Down Expand Up @@ -790,7 +788,7 @@ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result)
*/
if (!level && __ratelimit(&_rs)) {
scsi_print_result(cmd, NULL, FAILED);
if (driver_byte(result) == DRIVER_SENSE)
if (sense_valid)
scsi_print_sense(cmd);
scsi_print_command(cmd);
}
Expand Down Expand Up @@ -2152,8 +2150,7 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
* ILLEGAL REQUEST if the code page isn't supported */

if (!scsi_status_is_good(result)) {
if (driver_byte(result) == DRIVER_SENSE &&
scsi_sense_valid(sshdr)) {
if (scsi_sense_valid(sshdr)) {
if ((sshdr->sense_key == ILLEGAL_REQUEST) &&
(sshdr->asc == 0x20) && (sshdr->ascq == 0)) {
/*
Expand Down Expand Up @@ -3236,7 +3233,6 @@ EXPORT_SYMBOL(scsi_vpd_tpg_id);
void scsi_build_sense(struct scsi_cmnd *scmd, int desc, u8 key, u8 asc, u8 ascq)
{
scsi_build_sense_buffer(desc, scmd->sense_buffer, key, asc, ascq);
scmd->result = (DRIVER_SENSE << 24) | (DID_OK << 16) |
SAM_STAT_CHECK_CONDITION;
scmd->result = SAM_STAT_CHECK_CONDITION;
}
EXPORT_SYMBOL_GPL(scsi_build_sense);
2 changes: 1 addition & 1 deletion drivers/scsi/scsi_scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,7 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
* INQUIRY should not yield UNIT_ATTENTION
* but many buggy devices do so anyway.
*/
if (driver_byte(result) == DRIVER_SENSE &&
if (scsi_status_is_check_condition(result) &&
scsi_sense_valid(&sshdr)) {
if ((sshdr.sense_key == UNIT_ATTENTION) &&
((sshdr.asc == 0x28) ||
Expand Down
2 changes: 1 addition & 1 deletion drivers/scsi/scsi_transport_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ static int spi_execute(struct scsi_device *sdev, const void *cmd,
REQ_FAILFAST_TRANSPORT |
REQ_FAILFAST_DRIVER,
RQF_PM, NULL);
if (result < 0 || driver_byte(result) != DRIVER_SENSE ||
if (result < 0 || !scsi_sense_valid(sshdr) ||
sshdr->sense_key != UNIT_ATTENTION)
break;
}
Expand Down
Loading

0 comments on commit 464a00c

Please sign in to comment.