]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg/Ufs: Wait fDeviceInit be cleared by devices during init
authorHao Wu <hao.a.wu@intel.com>
Tue, 21 Mar 2017 05:22:36 +0000 (13:22 +0800)
committerHao Wu <hao.a.wu@intel.com>
Thu, 20 Apr 2017 05:09:51 +0000 (13:09 +0800)
In the origin codes, the host sets the fDeviceInit flag to initiate device
initialization, but does not check whether the device resets this flag
to indicate the device initialization is completed.

Details can be referred at UFS 2.0 Spec Section 14.2 - Flags.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Mateusz Albecki <mateusz.albecki@intel.com>
Signed-off-by: Hao Wu <hao.a.wu@intel.com>
Reviewed-by: Feng Tian <feng.tian@intel.com>
MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.c
MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.h
MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruHci.c

index 63b90de9918fce1abd7e467856177c2d93e62738..68a44367b539721b5eeb6e373715008f6c51aad5 100644 (file)
@@ -729,6 +729,48 @@ UfsPassThruDriverBindingSupported (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Finishes device initialization by setting fDeviceInit flag and waiting untill device responds by\r
+  clearing it.\r
+\r
+  @param[in] Private  Pointer to the UFS_PASS_THRU_PRIVATE_DATA.\r
+\r
+  @retval EFI_SUCCESS  The operation succeeds.\r
+  @retval Others       The operation fails.\r
+\r
+**/\r
+EFI_STATUS\r
+UfsFinishDeviceInitialization (\r
+  IN UFS_PASS_THRU_PRIVATE_DATA  *Private\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT8  DeviceInitStatus;\r
+  UINT8  Timeout;\r
+\r
+  DeviceInitStatus = 0xFF;\r
+\r
+  //\r
+  // The host enables the device initialization completion by setting fDeviceInit flag.\r
+  //\r
+  Status = UfsSetFlag (Private, UfsFlagDevInit);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Timeout = 5;\r
+  do {\r
+    Status = UfsReadFlag (Private, UfsFlagDevInit, &DeviceInitStatus);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+    MicroSecondDelay (1);\r
+    Timeout--;\r
+  } while (DeviceInitStatus != 0 && Timeout != 0);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 /**\r
   Starts a device controller or a bus controller.\r
 \r
@@ -777,7 +819,7 @@ UfsPassThruDriverBindingStart (
   UFS_PASS_THRU_PRIVATE_DATA            *Private;\r
   UINTN                                 UfsHcBase;\r
   UINT32                                Index;\r
-  UFS_CONFIG_DESC                       Config;\r
+  UFS_UNIT_DESC                         UnitDescriptor;\r
 \r
   Status    = EFI_SUCCESS;\r
   UfsHc     = NULL;\r
@@ -844,21 +886,9 @@ UfsPassThruDriverBindingStart (
     goto Error;\r
   }\r
 \r
-  //\r
-  // The host enables the device initialization completion by setting fDeviceInit flag.\r
-  //\r
-  Status = UfsSetFlag (Private, UfsFlagDevInit);\r
+  Status = UfsFinishDeviceInitialization (Private);\r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((DEBUG_ERROR, "Ufs Set fDeviceInit Flag Error, Status = %r\n", Status));\r
-    goto Error;\r
-  }\r
-\r
-  //\r
-  // Get Ufs Device's Lun Info by reading Configuration Descriptor.\r
-  //\r
-  Status = UfsRwDeviceDesc (Private, TRUE, UfsConfigDesc, 0, 0, &Config, sizeof (UFS_CONFIG_DESC));\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG ((DEBUG_ERROR, "Ufs Get Configuration Descriptor Error, Status = %r\n", Status));\r
+    DEBUG ((DEBUG_ERROR, "Device failed to finish initialization, Status = %r\n", Status));\r
     goto Error;\r
   }\r
 \r
@@ -867,9 +897,14 @@ UfsPassThruDriverBindingStart (
   // TODO: Parse device descriptor to decide if exposing RPMB LUN to upper layer for authentication access.\r
   //\r
   for (Index = 0; Index < 8; Index++) {\r
-    if (Config.UnitDescConfParams[Index].LunEn != 0) {\r
+    Status = UfsRwDeviceDesc (Private, TRUE, UfsUnitDesc, (UINT8) Index, 0, &UnitDescriptor, sizeof (UFS_UNIT_DESC));\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((DEBUG_ERROR, "Failed to read unit descriptor, index = %X, status = %r\n", Index, Status));\r
+      continue;\r
+    }\r
+    if (UnitDescriptor.LunEn == 0x1) {\r
+      DEBUG ((DEBUG_INFO, "UFS LUN %X is enabled\n", Index));\r
       Private->Luns.BitMask |= (BIT0 << Index);\r
-      DEBUG ((DEBUG_INFO, "Ufs Lun %d is enabled\n", Index));\r
     }\r
   }\r
 \r
index 7fc82bae7a3e0783ca083cc2f4e4b49a7b688d84..bdc64f779309039f9c451cf94c4e0ea1649bfbbc 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 \r
-  Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
@@ -122,16 +122,13 @@ typedef struct {
 \r
 typedef struct _UFS_DEVICE_MANAGEMENT_REQUEST_PACKET {\r
   UINT64           Timeout;\r
-  VOID             *InDataBuffer;\r
-  VOID             *OutDataBuffer;\r
+  VOID             *DataBuffer;\r
   UINT8            Opcode;\r
   UINT8            DescId;\r
   UINT8            Index;\r
   UINT8            Selector;\r
-  UINT32           InTransferLength;\r
-  UINT32           OutTransferLength;\r
+  UINT32           TransferLength;\r
   UINT8            DataDirection;\r
-  UINT8            Ocs;\r
 } UFS_DEVICE_MANAGEMENT_REQUEST_PACKET;\r
 \r
 //\r
@@ -716,6 +713,25 @@ UfsSetFlag (
   IN  UINT8                        FlagId\r
   );\r
 \r
+/**\r
+  Read specified flag from a UFS device.\r
+\r
+  @param[in]  Private           The pointer to the UFS_PASS_THRU_PRIVATE_DATA data structure.\r
+  @param[in]  FlagId            The ID of flag to be read.\r
+  @param[out] Value             The flag's value.\r
+\r
+  @retval EFI_SUCCESS           The flag was read successfully.\r
+  @retval EFI_DEVICE_ERROR      A device error occurred while attempting to read the flag.\r
+  @retval EFI_TIMEOUT           A timeout occurred while waiting for the completion of reading the flag.\r
+\r
+**/\r
+EFI_STATUS\r
+UfsReadFlag (\r
+  IN     UFS_PASS_THRU_PRIVATE_DATA   *Private,\r
+  IN     UINT8                        FlagId,\r
+     OUT UINT8                        *Value\r
+  );\r
+\r
 /**\r
   Read or write specified device descriptor of a UFS device.\r
 \r
@@ -743,6 +759,31 @@ UfsRwDeviceDesc (
   IN     UINT32                       DescSize\r
   );\r
 \r
+/**\r
+  Read or write specified attribute of a UFS device.\r
+\r
+  @param[in]      Private       The pointer to the UFS_PASS_THRU_PRIVATE_DATA data structure.\r
+  @param[in]      Read          The boolean variable to show r/w direction.\r
+  @param[in]      AttrId        The ID of Attribute.\r
+  @param[in]      Index         The Index of Attribute.\r
+  @param[in]      Selector      The Selector of Attribute.\r
+  @param[in, out] Attributes    The value of Attribute to be read or written.\r
+\r
+  @retval EFI_SUCCESS           The Attribute was read/written successfully.\r
+  @retval EFI_DEVICE_ERROR      A device error occurred while attempting to r/w the Attribute.\r
+  @retval EFI_TIMEOUT           A timeout occurred while waiting for the completion of r/w the Attribute.\r
+\r
+**/\r
+EFI_STATUS\r
+UfsRwAttributes (\r
+  IN     UFS_PASS_THRU_PRIVATE_DATA   *Private,\r
+  IN     BOOLEAN                      Read,\r
+  IN     UINT8                        AttrId,\r
+  IN     UINT8                        Index,\r
+  IN     UINT8                        Selector,\r
+  IN OUT UINT32                       *Attributes\r
+  );\r
+\r
 /**\r
   Sends NOP IN cmd to a UFS device for initialization process request.\r
   For more details, please refer to UFS 2.0 spec Figure 13.3.\r
index 822554cebbe29baaf6dd7f0596ce6f8761ff26f3..a19bdcc3cc397fdd36ab07aebbd58775b7870b6d 100644 (file)
@@ -602,32 +602,13 @@ UfsCreateDMCommandDesc (
   }\r
 \r
   DataDirection = Packet->DataDirection;\r
-  if (DataDirection == UfsDataIn) {\r
-    DataSize = Packet->InTransferLength;\r
-    Data     = Packet->InDataBuffer;\r
-  } else if (DataDirection == UfsDataOut) {\r
-    DataSize = Packet->OutTransferLength;\r
-    Data     = Packet->OutDataBuffer;\r
-  } else {\r
-    DataSize = 0;\r
-    Data     = NULL;\r
-  }\r
-\r
-  if (((Opcode != UtpQueryFuncOpcodeSetFlag) && (Opcode != UtpQueryFuncOpcodeClrFlag) && (Opcode != UtpQueryFuncOpcodeTogFlag))\r
-    && ((DataSize == 0) || (Data == NULL))) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (((Opcode == UtpQueryFuncOpcodeSetFlag) || (Opcode == UtpQueryFuncOpcodeClrFlag) || (Opcode == UtpQueryFuncOpcodeTogFlag))\r
-    && ((DataSize != 0) || (Data != NULL))) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if ((Opcode == UtpQueryFuncOpcodeWrAttr) && (DataSize != sizeof (UINT32))) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
+  DataSize      = Packet->TransferLength;\r
+  Data          = Packet->DataBuffer;\r
 \r
   if ((Opcode == UtpQueryFuncOpcodeWrDesc) || (Opcode == UtpQueryFuncOpcodeRdDesc)) {\r
+    if (DataSize == 0 || Data == NULL) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
     TotalLen = ROUNDUP8 (sizeof (UTP_QUERY_REQ_UPIU)) + ROUNDUP8 (sizeof (UTP_QUERY_RESP_UPIU)) + ROUNDUP8 (DataSize);\r
   } else {\r
     TotalLen = ROUNDUP8 (sizeof (UTP_QUERY_REQ_UPIU)) + ROUNDUP8 (sizeof (UTP_QUERY_RESP_UPIU));\r
@@ -868,60 +849,84 @@ UfsStopExecCmd (
 }\r
 \r
 /**\r
-  Read or write specified device descriptor of a UFS device.\r
+  Extracts return data from query response upiu.\r
 \r
-  @param[in]      Private       The pointer to the UFS_PASS_THRU_PRIVATE_DATA data structure.\r
-  @param[in]      Read          The boolean variable to show r/w direction.\r
-  @param[in]      DescId        The ID of device descriptor.\r
-  @param[in]      Index         The Index of device descriptor.\r
-  @param[in]      Selector      The Selector of device descriptor.\r
-  @param[in, out] Descriptor    The buffer of device descriptor to be read or written.\r
-  @param[in]      DescSize      The size of device descriptor buffer.\r
+  @param[in] Packet     Pointer to the UFS_DEVICE_MANAGEMENT_REQUEST_PACKET.\r
+  @param[in] QueryResp  Pointer to the query response.\r
 \r
-  @retval EFI_SUCCESS           The device descriptor was read/written successfully.\r
-  @retval EFI_DEVICE_ERROR      A device error occurred while attempting to r/w the device descriptor.\r
-  @retval EFI_TIMEOUT           A timeout occurred while waiting for the completion of r/w the device descriptor.\r
+  @retval EFI_INVALID_PARAMETER Packet or QueryResp are empty or opcode is invalid.\r
+  @retval EFI_SUCCESS           Data extracted.\r
 \r
 **/\r
 EFI_STATUS\r
-UfsRwDeviceDesc (\r
-  IN     UFS_PASS_THRU_PRIVATE_DATA   *Private,\r
-  IN     BOOLEAN                      Read,\r
-  IN     UINT8                        DescId,\r
-  IN     UINT8                        Index,\r
-  IN     UINT8                        Selector,\r
-  IN OUT VOID                         *Descriptor,\r
-  IN     UINT32                       DescSize\r
+UfsGetReturnDataFromQueryResponse (\r
+  IN UFS_DEVICE_MANAGEMENT_REQUEST_PACKET  *Packet,\r
+  IN UTP_QUERY_RESP_UPIU                   *QueryResp\r
   )\r
 {\r
-  EFI_STATUS                           Status;\r
-  UFS_DEVICE_MANAGEMENT_REQUEST_PACKET Packet;\r
-  UINT8                                Slot;\r
-  UTP_TRD                              *Trd;\r
-  UTP_QUERY_RESP_UPIU                  *QueryResp;\r
-  UINT32                               CmdDescSize;\r
-  UINT16                               ReturnDataSize;\r
-  VOID                                 *CmdDescHost;\r
-  VOID                                 *CmdDescMapping;\r
-  EDKII_UFS_HOST_CONTROLLER_PROTOCOL   *UfsHc;\r
+  UINT16  ReturnDataSize;\r
+  UINT32  ReturnData;\r
 \r
-  ZeroMem (&Packet, sizeof (UFS_DEVICE_MANAGEMENT_REQUEST_PACKET));\r
+  if (Packet == NULL || QueryResp == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
 \r
-  if (Read) {\r
-    Packet.DataDirection     = UfsDataIn;\r
-    Packet.InDataBuffer      = Descriptor;\r
-    Packet.InTransferLength  = DescSize;\r
-    Packet.Opcode            = UtpQueryFuncOpcodeRdDesc;\r
-  } else {\r
-    Packet.DataDirection     = UfsDataOut;\r
-    Packet.OutDataBuffer     = Descriptor;\r
-    Packet.OutTransferLength = DescSize;\r
-    Packet.Opcode            = UtpQueryFuncOpcodeWrDesc;\r
+  switch (Packet->Opcode) {\r
+    case UtpQueryFuncOpcodeRdDesc:\r
+      ReturnDataSize = QueryResp->Tsf.Length;\r
+      SwapLittleEndianToBigEndian ((UINT8*)&ReturnDataSize, sizeof (UINT16));\r
+      CopyMem (Packet->DataBuffer, (QueryResp + 1), ReturnDataSize);\r
+      Packet->TransferLength = ReturnDataSize;\r
+      break;\r
+    case UtpQueryFuncOpcodeWrDesc:\r
+      ReturnDataSize = QueryResp->Tsf.Length;\r
+      SwapLittleEndianToBigEndian ((UINT8*)&ReturnDataSize, sizeof (UINT16));\r
+      Packet->TransferLength = ReturnDataSize;\r
+      break;\r
+    case UtpQueryFuncOpcodeRdFlag:\r
+    case UtpQueryFuncOpcodeSetFlag:\r
+    case UtpQueryFuncOpcodeClrFlag:\r
+    case UtpQueryFuncOpcodeTogFlag:\r
+      CopyMem (Packet->DataBuffer, &QueryResp->Tsf.Value, sizeof (UINT8));\r
+      break;\r
+    case UtpQueryFuncOpcodeRdAttr:\r
+    case UtpQueryFuncOpcodeWrAttr:\r
+      ReturnData = QueryResp->Tsf.Value;\r
+      SwapLittleEndianToBigEndian ((UINT8*) &ReturnData, sizeof (UINT32));\r
+      CopyMem (Packet->DataBuffer, &ReturnData, sizeof (UINT32));\r
+      break;\r
+    default:\r
+      return EFI_INVALID_PARAMETER;\r
   }\r
-  Packet.DescId              = DescId;\r
-  Packet.Index               = Index;\r
-  Packet.Selector            = Selector;\r
-  Packet.Timeout             = UFS_TIMEOUT;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Creates Transfer Request descriptor and sends Query Request to the device.\r
+\r
+  @param[in] Private Pointer to the UFS_PASS_THRU_PRIVATE_DATA.\r
+  @param[in] Packet  Pointer to the UFS_DEVICE_MANAGEMENT_REQUEST_PACKET.\r
+\r
+  @retval EFI_SUCCESS           The device descriptor was read/written successfully.\r
+  @retval EFI_DEVICE_ERROR      A device error occurred while attempting to r/w the device descriptor.\r
+  @retval EFI_TIMEOUT           A timeout occurred while waiting for the completion of r/w the device descriptor.\r
+\r
+**/\r
+EFI_STATUS\r
+UfsSendDmRequestRetry (\r
+  IN UFS_PASS_THRU_PRIVATE_DATA            *Private,\r
+  IN UFS_DEVICE_MANAGEMENT_REQUEST_PACKET  *Packet\r
+  )\r
+{\r
+  UINT8                               Slot;\r
+  UTP_TRD                             *Trd;\r
+  VOID                                *CmdDescHost;\r
+  VOID                                *CmdDescMapping;\r
+  UINT32                              CmdDescSize;\r
+  EDKII_UFS_HOST_CONTROLLER_PROTOCOL  *UfsHc;\r
+  UTP_QUERY_RESP_UPIU                 *QueryResp;\r
+  EFI_STATUS                          Status;\r
 \r
   //\r
   // Find out which slot of transfer request list is available.\r
@@ -935,14 +940,12 @@ UfsRwDeviceDesc (
   //\r
   // Fill transfer request descriptor to this slot.\r
   //\r
-  Status = UfsCreateDMCommandDesc (Private, &Packet, Trd, &CmdDescHost, &CmdDescMapping);\r
+  Status = UfsCreateDMCommandDesc (Private, Packet, Trd, &CmdDescHost, &CmdDescMapping);\r
   if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "Failed to create DM command descriptor\n"));\r
     return Status;\r
   }\r
 \r
-  //\r
-  // Check the transfer request result.\r
-  //\r
   UfsHc       = Private->UfsHostController;\r
   QueryResp   = (UTP_QUERY_RESP_UPIU*)((UINT8*)CmdDescHost + Trd->RuO * sizeof (UINT32));\r
   ASSERT (QueryResp != NULL);\r
@@ -955,30 +958,23 @@ UfsRwDeviceDesc (
 \r
   //\r
   // Wait for the completion of the transfer request.\r
-  //  \r
-  Status = UfsWaitMemSet (Private, UFS_HC_UTRLDBR_OFFSET, BIT0 << Slot, 0, Packet.Timeout);\r
+  //\r
+  Status = UfsWaitMemSet (Private, UFS_HC_UTRLDBR_OFFSET, BIT0, 0, Packet->Timeout);\r
   if (EFI_ERROR (Status)) {\r
     goto Exit;\r
   }\r
 \r
-  if (QueryResp->QueryResp != 0) {\r
+  if (Trd->Ocs != 0 || QueryResp->QueryResp != UfsUtpQueryResponseSuccess) {\r
+    DEBUG ((DEBUG_ERROR, "Failed to send query request, OCS = %X, QueryResp = %X\n", Trd->Ocs, QueryResp->QueryResp));\r
     DumpQueryResponseResult (QueryResp->QueryResp);\r
     Status = EFI_DEVICE_ERROR;\r
     goto Exit;\r
   }\r
 \r
-  if (Trd->Ocs == 0) {\r
-    ReturnDataSize = QueryResp->Tsf.Length;\r
-    SwapLittleEndianToBigEndian ((UINT8*)&ReturnDataSize, sizeof (UINT16));\r
-\r
-    if (Read) {\r
-      CopyMem (Packet.InDataBuffer, (QueryResp + 1), ReturnDataSize);\r
-      Packet.InTransferLength = ReturnDataSize;\r
-    } else {\r
-      Packet.OutTransferLength = ReturnDataSize;\r
-    }\r
-  } else {\r
-    Status = EFI_DEVICE_ERROR;\r
+  Status = UfsGetReturnDataFromQueryResponse (Packet, QueryResp);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "Failed to get return data from query response\n"));\r
+    goto Exit;\r
   }\r
 \r
 Exit:\r
@@ -996,6 +992,87 @@ Exit:
   return Status;\r
 }\r
 \r
+/**\r
+  Sends Query Request to the device. Query is sent until device responds correctly or counter runs out.\r
+\r
+  @param[in] Private Pointer to the UFS_PASS_THRU_PRIVATE_DATA.\r
+  @param[in] Packet  Pointer to the UFS_DEVICE_MANAGEMENT_PACKET.\r
+\r
+  @retval EFI_SUCCESS           The device responded correctly to the Query request.\r
+  @retval EFI_DEVICE_ERROR      A device error occurred while waiting for the response from the device.\r
+  @retval EFI_TIMEOUT           A timeout occurred while waiting for the completion of the operation.\r
+\r
+**/\r
+EFI_STATUS\r
+UfsSendDmRequest (\r
+  IN UFS_PASS_THRU_PRIVATE_DATA            *Private,\r
+  IN UFS_DEVICE_MANAGEMENT_REQUEST_PACKET  *Packet\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT8       Retry;\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+  for (Retry = 0; Retry < 5; Retry ++) {\r
+    Status = UfsSendDmRequestRetry (Private, Packet);\r
+    if (!EFI_ERROR (Status)) {\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
+  DEBUG ((DEBUG_ERROR, "Failed to get response from the device after %d retries\n", Retry));\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Read or write specified device descriptor of a UFS device.\r
+\r
+  @param[in]      Private       The pointer to the UFS_PASS_THRU_PRIVATE_DATA data structure.\r
+  @param[in]      Read          The boolean variable to show r/w direction.\r
+  @param[in]      DescId        The ID of device descriptor.\r
+  @param[in]      Index         The Index of device descriptor.\r
+  @param[in]      Selector      The Selector of device descriptor.\r
+  @param[in, out] Descriptor    The buffer of device descriptor to be read or written.\r
+  @param[in]      DescSize      The size of device descriptor buffer.\r
+\r
+  @retval EFI_SUCCESS           The device descriptor was read/written successfully.\r
+  @retval EFI_DEVICE_ERROR      A device error occurred while attempting to r/w the device descriptor.\r
+  @retval EFI_TIMEOUT           A timeout occurred while waiting for the completion of r/w the device descriptor.\r
+\r
+**/\r
+EFI_STATUS\r
+UfsRwDeviceDesc (\r
+  IN     UFS_PASS_THRU_PRIVATE_DATA   *Private,\r
+  IN     BOOLEAN                      Read,\r
+  IN     UINT8                        DescId,\r
+  IN     UINT8                        Index,\r
+  IN     UINT8                        Selector,\r
+  IN OUT VOID                         *Descriptor,\r
+  IN     UINT32                       DescSize\r
+  )\r
+{\r
+  UFS_DEVICE_MANAGEMENT_REQUEST_PACKET Packet;\r
+\r
+  ZeroMem (&Packet, sizeof (UFS_DEVICE_MANAGEMENT_REQUEST_PACKET));\r
+\r
+  if (Read) {\r
+    Packet.DataDirection     = UfsDataIn;\r
+    Packet.Opcode            = UtpQueryFuncOpcodeRdDesc;\r
+  } else {\r
+    Packet.DataDirection     = UfsDataOut;\r
+    Packet.Opcode            = UtpQueryFuncOpcodeWrDesc;\r
+  }\r
+  Packet.DataBuffer          = Descriptor;\r
+  Packet.TransferLength      = DescSize;\r
+  Packet.DescId              = DescId;\r
+  Packet.Index               = Index;\r
+  Packet.Selector            = Selector;\r
+  Packet.Timeout             = UFS_TIMEOUT;\r
+\r
+  return UfsSendDmRequest (Private, &Packet);\r
+}\r
+\r
 /**\r
   Read or write specified attribute of a UFS device.\r
 \r
@@ -1021,16 +1098,7 @@ UfsRwAttributes (
   IN OUT UINT32                       *Attributes\r
   )\r
 {\r
-  EFI_STATUS                           Status;\r
   UFS_DEVICE_MANAGEMENT_REQUEST_PACKET Packet;\r
-  UINT8                                Slot;\r
-  UTP_TRD                              *Trd;\r
-  UTP_QUERY_RESP_UPIU                  *QueryResp;\r
-  UINT32                               CmdDescSize;\r
-  UINT32                               ReturnData;\r
-  VOID                                 *CmdDescHost;\r
-  VOID                                 *CmdDescMapping;\r
-  EDKII_UFS_HOST_CONTROLLER_PROTOCOL   *UfsHc;\r
 \r
   ZeroMem (&Packet, sizeof (UFS_DEVICE_MANAGEMENT_REQUEST_PACKET));\r
 \r
@@ -1041,77 +1109,13 @@ UfsRwAttributes (
     Packet.DataDirection     = UfsDataOut;\r
     Packet.Opcode            = UtpQueryFuncOpcodeWrAttr;\r
   }\r
+  Packet.DataBuffer          = Attributes;\r
   Packet.DescId              = AttrId;\r
   Packet.Index               = Index;\r
   Packet.Selector            = Selector;\r
   Packet.Timeout             = UFS_TIMEOUT;\r
 \r
-  //\r
-  // Find out which slot of transfer request list is available.\r
-  //\r
-  Status = UfsFindAvailableSlotInTrl (Private, &Slot);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-  \r
-  Trd = ((UTP_TRD*)Private->UtpTrlBase) + Slot;\r
-  //\r
-  // Fill transfer request descriptor to this slot.\r
-  //\r
-  Status = UfsCreateDMCommandDesc (Private, &Packet, Trd, &CmdDescHost, &CmdDescMapping);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Check the transfer request result.\r
-  //\r
-  UfsHc       = Private->UfsHostController;\r
-  QueryResp   = (UTP_QUERY_RESP_UPIU*)((UINT8*)CmdDescHost + Trd->RuO * sizeof (UINT32));\r
-  ASSERT (QueryResp != NULL);\r
-  CmdDescSize = Trd->RuO * sizeof (UINT32) + Trd->RuL * sizeof (UINT32);\r
-\r
-  //\r
-  // Start to execute the transfer request.\r
-  //\r
-  UfsStartExecCmd (Private, Slot);\r
-\r
-  //\r
-  // Wait for the completion of the transfer request.\r
-  //  \r
-  Status = UfsWaitMemSet (Private, UFS_HC_UTRLDBR_OFFSET, BIT0 << Slot, 0, Packet.Timeout);\r
-  if (EFI_ERROR (Status)) {\r
-    goto Exit;\r
-  }\r
-\r
-  if (QueryResp->QueryResp != 0) {\r
-    DumpQueryResponseResult (QueryResp->QueryResp);\r
-    Status = EFI_DEVICE_ERROR;\r
-    goto Exit;\r
-  }\r
-\r
-  if (Trd->Ocs == 0) {\r
-    ReturnData = QueryResp->Tsf.Value;\r
-    SwapLittleEndianToBigEndian ((UINT8*)&ReturnData, sizeof (UINT32));\r
-    *Attributes = ReturnData;\r
-  } else {\r
-    Status = EFI_DEVICE_ERROR;\r
-  }\r
-\r
-Exit:\r
-  UfsHc->Flush (UfsHc);\r
-\r
-  UfsStopExecCmd (Private, Slot);\r
-\r
-  if (CmdDescMapping != NULL) {\r
-    UfsHc->Unmap (UfsHc, CmdDescMapping);\r
-  }\r
-\r
-  if (CmdDescHost != NULL) {\r
-    UfsHc->FreeBuffer (UfsHc, EFI_SIZE_TO_PAGES (CmdDescSize), CmdDescHost);\r
-  }\r
-\r
-  return Status;\r
+  return UfsSendDmRequest (Private, &Packet);\r
 }\r
 \r
 /**\r
@@ -1135,15 +1139,7 @@ UfsRwFlags (
   IN OUT UINT8                        *Value\r
   )\r
 {\r
-  EFI_STATUS                           Status;\r
   UFS_DEVICE_MANAGEMENT_REQUEST_PACKET Packet;\r
-  UINT8                                Slot;\r
-  UTP_TRD                              *Trd;\r
-  UTP_QUERY_RESP_UPIU                  *QueryResp;\r
-  UINT32                               CmdDescSize;\r
-  VOID                                 *CmdDescHost;\r
-  VOID                                 *CmdDescMapping;\r
-  EDKII_UFS_HOST_CONTROLLER_PROTOCOL   *UfsHc;\r
 \r
   if (Value == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -1165,74 +1161,13 @@ UfsRwFlags (
       return EFI_INVALID_PARAMETER;\r
     }\r
   }\r
+  Packet.DataBuffer          = Value;\r
   Packet.DescId              = FlagId;\r
   Packet.Index               = 0;\r
   Packet.Selector            = 0;\r
   Packet.Timeout             = UFS_TIMEOUT;\r
 \r
-  //\r
-  // Find out which slot of transfer request list is available.\r
-  //\r
-  Status = UfsFindAvailableSlotInTrl (Private, &Slot);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Fill transfer request descriptor to this slot.\r
-  //\r
-  Trd    = ((UTP_TRD*)Private->UtpTrlBase) + Slot;\r
-  Status = UfsCreateDMCommandDesc (Private, &Packet, Trd, &CmdDescHost, &CmdDescMapping);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Check the transfer request result.\r
-  //\r
-  UfsHc       = Private->UfsHostController;\r
-  QueryResp   = (UTP_QUERY_RESP_UPIU*)((UINT8*)CmdDescHost + Trd->RuO * sizeof (UINT32));\r
-  ASSERT (QueryResp != NULL);\r
-  CmdDescSize = Trd->RuO * sizeof (UINT32) + Trd->RuL * sizeof (UINT32);\r
-\r
-  //\r
-  // Start to execute the transfer request.\r
-  //\r
-  UfsStartExecCmd (Private, Slot);\r
-\r
-  //\r
-  // Wait for the completion of the transfer request.\r
-  //  \r
-  Status = UfsWaitMemSet (Private, UFS_HC_UTRLDBR_OFFSET, BIT0 << Slot, 0, Packet.Timeout);\r
-  if (EFI_ERROR (Status)) {\r
-    goto Exit;\r
-  }\r
-\r
-  if (QueryResp->QueryResp != 0) {\r
-    DumpQueryResponseResult (QueryResp->QueryResp);\r
-    Status = EFI_DEVICE_ERROR;\r
-    goto Exit;\r
-  }\r
-\r
-  if (Trd->Ocs == 0) {\r
-    *Value = (UINT8)QueryResp->Tsf.Value;\r
-  } else {\r
-    Status = EFI_DEVICE_ERROR;\r
-  }\r
-\r
-Exit:\r
-  UfsHc->Flush (UfsHc);\r
-\r
-  UfsStopExecCmd (Private, Slot);\r
-\r
-  if (CmdDescMapping != NULL) {\r
-    UfsHc->Unmap (UfsHc, CmdDescMapping);\r
-  }\r
-  if (CmdDescHost != NULL) {\r
-    UfsHc->FreeBuffer (UfsHc, EFI_SIZE_TO_PAGES (CmdDescSize), CmdDescHost);\r
-  }\r
-\r
-  return Status;\r
+  return UfsSendDmRequest (Private, &Packet);\r
 }\r
 \r
 /**\r