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
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
© 2016 - 2024 Red Hat, Inc.