Commit 5373081b authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull SCSI fixes from James Bottomley:
 "Ten fixes.

  Of the three core changes, the two large ones are a complete reversion
  of the async rework and an ALUA timing rework (the latter shouldn't
  affect non-ALUA paths).

  The remaining patches are all small and all but one in drivers"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
  scsi: sd: Revert "Rework asynchronous resume support"
  scsi: core: Fix passthrough retry counter handling
  scsi: ufs: core: Reduce the power mode change timeout
  scsi: storvsc: Remove WQ_MEM_RECLAIM from storvsc_error_wq
  scsi: ufs: host: ufs-exynos: Make fsd_ufs_drvs static
  scsi: megaraid_sas: Remove unnecessary kfree()
  scsi: megaraid_sas: Fix double kfree()
  scsi: ufs: core: Enable link lost interrupt
  scsi: core: Allow the ALUA transitioning state enough time
  scsi: qla2xxx: Disable ATIO interrupt coalesce for quad port ISP27XX
parents 8238b457 785538bf
Loading
Loading
Loading
Loading
+2 −6
Original line number Diff line number Diff line
@@ -7153,22 +7153,18 @@ static int megasas_alloc_ctrl_mem(struct megasas_instance *instance)
	switch (instance->adapter_type) {
	case MFI_SERIES:
		if (megasas_alloc_mfi_ctrl_mem(instance))
			goto fail;
			return -ENOMEM;
		break;
	case AERO_SERIES:
	case VENTURA_SERIES:
	case THUNDERBOLT_SERIES:
	case INVADER_SERIES:
		if (megasas_alloc_fusion_context(instance))
			goto fail;
			return -ENOMEM;
		break;
	}

	return 0;
 fail:
	kfree(instance->reply_map);
	instance->reply_map = NULL;
	return -ENOMEM;
}

/*
+0 −1
Original line number Diff line number Diff line
@@ -5310,7 +5310,6 @@ megasas_alloc_fusion_context(struct megasas_instance *instance)
		if (!fusion->log_to_span) {
			dev_err(&instance->pdev->dev, "Failed from %s %d\n",
				__func__, __LINE__);
			kfree(instance->ctrl_context);
			return -ENOMEM;
		}
	}
+2 −8
Original line number Diff line number Diff line
@@ -6935,14 +6935,8 @@ qlt_24xx_config_rings(struct scsi_qla_host *vha)

	if (ha->flags.msix_enabled) {
		if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
			if (IS_QLA2071(ha)) {
				/* 4 ports Baker: Enable Interrupt Handshake */
				icb->msix_atio = 0;
				icb->firmware_options_2 |= cpu_to_le32(BIT_26);
			} else {
			icb->msix_atio = cpu_to_le16(msix->entry);
			icb->firmware_options_2 &= cpu_to_le32(~BIT_26);
			}
			ql_dbg(ql_dbg_init, vha, 0xf072,
			    "Registering ICB vector 0x%x for atio que.\n",
			    msix->entry);
+27 −20
Original line number Diff line number Diff line
@@ -111,7 +111,7 @@ scsi_set_blocked(struct scsi_cmnd *cmd, int reason)
	}
}

static void scsi_mq_requeue_cmd(struct scsi_cmnd *cmd)
static void scsi_mq_requeue_cmd(struct scsi_cmnd *cmd, unsigned long msecs)
{
	struct request *rq = scsi_cmd_to_rq(cmd);

@@ -121,6 +121,11 @@ static void scsi_mq_requeue_cmd(struct scsi_cmnd *cmd)
	} else {
		WARN_ON_ONCE(true);
	}

	if (msecs) {
		blk_mq_requeue_request(rq, false);
		blk_mq_delay_kick_requeue_list(rq->q, msecs);
	} else
		blk_mq_requeue_request(rq, true);
}

@@ -651,14 +656,6 @@ static unsigned int scsi_rq_err_bytes(const struct request *rq)
	return bytes;
}

/* Helper for scsi_io_completion() when "reprep" action required. */
static void scsi_io_completion_reprep(struct scsi_cmnd *cmd,
				      struct request_queue *q)
{
	/* A new command will be prepared and issued. */
	scsi_mq_requeue_cmd(cmd);
}

