[PATCH] UFS error handling for reject upiu.
Deenadayalan K
dayalancse at gmail.com
Sun Jun 21 12:28:47 CEST 2026
>From 8ce84d4e1e9c34d7b36d40e5e5678da52070af02 Mon Sep 17 00:00:00 2001
From: Deenadayalan K <dayalancse at gmail.com>
Date: Sun, 21 Jun 2026 15:15:16 +0530
Subject: [PATCH] UFS error handling for reject upiu.
ufshcd_handle_reject_upiu - Handle and display REJECT UPIU fields
Per UFS spec, the device sends a REJECT UPIU when it
receives a UPIU with an invalid Transaction Type. This function extracts
and displays the REJECT UPIU header fields for diagnostics.
task tag appears default 0 for UPIUs, it is a unique id for each UPIU
If UFS host controller gets a reject upiu for the request UPIU then
it does make sense to reattempt to issue the same request UPIU again
a possible scenario where UFS device is not supporting though it is a valid
transaction type.
Signed-off-by: Deenadayalan K <dayalancse at gmail.com>
---
drivers/ufs/ufs-uclass.c | 60 ++++++++++++++++++++++++++++++++++------
1 file changed, 52 insertions(+), 8 deletions(-)
diff --git a/drivers/ufs/ufs-uclass.c b/drivers/ufs/ufs-uclass.c
index 6a51f337e47..fcafebd5203 100644
--- a/drivers/ufs/ufs-uclass.c
+++ b/drivers/ufs/ufs-uclass.c
@@ -1020,6 +1020,56 @@ static int ufshcd_copy_query_response(struct ufs_hba
*hba)
return 0;
}
+/**
+ * ufshcd_handle_reject_upiu - Handle and display REJECT UPIU fields
+ *
+ * Per UFS spec, the device sends a REJECT UPIU when it
+ * receives a UPIU with an invalid Transaction Type. This function extracts
+ * and displays the REJECT UPIU header fields for diagnostics.
+ */
+static int ufshcd_handle_reject_upiu(struct ufs_hba *hba)
+{
+ u32 dword_0 = be32_to_cpu(hba->ucd_rsp_ptr->header.dword_0);
+ u32 dword_1 = be32_to_cpu(hba->ucd_rsp_ptr->header.dword_1);
+ u8 *rsp = (u8 *)&hba->ucd_rsp_ptr->header;
+ u8 trans_type = (dword_0 >> 24) & 0xFF;
+ u8 hd = (trans_type >> 7) & 0x1;
+ u8 dd = (trans_type >> 6) & 0x1;
+ u8 flags = (dword_0 >> 16) & 0xFF;
+ u8 lun = (dword_0 >> 8) & 0xFF;
+ u8 task_tag = dword_0 & 0xFF;
+ u8 iid = (dword_1 >> 24) & 0x0F;
+ u8 ext_iid = (dword_1 >> 20) & 0x0F;
+ u8 response = (dword_1 >> 8) & 0xFF;
+ u8 basic_hdr_status = rsp[12];
+ u8 e2e_status = rsp[14];
+
+ dev_err(hba->dev, "%s: Reject UPIU: LUN=0x%02x Task Tag=0x%02x IID=0x%x
EXT_IID=0x%x Response=0x%02x Basic Header Status=0x%02x E2E Status=0x%02x",
+ __func__, lun, task_tag, iid, ext_iid, response, basic_hdr_status,
e2e_status);
+
+ if (response != 0x01)
+ dev_warn(hba->dev, "Reject UPIU: Unexpected Response=0x%02x (expected
0x01 Target Failure)\n",
+ response);
+
+ if (hd && (e2e_status & BIT(0)))
+ dev_err(hba->dev, "Reject UPIU: Header E2ECRC error detected (HD=1, E2E
Status bit0=1)\n");
+
+ if (dd && (e2e_status & BIT(1)))
+ dev_err(hba->dev, "Reject UPIU: Data E2ECRC error detected (DD=1, E2E
Status bit1=1)\n");
+
+ if (!hd && !dd && (e2e_status & (BIT(0) | BIT(1))))
+ dev_warn(hba->dev, "Reject UPIU: Unexpected E2E Status=0x%02x when CRC is
disabled (HD=0, DD=0)\n",
+ e2e_status);
+
+ /* task tag appears default 0 for UPIUs, it is a unique id for each UPIU
+ * If UFS host controller gets a reject upiu for the request UPIU then
+ * it does make sense to reattempt to issue the same request UPIU again
+ * a possible scenario where UFS device is not supporting though it is a
valid
+ * transaction type.
+ */
+ return -EPERM;
+}
+
/**
* ufshcd_exec_dev_cmd - API for sending device management requests
*/
@@ -1053,10 +1103,7 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba,
enum dev_cmd_type cmd_type,
err = ufshcd_copy_query_response(hba);
break;
case UPIU_TRANSACTION_REJECT_UPIU:
- /* TODO: handle Reject UPIU Response */
- err = -EPERM;
- dev_err(hba->dev, "%s: Reject UPIU not fully implemented\n",
- __func__);
+ err = ufshcd_handle_reject_upiu(hba);
break;
default:
err = -EINVAL;
@@ -1687,10 +1734,7 @@ static int ufs_scsi_exec(struct udevice *scsi_dev,
struct scsi_cmd *pccb)
break;
case UPIU_TRANSACTION_REJECT_UPIU:
- /* TODO: handle Reject UPIU Response */
- dev_err(hba->dev,
- "Reject UPIU not fully implemented\n");
- return -EINVAL;
+ return ufshcd_handle_reject_upiu(hba);
default:
dev_err(hba->dev,
"Unexpected request response code = %x\n",
More information about the U-Boot
mailing list