From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 7DB0A2095D8C7 for ; Wed, 19 Jul 2017 19:17:07 -0700 (PDT) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 19 Jul 2017 19:19:02 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.40,382,1496127600"; d="scan'208";a="113325030" Received: from shwdeopenpsi014.ccr.corp.intel.com ([10.239.9.13]) by orsmga002.jf.intel.com with ESMTP; 19 Jul 2017 19:19:01 -0700 From: Hao Wu To: edk2-devel@lists.01.org Cc: Hao Wu , Star Zeng Date: Thu, 20 Jul 2017 10:18:34 +0800 Message-Id: <20170720021835.10808-2-hao.a.wu@intel.com> X-Mailer: git-send-email 2.12.0.windows.1 In-Reply-To: <20170720021835.10808-1-hao.a.wu@intel.com> References: <20170720021835.10808-1-hao.a.wu@intel.com> Subject: [PATCH 1/2] MdeModulePkg/UfsPassThruDxe: Add impl of UFS Device Config Protocol X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 20 Jul 2017 02:17:07 -0000 Cc: Star Zeng Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Hao Wu --- 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.
+ 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 #include +#include #include #include @@ -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.
+# Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.
# # 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