static bool scsi_cmd_runtime_exceeced(struct scsi_cmnd *cmd)
{
	struct request *req = scsi_cmd_to_rq(cmd);
@@ -676,14 +673,21 @@ static bool scsi_cmd_runtime_exceeced(struct scsi_cmnd *cmd)
	return false;
}

/*
 * When ALUA transition state is returned, reprep the cmd to
 * use the ALUA handler's transition timeout. Delay the reprep
 * 1 sec to avoid aggressive retries of the target in that
 * state.
 */
#define ALUA_TRANSITION_REPREP_DELAY	1000

/* Helper for scsi_io_completion() when special action required. */
static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result)
{
	struct request_queue *q = cmd->device->request_queue;
	struct request *req = scsi_cmd_to_rq(cmd);
	int level = 0;
	enum {ACTION_FAIL, ACTION_REPREP, ACTION_RETRY,
	      ACTION_DELAYED_RETRY} action;
	enum {ACTION_FAIL, ACTION_REPREP, ACTION_DELAYED_REPREP,
	      ACTION_RETRY, ACTION_DELAYED_RETRY} action;
	struct scsi_sense_hdr sshdr;
	bool sense_valid;
	bool sense_current = true;      /* false implies "deferred sense" */
@@ -772,8 +776,8 @@ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result)
					action = ACTION_DELAYED_RETRY;
					break;
				case 0x0a: /* ALUA state transition */
					blk_stat = BLK_STS_TRANSPORT;
					fallthrough;
					action = ACTION_DELAYED_REPREP;
					break;
				default:
					action = ACTION_FAIL;
					break;
@@ -832,7 +836,10 @@ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result)
			return;
		fallthrough;
	case ACTION_REPREP:
		scsi_io_completion_reprep(cmd, q);
		scsi_mq_requeue_cmd(cmd, 0);
		break;
	case ACTION_DELAYED_REPREP:
		scsi_mq_requeue_cmd(cmd, ALUA_TRANSITION_REPREP_DELAY);
		break;
	case ACTION_RETRY:
		/* Retry the same command immediately */
@@ -926,7 +933,7 @@ static int scsi_io_completion_nz_result(struct scsi_cmnd *cmd, int result,
 * command block will be released and the queue function will be goosed. If we
 * are not done then we have to figure out what to do next:
 *
 *   a) We can call scsi_io_completion_reprep().  The request will be
 *   a) We can call scsi_mq_requeue_cmd().  The request will be
 *	unprepared and put back on the queue.  Then a new command will
 *	be created for it.  This should be used if we made forward
 *	progress, or if we want to switch from READ(10) to READ(6) for
@@ -942,7 +949,6 @@ static int scsi_io_completion_nz_result(struct scsi_cmnd *cmd, int result,
void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
{
	int result = cmd->result;
	struct request_queue *q = cmd->device->request_queue;
	struct request *req = scsi_cmd_to_rq(cmd);
	blk_status_t blk_stat = BLK_STS_OK;

@@ -979,7 +985,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
	 * request just queue the command up again.
	 */
	if (likely(result == 0))
		scsi_io_completion_reprep(cmd, q);
		scsi_mq_requeue_cmd(cmd, 0);
	else
		scsi_io_completion_action(cmd, result);
}
@@ -1542,7 +1548,6 @@ static blk_status_t scsi_prepare_cmd(struct request *req)
	scsi_init_command(sdev, cmd);

	cmd->eh_eflags = 0;
	cmd->allowed = 0;
	cmd->prot_type = 0;
	cmd->prot_flags = 0;
	cmd->submitter = 0;
@@ -1593,6 +1598,8 @@ static blk_status_t scsi_prepare_cmd(struct request *req)
			return ret;
	}

	/* Usually overridden by the ULP */
	cmd->allowed = 0;
	memset(cmd->cmnd, 0, sizeof(cmd->cmnd));
	return scsi_cmd_to_driver(cmd)->init_command(cmd);
}
+18 −66
Original line number Diff line number Diff line
@@ -103,7 +103,6 @@ static void sd_config_discard(struct scsi_disk *, unsigned int);
static void sd_config_write_same(struct scsi_disk *);
static int  sd_revalidate_disk(struct gendisk *);
static void sd_unlock_native_capacity(struct gendisk *disk);
static void sd_start_done_work(struct work_struct *work);
static int  sd_probe(struct device *);
static int  sd_remove(struct device *);
static void sd_shutdown(struct device *);
@@ -3471,7 +3470,6 @@ static int sd_probe(struct device *dev)
	sdkp->max_retries = SD_MAX_RETRIES;
	atomic_set(&sdkp->openers, 0);
	atomic_set(&sdkp->device->ioerr_cnt, 0);
	INIT_WORK(&sdkp->start_done_work, sd_start_done_work);

	if (!sdp->request_queue->rq_timeout) {
		if (sdp->type != TYPE_MOD)
@@ -3594,69 +3592,12 @@ static void scsi_disk_release(struct device *dev)
	kfree(sdkp);
}

