public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH 0/2] Implementation of UFS Device Config Protocol
@ 2017-07-20  2:18 Hao Wu
  2017-07-20  2:18 ` [PATCH 1/2] MdeModulePkg/UfsPassThruDxe: Add impl " Hao Wu
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Hao Wu @ 2017-07-20  2:18 UTC (permalink / raw)
  To: edk2-devel; +Cc: Hao Wu, Star Zeng

The series adds the implementation of UFS Device Config Protocol in the
UfsPassThruDxe driver.

Also, the series resolves a 'Write Descriptor' operation failure issue in
the UFS drivers.

Cc: Star Zeng <star.zeng@intel.com>

Hao Wu (2):
  MdeModulePkg/UfsPassThruDxe: Add impl of UFS Device Config Protocol
  MdeModulePkg/Ufs: Set 'Data Segment Length' field for Write Descriptor

 MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsHci.c                |   3 +
 MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsDevConfigProtocol.c | 196 ++++++++++++++++++++
 MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.c          |  24 ++-
 MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.h          | 133 ++++++++++++-
 MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruDxe.inf     |   4 +-
 MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruHci.c       |  43 ++++-
 6 files changed, 389 insertions(+), 14 deletions(-)
 create mode 100644 MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsDevConfigProtocol.c

-- 
2.12.0.windows.1



^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/2] MdeModulePkg/UfsPassThruDxe: Add impl of UFS Device Config Protocol
  2017-07-20  2:18 [PATCH 0/2] Implementation of UFS Device Config Protocol Hao Wu
@ 2017-07-20  2:18 ` Hao Wu
  2017-07-20  2:18 ` [PATCH 2/2] MdeModulePkg/Ufs: Set 'Data Segment Length' field for Write Descriptor Hao Wu
  2017-08-02  8:08 ` [PATCH 0/2] Implementation of UFS Device Config Protocol Zeng, Star
  2 siblings, 0 replies; 4+ messages in thread
From: Hao Wu @ 2017-07-20  2:18 UTC (permalink / raw)
  To: edk2-devel; +Cc: Hao Wu, Star Zeng

Cc: Star Zeng <star.zeng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Hao Wu <hao.a.wu@intel.com>
---
 MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsDevConfigProtocol.c | 196 ++++++++++++++++++++
 MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.c          |  24 ++-
 MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.h          | 133 ++++++++++++-
 MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruDxe.inf     |   4 +-
 MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruHci.c       |  40 +++-
 5 files changed, 383 insertions(+), 14 deletions(-)

