Commit b8e162f9 authored by Bart Van Assche's avatar Bart Van Assche Committed by Martin K. Petersen
Browse files

scsi: core: Introduce enum scsi_disposition

Improve readability of the code in the SCSI core by introducing an
enumeration type for the values used internally that decide how to continue
processing a SCSI command. The eh_*_handler return values have not been
changed because that would involve modifying all SCSI drivers.

The output of the following command has been inspected to verify that no
out-of-range values are assigned to a variable of type enum
scsi_disposition:

KCFLAGS=-Wassign-enum make CC=clang W=1 drivers/scsi/

Link: https://lore.kernel.org/r/20210415220826.29438-6-bvanassche@acm.org


Cc: Christoph Hellwig <hch@lst.de>
Cc: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Cc: Hannes Reinecke <hare@suse.de>
Cc: Daniel Wagner <dwagner@suse.de>
Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 280e91b0
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1599,7 +1599,7 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc,
	}

	if (qc->flags & ATA_QCFLAG_SENSE_VALID) {
		int ret = scsi_check_sense(qc->scsicmd);
		enum scsi_disposition ret = scsi_check_sense(qc->scsicmd);
		/*
		 * SUCCESS here means that the sense code could be
		 * evaluated and should be passed to the upper layers
+2 −2
Original line number Diff line number Diff line
@@ -405,7 +405,7 @@ static char print_alua_state(unsigned char state)
	}
}

static int alua_check_sense(struct scsi_device *sdev,
static enum scsi_disposition alua_check_sense(struct scsi_device *sdev,
					      struct scsi_sense_hdr *sense_hdr)
{
	struct alua_dh_data *h = sdev->handler_data;
+2 −2
Original line number Diff line number Diff line
@@ -280,7 +280,7 @@ static int send_trespass_cmd(struct scsi_device *sdev,
	return res;
}

static int clariion_check_sense(struct scsi_device *sdev,
static enum scsi_disposition clariion_check_sense(struct scsi_device *sdev,
					struct scsi_sense_hdr *sense_hdr)
{
	switch (sense_hdr->sense_key) {
+2 −2
Original line number Diff line number Diff line
@@ -656,7 +656,7 @@ static blk_status_t rdac_prep_fn(struct scsi_device *sdev, struct request *req)
	return BLK_STS_OK;
}

static int rdac_check_sense(struct scsi_device *sdev,
static enum scsi_disposition rdac_check_sense(struct scsi_device *sdev,
					      struct scsi_sense_hdr *sense_hdr)
{
	struct rdac_dh_data *h = sdev->handler_data;
+34 −30
Original line number Diff line number Diff line
@@ -60,7 +60,7 @@ static void scsi_eh_done(struct scsi_cmnd *scmd);
#define HOST_RESET_SETTLE_TIME  (10)

static int scsi_eh_try_stu(struct scsi_cmnd *scmd);
static int scsi_try_to_abort_cmd(struct scsi_host_template *,
static enum scsi_disposition scsi_try_to_abort_cmd(struct scsi_host_template *,
						   struct scsi_cmnd *);

void scsi_eh_wakeup(struct Scsi_Host *shost)
@@ -151,7 +151,7 @@ scmd_eh_abort_handler(struct work_struct *work)
	struct scsi_cmnd *scmd =
		container_of(work, struct scsi_cmnd, abort_work.work);
	struct scsi_device *sdev = scmd->device;
	int rtn;
	enum scsi_disposition rtn;

	if (scsi_host_eh_past_deadline(sdev->host)) {
		SCSI_LOG_ERROR_RECOVERY(3,
@@ -498,7 +498,7 @@ static void scsi_report_sense(struct scsi_device *sdev,
 *	When a deferred error is detected the current command has
 *	not been executed and needs retrying.
 */
int scsi_check_sense(struct scsi_cmnd *scmd)
enum scsi_disposition scsi_check_sense(struct scsi_cmnd *scmd)
{
	struct scsi_device *sdev = scmd->device;
	struct scsi_sense_hdr sshdr;
@@ -512,7 +512,7 @@ int scsi_check_sense(struct scsi_cmnd *scmd)
		return NEEDS_RETRY;

	if (sdev->handler && sdev->handler->check_sense) {
		int rc;
		enum scsi_disposition rc;

		rc = sdev->handler->check_sense(sdev, &sshdr);
		if (rc != SCSI_RETURN_NOT_HANDLED)
@@ -723,7 +723,7 @@ static void scsi_handle_queue_full(struct scsi_device *sdev)
 *    don't allow for the possibility of retries here, and we are a lot
 *    more restrictive about what we consider acceptable.
 */
static int scsi_eh_completed_normally(struct scsi_cmnd *scmd)
static enum scsi_disposition scsi_eh_completed_normally(struct scsi_cmnd *scmd)
{
	/*
	 * first check the host byte, to see if there is anything in there
@@ -804,10 +804,10 @@ static void scsi_eh_done(struct scsi_cmnd *scmd)
 * scsi_try_host_reset - ask host adapter to reset itself
 * @scmd:	SCSI cmd to send host reset.
 */
static int scsi_try_host_reset(struct scsi_cmnd *scmd)
static enum scsi_disposition scsi_try_host_reset(struct scsi_cmnd *scmd)
{
	unsigned long flags;
	int rtn;
	enum scsi_disposition rtn;
	struct Scsi_Host *host = scmd->device->host;
	struct scsi_host_template *hostt = host->hostt;

@@ -834,10 +834,10 @@ static int scsi_try_host_reset(struct scsi_cmnd *scmd)
 * scsi_try_bus_reset - ask host to perform a bus reset
 * @scmd:	SCSI cmd to send bus reset.
 */
static int scsi_try_bus_reset(struct scsi_cmnd *scmd)
static enum scsi_disposition scsi_try_bus_reset(struct scsi_cmnd *scmd)
{
	unsigned long flags;
	int rtn;
	enum scsi_disposition rtn;
	struct Scsi_Host *host = scmd->device->host;
	struct scsi_host_template *hostt = host->hostt;

@@ -876,10 +876,10 @@ static void __scsi_report_device_reset(struct scsi_device *sdev, void *data)
 *    timer on it, and set the host back to a consistent state prior to
 *    returning.
 */
static int scsi_try_target_reset(struct scsi_cmnd *scmd)
static enum scsi_disposition scsi_try_target_reset(struct scsi_cmnd *scmd)
{
	unsigned long flags;
	int rtn;
	enum scsi_disposition rtn;
	struct Scsi_Host *host = scmd->device->host;
	struct scsi_host_template *hostt = host->hostt;

@@ -907,9 +907,9 @@ static int scsi_try_target_reset(struct scsi_cmnd *scmd)
 *    timer on it, and set the host back to a consistent state prior to
 *    returning.
 */
static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd)
static enum scsi_disposition scsi_try_bus_device_reset(struct scsi_cmnd *scmd)
{
	int rtn;
	enum scsi_disposition rtn;
	struct scsi_host_template *hostt = scmd->device->host->hostt;

	if (!hostt->eh_device_reset_handler)
@@ -938,8 +938,8 @@ static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd)
 *    if the device is temporarily unavailable (eg due to a
 *    link down on FibreChannel)
 */
static int scsi_try_to_abort_cmd(struct scsi_host_template *hostt,
				 struct scsi_cmnd *scmd)
static enum scsi_disposition
scsi_try_to_abort_cmd(struct scsi_host_template *hostt, struct scsi_cmnd *scmd)
{
	if (!hostt->eh_abort_handler)
		return FAILED;
@@ -1072,8 +1072,8 @@ EXPORT_SYMBOL(scsi_eh_restore_cmnd);
 * Return value:
 *    SUCCESS or FAILED or NEEDS_RETRY
 */
static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
			     int cmnd_size, int timeout, unsigned sense_bytes)
static enum scsi_disposition scsi_send_eh_cmnd(struct scsi_cmnd *scmd,
	unsigned char *cmnd, int cmnd_size, int timeout, unsigned sense_bytes)
{
	struct scsi_device *sdev = scmd->device;
	struct Scsi_Host *shost = sdev->host;
@@ -1180,12 +1180,13 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
 *    that we obtain it on our own. This function will *not* return until
 *    the command either times out, or it completes.
 */
static int scsi_request_sense(struct scsi_cmnd *scmd)
static enum scsi_disposition scsi_request_sense(struct scsi_cmnd *scmd)
{
	return scsi_send_eh_cmnd(scmd, NULL, 0, scmd->device->eh_timeout, ~0);
}

static int scsi_eh_action(struct scsi_cmnd *scmd, int rtn)
static enum scsi_disposition
scsi_eh_action(struct scsi_cmnd *scmd, enum scsi_disposition rtn)
{
	if (!blk_rq_is_passthrough(scmd->request)) {
		struct scsi_driver *sdrv = scsi_cmd_to_driver(scmd);
@@ -1238,7 +1239,7 @@ int scsi_eh_get_sense(struct list_head *work_q,
{
	struct scsi_cmnd *scmd, *next;
	struct Scsi_Host *shost;
	int rtn;
	enum scsi_disposition rtn;

	/*
	 * If SCSI_EH_ABORT_SCHEDULED has been set, it is timeout IO,
@@ -1316,7 +1317,8 @@ EXPORT_SYMBOL_GPL(scsi_eh_get_sense);
static int scsi_eh_tur(struct scsi_cmnd *scmd)
{
	static unsigned char tur_command[6] = {TEST_UNIT_READY, 0, 0, 0, 0, 0};
	int retry_cnt = 1, rtn;
	int retry_cnt = 1;
	enum scsi_disposition rtn;

retry_tur:
	rtn = scsi_send_eh_cmnd(scmd, tur_command, 6,
@@ -1404,7 +1406,8 @@ static int scsi_eh_try_stu(struct scsi_cmnd *scmd)
	static unsigned char stu_command[6] = {START_STOP, 0, 0, 0, 1, 0};

	if (scmd->device->allow_restart) {
		int i, rtn = NEEDS_RETRY;
		int i;
		enum scsi_disposition rtn = NEEDS_RETRY;

		for (i = 0; rtn == NEEDS_RETRY && i < 2; i++)
			rtn = scsi_send_eh_cmnd(scmd, stu_command, 6, scmd->device->request_queue->rq_timeout, 0);
@@ -1498,7 +1501,7 @@ static int scsi_eh_bus_device_reset(struct Scsi_Host *shost,
{
	struct scsi_cmnd *scmd, *bdr_scmd, *next;
	struct scsi_device *sdev;
	int rtn;
	enum scsi_disposition rtn;

	shost_for_each_device(sdev, shost) {
		if (scsi_host_eh_past_deadline(shost)) {
@@ -1565,7 +1568,7 @@ static int scsi_eh_target_reset(struct Scsi_Host *shost,

	while (!list_empty(&tmp_list)) {
		struct scsi_cmnd *next, *scmd;
		int rtn;
		enum scsi_disposition rtn;
		unsigned int id;

		if (scsi_host_eh_past_deadline(shost)) {
@@ -1623,7 +1626,7 @@ static int scsi_eh_bus_reset(struct Scsi_Host *shost,
	struct scsi_cmnd *scmd, *chan_scmd, *next;
	LIST_HEAD(check_list);
	unsigned int channel;
	int rtn;
	enum scsi_disposition rtn;

	/*
	 * we really want to loop over the various channels, and do this on
@@ -1694,7 +1697,7 @@ static int scsi_eh_host_reset(struct Scsi_Host *shost,
{
	struct scsi_cmnd *scmd, *next;
	LIST_HEAD(check_list);
	int rtn;
	enum scsi_disposition rtn;

	if (!list_empty(work_q)) {
		scmd = list_entry(work_q->next,
@@ -1800,9 +1803,9 @@ int scsi_noretry_cmd(struct scsi_cmnd *scmd)
 *    doesn't require the error handler read (i.e. we don't need to
 *    abort/reset), this function should return SUCCESS.
 */
int scsi_decide_disposition(struct scsi_cmnd *scmd)
enum scsi_disposition scsi_decide_disposition(struct scsi_cmnd *scmd)
{
	int rtn;
	enum scsi_disposition rtn;

	/*
	 * if the device is offline, then we clearly just pass the result back
@@ -2365,7 +2368,8 @@ scsi_ioctl_reset(struct scsi_device *dev, int __user *arg)
	struct Scsi_Host *shost = dev->host;
	struct request *rq;
	unsigned long flags;
	int error = 0, rtn, val;
	int error = 0, val;
	enum scsi_disposition rtn;

	if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
		return -EACCES;
Loading