/* Process sense data after a START command finished. */
static void sd_start_done_work(struct work_struct *work)
{
	struct scsi_disk *sdkp = container_of(work, typeof(*sdkp),
					      start_done_work);
	struct scsi_sense_hdr sshdr;
	int res = sdkp->start_result;

	if (res == 0)
		return;

	sd_print_result(sdkp, "Start/Stop Unit failed", res);

	if (res < 0)
		return;

	if (scsi_normalize_sense(sdkp->start_sense_buffer,
				 sdkp->start_sense_len, &sshdr))
		sd_print_sense_hdr(sdkp, &sshdr);
}

/* A START command finished. May be called from interrupt context. */
static void sd_start_done(struct request *req, blk_status_t status)
{
	const struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(req);
	struct scsi_disk *sdkp = scsi_disk(req->q->disk);

	sdkp->start_result = scmd->result;
	WARN_ON_ONCE(scmd->sense_len > SCSI_SENSE_BUFFERSIZE);
	sdkp->start_sense_len = scmd->sense_len;
	memcpy(sdkp->start_sense_buffer, scmd->sense_buffer,
	       ARRAY_SIZE(sdkp->start_sense_buffer));
	WARN_ON_ONCE(!schedule_work(&sdkp->start_done_work));
}

/* Submit a START command asynchronously. */
static int sd_submit_start(struct scsi_disk *sdkp, u8 cmd[], u8 cmd_len)
{
	struct scsi_device *sdev = sdkp->device;
	struct request_queue *q = sdev->request_queue;
	struct request *req;
	struct scsi_cmnd *scmd;

	req = scsi_alloc_request(q, REQ_OP_DRV_IN, BLK_MQ_REQ_PM);
	if (IS_ERR(req))
		return PTR_ERR(req);

	scmd = blk_mq_rq_to_pdu(req);
	scmd->cmd_len = cmd_len;
	memcpy(scmd->cmnd, cmd, cmd_len);
	scmd->allowed = sdkp->max_retries;
	req->timeout = SD_TIMEOUT;
	req->rq_flags |= RQF_PM | RQF_QUIET;
	req->end_io = sd_start_done;
	blk_execute_rq_nowait(req, /*at_head=*/true);

	return 0;
}

static int sd_start_stop_device(struct scsi_disk *sdkp, int start)
{
	unsigned char cmd[6] = { START_STOP };	/* START_VALID */
	struct scsi_sense_hdr sshdr;
	struct scsi_device *sdp = sdkp->device;
	int res;

	if (start)
		cmd[4] |= 1;	/* START */
@@ -3667,10 +3608,23 @@ static int sd_start_stop_device(struct scsi_disk *sdkp, int start)
	if (!scsi_device_online(sdp))
		return -ENODEV;

	/* Wait until processing of sense data has finished. */
	flush_work(&sdkp->start_done_work);
	res = scsi_execute(sdp, cmd, DMA_NONE, NULL, 0, NULL, &sshdr,
			SD_TIMEOUT, sdkp->max_retries, 0, RQF_PM, NULL);
	if (res) {
		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)
				res = 0;
		}
	}

	return sd_submit_start(sdkp, cmd, sizeof(cmd));
	/* SCSI error codes must not go to the generic layer */
	if (res)
		return -EIO;

	return 0;
}

/*
@@ -3697,8 +3651,6 @@ static void sd_shutdown(struct device *dev)
		sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n");
		sd_start_stop_device(sdkp, 0);
	}

	flush_work(&sdkp->start_done_work);
}

static int sd_suspend_common(struct device *dev, bool ignore_stop_errors)
Loading