diff --git a/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsDevConfigProtocol.c b/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsDevConfigProtocol.c
new file mode 100644
index 0000000000..1b5a7cef61
--- /dev/null
+++ b/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsDevConfigProtocol.c
@@ -0,0 +1,196 @@
+/** @file
+  The implementation of the EFI UFS Device Config Protocol.
+
+  Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "UfsPassThru.h"
+
+/**
+  Read or write specified device descriptor of a UFS device.
+
+  The function is used to read/write UFS device descriptors. The consumer of this API is
+  responsible for allocating the data buffer pointed by Descriptor.
+
+  @param[in]      This          The pointer to the EFI_UFS_DEVICE_CONFIG_PROTOCOL instance.
+  @param[in]      Read          The boolean variable to show r/w direction.
+  @param[in]      DescId        The ID of device descriptor.
+  @param[in]      Index         The Index of device descriptor.
+  @param[in]      Selector      The Selector of device descriptor.
+  @param[in, out] Descriptor    The buffer of device descriptor to be read or written.
+  @param[in, out] DescSize      The size of device descriptor buffer. On input, the size, in bytes,
+                                of the data buffer specified by Descriptor. On output, the number
+                                of bytes that were actually transferred.
+
+  @retval EFI_SUCCESS           The device descriptor is read/written successfully.
+  @retval EFI_INVALID_PARAMETER This is NULL or Descriptor is NULL or DescSize is NULL.
+                                DescId, Index and Selector are invalid combination to point to a
+                                type of UFS device descriptor.
+  @retval EFI_DEVICE_ERROR      The device descriptor is not read/written successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+UfsRwUfsDescriptor (
+  IN EFI_UFS_DEVICE_CONFIG_PROTOCOL    *This,
+  IN BOOLEAN                           Read,
+  IN UINT8                             DescId,
+  IN UINT8                             Index,
+  IN UINT8                             Selector,
+  IN OUT UINT8                         *Descriptor,
+  IN OUT UINT32                        *DescSize
+  )
+{
+  EFI_STATUS                    Status;
+  UFS_PASS_THRU_PRIVATE_DATA    *Private;
+
+  Private = UFS_PASS_THRU_PRIVATE_DATA_FROM_DEV_CONFIG (This);
+
+  if ((This == NULL) || (Descriptor == NULL) || (DescSize == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = UfsRwDeviceDesc (
+             Private,
+             Read,
+             DescId,
+             Index,
+             Selector,
+             Descriptor,
+             DescSize
+             );
+  if (Status == EFI_TIMEOUT) {
+    Status = EFI_DEVICE_ERROR;
+  }
+  return Status;
+}
+
+/**
+  Read or write specified flag of a UFS device.
+
+  The function is used to read/write UFS flag descriptors. The consumer of this API is responsible
+  for allocating the buffer pointed by Flag. The buffer size is 1 byte as UFS flag descriptor is
+  just a single Boolean value that represents a TRUE or FALSE, '0' or '1', ON or OFF type of value.
+
+  @param[in]      This          The pointer to the EFI_UFS_DEVICE_CONFIG_PROTOCOL instance.
+  @param[in]      Read          The boolean variable to show r/w direction.
+  @param[in]      FlagId        The ID of flag to be read or written.
+  @param[in, out] Flag          The buffer to set or clear flag.
+
+  @retval EFI_SUCCESS           The flag descriptor is set/clear successfully.
+  @retval EFI_INVALID_PARAMETER This is NULL or Flag is NULL.
+                                FlagId is an invalid UFS flag ID.
+  @retval EFI_DEVICE_ERROR      The flag is not set/clear successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+UfsRwUfsFlag (
+  IN EFI_UFS_DEVICE_CONFIG_PROTOCOL    *This,
+  IN BOOLEAN                           Read,
+  IN UINT8                             FlagId,
+  IN OUT UINT8                         *Flag
+  )
+{
+  EFI_STATUS                    Status;
+  UFS_PASS_THRU_PRIVATE_DATA    *Private;
+
+  Private = UFS_PASS_THRU_PRIVATE_DATA_FROM_DEV_CONFIG (This);
+
+  if ((This == NULL) || (Flag == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = UfsRwFlags (Private, Read, FlagId, Flag);
+  if (Status == EFI_TIMEOUT) {
+    Status = EFI_DEVICE_ERROR;
+  }
+  return Status;
+}
+
+/**
+  Read or write specified attribute of a UFS device.
+
+  The function is used to read/write UFS attributes. The consumer of this API is responsible for
+  allocating the data buffer pointed by Attribute.
+
+  @param[in]      This          The pointer to the EFI_UFS_DEVICE_CONFIG_PROTOCOL instance.
+  @param[in]      Read          The boolean variable to show r/w direction.
+  @param[in]      AttrId        The ID of Attribute.
+  @param[in]      Index         The Index of Attribute.
+  @param[in]      Selector      The Selector of Attribute.
+  @param[in, out] Attribute     The buffer of Attribute to be read or written.
+  @param[in, out] AttrSize      The size of Attribute buffer. On input, the size, in bytes, of the
+                                data buffer specified by Attribute. On output, the number of bytes
+                                that were actually transferred.
+
+  @retval EFI_SUCCESS           The attribute is read/written successfully.
+  @retval EFI_INVALID_PARAMETER This is NULL or Attribute is NULL or AttrSize is NULL.
+                                AttrId, Index and Selector are invalid combination to point to a
+                                type of UFS attribute.
+  @retval EFI_DEVICE_ERROR      The attribute is not read/written successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+UfsRwUfsAttribute (
+  IN EFI_UFS_DEVICE_CONFIG_PROTOCOL    *This,
+  IN BOOLEAN                           Read,
+  IN UINT8                             AttrId,
+  IN UINT8                             Index,
+  IN UINT8                             Selector,
+  IN OUT UINT8                         *Attribute,
+  IN OUT UINT32                        *AttrSize
+  )
+{
+  EFI_STATUS                    Status;
+  UFS_PASS_THRU_PRIVATE_DATA    *Private;
+  UINT32                        Attribute32;
+
+  Private = UFS_PASS_THRU_PRIVATE_DATA_FROM_DEV_CONFIG (This);
+  Attribute32 = 0;
+
+  if ((This == NULL) || (Attribute == NULL) || (AttrSize == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // According to UFS Version 2.1 Spec (JESD220C) Section 14.3, the size of a attribute will not
+  // exceed 32-bit.
+  //
+  if (*AttrSize > 4) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (!Read) {
+    CopyMem (&Attribute32, Attribute, *AttrSize);
+  }
+
+  Status = UfsRwAttributes (
+             Private,
+             Read,
+             AttrId,
+             Index,
+             Selector,
+             &Attribute32
+             );
+  if (!EFI_ERROR (Status)) {
+    if (Read) {
+      CopyMem (Attribute, &Attribute32, *AttrSize);
+    }
+  } else {
+    *AttrSize = 0;
+    if (Status == EFI_TIMEOUT) {
+      Status = EFI_DEVICE_ERROR;
+    }
+  }
+  return Status;
+}
diff --git a/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.c b/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.c
index e27f4fbab1..e24eb40333 100644
--- a/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.c
+++ b/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.c
@@ -34,6 +34,11 @@ UFS_PASS_THRU_PRIVATE_DATA gUfsPassThruTemplate = {
     UfsPassThruResetTargetLun,
     UfsPassThruGetNextTarget
   },
+  {                               // UfsDevConfig
+    UfsRwUfsDescriptor,
+    UfsRwUfsFlag,
+    UfsRwUfsAttribute
+  },
   0,                              // UfsHostController
   0,                              // UfsHcBase
   0,                              // Capabilities
@@ -820,6 +825,7 @@ UfsPassThruDriverBindingStart (
   UINTN                                 UfsHcBase;
   UINT32                                Index;
   UFS_UNIT_DESC                         UnitDescriptor;
+  UINT32                                UnitDescriptorSize;
 
   Status    = EFI_SUCCESS;
   UfsHc     = NULL;
@@ -896,8 +902,9 @@ UfsPassThruDriverBindingStart (
   // Check if 8 common luns are active and set corresponding bit mask.
   // TODO: Parse device descriptor to decide if exposing RPMB LUN to upper layer for authentication access.
   //
+  UnitDescriptorSize = sizeof (UFS_UNIT_DESC);
   for (Index = 0; Index < 8; Index++) {
-    Status = UfsRwDeviceDesc (Private, TRUE, UfsUnitDesc, (UINT8) Index, 0, &UnitDescriptor, sizeof (UFS_UNIT_DESC));
+    Status = UfsRwDeviceDesc (Private, TRUE, UfsUnitDesc, (UINT8) Index, 0, &UnitDescriptor, &UnitDescriptorSize);
     if (EFI_ERROR (Status)) {
       DEBUG ((DEBUG_ERROR, "Failed to read unit descriptor, index = %X, status = %r\n", Index, Status));
       continue;
@@ -933,11 +940,13 @@ UfsPassThruDriverBindingStart (
     goto Error;
   }
 
-  Status = gBS->InstallProtocolInterface (
+  Status = gBS->InstallMultipleProtocolInterfaces (
                   &Controller,
                   &gEfiExtScsiPassThruProtocolGuid,
-                  EFI_NATIVE_INTERFACE,
-                  &(Private->ExtScsiPassThru)
+                  &(Private->ExtScsiPassThru),
+                  &gEfiUfsDeviceConfigProtocolGuid,
+                  &(Private->UfsDevConfig),
+                  NULL
                   );
   ASSERT_EFI_ERROR (Status);
 
@@ -1057,10 +1066,13 @@ UfsPassThruDriverBindingStop (
     }
   }
 
-  Status = gBS->UninstallProtocolInterface (
+  Status = gBS->UninstallMultipleProtocolInterfaces (
                   Controller,
                   &gEfiExtScsiPassThruProtocolGuid,
-                  &(Private->ExtScsiPassThru)
+                  &(Private->ExtScsiPassThru),
+                  &gEfiUfsDeviceConfigProtocolGuid,
+                  &(Private->UfsDevConfig),
+                  NULL
                   );
 
   if (EFI_ERROR (Status)) {
diff --git a/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.h b/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.h
index bdc64f7793..6c71983258 100644
--- a/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.h
+++ b/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.h
@@ -17,6 +17,7 @@
 #include <Uefi.h>
 
 #include <Protocol/ScsiPassThruExt.h>
+#include <Protocol/UfsDeviceConfig.h>
 #include <Protocol/UfsHostController.h>
 
 #include <Library/DebugLib.h>
@@ -63,6 +64,7 @@ typedef struct _UFS_PASS_THRU_PRIVATE_DATA {
   EFI_HANDLE                          Handle;
   EFI_EXT_SCSI_PASS_THRU_MODE         ExtScsiPassThruMode;
   EFI_EXT_SCSI_PASS_THRU_PROTOCOL     ExtScsiPassThru;
+  EFI_UFS_DEVICE_CONFIG_PROTOCOL      UfsDevConfig;
   EDKII_UFS_HOST_CONTROLLER_PROTOCOL  *UfsHostController;
   UINTN                               UfsHcBase;
   UINT32                              Capabilities;
@@ -120,6 +122,13 @@ typedef struct {
       UFS_PASS_THRU_SIG \
       )
 
+#define UFS_PASS_THRU_PRIVATE_DATA_FROM_DEV_CONFIG(a) \
+  CR (a, \
+      UFS_PASS_THRU_PRIVATE_DATA, \
+      UfsDevConfig, \
+      UFS_PASS_THRU_SIG \
+      )
+
 typedef struct _UFS_DEVICE_MANAGEMENT_REQUEST_PACKET {
   UINT64           Timeout;
   VOID             *DataBuffer;
@@ -733,6 +742,27 @@ UfsReadFlag (
   );
 
 /**
+  Read or write specified flag of a UFS device.
+
+  @param[in]      Private       The pointer to the UFS_PASS_THRU_PRIVATE_DATA data structure.
+  @param[in]      Read          The boolean variable to show r/w direction.
+  @param[in]      FlagId        The ID of flag to be read or written.
+  @param[in, out] Value         The value to set or clear flag.
+
+  @retval EFI_SUCCESS           The flag was read/written successfully.
+  @retval EFI_DEVICE_ERROR      A device error occurred while attempting to r/w the flag.
+  @retval EFI_TIMEOUT           A timeout occurred while waiting for the completion of r/w the flag.
+
+**/
+EFI_STATUS
+UfsRwFlags (
+  IN     UFS_PASS_THRU_PRIVATE_DATA   *Private,
+  IN     BOOLEAN                      Read,
+  IN     UINT8                        FlagId,
+  IN OUT UINT8                        *Value
+  );
+
+/**
   Read or write specified device descriptor of a UFS device.
 
   @param[in]      Private       The pointer to the UFS_PASS_THRU_PRIVATE_DATA data structure.
@@ -741,7 +771,9 @@ UfsReadFlag (
   @param[in]      Index         The Index of device descriptor.
   @param[in]      Selector      The Selector of device descriptor.
   @param[in, out] Descriptor    The buffer of device descriptor to be read or written.
-  @param[in]      DescSize      The size of device descriptor buffer.
+  @param[in, out] DescSize      The size of device descriptor buffer. On input, the size, in bytes,
+                                of the data buffer specified by Descriptor. On output, the number
+                                of bytes that were actually transferred.
 
   @retval EFI_SUCCESS           The device descriptor was read/written successfully.
   @retval EFI_DEVICE_ERROR      A device error occurred while attempting to r/w the device descriptor.
@@ -756,7 +788,7 @@ UfsRwDeviceDesc (
   IN     UINT8                        Index,
   IN     UINT8                        Selector,
   IN OUT VOID                         *Descriptor,
-  IN     UINT32                       DescSize
+  IN OUT UINT32                       *DescSize
   );
 
 /**
@@ -833,6 +865,103 @@ SignalCallerEvent (
   IN UFS_PASS_THRU_TRANS_REQ         *TransReq
   );
 
+/**
+  Read or write specified device descriptor of a UFS device.
+
+  The function is used to read/write UFS device descriptors. The consumer of this API is
+  responsible for allocating the data buffer pointed by Descriptor.
+
+  @param[in]      This          The pointer to the EFI_UFS_DEVICE_CONFIG_PROTOCOL instance.
+  @param[in]      Read          The boolean variable to show r/w direction.
+  @param[in]      DescId        The ID of device descriptor.
+  @param[in]      Index         The Index of device descriptor.
+  @param[in]      Selector      The Selector of device descriptor.
+  @param[in, out] Descriptor    The buffer of device descriptor to be read or written.
+  @param[in, out] DescSize      The size of device descriptor buffer. On input, the size, in bytes,
+                                of the data buffer specified by Descriptor. On output, the number
+                                of bytes that were actually transferred.
+
+  @retval EFI_SUCCESS           The device descriptor is read/written successfully.
+  @retval EFI_INVALID_PARAMETER This is NULL or Descriptor is NULL or DescSize is NULL.
+                                DescId, Index and Selector are invalid combination to point to a
+                                type of UFS device descriptor.
+  @retval EFI_DEVICE_ERROR      The device descriptor is not read/written successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+UfsRwUfsDescriptor (
+  IN EFI_UFS_DEVICE_CONFIG_PROTOCOL    *This,
+  IN BOOLEAN                           Read,
+  IN UINT8                             DescId,
+  IN UINT8                             Index,
+  IN UINT8                             Selector,
+  IN OUT UINT8                         *Descriptor,
+  IN OUT UINT32                        *DescSize
+  );
+
+/**
+  Read or write specified flag of a UFS device.
+
+  The function is used to read/write UFS flag descriptors. The consumer of this API is responsible
+  for allocating the buffer pointed by Flag. The buffer size is 1 byte as UFS flag descriptor is
+  just a single Boolean value that represents a TRUE or FALSE, '0' or '1', ON or OFF type of value.
+
+  @param[in]      This          The pointer to the EFI_UFS_DEVICE_CONFIG_PROTOCOL instance.
+  @param[in]      Read          The boolean variable to show r/w direction.
+  @param[in]      FlagId        The ID of flag to be read or written.
+  @param[in, out] Flag          The buffer to set or clear flag.
+
+  @retval EFI_SUCCESS           The flag descriptor is set/clear successfully.
+  @retval EFI_INVALID_PARAMETER This is NULL or Flag is NULL.
+                                FlagId is an invalid UFS flag ID.
+  @retval EFI_DEVICE_ERROR      The flag is not set/clear successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+UfsRwUfsFlag (
+  IN EFI_UFS_DEVICE_CONFIG_PROTOCOL    *This,
+  IN BOOLEAN                           Read,
+  IN UINT8                             FlagId,
+  IN OUT UINT8                         *Flag
+  );
+
+/**
+  Read or write specified attribute of a UFS device.
+
+  The function is used to read/write UFS attributes. The consumer of this API is responsible for
+  allocating the data buffer pointed by Attribute.
+
+  @param[in]      This          The pointer to the EFI_UFS_DEVICE_CONFIG_PROTOCOL instance.
+  @param[in]      Read          The boolean variable to show r/w direction.
+  @param[in]      AttrId        The ID of Attribute.
+  @param[in]      Index         The Index of Attribute.
+  @param[in]      Selector      The Selector of Attribute.
+  @param[in, out] Attribute     The buffer of Attribute to be read or written.
+  @param[in, out] AttrSize      The size of Attribute buffer. On input, the size, in bytes, of the
+                                data buffer specified by Attribute. On output, the number of bytes
+                                that were actually transferred.
+
+  @retval EFI_SUCCESS           The attribute is read/written successfully.
+  @retval EFI_INVALID_PARAMETER This is NULL or Attribute is NULL or AttrSize is NULL.
+                                AttrId, Index and Selector are invalid combination to point to a
+                                type of UFS attribute.
+  @retval EFI_DEVICE_ERROR      The attribute is not read/written successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+UfsRwUfsAttribute (
+  IN EFI_UFS_DEVICE_CONFIG_PROTOCOL    *This,
+  IN BOOLEAN                           Read,
+  IN UINT8                             AttrId,
+  IN UINT8                             Index,
+  IN UINT8                             Selector,
+  IN OUT UINT8                         *Attribute,
+  IN OUT UINT32                        *AttrSize
+  );
+
 extern EFI_COMPONENT_NAME_PROTOCOL  gUfsPassThruComponentName;
 extern EFI_COMPONENT_NAME2_PROTOCOL gUfsPassThruComponentName2;
 extern EFI_DRIVER_BINDING_PROTOCOL  gUfsPassThruDriverBinding;
diff --git a/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruDxe.inf b/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruDxe.inf
index c90c72f915..467c533ceb 100644
--- a/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruDxe.inf
+++ b/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruDxe.inf
@@ -1,7 +1,7 @@
 ## @file
 # Description file for the Universal Flash Storage (UFS) Pass Thru driver.
 #
-# Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD License
@@ -34,6 +34,7 @@
 
 [Sources]
   ComponentName.c
+  UfsDevConfigProtocol.c
   UfsPassThru.c
   UfsPassThru.h
   UfsPassThruHci.c
@@ -56,6 +57,7 @@
 
 [Protocols]
   gEfiExtScsiPassThruProtocolGuid               ## BY_START
+  gEfiUfsDeviceConfigProtocolGuid               ## BY_START
   gEdkiiUfsHostControllerProtocolGuid           ## TO_START
 
 [UserExtensions.TianoCore."ExtraFiles"]
diff --git a/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruHci.c b/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruHci.c
index a19bdcc3cc..5fa635523a 100644
--- a/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruHci.c
+++ b/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruHci.c
@@ -909,6 +909,8 @@ UfsGetReturnDataFromQueryResponse (
   @param[in] Packet  Pointer to the UFS_DEVICE_MANAGEMENT_REQUEST_PACKET.
 
   @retval EFI_SUCCESS           The device descriptor was read/written successfully.
+  @retval EFI_INVALID_PARAMETER The DescId, Index and Selector fields in Packet are invalid
+                                combination to point to a type of UFS device descriptor.
   @retval EFI_DEVICE_ERROR      A device error occurred while attempting to r/w the device descriptor.
   @retval EFI_TIMEOUT           A timeout occurred while waiting for the completion of r/w the device descriptor.
 
@@ -967,7 +969,14 @@ UfsSendDmRequestRetry (
   if (Trd->Ocs != 0 || QueryResp->QueryResp != UfsUtpQueryResponseSuccess) {
     DEBUG ((DEBUG_ERROR, "Failed to send query request, OCS = %X, QueryResp = %X\n", Trd->Ocs, QueryResp->QueryResp));
     DumpQueryResponseResult (QueryResp->QueryResp);
-    Status = EFI_DEVICE_ERROR;
+
+    if ((QueryResp->QueryResp == UfsUtpQueryResponseInvalidSelector) ||
+        (QueryResp->QueryResp == UfsUtpQueryResponseInvalidIndex) ||
+        (QueryResp->QueryResp == UfsUtpQueryResponseInvalidIdn)) {
+      Status = EFI_INVALID_PARAMETER;
+    } else {
+      Status = EFI_DEVICE_ERROR;
+    }
     goto Exit;
   }
 
@@ -999,6 +1008,8 @@ Exit:
   @param[in] Packet  Pointer to the UFS_DEVICE_MANAGEMENT_PACKET.
 
   @retval EFI_SUCCESS           The device responded correctly to the Query request.
+  @retval EFI_INVALID_PARAMETER The DescId, Index and Selector fields in Packet are invalid
+                                combination to point to a type of UFS device descriptor.
   @retval EFI_DEVICE_ERROR      A device error occurred while waiting for the response from the device.
   @retval EFI_TIMEOUT           A timeout occurred while waiting for the completion of the operation.
 
@@ -1034,9 +1045,13 @@ UfsSendDmRequest (
   @param[in]      Index         The Index of device descriptor.
   @param[in]      Selector      The Selector of device descriptor.
   @param[in, out] Descriptor    The buffer of device descriptor to be read or written.
-  @param[in]      DescSize      The size of device descriptor buffer.
+  @param[in, out] DescSize      The size of device descriptor buffer. On input, the size, in bytes,
+                                of the data buffer specified by Descriptor. On output, the number
+                                of bytes that were actually transferred.
 
   @retval EFI_SUCCESS           The device descriptor was read/written successfully.
+  @retval EFI_INVALID_PARAMETER DescId, Index and Selector are invalid combination to point to a
+                                type of UFS device descriptor.
   @retval EFI_DEVICE_ERROR      A device error occurred while attempting to r/w the device descriptor.
   @retval EFI_TIMEOUT           A timeout occurred while waiting for the completion of r/w the device descriptor.
 
@@ -1049,10 +1064,15 @@ UfsRwDeviceDesc (
   IN     UINT8                        Index,
   IN     UINT8                        Selector,
   IN OUT VOID                         *Descriptor,
-  IN     UINT32                       DescSize
+  IN OUT UINT32                       *DescSize
   )
 {
   UFS_DEVICE_MANAGEMENT_REQUEST_PACKET Packet;
+  EFI_STATUS                           Status;
+
+  if (DescSize == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
 
   ZeroMem (&Packet, sizeof (UFS_DEVICE_MANAGEMENT_REQUEST_PACKET));
 
@@ -1064,13 +1084,20 @@ UfsRwDeviceDesc (
     Packet.Opcode            = UtpQueryFuncOpcodeWrDesc;
   }
   Packet.DataBuffer          = Descriptor;
-  Packet.TransferLength      = DescSize;
+  Packet.TransferLength      = *DescSize;
   Packet.DescId              = DescId;
   Packet.Index               = Index;
   Packet.Selector            = Selector;
   Packet.Timeout             = UFS_TIMEOUT;
 
-  return UfsSendDmRequest (Private, &Packet);
+  Status = UfsSendDmRequest (Private, &Packet);
+  if (EFI_ERROR (Status)) {
+    *DescSize = 0;
+  } else {
+    *DescSize = Packet.TransferLength;
+  }
+
+  return Status;
 }
 
 /**
@@ -1084,6 +1111,8 @@ UfsRwDeviceDesc (
   @param[in, out] Attributes    The value of Attribute to be read or written.
 
   @retval EFI_SUCCESS           The Attribute was read/written successfully.
+  @retval EFI_INVALID_PARAMETER AttrId, Index and Selector are invalid combination to point to a
+                                type of UFS device descriptor.
   @retval EFI_DEVICE_ERROR      A device error occurred while attempting to r/w the Attribute.
   @retval EFI_TIMEOUT           A timeout occurred while waiting for the completion of r/w the Attribute.
 
@@ -1127,6 +1156,7 @@ UfsRwAttributes (
   @param[in, out] Value         The value to set or clear flag.
 
   @retval EFI_SUCCESS           The flag was read/written successfully.
+  @retval EFI_INVALID_PARAMETER FlagId is an invalid UFS flag ID.
   @retval EFI_DEVICE_ERROR      A device error occurred while attempting to r/w the flag.
   @retval EFI_TIMEOUT           A timeout occurred while waiting for the completion of r/w the flag.
 
-- 
2.12.0.windows.1



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] MdeModulePkg/Ufs: Set 'Data Segment Length' field for Write Descriptor
  2017-07-20  2:18 [PATCH 0/2] Implementation of UFS Device Config Protocol Hao Wu
  2017-07-20  2:18 ` [PATCH 1/2] MdeModulePkg/UfsPassThruDxe: Add impl " Hao Wu
@ 2017-07-20  2:18 ` Hao Wu
  2017-08-02  8:08 ` [PATCH 0/2] Implementation of UFS Device Config Protocol Zeng, Star
  2 siblings, 0 replies; 4+ messages in thread
From: Hao Wu @ 2017-07-20  2:18 UTC (permalink / raw)
  To: edk2-devel; +Cc: Hao Wu, Star Zeng

According to the Universal Flash Storage (UFS) Version 2.1 (JESD220C) spec
Section 10.7.8.5, the DATA SEGMENT LENGTH field of the UPIU shall also be
set to number of descriptor bytes to write.

The origin codes miss the above operation.

Cc: Star Zeng <star.zeng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Hao Wu <hao.a.wu@intel.com>
---
 MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsHci.c          | 3 +++
 MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruHci.c | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsHci.c b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsHci.c
index 1ef6c8878b..9c72c1dede 100644
--- a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsHci.c
+++ b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsHci.c
@@ -407,6 +407,9 @@ UfsInitQueryRequestUpiu (
 
   if (Opcode == UtpQueryFuncOpcodeWrDesc) {
     CopyMem (QueryReq + 1, Data, DataSize);
+
+    SwapLittleEndianToBigEndian ((UINT8*)&DataSize, sizeof (UINT16));
+    QueryReq->DataSegLen = (UINT16)DataSize;
   }
 
   return EFI_SUCCESS;
diff --git a/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruHci.c b/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruHci.c
index 5fa635523a..4b7df74501 100644
--- a/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruHci.c
+++ b/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruHci.c
@@ -478,6 +478,9 @@ UfsInitQueryRequestUpiu (
 
   if (Opcode == UtpQueryFuncOpcodeWrDesc) {
     CopyMem (QueryReq + 1, Data, DataSize);
+
+    SwapLittleEndianToBigEndian ((UINT8*)&DataSize, sizeof (UINT16));
+    QueryReq->DataSegLen = (UINT16)DataSize;
   }
 
   return EFI_SUCCESS;
-- 
2.12.0.windows.1



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 0/2] Implementation of UFS Device Config Protocol
  2017-07-20  2:18 [PATCH 0/2] Implementation of UFS Device Config Protocol Hao Wu
  2017-07-20  2:18 ` [PATCH 1/2] MdeModulePkg/UfsPassThruDxe: Add impl " Hao Wu
  2017-07-20  2:18 ` [PATCH 2/2] MdeModulePkg/Ufs: Set 'Data Segment Length' field for Write Descriptor Hao Wu
@ 2017-08-02  8:08 ` Zeng, Star
  2 siblings, 0 replies; 4+ messages in thread
From: Zeng, Star @ 2017-08-02  8:08 UTC (permalink / raw)
  To: Wu, Hao A, edk2-devel@lists.01.org; +Cc: Zeng, Star

Reviewed-by: Star Zeng <star.zeng@intel.com>

-----Original Message-----
From: Wu, Hao A 
Sent: Thursday, July 20, 2017 10:19 AM
To: edk2-devel@lists.01.org
Cc: Wu, Hao A <hao.a.wu@intel.com>; Zeng, Star <star.zeng@intel.com>
Subject: [PATCH 0/2] Implementation of UFS Device Config Protocol

The series adds the implementation of UFS Device Config Protocol in the UfsPassThruDxe driver.

Also, the series resolves a 'Write Descriptor' operation failure issue in the UFS drivers.

Cc: Star Zeng <star.zeng@intel.com>

Hao Wu (2):
  MdeModulePkg/UfsPassThruDxe: Add impl of UFS Device Config Protocol
  MdeModulePkg/Ufs: Set 'Data Segment Length' field for Write Descriptor

 MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsHci.c                |   3 +
 MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsDevConfigProtocol.c | 196 ++++++++++++++++++++
 MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.c          |  24 ++-
 MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.h          | 133 ++++++++++++-
 MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruDxe.inf     |   4 +-
 MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruHci.c       |  43 ++++-
 6 files changed, 389 insertions(+), 14 deletions(-)  create mode 100644 MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsDevConfigProtocol.c

--
2.12.0.windows.1



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2017-08-02  8:06 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-07-20  2:18 [PATCH 0/2] Implementation of UFS Device Config Protocol Hao Wu
2017-07-20  2:18 ` [PATCH 1/2] MdeModulePkg/UfsPassThruDxe: Add impl " Hao Wu
2017-07-20  2:18 ` [PATCH 2/2] MdeModulePkg/Ufs: Set 'Data Segment Length' field for Write Descriptor Hao Wu
2017-08-02  8:08 ` [PATCH 0/2] Implementation of UFS Device Config Protocol Zeng, Star

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox