From 5a7e56907cd7eb2cced8548bc367a4f0f3ca1f70 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 29 Mar 2022 13:47:10 -0700 Subject: [PATCH] FROMLIST: scsi: ufs: Add suspend/resume SCSI command processing support This functionality is needed by UFS drivers to e.g. suspend SCSI command processing while reprogramming encryption keys if the hardware does not support concurrent I/O and key reprogramming. Bug: 227177294 Link: https://lore.kernel.org/all/20220427233855.2685505-5-bvanassche@acm.org/ Change-Id: I10f11e67da81fae7063674838760903d2c178baf Signed-off-by: Bart Van Assche --- drivers/scsi/ufs/ufshcd.c | 20 ++++++++++++++++++++ drivers/scsi/ufs/ufshcd.h | 3 +++ 2 files changed, 23 insertions(+) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 226e161bcee2..75f78a40755b 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -1681,6 +1681,26 @@ unblock_reqs: ufshcd_scsi_unblock_requests(hba); } +/* + * Block processing of new SCSI commands and wait until pending SCSI + * commands and TMFs have finished. ufshcd_exec_dev_cmd() and + * ufshcd_issue_devman_upiu_cmd() are not affected by this function. + * + * Return: 0 upon success; -EBUSY upon timeout. + */ +int ufshcd_freeze_scsi_devs(struct ufs_hba *hba, u64 timeout_us) +{ + return ufshcd_clock_scaling_prepare(hba, timeout_us); +} +EXPORT_SYMBOL_GPL(ufshcd_freeze_scsi_devs); + +/* Resume processing of SCSI commands. */ +void ufshcd_unfreeze_scsi_devs(struct ufs_hba *hba) +{ + ufshcd_clock_scaling_unprepare(hba, true); +} +EXPORT_SYMBOL_GPL(ufshcd_unfreeze_scsi_devs); + /** * ufshcd_hold - Enable clocks that were gated earlier due to ufshcd_release. * Also, exit from hibern8 mode and set the link as active. diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index dff8f8d79bea..186c4f4bc74b 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -1224,6 +1224,9 @@ int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index, int ufshcd_hold(struct ufs_hba *hba, bool async); void ufshcd_release(struct ufs_hba *hba); +int ufshcd_freeze_scsi_devs(struct ufs_hba *hba, u64 timeout_us); +void ufshcd_unfreeze_scsi_devs(struct ufs_hba *hba); + void ufshcd_map_desc_id_to_length(struct ufs_hba *hba, enum desc_idn desc_id, int *desc_length);