* [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