From c7299ff33ebfabe35baa6656590d977dedfba5b0 Mon Sep 17 00:00:00 2001 From: Alexey Charkov Date: Mon, 16 Mar 2026 20:50:45 +0400 Subject: [PATCH 1/3] ufs: rockchip: Make use of controller resets Assert Rockchip UFS controller resets during initialization and HCE enable, as it is done by the Linux driver. This is required to make some UFS chips, such as Foresee FEUDNN064G-C2G0, work properly. Note that the resets were already requested in the probe function, just not used. Signed-off-by: Alexey Charkov Link: https://patch.msgid.link/20260316-rockchip-ufs-reset-v1-1-808eb017459a@flipper.net Signed-off-by: Neil Armstrong --- drivers/ufs/ufs-rockchip.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/ufs/ufs-rockchip.c b/drivers/ufs/ufs-rockchip.c index a13236c7f76..dc4b9b5c86d 100644 --- a/drivers/ufs/ufs-rockchip.c +++ b/drivers/ufs/ufs-rockchip.c @@ -19,13 +19,22 @@ #include "unipro.h" #include "ufs-rockchip.h" +static void ufs_rockchip_controller_reset(struct ufs_rockchip_host *host) +{ + reset_assert_bulk(&host->rsts); + udelay(1); + reset_deassert_bulk(&host->rsts); +} + static int ufs_rockchip_hce_enable_notify(struct ufs_hba *hba, enum ufs_notify_change_status status) { int err = 0; - if (status != POST_CHANGE) + if (status != POST_CHANGE) { + ufs_rockchip_controller_reset(dev_get_priv(hba->dev)); return 0; + } ufshcd_dme_reset(hba); ufshcd_dme_enable(hba); @@ -150,6 +159,8 @@ static int ufs_rockchip_common_init(struct ufs_hba *hba) return err; } + ufs_rockchip_controller_reset(host); + err = gpio_request_by_name(dev, "reset-gpios", 0, &host->device_reset, GPIOD_IS_OUT | GPIOD_ACTIVE_LOW); if (err) { From c7ebdb9871dfd6e170a6dfeee39be234c37a4b53 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 30 Mar 2026 01:11:36 +0200 Subject: [PATCH 2/3] ufs: core: Fix heap corruption due to out of bounds write The ufshcd_read_string_desc() can perform out of bounds write and corrupt heap in case the input utf-16 string contains code points which convert to anything more than plain 7-bit ASCII string. This occurs because utf16_to_utf8(dst, src, size) in U-Boot behaves differently than Linux utf16s_to_utf8s(..., maxlen), but the porting process did not take that into consideration. The U-Boot variant of the function converts up to $size utf-16 fixed-length 16-bit input characters into as many 1..4 Byte long variable-length utf-8 output characters. That means for 16 Byte input, the output can be up to 64 Bytes long. The Linux variant converts up utf-16 input into up to $maxlen Bytes worth of utf-8 output, but stops at the $maxlen limit. That means for 16 Byte input with maxlen=32, the processing will stop after writing 32 output Bytes. In case of U-Boot, use of utf16_to_utf8() leads to potential corruption of data past the $size Bytes and therefore corruption of surrounding content on the heap. The fix is as simple, allocate buffer that is sufficient to fit the utf-8 string. The rest of the code in ufshcd_read_string_desc() does correctly limit the buffer to fit into the DMA descriptor afterward. Signed-off-by: Marek Vasut Link: https://patch.msgid.link/20260329231151.332108-1-marek.vasut+renesas@mailbox.org Signed-off-by: Neil Armstrong --- drivers/ufs/ufs-uclass.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/ufs/ufs-uclass.c b/drivers/ufs/ufs-uclass.c index 81fd431f951..6a51f337e47 100644 --- a/drivers/ufs/ufs-uclass.c +++ b/drivers/ufs/ufs-uclass.c @@ -1751,7 +1751,15 @@ static int ufshcd_read_string_desc(struct ufs_hba *hba, int desc_index, goto out; } - buff_ascii = kmalloc(ascii_len, GFP_KERNEL); + /* + * utf-8 is encoded using up to 4-Bytes per character, + * however, we only allocate such a buffer because the + * utf16_to_utf8() converts the entire $ascii_len worth + * of input characters into up to 4-Byte long utf-8 + * characters. The rest of the function uses only up to + * $ascii_len bytes of that utf-8 string. + */ + buff_ascii = kmalloc(ascii_len * 4, GFP_KERNEL); if (!buff_ascii) { err = -ENOMEM; goto out; From 1089ed95f54e43ddbbe19712b69d9ace374e572c Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 15 Apr 2026 23:58:08 +0200 Subject: [PATCH 3/3] ufs: rcar-gen5: Update line reset configuration Synchronize line reset configuration with SDK 4.28 parameters. These values are programmed into the PHY. Signed-off-by: Marek Vasut Link: https://patch.msgid.link/20260415215837.448867-1-marek.vasut+renesas@mailbox.org Signed-off-by: Neil Armstrong --- drivers/ufs/ufs-renesas-rcar-gen5.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/ufs/ufs-renesas-rcar-gen5.c b/drivers/ufs/ufs-renesas-rcar-gen5.c index a21ae3f390e..a9473cd60b1 100644 --- a/drivers/ufs/ufs-renesas-rcar-gen5.c +++ b/drivers/ufs/ufs-renesas-rcar-gen5.c @@ -92,14 +92,14 @@ static int ufs_renesas_pre_init(struct ufs_hba *hba) ufs_dme_command(hba, 0x00000002, 0x81010000, 0x00000000, 0x00000005); ufs_dme_command(hba, 0x00000002, 0x81150000, 0x00000000, 0x00000001); ufs_dme_command(hba, 0x00000002, 0x81180000, 0x00000000, 0x00000001); - ufs_dme_command(hba, 0x00000002, 0x80090000, 0x00000000, 0x00000000); - ufs_dme_command(hba, 0x00000002, 0x800a0000, 0x00000000, 0x000000c8); - ufs_dme_command(hba, 0x00000002, 0x80090001, 0x00000000, 0x00000000); - ufs_dme_command(hba, 0x00000002, 0x800a0001, 0x00000000, 0x000000c8); - ufs_dme_command(hba, 0x00000002, 0x800a0004, 0x00000000, 0x00000000); - ufs_dme_command(hba, 0x00000002, 0x800b0004, 0x00000000, 0x00000064); - ufs_dme_command(hba, 0x00000002, 0x800a0005, 0x00000000, 0x00000000); - ufs_dme_command(hba, 0x00000002, 0x800b0005, 0x00000000, 0x00000064); + ufs_dme_command(hba, 0x00000002, 0x80090000, 0x00000000, 0x0000000c); + ufs_dme_command(hba, 0x00000002, 0x800a0000, 0x00000000, 0x00000080); + ufs_dme_command(hba, 0x00000002, 0x80090001, 0x00000000, 0x0000000c); + ufs_dme_command(hba, 0x00000002, 0x800a0001, 0x00000000, 0x00000080); + ufs_dme_command(hba, 0x00000002, 0x800a0004, 0x00000000, 0x00000003); + ufs_dme_command(hba, 0x00000002, 0x800b0004, 0x00000000, 0x000000ea); + ufs_dme_command(hba, 0x00000002, 0x800a0005, 0x00000000, 0x00000003); + ufs_dme_command(hba, 0x00000002, 0x800b0005, 0x00000000, 0x000000ea); ufs_dme_command(hba, 0x00000002, 0xd0850000, 0x00000000, 0x00000001); writew(0x0001, priv->phy_base + 0x20000);