/** @file\r
\r
Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php.\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
return EFI_SUCCESS;\r
}\r
\r
-/**\r
- Find out available slot in task management transfer list of a UFS device.\r
-\r
- @param[in] Private The pointer to the UFS_PEIM_HC_PRIVATE_DATA data structure.\r
- @param[out] Slot The available slot.\r
-\r
- @retval EFI_SUCCESS The available slot was found successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-UfsFindAvailableSlotInTmrl (\r
- IN UFS_PEIM_HC_PRIVATE_DATA *Private,\r
- OUT UINT8 *Slot\r
- )\r
-{\r
- ASSERT ((Private != NULL) && (Slot != NULL));\r
-\r
- //\r
- // The simplest algo to always use slot 0.\r
- // TODO: enhance it to support async transfer with multiple slot.\r
- //\r
- *Slot = 0;\r
\r
- return EFI_SUCCESS;\r
-}\r
\r
/**\r
Start specified slot in transfer list of a UFS device.\r
SwapLittleEndianToBigEndian ((UINT8*)&ReturnDataSize, sizeof (UINT16));\r
\r
if (Read) {\r
+ //\r
+ // Make sure the hardware device does not return more data than expected.\r
+ //\r
+ if (ReturnDataSize > Packet.InTransferLength) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto Exit;\r
+ }\r
+\r
CopyMem (Packet.InDataBuffer, (QueryResp + 1), ReturnDataSize);\r
Packet.InTransferLength = ReturnDataSize;\r
} else {\r
return Status;\r
}\r
\r
-/**\r
- Read or write specified attribute of a UFS device.\r
-\r
- @param[in] Private The pointer to the UFS_PEIM_HC_PRIVATE_DATA data structure.\r
- @param[in] Read The boolean variable to show r/w direction.\r
- @param[in] AttrId The ID of Attribute.\r
- @param[in] Index The Index of Attribute.\r
- @param[in] Selector The Selector of Attribute.\r
- @param[in, out] Attributes The value of Attribute to be read or written.\r
-\r
- @retval EFI_SUCCESS The Attribute was read/written successfully.\r
- @retval EFI_DEVICE_ERROR A device error occurred while attempting to r/w the Attribute.\r
- @retval EFI_TIMEOUT A timeout occurred while waiting for the completion of r/w the Attribute.\r
-\r
-**/\r
-EFI_STATUS\r
-UfsRwAttributes (\r
- IN UFS_PEIM_HC_PRIVATE_DATA *Private,\r
- IN BOOLEAN Read,\r
- IN UINT8 AttrId,\r
- IN UINT8 Index,\r
- IN UINT8 Selector,\r
- IN OUT UINT32 *Attributes\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UFS_DEVICE_MANAGEMENT_REQUEST_PACKET Packet;\r
- UINT8 Slot;\r
- UTP_TRD *Trd;\r
- UINTN Address;\r
- UTP_QUERY_RESP_UPIU *QueryResp;\r
- UINT8 *CmdDescBase;\r
- UINT32 CmdDescSize;\r
- UINT32 ReturnData;\r
-\r
- ZeroMem (&Packet, sizeof (UFS_DEVICE_MANAGEMENT_REQUEST_PACKET));\r
-\r
- if (Read) {\r
- Packet.DataDirection = UfsDataIn;\r
- Packet.Opcode = UtpQueryFuncOpcodeRdAttr;\r
- } else {\r
- Packet.DataDirection = UfsDataOut;\r
- Packet.Opcode = UtpQueryFuncOpcodeWrAttr;\r
- }\r
- Packet.DescId = AttrId;\r
- Packet.Index = Index;\r
- Packet.Selector = Selector;\r
- Packet.Timeout = UFS_TIMEOUT;\r
-\r
- //\r
- // Find out which slot of transfer request list is available.\r
- //\r
- Status = UfsFindAvailableSlotInTrl (Private, &Slot);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
\r
- Trd = ((UTP_TRD*)Private->UtpTrlBase) + Slot;\r
- //\r
- // Fill transfer request descriptor to this slot.\r
- //\r
- Status = UfsCreateDMCommandDesc (Private, &Packet, Trd);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Check the transfer request result.\r
- //\r
- CmdDescBase = (UINT8 *)(UINTN)(LShiftU64 ((UINT64)Trd->UcdBaU, 32) | LShiftU64 ((UINT64)Trd->UcdBa, 7));\r
- QueryResp = (UTP_QUERY_RESP_UPIU*)(CmdDescBase + Trd->RuO * sizeof (UINT32));\r
- CmdDescSize = Trd->RuO * sizeof (UINT32) + Trd->RuL * sizeof (UINT32);\r
-\r
- //\r
- // Start to execute the transfer request.\r
- //\r
- UfsStartExecCmd (Private, Slot);\r
-\r
- //\r
- // Wait for the completion of the transfer request.\r
- //\r
- Address = Private->UfsHcBase + UFS_HC_UTRLDBR_OFFSET;\r
- Status = UfsWaitMemSet (Address, BIT0 << Slot, 0, Packet.Timeout);\r
- if (EFI_ERROR (Status)) {\r
- goto Exit;\r
- }\r
-\r
- if (QueryResp->QueryResp != 0) {\r
- DumpQueryResponseResult (QueryResp->QueryResp);\r
- Status = EFI_DEVICE_ERROR;\r
- goto Exit;\r
- }\r
-\r
- if (Trd->Ocs == 0) {\r
- ReturnData = QueryResp->Tsf.Value;\r
- SwapLittleEndianToBigEndian ((UINT8*)&ReturnData, sizeof (UINT32));\r
- *Attributes = ReturnData;\r
- } else {\r
- Status = EFI_DEVICE_ERROR;\r
- }\r
-\r
-Exit:\r
- UfsStopExecCmd (Private, Slot);\r
- UfsPeimFreeMem (Private->Pool, CmdDescBase, CmdDescSize);\r
-\r
- return Status;\r
-}\r
\r
/**\r
Read or write specified flag of a UFS device.\r
return Status;\r
}\r
\r
-/**\r
- Clear specified flag to 0 on a UFS device.\r
\r
- @param[in] Private The pointer to the UFS_PEIM_HC_PRIVATE_DATA data structure.\r
- @param[in] FlagId The ID of flag to be cleared.\r
-\r
- @retval EFI_SUCCESS The flag was cleared successfully.\r
- @retval EFI_DEVICE_ERROR A device error occurred while attempting to clear the flag.\r
- @retval EFI_TIMEOUT A timeout occurred while waiting for the completion of clearing the flag.\r
-\r
-**/\r
-EFI_STATUS\r
-UfsClearFlag (\r
- IN UFS_PEIM_HC_PRIVATE_DATA *Private,\r
- IN UINT8 FlagId\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT8 Value;\r
-\r
- Value = 0;\r
- Status = UfsRwFlags (Private, FALSE, FlagId, &Value);\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Read specified flag from a UFS device.\r
-\r
- @param[in] Private The pointer to the UFS_PEIM_HC_PRIVATE_DATA data structure.\r
- @param[in] FlagId The ID of flag to be read.\r
- @param[out] Value The flag's value.\r
-\r
- @retval EFI_SUCCESS The flag was read successfully.\r
- @retval EFI_DEVICE_ERROR A device error occurred while attempting to read the flag.\r
- @retval EFI_TIMEOUT A timeout occurred while waiting for the completion of reading the flag.\r
-\r
-**/\r
-EFI_STATUS\r
-UfsReadFlag (\r
- IN UFS_PEIM_HC_PRIVATE_DATA *Private,\r
- IN UINT8 FlagId,\r
- OUT UINT8 *Value\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- Status = UfsRwFlags (Private, TRUE, FlagId, Value);\r
-\r
- return Status;\r
-}\r
\r
/**\r
Sends NOP IN cmd to a UFS device for initialization process request.\r
SwapLittleEndianToBigEndian ((UINT8*)&SenseDataLen, sizeof (UINT16));\r
\r
if ((Packet->SenseDataLength != 0) && (Packet->SenseData != NULL)) {\r
- CopyMem (Packet->SenseData, Response->SenseData, SenseDataLen);\r
- Packet->SenseDataLength = (UINT8)SenseDataLen;\r
+ //\r
+ // Make sure the hardware device does not return more data than expected.\r
+ //\r
+ if (SenseDataLen <= Packet->SenseDataLength) {\r
+ CopyMem (Packet->SenseData, Response->SenseData, SenseDataLen);\r
+ Packet->SenseDataLength = (UINT8)SenseDataLen;\r
+ } else {\r
+ Packet->SenseDataLength = 0;\r
+ }\r
}\r
\r
//\r