The patch below does not apply to the 6.6-stable tree. If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to stable@vger.kernel.org.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.6.y git checkout FETCH_HEAD git cherry-pick -x d968e99488c4b08259a324a89e4ed17bf36561a4 # <resolve conflicts, build, test, etc.> git commit -s git send-email --to 'stable@vger.kernel.org' --in-reply-to '2025110940-control-hence-f9a8@gregkh' --subject-prefix 'PATCH 6.6.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From d968e99488c4b08259a324a89e4ed17bf36561a4 Mon Sep 17 00:00:00 2001 From: Adrian Hunter adrian.hunter@intel.com Date: Fri, 24 Oct 2025 11:59:17 +0300 Subject: [PATCH] scsi: ufs: ufs-pci: Set UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCE for Intel ADL
Link startup becomes unreliable for Intel Alder Lake based host controllers when a 2nd DME_LINKSTARTUP is issued unnecessarily. Employ UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCE to suppress that from happening.
Fixes: 7dc9fb47bc9a ("scsi: ufs: ufs-pci: Add support for Intel ADL") Cc: stable@vger.kernel.org Signed-off-by: Adrian Hunter adrian.hunter@intel.com Reviewed-by: Bart Van Assche bvanassche@acm.org Link: https://patch.msgid.link/20251024085918.31825-4-adrian.hunter@intel.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com
diff --git a/drivers/ufs/host/ufshcd-pci.c b/drivers/ufs/host/ufshcd-pci.c index 89f88b693850..5f65dfad1a71 100644 --- a/drivers/ufs/host/ufshcd-pci.c +++ b/drivers/ufs/host/ufshcd-pci.c @@ -428,7 +428,8 @@ static int ufs_intel_lkf_init(struct ufs_hba *hba) static int ufs_intel_adl_init(struct ufs_hba *hba) { hba->nop_out_timeout = 200; - hba->quirks |= UFSHCD_QUIRK_BROKEN_AUTO_HIBERN8; + hba->quirks |= UFSHCD_QUIRK_BROKEN_AUTO_HIBERN8 | + UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCE; hba->caps |= UFSHCD_CAP_WB_EN; return ufs_intel_common_init(hba); }
From: Eric Biggers ebiggers@google.com
[ Upstream commit c2a90eee29f41630225c9a64d26c425e1d50b401 ]
Add UFSHCD_QUIRK_CUSTOM_CRYPTO_PROFILE which lets UFS host drivers initialize the blk_crypto_profile themselves rather than have it be initialized by ufshcd-core according to the UFSHCI standard. This is needed to support inline encryption on the "Exynos" UFS controller which has a nonstandard interface.
Reviewed-by: Bart Van Assche bvanassche@acm.org Reviewed-by: Peter Griffin peter.griffin@linaro.org Signed-off-by: Eric Biggers ebiggers@google.com Link: https://lore.kernel.org/r/20240708235330.103590-2-ebiggers@kernel.org Reviewed-by: Alim Akhtar alim.akhtar@samsung.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Stable-dep-of: d968e99488c4 ("scsi: ufs: ufs-pci: Set UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCE for Intel ADL") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/ufs/core/ufshcd-crypto.c | 10 +++++++--- include/ufs/ufshcd.h | 9 +++++++++ 2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/drivers/ufs/core/ufshcd-crypto.c b/drivers/ufs/core/ufshcd-crypto.c index f2c4422cab864..debc925ae439b 100644 --- a/drivers/ufs/core/ufshcd-crypto.c +++ b/drivers/ufs/core/ufshcd-crypto.c @@ -159,6 +159,9 @@ int ufshcd_hba_init_crypto_capabilities(struct ufs_hba *hba) int err = 0; enum blk_crypto_mode_num blk_mode_num;
+ if (hba->quirks & UFSHCD_QUIRK_CUSTOM_CRYPTO_PROFILE) + return 0; + /* * Don't use crypto if either the hardware doesn't advertise the * standard crypto capability bit *or* if the vendor specific driver @@ -228,9 +231,10 @@ void ufshcd_init_crypto(struct ufs_hba *hba) if (!(hba->caps & UFSHCD_CAP_CRYPTO)) return;
- /* Clear all keyslots - the number of keyslots is (CFGC + 1) */ - for (slot = 0; slot < hba->crypto_capabilities.config_count + 1; slot++) - ufshcd_clear_keyslot(hba, slot); + /* Clear all keyslots. */ + for (slot = 0; slot < hba->crypto_profile.num_slots; slot++) + hba->crypto_profile.ll_ops.keyslot_evict(&hba->crypto_profile, + NULL, slot); }
void ufshcd_crypto_register(struct ufs_hba *hba, struct request_queue *q) diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index e9db9682316a2..21d03510efb66 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -642,6 +642,15 @@ enum ufshcd_quirks { * thus need this quirk to skip related flow. */ UFSHCD_QUIRK_MCQ_BROKEN_RTC = 1 << 21, + + /* + * This quirk needs to be enabled if the host controller supports inline + * encryption but it needs to initialize the crypto capabilities in a + * nonstandard way and/or needs to override blk_crypto_ll_ops. If + * enabled, the standard code won't initialize the blk_crypto_profile; + * ufs_hba_variant_ops::init() must do it instead. + */ + UFSHCD_QUIRK_CUSTOM_CRYPTO_PROFILE = 1 << 22, };
enum ufshcd_caps {
From: Eric Biggers ebiggers@google.com
[ Upstream commit ec99818afb03b1ebeb0b6ed0d5fd42143be79586 ]
Fold ufshcd_clear_keyslot() into its only remaining caller.
Reviewed-by: Bart Van Assche bvanassche@acm.org Reviewed-by: Peter Griffin peter.griffin@linaro.org Signed-off-by: Eric Biggers ebiggers@google.com Link: https://lore.kernel.org/r/20240708235330.103590-3-ebiggers@kernel.org Reviewed-by: Alim Akhtar alim.akhtar@samsung.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Stable-dep-of: d968e99488c4 ("scsi: ufs: ufs-pci: Set UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCE for Intel ADL") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/ufs/core/ufshcd-crypto.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-)
diff --git a/drivers/ufs/core/ufshcd-crypto.c b/drivers/ufs/core/ufshcd-crypto.c index debc925ae439b..b4980fd91cee7 100644 --- a/drivers/ufs/core/ufshcd-crypto.c +++ b/drivers/ufs/core/ufshcd-crypto.c @@ -95,8 +95,12 @@ static int ufshcd_crypto_keyslot_program(struct blk_crypto_profile *profile, return err; }
-static int ufshcd_clear_keyslot(struct ufs_hba *hba, int slot) +static int ufshcd_crypto_keyslot_evict(struct blk_crypto_profile *profile, + const struct blk_crypto_key *key, + unsigned int slot) { + struct ufs_hba *hba = + container_of(profile, struct ufs_hba, crypto_profile); /* * Clear the crypto cfg on the device. Clearing CFGE * might not be sufficient, so just clear the entire cfg. @@ -106,16 +110,6 @@ static int ufshcd_clear_keyslot(struct ufs_hba *hba, int slot) return ufshcd_program_key(hba, &cfg, slot); }
-static int ufshcd_crypto_keyslot_evict(struct blk_crypto_profile *profile, - const struct blk_crypto_key *key, - unsigned int slot) -{ - struct ufs_hba *hba = - container_of(profile, struct ufs_hba, crypto_profile); - - return ufshcd_clear_keyslot(hba, slot); -} - bool ufshcd_crypto_enable(struct ufs_hba *hba) { if (!(hba->caps & UFSHCD_CAP_CRYPTO))
From: Eric Biggers ebiggers@google.com
[ Upstream commit e95881e0081a30e132b5ca087f1e07fc08608a7e ]
Add UFSHCD_QUIRK_BROKEN_CRYPTO_ENABLE which tells the UFS core to not use the crypto enable bit defined by the UFS specification. This is needed to support inline encryption on the "Exynos" UFS controller.
Reviewed-by: Bart Van Assche bvanassche@acm.org Reviewed-by: Peter Griffin peter.griffin@linaro.org Signed-off-by: Eric Biggers ebiggers@google.com Link: https://lore.kernel.org/r/20240708235330.103590-4-ebiggers@kernel.org Reviewed-by: Alim Akhtar alim.akhtar@samsung.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Stable-dep-of: d968e99488c4 ("scsi: ufs: ufs-pci: Set UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCE for Intel ADL") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/ufs/core/ufshcd-crypto.c | 8 ++++++++ include/ufs/ufshcd.h | 7 +++++++ 2 files changed, 15 insertions(+)
diff --git a/drivers/ufs/core/ufshcd-crypto.c b/drivers/ufs/core/ufshcd-crypto.c index b4980fd91cee7..a714dad82cd1f 100644 --- a/drivers/ufs/core/ufshcd-crypto.c +++ b/drivers/ufs/core/ufshcd-crypto.c @@ -110,6 +110,10 @@ static int ufshcd_crypto_keyslot_evict(struct blk_crypto_profile *profile, return ufshcd_program_key(hba, &cfg, slot); }
+/* + * Reprogram the keyslots if needed, and return true if CRYPTO_GENERAL_ENABLE + * should be used in the host controller initialization sequence. + */ bool ufshcd_crypto_enable(struct ufs_hba *hba) { if (!(hba->caps & UFSHCD_CAP_CRYPTO)) @@ -117,6 +121,10 @@ bool ufshcd_crypto_enable(struct ufs_hba *hba)
/* Reset might clear all keys, so reprogram all the keys. */ blk_crypto_reprogram_all_keys(&hba->crypto_profile); + + if (hba->quirks & UFSHCD_QUIRK_BROKEN_CRYPTO_ENABLE) + return false; + return true; }
diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index 21d03510efb66..3a3183dc899c3 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -651,6 +651,13 @@ enum ufshcd_quirks { * ufs_hba_variant_ops::init() must do it instead. */ UFSHCD_QUIRK_CUSTOM_CRYPTO_PROFILE = 1 << 22, + + /* + * This quirk needs to be enabled if the host controller supports inline + * encryption but does not support the CRYPTO_GENERAL_ENABLE bit, i.e. + * host controller initialization fails if that bit is set. + */ + UFSHCD_QUIRK_BROKEN_CRYPTO_ENABLE = 1 << 23, };
enum ufshcd_caps {
From: Eric Biggers ebiggers@google.com
[ Upstream commit 8ecea3da1567e0648b5d37a6faec73fc9c8571ba ]
Add a variant op to allow host drivers to initialize nonstandard crypto-related fields in the PRDT. This is needed to support inline encryption on the "Exynos" UFS controller.
Note that this will be used together with the support for overriding the PRDT entry size that was already added by commit ada1e653a5ea ("scsi: ufs: core: Allow UFS host drivers to override the sg entry size").
Reviewed-by: Bart Van Assche bvanassche@acm.org Reviewed-by: Peter Griffin peter.griffin@linaro.org Signed-off-by: Eric Biggers ebiggers@google.com Link: https://lore.kernel.org/r/20240708235330.103590-5-ebiggers@kernel.org Reviewed-by: Alim Akhtar alim.akhtar@samsung.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Stable-dep-of: d968e99488c4 ("scsi: ufs: ufs-pci: Set UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCE for Intel ADL") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/ufs/core/ufshcd-crypto.h | 19 +++++++++++++++++++ drivers/ufs/core/ufshcd.c | 2 +- include/ufs/ufshcd.h | 4 ++++ 3 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/drivers/ufs/core/ufshcd-crypto.h b/drivers/ufs/core/ufshcd-crypto.h index be8596f20ba2f..3eb8df42e1942 100644 --- a/drivers/ufs/core/ufshcd-crypto.h +++ b/drivers/ufs/core/ufshcd-crypto.h @@ -37,6 +37,19 @@ ufshcd_prepare_req_desc_hdr_crypto(struct ufshcd_lrb *lrbp, h->dunu = cpu_to_le32(upper_32_bits(lrbp->data_unit_num)); }
+static inline int ufshcd_crypto_fill_prdt(struct ufs_hba *hba, + struct ufshcd_lrb *lrbp) +{ + struct scsi_cmnd *cmd = lrbp->cmd; + const struct bio_crypt_ctx *crypt_ctx = scsi_cmd_to_rq(cmd)->crypt_ctx; + + if (crypt_ctx && hba->vops && hba->vops->fill_crypto_prdt) + return hba->vops->fill_crypto_prdt(hba, crypt_ctx, + lrbp->ucd_prdt_ptr, + scsi_sg_count(cmd)); + return 0; +} + bool ufshcd_crypto_enable(struct ufs_hba *hba);
int ufshcd_hba_init_crypto_capabilities(struct ufs_hba *hba); @@ -54,6 +67,12 @@ static inline void ufshcd_prepare_req_desc_hdr_crypto(struct ufshcd_lrb *lrbp, struct request_desc_header *h) { }
+static inline int ufshcd_crypto_fill_prdt(struct ufs_hba *hba, + struct ufshcd_lrb *lrbp) +{ + return 0; +} + static inline bool ufshcd_crypto_enable(struct ufs_hba *hba) { return false; diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 7dcdaac31546b..8b7033cd6cdbb 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -2586,7 +2586,7 @@ static int ufshcd_map_sg(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
ufshcd_sgl_to_prdt(hba, lrbp, sg_segments, scsi_sglist(cmd));
- return 0; + return ufshcd_crypto_fill_prdt(hba, lrbp); }
/** diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index 3a3183dc899c3..9ba8162c00a5e 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -323,6 +323,7 @@ struct ufs_pwr_mode_info { * @device_reset: called to issue a reset pulse on the UFS device * @config_scaling_param: called to configure clock scaling parameters * @program_key: program or evict an inline encryption key + * @fill_crypto_prdt: initialize crypto-related fields in the PRDT * @event_notify: called to notify important events * @mcq_config_resource: called to configure MCQ platform resources * @get_hba_mac: called to get vendor specific mac value, mandatory for mcq mode @@ -366,6 +367,9 @@ struct ufs_hba_variant_ops { struct devfreq_simple_ondemand_data *data); int (*program_key)(struct ufs_hba *hba, const union ufs_crypto_cfg_entry *cfg, int slot); + int (*fill_crypto_prdt)(struct ufs_hba *hba, + const struct bio_crypt_ctx *crypt_ctx, + void *prdt, unsigned int num_segments); void (*event_notify)(struct ufs_hba *hba, enum ufs_event_type evt, void *data); int (*mcq_config_resource)(struct ufs_hba *hba);
From: Eric Biggers ebiggers@google.com
[ Upstream commit 4c45dba50a3750a0834353c4187e7896b158bc0c ]
Since the nonstandard inline encryption support on Exynos SoCs requires that raw cryptographic keys be copied into the PRDT, it is desirable to zeroize those keys after each request to keep them from being left in memory. Therefore, add a quirk bit that enables the zeroization.
We could instead do the zeroization unconditionally. However, using a quirk bit avoids adding the zeroization overhead to standard devices.
Reviewed-by: Bart Van Assche bvanassche@acm.org Reviewed-by: Peter Griffin peter.griffin@linaro.org Signed-off-by: Eric Biggers ebiggers@google.com Link: https://lore.kernel.org/r/20240708235330.103590-6-ebiggers@kernel.org Reviewed-by: Alim Akhtar alim.akhtar@samsung.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Stable-dep-of: d968e99488c4 ("scsi: ufs: ufs-pci: Set UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCE for Intel ADL") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/ufs/core/ufshcd-crypto.h | 17 +++++++++++++++++ drivers/ufs/core/ufshcd.c | 1 + include/ufs/ufshcd.h | 8 ++++++++ 3 files changed, 26 insertions(+)
diff --git a/drivers/ufs/core/ufshcd-crypto.h b/drivers/ufs/core/ufshcd-crypto.h index 3eb8df42e1942..89bb97c14c15b 100644 --- a/drivers/ufs/core/ufshcd-crypto.h +++ b/drivers/ufs/core/ufshcd-crypto.h @@ -50,6 +50,20 @@ static inline int ufshcd_crypto_fill_prdt(struct ufs_hba *hba, return 0; }
+static inline void ufshcd_crypto_clear_prdt(struct ufs_hba *hba, + struct ufshcd_lrb *lrbp) +{ + if (!(hba->quirks & UFSHCD_QUIRK_KEYS_IN_PRDT)) + return; + + if (!(scsi_cmd_to_rq(lrbp->cmd)->crypt_ctx)) + return; + + /* Zeroize the PRDT because it can contain cryptographic keys. */ + memzero_explicit(lrbp->ucd_prdt_ptr, + ufshcd_sg_entry_size(hba) * scsi_sg_count(lrbp->cmd)); +} + bool ufshcd_crypto_enable(struct ufs_hba *hba);
int ufshcd_hba_init_crypto_capabilities(struct ufs_hba *hba); @@ -73,6 +87,9 @@ static inline int ufshcd_crypto_fill_prdt(struct ufs_hba *hba, return 0; }
+static inline void ufshcd_crypto_clear_prdt(struct ufs_hba *hba, + struct ufshcd_lrb *lrbp) { } + static inline bool ufshcd_crypto_enable(struct ufs_hba *hba) { return false; diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 8b7033cd6cdbb..6990886a54c5d 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -5509,6 +5509,7 @@ void ufshcd_release_scsi_cmd(struct ufs_hba *hba, struct scsi_cmnd *cmd = lrbp->cmd;
scsi_dma_unmap(cmd); + ufshcd_crypto_clear_prdt(hba, lrbp); ufshcd_release(hba); ufshcd_clk_scaling_update_busy(hba); } diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index 9ba8162c00a5e..40b457b4c831e 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -662,6 +662,14 @@ enum ufshcd_quirks { * host controller initialization fails if that bit is set. */ UFSHCD_QUIRK_BROKEN_CRYPTO_ENABLE = 1 << 23, + + /* + * This quirk needs to be enabled if the host controller driver copies + * cryptographic keys into the PRDT in order to send them to hardware, + * and therefore the PRDT should be zeroized after each request (as per + * the standard best practice for managing keys). + */ + UFSHCD_QUIRK_KEYS_IN_PRDT = 1 << 24, };
enum ufshcd_caps {
From: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org
[ Upstream commit cd06b713a6880997ca5aecac8e33d5f9c541749e ]
'Legacy Queue & Single Doorbell Support (LSDBS)' field in the controller capabilities register is supposed to report whether the legacy single doorbell mode is supported in the controller or not. But some controllers report '1' in this field which corresponds to 'LSDB not supported', but they indeed support LSDB. So let's add a quirk to handle those controllers.
If the quirk is enabled by the controller driver, then LSDBS register field will be ignored and legacy single doorbell mode is assumed to be enabled always.
Tested-by: Amit Pundir amit.pundir@linaro.org Signed-off-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Link: https://lore.kernel.org/r/20240816-ufs-bug-fix-v3-1-e6fe0e18e2a3@linaro.org Reviewed-by: Bart Van Assche bvanassche@acm.org Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Stable-dep-of: d968e99488c4 ("scsi: ufs: ufs-pci: Set UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCE for Intel ADL") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/ufs/core/ufshcd.c | 6 +++++- include/ufs/ufshcd.h | 8 ++++++++ 2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 6990886a54c5d..8e24cdc8a29b9 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -2365,7 +2365,11 @@ static inline int ufshcd_hba_capabilities(struct ufs_hba *hba) * 0h: legacy single doorbell support is available * 1h: indicate that legacy single doorbell support has been removed */ - hba->lsdb_sup = !FIELD_GET(MASK_LSDB_SUPPORT, hba->capabilities); + if (!(hba->quirks & UFSHCD_QUIRK_BROKEN_LSDBS_CAP)) + hba->lsdb_sup = !FIELD_GET(MASK_LSDB_SUPPORT, hba->capabilities); + else + hba->lsdb_sup = true; + if (!hba->mcq_sup) return 0;
diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index 40b457b4c831e..dac568503e905 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -670,6 +670,14 @@ enum ufshcd_quirks { * the standard best practice for managing keys). */ UFSHCD_QUIRK_KEYS_IN_PRDT = 1 << 24, + + /* + * This quirk indicates that the controller reports the value 1 (not + * supported) in the Legacy Single DoorBell Support (LSDBS) bit of the + * Controller Capabilities register although it supports the legacy + * single doorbell mode. + */ + UFSHCD_QUIRK_BROKEN_LSDBS_CAP = 1 << 25, };
enum ufshcd_caps {
From: Adrian Hunter adrian.hunter@intel.com
[ Upstream commit d34caa89a132cd69efc48361d4772251546fdb88 ]
ufshcd_link_startup() has a facility (link_startup_again) to issue DME_LINKSTARTUP a 2nd time even though the 1st time was successful.
Some older hardware benefits from that, however the behaviour is non-standard, and has been found to cause link startup to be unreliable for some Intel Alder Lake based host controllers.
Add UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCE to suppress link_startup_again, in preparation for setting the quirk for affected controllers.
Fixes: 7dc9fb47bc9a ("scsi: ufs: ufs-pci: Add support for Intel ADL") Cc: stable@vger.kernel.org Signed-off-by: Adrian Hunter adrian.hunter@intel.com Reviewed-by: Bart Van Assche bvanassche@acm.org Link: https://patch.msgid.link/20251024085918.31825-3-adrian.hunter@intel.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Stable-dep-of: d968e99488c4 ("scsi: ufs: ufs-pci: Set UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCE for Intel ADL") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/ufs/core/ufshcd.c | 3 ++- include/ufs/ufshcd.h | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 8e24cdc8a29b9..fcaf4b9c950e4 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -4977,7 +4977,8 @@ static int ufshcd_link_startup(struct ufs_hba *hba) * If UFS device isn't active then we will have to issue link startup * 2 times to make sure the device state move to active. */ - if (!ufshcd_is_ufs_dev_active(hba)) + if (!(hba->quirks & UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCE) && + !ufshcd_is_ufs_dev_active(hba)) link_startup_again = true;
link_startup: diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index dac568503e905..3e81a2168d704 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -678,6 +678,13 @@ enum ufshcd_quirks { * single doorbell mode. */ UFSHCD_QUIRK_BROKEN_LSDBS_CAP = 1 << 25, + + /* + * This quirk indicates that DME_LINKSTARTUP should not be issued a 2nd + * time (refer link_startup_again) after the 1st time was successful, + * because it causes link startup to become unreliable. + */ + UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCE = 1 << 26, };
enum ufshcd_caps {
From: Adrian Hunter adrian.hunter@intel.com
[ Upstream commit d968e99488c4b08259a324a89e4ed17bf36561a4 ]
Link startup becomes unreliable for Intel Alder Lake based host controllers when a 2nd DME_LINKSTARTUP is issued unnecessarily. Employ UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCE to suppress that from happening.
Fixes: 7dc9fb47bc9a ("scsi: ufs: ufs-pci: Add support for Intel ADL") Cc: stable@vger.kernel.org Signed-off-by: Adrian Hunter adrian.hunter@intel.com Reviewed-by: Bart Van Assche bvanassche@acm.org Link: https://patch.msgid.link/20251024085918.31825-4-adrian.hunter@intel.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/ufs/host/ufshcd-pci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/ufs/host/ufshcd-pci.c b/drivers/ufs/host/ufshcd-pci.c index c38ea3395b2c1..5412855d6832e 100644 --- a/drivers/ufs/host/ufshcd-pci.c +++ b/drivers/ufs/host/ufshcd-pci.c @@ -460,7 +460,8 @@ static int ufs_intel_lkf_init(struct ufs_hba *hba) static int ufs_intel_adl_init(struct ufs_hba *hba) { hba->nop_out_timeout = 200; - hba->quirks |= UFSHCD_QUIRK_BROKEN_AUTO_HIBERN8; + hba->quirks |= UFSHCD_QUIRK_BROKEN_AUTO_HIBERN8 | + UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCE; hba->caps |= UFSHCD_CAP_WB_EN; return ufs_intel_common_init(hba); }
linux-stable-mirror@lists.linaro.org