[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