UfsPassThruDxe driver is used to produce EFI_EXT_SCSI_PASS_THRU protocol interface\r
for upper layer application to execute UFS-supported SCSI cmds.\r
\r
- Copyright (c) 2014 - 2017, 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
+ Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
break;\r
case 0x08:\r
DEBUG ((DEBUG_VERBOSE, "UIC configuration command fails - PEER_COMMUNICATION_FAILURE\n"));\r
- break; \r
+ break;\r
case 0x09:\r
DEBUG ((DEBUG_VERBOSE, "UIC configuration command fails - BUSY\n"));\r
break;\r
case 0x0A:\r
DEBUG ((DEBUG_VERBOSE, "UIC configuration command fails - DME_FAILURE\n"));\r
- break; \r
+ break;\r
default :\r
ASSERT (FALSE);\r
break;\r
break;\r
case 0x01:\r
DEBUG ((DEBUG_VERBOSE, "UIC control command fails - FAILURE\n"));\r
- break; \r
+ break;\r
default :\r
ASSERT (FALSE);\r
break;\r
break;\r
case 0xFE:\r
DEBUG ((DEBUG_VERBOSE, "Query Response with Invalid Opcode\n"));\r
- break; \r
+ break;\r
case 0xFF:\r
DEBUG ((DEBUG_VERBOSE, "Query Response with General Failure\n"));\r
break;\r
SwapLittleEndianToBigEndian ((UINT8*)&Length, sizeof (Length));\r
TsfBase->Length = Length;\r
}\r
- \r
+\r
if (Opcode == UtpQueryFuncOpcodeWrAttr) {\r
SwapLittleEndianToBigEndian ((UINT8*)&Value, sizeof (Value));\r
TsfBase->Value = Value;\r
\r
if (Opcode == UtpQueryFuncOpcodeWrDesc) {\r
CopyMem (QueryReq + 1, Data, DataSize);\r
+\r
+ SwapLittleEndianToBigEndian ((UINT8*)&DataSize, sizeof (UINT16));\r
+ QueryReq->DataSegLen = (UINT16)DataSize;\r
}\r
\r
return EFI_SUCCESS;\r
return EFI_NOT_READY;\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_PASS_THRU_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_PASS_THRU_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
UfsStartExecCmd (\r
IN UFS_PASS_THRU_PRIVATE_DATA *Private,\r
IN UINT8 Slot\r
- ) \r
+ )\r
{\r
UINT32 Data;\r
EFI_STATUS Status;\r
UfsStopExecCmd (\r
IN UFS_PASS_THRU_PRIVATE_DATA *Private,\r
IN UINT8 Slot\r
- ) \r
+ )\r
{\r
UINT32 Data;\r
EFI_STATUS Status;\r
@param[in] QueryResp Pointer to the query response.\r
\r
@retval EFI_INVALID_PARAMETER Packet or QueryResp are empty or opcode is invalid.\r
+ @retval EFI_DEVICE_ERROR Data returned from device is invalid.\r
@retval EFI_SUCCESS Data extracted.\r
\r
**/\r
case UtpQueryFuncOpcodeRdDesc:\r
ReturnDataSize = QueryResp->Tsf.Length;\r
SwapLittleEndianToBigEndian ((UINT8*)&ReturnDataSize, sizeof (UINT16));\r
+ //\r
+ // Make sure the hardware device does not return more data than expected.\r
+ //\r
+ if (ReturnDataSize > Packet->TransferLength) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
CopyMem (Packet->DataBuffer, (QueryResp + 1), ReturnDataSize);\r
Packet->TransferLength = ReturnDataSize;\r
break;\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- \r
+\r
Trd = ((UTP_TRD*)Private->UtpTrlBase) + Slot;\r
//\r
// Fill transfer request descriptor to this slot.\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_PASS_THRU_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_PASS_THRU_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
//\r
// Wait for the completion of the transfer request.\r
- // \r
+ //\r
Status = UfsWaitMemSet (Private, UFS_HC_UTRLDBR_OFFSET, BIT0 << Slot, 0, UFS_TIMEOUT);\r
if (EFI_ERROR (Status)) {\r
goto Exit;\r
\r
//\r
// Wait for the completion of the transfer request.\r
- // \r
+ //\r
Status = UfsWaitMemSet (Private, UFS_HC_UTRLDBR_OFFSET, BIT0 << TransReq->Slot, 0, Packet->Timeout);\r
if (EFI_ERROR (Status)) {\r
goto Exit;\r
ASSERT (Response != NULL);\r
SenseDataLen = Response->SenseDataLen;\r
SwapLittleEndianToBigEndian ((UINT8*)&SenseDataLen, sizeof (UINT16));\r
- \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
\r
//\r
// UFS 2.0 spec section 5.3.1 Offset:0x20 IS.Bit10 UIC Command Completion Status (UCCS)\r
- // This bit is set to '1' by the host controller upon completion of a UIC command. \r
+ // This bit is set to '1' by the host controller upon completion of a UIC command.\r
//\r
Status = UfsWaitMemSet (Private, UFS_HC_IS_OFFSET, UFS_HC_IS_UCCS, UFS_HC_IS_UCCS, UFS_TIMEOUT);\r
if (EFI_ERROR (Status)) {\r
EFI_PHYSICAL_ADDRESS CmdDescPhyAddr;\r
VOID *CmdDescMapping;\r
EFI_STATUS Status;\r
- \r
+\r
//\r
// Initial h/w and s/w context for future operations.\r
//\r
UINT8 Nutrs;\r
VOID *CmdDescHost;\r
EFI_PHYSICAL_ADDRESS CmdDescPhyAddr;\r
- VOID *CmdDescMapping; \r
+ VOID *CmdDescMapping;\r
EFI_STATUS Status;\r
\r
//\r
}\r
\r
Private->UtpTrlBase = CmdDescHost;\r
- Private->Nutrs = Nutrs; \r
+ Private->Nutrs = Nutrs;\r
Private->TrlMapping = CmdDescMapping;\r
\r
//\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