From: Bean Huo <[email protected]>
Hi UFS driver developers/reviewers
Here are some changes to the UFS HPB driver. They are all based on Martin's Git repo
5.18/scsi-staging branch. Please refer to the patch submission information for the
specific purpose of each patch. I tested them on my own platform. Please have a review
and any comments and suggestions are welcome.
v1--v2:
1. Increase the submission information of the cover letter.
2. Fix coding style issues in patch 4/5
3. Add new patch 5/5.
Bean Huo (5):
scsi: ufshpb: Merge ufshpb_reset() and ufshpb_reset_host()
scsi: ufshpb: Remove 0 assignment for enum value
scsi: ufshpb: Cleanup the handler when device reset HPB information
scsi: ufshpb: Add handing of device reset HPB regions Infos in HPB
device mode
scsi: ufshpb: Cleanup ufshpb_suspend/resume
drivers/scsi/ufs/ufshcd.c | 4 +-
drivers/scsi/ufs/ufshpb.c | 157 ++++++++++++++++++++++----------------
drivers/scsi/ufs/ufshpb.h | 10 +--
3 files changed, 98 insertions(+), 73 deletions(-)
--
2.34.1
From: Bean Huo <[email protected]>
ufshpb_resume() is only called when the HPB state is HPB_SUSPEND, so
the check statement for "ufshpb_get_state(hpb) != HPB_PRESENT" is useless.
Signed-off-by: Bean Huo <[email protected]>
---
drivers/scsi/ufs/ufshpb.c | 15 ++++-----------
1 file changed, 4 insertions(+), 11 deletions(-)
diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c
index 4b15fa862beb..0e3bfd241f87 100644
--- a/drivers/scsi/ufs/ufshpb.c
+++ b/drivers/scsi/ufs/ufshpb.c
@@ -2354,11 +2354,9 @@ void ufshpb_suspend(struct ufs_hba *hba)
shost_for_each_device(sdev, hba->host) {
hpb = ufshpb_get_hpb_data(sdev);
- if (!hpb)
+ if (!hpb || ufshpb_get_state(hpb) != HPB_PRESENT)
continue;
- if (ufshpb_get_state(hpb) != HPB_PRESENT)
- continue;
ufshpb_set_state(hpb, HPB_SUSPEND);
ufshpb_cancel_jobs(hpb);
}
@@ -2371,20 +2369,15 @@ void ufshpb_resume(struct ufs_hba *hba)
shost_for_each_device(sdev, hba->host) {
hpb = ufshpb_get_hpb_data(sdev);
- if (!hpb)
+ if (!hpb || ufshpb_get_state(hpb) != HPB_SUSPEND)
continue;
- if ((ufshpb_get_state(hpb) != HPB_PRESENT) &&
- (ufshpb_get_state(hpb) != HPB_SUSPEND))
- continue;
ufshpb_set_state(hpb, HPB_PRESENT);
ufshpb_kick_map_work(hpb);
if (hpb->is_hcm) {
- unsigned int poll =
- hpb->params.timeout_polling_interval_ms;
+ unsigned int poll = hpb->params.timeout_polling_interval_ms;
- schedule_delayed_work(&hpb->ufshpb_read_to_work,
- msecs_to_jiffies(poll));
+ schedule_delayed_work(&hpb->ufshpb_read_to_work, msecs_to_jiffies(poll));
}
}
}
--
2.34.1
From: Bean Huo <[email protected]>
If the first enumerator has no initializer, the value of the corresponding
constant is zero.
Signed-off-by: Bean Huo <[email protected]>
---
drivers/scsi/ufs/ufshpb.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/scsi/ufs/ufshpb.h
index 2825ec69a6a6..b7e2817d4e76 100644
--- a/drivers/scsi/ufs/ufshpb.h
+++ b/drivers/scsi/ufs/ufshpb.h
@@ -59,8 +59,8 @@ enum UFSHPB_MODE {
};
enum UFSHPB_STATE {
- HPB_INIT = 0,
- HPB_PRESENT = 1,
+ HPB_INIT,
+ HPB_PRESENT,
HPB_SUSPEND,
HPB_FAILED,
HPB_RESET,
--
2.34.1
From: Bean Huo <[email protected]>
"When the device is powered off by the host, the device may restore L2P map data
upon power up or build from the host’s HPB READ command. In case device powered
up and lost HPB information, device can signal to the host through HPB Sense data,
by setting HPB Operation as ‘2’ which will inform the host that device reset HPB
information."
This patch is to clean up the handler and make the intent of this handler more
readable, no functional change.
Signed-off-by: Bean Huo <[email protected]>
---
drivers/scsi/ufs/ufshpb.c | 35 +++++++++++++++++++++++------------
1 file changed, 23 insertions(+), 12 deletions(-)
diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c
index 9df032e82ec3..4538164fc493 100644
--- a/drivers/scsi/ufs/ufshpb.c
+++ b/drivers/scsi/ufs/ufshpb.c
@@ -1231,7 +1231,10 @@ static void ufshpb_rsp_req_region_update(struct ufshpb_lu *hpb,
queue_work(ufshpb_wq, &hpb->map_work);
}
-static void ufshpb_dev_reset_handler(struct ufshpb_lu *hpb)
+/*
+ * Set the flags of all active regions to RGN_FLAG_UPDATE to let host side reload L2P entries later
+ */
+static void ufshpb_set_regions_update(struct ufshpb_lu *hpb)
{
struct victim_select_info *lru_info = &hpb->lru_info;
struct ufshpb_region *rgn;
@@ -1245,6 +1248,24 @@ static void ufshpb_dev_reset_handler(struct ufshpb_lu *hpb)
spin_unlock_irqrestore(&hpb->rgn_state_lock, flags);
}
+static void ufshpb_dev_reset_handler(struct ufs_hba *hba)
+{
+ struct scsi_device *sdev;
+ struct ufshpb_lu *hpb;
+
+ __shost_for_each_device(sdev, hba->host) {
+ hpb = ufshpb_get_hpb_data(sdev);
+ if (hpb && hpb->is_hcm)
+ /*
+ * For the HPB host mode, in case device powered up and lost HPB
+ * information, we will set the region flag to be RGN_FLAG_UPDATE,
+ * it will let host reload its L2P entries(re-activate the region
+ * in the UFS device).
+ */
+ ufshpb_set_regions_update(hpb);
+ }
+}
+
/*
* This function will parse recommended active subregion information in sense
* data field of response UPIU with SAM_STAT_GOOD state.
@@ -1319,17 +1340,7 @@ void ufshpb_rsp_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
case HPB_RSP_DEV_RESET:
dev_warn(&hpb->sdev_ufs_lu->sdev_dev,
"UFS device lost HPB information during PM.\n");
-
- if (hpb->is_hcm) {
- struct scsi_device *sdev;
-
- __shost_for_each_device(sdev, hba->host) {
- struct ufshpb_lu *h = sdev->hostdata;
-
- if (h)
- ufshpb_dev_reset_handler(h);
- }
- }
+ ufshpb_dev_reset_handler(hba);
break;
default:
--
2.34.1