Commit 102c16a1 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull SCSI fixes from James Bottomley:
 "Small ufs fixes and a core change to clear the command private area on
  every retry (which fixes a reported bug in virtio_scsi)"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
  scsi: ufs: core: bsg: Fix crash when arpmb command fails
  scsi: ufs: core: Set default runtime/system PM levels before ufshcd_hba_init()
  scsi: core: Clear driver private data when retrying request
  scsi: ufs: core: Fix ufshcd_is_ufs_dev_busy() and ufshcd_eh_timed_out()
parents f4ce1f33 f27a9584
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -1669,13 +1669,6 @@ static blk_status_t scsi_prepare_cmd(struct request *req)
	if (in_flight)
		__set_bit(SCMD_STATE_INFLIGHT, &cmd->state);

	/*
	 * Only clear the driver-private command data if the LLD does not supply
	 * a function to initialize that data.
	 */
	if (!shost->hostt->init_cmd_priv)
		memset(cmd + 1, 0, shost->hostt->cmd_size);

	cmd->prot_op = SCSI_PROT_NORMAL;
	if (blk_rq_bytes(req))
		cmd->sc_data_direction = rq_dma_dir(req);
@@ -1842,6 +1835,13 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx,
	if (!scsi_host_queue_ready(q, shost, sdev, cmd))
		goto out_dec_target_busy;

	/*
	 * Only clear the driver-private command data if the LLD does not supply
	 * a function to initialize that data.
	 */
	if (shost->hostt->cmd_size && !shost->hostt->init_cmd_priv)
		memset(cmd + 1, 0, shost->hostt->cmd_size);

	if (!(req->rq_flags & RQF_DONTPREP)) {
		ret = scsi_prepare_cmd(req);
		if (ret != BLK_STS_OK)
+4 −2
Original line number Diff line number Diff line
@@ -194,10 +194,12 @@ static int ufs_bsg_request(struct bsg_job *job)
	ufshcd_rpm_put_sync(hba);
	kfree(buff);
	bsg_reply->result = ret;
	job->reply_len = !rpmb ? sizeof(struct ufs_bsg_reply) : sizeof(struct ufs_rpmb_reply);
	/* complete the job here only if no error */
	if (ret == 0)
	if (ret == 0) {
		job->reply_len = rpmb ? sizeof(struct ufs_rpmb_reply) :
					sizeof(struct ufs_bsg_reply);
		bsg_job_done(job, ret, bsg_reply->reply_payload_rcv_len);
	}

	return ret;
}
+19 −19
Original line number Diff line number Diff line
@@ -266,7 +266,7 @@ static bool ufshcd_has_pending_tasks(struct ufs_hba *hba)

static bool ufshcd_is_ufs_dev_busy(struct ufs_hba *hba)
{
	return hba->outstanding_reqs || ufshcd_has_pending_tasks(hba);
	return scsi_host_busy(hba->host) || ufshcd_has_pending_tasks(hba);
}

static const struct ufs_dev_quirk ufs_fixups[] = {
@@ -628,8 +628,8 @@ static void ufshcd_print_host_state(struct ufs_hba *hba)
	const struct scsi_device *sdev_ufs = hba->ufs_device_wlun;

	dev_err(hba->dev, "UFS Host state=%d\n", hba->ufshcd_state);
	dev_err(hba->dev, "outstanding reqs=0x%lx tasks=0x%lx\n",
		hba->outstanding_reqs, hba->outstanding_tasks);
	dev_err(hba->dev, "%d outstanding reqs, tasks=0x%lx\n",
		scsi_host_busy(hba->host), hba->outstanding_tasks);
	dev_err(hba->dev, "saved_err=0x%x, saved_uic_err=0x%x\n",
		hba->saved_err, hba->saved_uic_err);
	dev_err(hba->dev, "Device power mode=%d, UIC link state=%d\n",
@@ -8882,7 +8882,7 @@ static enum scsi_timeout_action ufshcd_eh_timed_out(struct scsi_cmnd *scmd)
	dev_info(hba->dev, "%s() finished; outstanding_tasks = %#lx.\n",
		 __func__, hba->outstanding_tasks);

	return hba->outstanding_reqs ? SCSI_EH_RESET_TIMER : SCSI_EH_DONE;
	return scsi_host_busy(hba->host) ? SCSI_EH_RESET_TIMER : SCSI_EH_DONE;
}

static const struct attribute_group *ufshcd_driver_groups[] = {
@@ -10431,6 +10431,21 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
	 */
	spin_lock_init(&hba->clk_gating.lock);

	/*
	 * Set the default power management level for runtime and system PM.
	 * Host controller drivers can override them in their
	 * 'ufs_hba_variant_ops::init' callback.
	 *
	 * Default power saving mode is to keep UFS link in Hibern8 state
	 * and UFS device in sleep state.
	 */
	hba->rpm_lvl = ufs_get_desired_pm_lvl_for_dev_link_state(
						UFS_SLEEP_PWR_MODE,
						UIC_LINK_HIBERN8_STATE);
	hba->spm_lvl = ufs_get_desired_pm_lvl_for_dev_link_state(
						UFS_SLEEP_PWR_MODE,
						UIC_LINK_HIBERN8_STATE);

	err = ufshcd_hba_init(hba);
	if (err)
		goto out_error;
@@ -10544,21 +10559,6 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
		goto out_disable;
	}

	/*
	 * Set the default power management level for runtime and system PM if
	 * not set by the host controller drivers.
	 * Default power saving mode is to keep UFS link in Hibern8 state
	 * and UFS device in sleep state.
	 */
	if (!hba->rpm_lvl)
		hba->rpm_lvl = ufs_get_desired_pm_lvl_for_dev_link_state(
						UFS_SLEEP_PWR_MODE,
						UIC_LINK_HIBERN8_STATE);
	if (!hba->spm_lvl)
		hba->spm_lvl = ufs_get_desired_pm_lvl_for_dev_link_state(
						UFS_SLEEP_PWR_MODE,
						UIC_LINK_HIBERN8_STATE);

	INIT_DELAYED_WORK(&hba->rpm_dev_flush_recheck_work, ufshcd_rpm_dev_flush_recheck_work);
	INIT_DELAYED_WORK(&hba->ufs_rtc_update_work, ufshcd_rtc_work);