]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
scsi: ufs: core: Add helpers to pause and resume command processing
authorCan Guo <can.guo@oss.qualcomm.com>
Wed, 25 Mar 2026 15:21:48 +0000 (08:21 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Fri, 27 Mar 2026 21:20:29 +0000 (17:20 -0400)
In preparation for supporting TX Equalization refreshing, introduce helper
functions to safely pause and resume command processing.

ufshcd_pause_command_processing() ensures the host is in a quiescent state
by stopping the block layer tagset, acquiring the necessary locks
(scan_mutex and clk_scaling_lock), and waiting for any in-flight commands
to complete within a specified timeout.

ufshcd_resume_command_processing() restores the host to its previous
operational state by reversing these steps in the correct order.

Reviewed-by: Bean Huo <beanhuo@micron.com>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Can Guo <can.guo@oss.qualcomm.com>
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Link: https://patch.msgid.link/20260325152154.1604082-7-can.guo@oss.qualcomm.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/ufs/core/ufshcd-priv.h
drivers/ufs/core/ufshcd.c

index 4c008230e8d67dea94492c4b35158bc25122d029..45904e5746b2d61c2fb4a6c3f1bcf50f3fbc22e7 100644 (file)
@@ -78,6 +78,8 @@ int ufshcd_mcq_sq_cleanup(struct ufs_hba *hba, int task_tag);
 int ufshcd_mcq_abort(struct scsi_cmnd *cmd);
 int ufshcd_try_to_abort_task(struct ufs_hba *hba, int tag);
 void ufshcd_release_scsi_cmd(struct ufs_hba *hba, struct scsi_cmnd *cmd);
+int ufshcd_pause_command_processing(struct ufs_hba *hba, u64 timeout_us);
+void ufshcd_resume_command_processing(struct ufs_hba *hba);
 
 /**
  * enum ufs_descr_fmt - UFS string descriptor format
index d78723dea951df4bc0a4a02641802bbac2e503bd..39e6d12e347a1eb5a6475082a04b18389214012e 100644 (file)
@@ -1363,6 +1363,48 @@ out:
        return ret;
 }
 
+/**
+ * ufshcd_pause_command_processing - Pause command processing
+ * @hba: per-adapter instance
+ * @timeout_us: timeout in microseconds to wait for pending commands to finish
+ *
+ * This function stops new command submissions and waits for existing commands
+ * to complete.
+ *
+ * Return: 0 on success, %-EBUSY if commands did not finish within @timeout_us.
+ * On failure, all acquired locks are released and the tagset is unquiesced.
+ */
+int ufshcd_pause_command_processing(struct ufs_hba *hba, u64 timeout_us)
+{
+       int ret = 0;
+
+       mutex_lock(&hba->host->scan_mutex);
+       blk_mq_quiesce_tagset(&hba->host->tag_set);
+       down_write(&hba->clk_scaling_lock);
+
+       if (ufshcd_wait_for_pending_cmds(hba, timeout_us)) {
+               ret = -EBUSY;
+               up_write(&hba->clk_scaling_lock);
+               blk_mq_unquiesce_tagset(&hba->host->tag_set);
+               mutex_unlock(&hba->host->scan_mutex);
+       }
+
+       return ret;
+}
+
+/**
+ * ufshcd_resume_command_processing - Resume command processing
+ * @hba: per-adapter instance
+ *
+ * This function resumes command submissions.
+ */
+void ufshcd_resume_command_processing(struct ufs_hba *hba)
+{
+       up_write(&hba->clk_scaling_lock);
+       blk_mq_unquiesce_tagset(&hba->host->tag_set);
+       mutex_unlock(&hba->host->scan_mutex);
+}
+
 /**
  * ufshcd_scale_gear - scale up/down UFS gear
  * @hba: per adapter instance