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 - 2015, Intel Corporation. All rights reserved.<BR>\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
case 0x00:\r
break;\r
case 0x01:\r
- DEBUG ((EFI_D_VERBOSE, "UIC configuration command fails - INVALID_MIB_ATTRIBUTE\n"));\r
+ DEBUG ((DEBUG_VERBOSE, "UIC configuration command fails - INVALID_MIB_ATTRIBUTE\n"));\r
break;\r
case 0x02:\r
- DEBUG ((EFI_D_VERBOSE, "UIC configuration command fails - INVALID_MIB_ATTRIBUTE_VALUE\n"));\r
+ DEBUG ((DEBUG_VERBOSE, "UIC configuration command fails - INVALID_MIB_ATTRIBUTE_VALUE\n"));\r
break;\r
case 0x03:\r
- DEBUG ((EFI_D_VERBOSE, "UIC configuration command fails - READ_ONLY_MIB_ATTRIBUTE\n"));\r
+ DEBUG ((DEBUG_VERBOSE, "UIC configuration command fails - READ_ONLY_MIB_ATTRIBUTE\n"));\r
break;\r
case 0x04:\r
- DEBUG ((EFI_D_VERBOSE, "UIC configuration command fails - WRITE_ONLY_MIB_ATTRIBUTE\n"));\r
+ DEBUG ((DEBUG_VERBOSE, "UIC configuration command fails - WRITE_ONLY_MIB_ATTRIBUTE\n"));\r
break;\r
case 0x05:\r
- DEBUG ((EFI_D_VERBOSE, "UIC configuration command fails - BAD_INDEX\n"));\r
+ DEBUG ((DEBUG_VERBOSE, "UIC configuration command fails - BAD_INDEX\n"));\r
break;\r
case 0x06:\r
- DEBUG ((EFI_D_VERBOSE, "UIC configuration command fails - LOCKED_MIB_ATTRIBUTE\n"));\r
+ DEBUG ((DEBUG_VERBOSE, "UIC configuration command fails - LOCKED_MIB_ATTRIBUTE\n"));\r
break;\r
case 0x07:\r
- DEBUG ((EFI_D_VERBOSE, "UIC configuration command fails - BAD_TEST_FEATURE_INDEX\n"));\r
+ DEBUG ((DEBUG_VERBOSE, "UIC configuration command fails - BAD_TEST_FEATURE_INDEX\n"));\r
break;\r
case 0x08:\r
- DEBUG ((EFI_D_VERBOSE, "UIC configuration command fails - PEER_COMMUNICATION_FAILURE\n"));\r
- break; \r
+ DEBUG ((DEBUG_VERBOSE, "UIC configuration command fails - PEER_COMMUNICATION_FAILURE\n"));\r
+ break;\r
case 0x09:\r
- DEBUG ((EFI_D_VERBOSE, "UIC configuration command fails - BUSY\n"));\r
+ DEBUG ((DEBUG_VERBOSE, "UIC configuration command fails - BUSY\n"));\r
break;\r
case 0x0A:\r
- DEBUG ((EFI_D_VERBOSE, "UIC configuration command fails - DME_FAILURE\n"));\r
- break; \r
+ DEBUG ((DEBUG_VERBOSE, "UIC configuration command fails - DME_FAILURE\n"));\r
+ break;\r
default :\r
ASSERT (FALSE);\r
break;\r
case 0x00:\r
break;\r
case 0x01:\r
- DEBUG ((EFI_D_VERBOSE, "UIC control command fails - FAILURE\n"));\r
- break; \r
+ DEBUG ((DEBUG_VERBOSE, "UIC control command fails - FAILURE\n"));\r
+ break;\r
default :\r
ASSERT (FALSE);\r
break;\r
{\r
switch (Result) {\r
case 0xF6:\r
- DEBUG ((EFI_D_VERBOSE, "Query Response with Parameter Not Readable\n"));\r
+ DEBUG ((DEBUG_VERBOSE, "Query Response with Parameter Not Readable\n"));\r
break;\r
case 0xF7:\r
- DEBUG ((EFI_D_VERBOSE, "Query Response with Parameter Not Writeable\n"));\r
+ DEBUG ((DEBUG_VERBOSE, "Query Response with Parameter Not Writeable\n"));\r
break;\r
case 0xF8:\r
- DEBUG ((EFI_D_VERBOSE, "Query Response with Parameter Already Written\n"));\r
+ DEBUG ((DEBUG_VERBOSE, "Query Response with Parameter Already Written\n"));\r
break;\r
case 0xF9:\r
- DEBUG ((EFI_D_VERBOSE, "Query Response with Invalid Length\n"));\r
+ DEBUG ((DEBUG_VERBOSE, "Query Response with Invalid Length\n"));\r
break;\r
case 0xFA:\r
- DEBUG ((EFI_D_VERBOSE, "Query Response with Invalid Value\n"));\r
+ DEBUG ((DEBUG_VERBOSE, "Query Response with Invalid Value\n"));\r
break;\r
case 0xFB:\r
- DEBUG ((EFI_D_VERBOSE, "Query Response with Invalid Selector\n"));\r
+ DEBUG ((DEBUG_VERBOSE, "Query Response with Invalid Selector\n"));\r
break;\r
case 0xFC:\r
- DEBUG ((EFI_D_VERBOSE, "Query Response with Invalid Index\n"));\r
+ DEBUG ((DEBUG_VERBOSE, "Query Response with Invalid Index\n"));\r
break;\r
case 0xFD:\r
- DEBUG ((EFI_D_VERBOSE, "Query Response with Invalid Idn\n"));\r
+ DEBUG ((DEBUG_VERBOSE, "Query Response with Invalid Idn\n"));\r
break;\r
case 0xFE:\r
- DEBUG ((EFI_D_VERBOSE, "Query Response with Invalid Opcode\n"));\r
- break; \r
+ DEBUG ((DEBUG_VERBOSE, "Query Response with Invalid Opcode\n"));\r
+ break;\r
case 0xFF:\r
- DEBUG ((EFI_D_VERBOSE, "Query Response with General Failure\n"));\r
+ DEBUG ((DEBUG_VERBOSE, "Query Response with General Failure\n"));\r
break;\r
default :\r
ASSERT (FALSE);\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
UINT8 *Remaining;\r
UINTN PrdtNumber;\r
\r
+ if ((BufferSize & (BIT0 | BIT1)) != 0) {\r
+ BufferSize &= ~(BIT0 | BIT1);\r
+ DEBUG ((DEBUG_WARN, "UfsInitUtpPrdt: The BufferSize [%d] is not dword-aligned!\n", BufferSize));\r
+ }\r
+\r
if (BufferSize == 0) {\r
return EFI_SUCCESS;\r
}\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
Trd->Int = UFS_INTERRUPT_COMMAND;\r
Trd->Dd = DataDirection;\r
Trd->Ct = UFS_STORAGE_COMMAND_TYPE;\r
+ Trd->Ocs = UFS_HC_TRD_OCS_INIT_VALUE;\r
Trd->UcdBa = (UINT32)RShiftU64 ((UINT64)CmdDescPhyAddr, 7);\r
Trd->UcdBaU = (UINT32)RShiftU64 ((UINT64)CmdDescPhyAddr, 32);\r
Trd->RuL = (UINT16)DivU64x32 ((UINT64)ROUNDUP8 (sizeof (UTP_RESPONSE_UPIU)), sizeof (UINT32));\r
}\r
\r
DataDirection = Packet->DataDirection;\r
- if (DataDirection == UfsDataIn) {\r
- DataSize = Packet->InTransferLength;\r
- Data = Packet->InDataBuffer;\r
- } else if (DataDirection == UfsDataOut) {\r
- DataSize = Packet->OutTransferLength;\r
- Data = Packet->OutDataBuffer;\r
- } else {\r
- DataSize = 0;\r
- Data = NULL;\r
- }\r
-\r
- if (((Opcode != UtpQueryFuncOpcodeSetFlag) && (Opcode != UtpQueryFuncOpcodeClrFlag) && (Opcode != UtpQueryFuncOpcodeTogFlag))\r
- && ((DataSize == 0) || (Data == NULL))) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (((Opcode == UtpQueryFuncOpcodeSetFlag) || (Opcode == UtpQueryFuncOpcodeClrFlag) || (Opcode == UtpQueryFuncOpcodeTogFlag))\r
- && ((DataSize != 0) || (Data != NULL))) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if ((Opcode == UtpQueryFuncOpcodeWrAttr) && (DataSize != sizeof (UINT32))) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
+ DataSize = Packet->TransferLength;\r
+ Data = Packet->DataBuffer;\r
\r
if ((Opcode == UtpQueryFuncOpcodeWrDesc) || (Opcode == UtpQueryFuncOpcodeRdDesc)) {\r
+ if (DataSize == 0 || Data == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
TotalLen = ROUNDUP8 (sizeof (UTP_QUERY_REQ_UPIU)) + ROUNDUP8 (sizeof (UTP_QUERY_RESP_UPIU)) + ROUNDUP8 (DataSize);\r
} else {\r
TotalLen = ROUNDUP8 (sizeof (UTP_QUERY_REQ_UPIU)) + ROUNDUP8 (sizeof (UTP_QUERY_RESP_UPIU));\r
Trd->Int = UFS_INTERRUPT_COMMAND;\r
Trd->Dd = DataDirection;\r
Trd->Ct = UFS_STORAGE_COMMAND_TYPE;\r
- Trd->Ocs = 0x0F;\r
+ Trd->Ocs = UFS_HC_TRD_OCS_INIT_VALUE;\r
Trd->UcdBa = (UINT32)RShiftU64 ((UINT64)CmdDescPhyAddr, 7);\r
Trd->UcdBaU = (UINT32)RShiftU64 ((UINT64)CmdDescPhyAddr, 32);\r
if (Opcode == UtpQueryFuncOpcodeWrDesc) {\r
Trd->RuL = (UINT16)DivU64x32 ((UINT64)ROUNDUP8 (sizeof (UTP_QUERY_RESP_UPIU)), sizeof (UINT32));\r
- Trd->RuO = (UINT16)DivU64x32 ((UINT64)(ROUNDUP8 (sizeof (UTP_QUERY_REQ_UPIU)) + ROUNDUP8 (DataSize)), sizeof (UINT32));\r
+ Trd->RuO = (UINT16)DivU64x32 ((UINT64)ROUNDUP8 (sizeof (UTP_QUERY_REQ_UPIU)) + ROUNDUP8 (DataSize), sizeof (UINT32));\r
} else {\r
- Trd->RuL = (UINT16)DivU64x32 ((UINT64)(ROUNDUP8 (sizeof (UTP_QUERY_RESP_UPIU)) + ROUNDUP8 (DataSize)), sizeof (UINT32));\r
+ Trd->RuL = (UINT16)DivU64x32 ((UINT64)ROUNDUP8 (sizeof (UTP_QUERY_RESP_UPIU)) + ROUNDUP8 (DataSize), sizeof (UINT32));\r
Trd->RuO = (UINT16)DivU64x32 ((UINT64)ROUNDUP8 (sizeof (UTP_QUERY_REQ_UPIU)), sizeof (UINT32));\r
}\r
\r
Trd->Int = UFS_INTERRUPT_COMMAND;\r
Trd->Dd = 0x00;\r
Trd->Ct = UFS_STORAGE_COMMAND_TYPE;\r
+ Trd->Ocs = UFS_HC_TRD_OCS_INIT_VALUE;\r
Trd->UcdBa = (UINT32)RShiftU64 ((UINT64)CmdDescPhyAddr, 7);\r
Trd->UcdBaU = (UINT32)RShiftU64 ((UINT64)CmdDescPhyAddr, 32);\r
Trd->RuL = (UINT16)DivU64x32 ((UINT64)ROUNDUP8 (sizeof (UTP_NOP_IN_UPIU)), sizeof (UINT32));\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
}\r
\r
/**\r
- Read or write specified device descriptor of a UFS device.\r
+ Extracts return data from query response upiu.\r
\r
- @param[in] Private The pointer to the UFS_PASS_THRU_PRIVATE_DATA data structure.\r
- @param[in] Read The boolean variable to show r/w direction.\r
- @param[in] DescId The ID of device descriptor.\r
- @param[in] Index The Index of device descriptor.\r
- @param[in] Selector The Selector of device descriptor.\r
- @param[in, out] Descriptor The buffer of device descriptor to be read or written.\r
- @param[in] DescSize The size of device descriptor buffer.\r
+ @param[in] Packet Pointer to the UFS_DEVICE_MANAGEMENT_REQUEST_PACKET.\r
+ @param[in] QueryResp Pointer to the query response.\r
\r
- @retval EFI_SUCCESS The device descriptor was read/written successfully.\r
- @retval EFI_DEVICE_ERROR A device error occurred while attempting to r/w the device descriptor.\r
- @retval EFI_TIMEOUT A timeout occurred while waiting for the completion of r/w the device descriptor.\r
+ @retval EFI_INVALID_PARAMETER Packet or QueryResp are empty or opcode is invalid.\r
+ @retval EFI_SUCCESS Data extracted.\r
\r
**/\r
EFI_STATUS\r
-UfsRwDeviceDesc (\r
- IN UFS_PASS_THRU_PRIVATE_DATA *Private,\r
- IN BOOLEAN Read,\r
- IN UINT8 DescId,\r
- IN UINT8 Index,\r
- IN UINT8 Selector,\r
- IN OUT VOID *Descriptor,\r
- IN UINT32 DescSize\r
+UfsGetReturnDataFromQueryResponse (\r
+ IN UFS_DEVICE_MANAGEMENT_REQUEST_PACKET *Packet,\r
+ IN UTP_QUERY_RESP_UPIU *QueryResp\r
)\r
{\r
- EFI_STATUS Status;\r
- UFS_DEVICE_MANAGEMENT_REQUEST_PACKET Packet;\r
- UINT8 Slot;\r
- UTP_TRD *Trd;\r
- UTP_QUERY_RESP_UPIU *QueryResp;\r
- UINT32 CmdDescSize;\r
- UINT16 ReturnDataSize;\r
- VOID *CmdDescHost;\r
- VOID *CmdDescMapping;\r
- EDKII_UFS_HOST_CONTROLLER_PROTOCOL *UfsHc;\r
+ UINT16 ReturnDataSize;\r
+ UINT32 ReturnData;\r
\r
- ZeroMem (&Packet, sizeof (UFS_DEVICE_MANAGEMENT_REQUEST_PACKET));\r
+ if (Packet == NULL || QueryResp == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
\r
- if (Read) {\r
- Packet.DataDirection = UfsDataIn;\r
- Packet.InDataBuffer = Descriptor;\r
- Packet.InTransferLength = DescSize;\r
- Packet.Opcode = UtpQueryFuncOpcodeRdDesc;\r
- } else {\r
- Packet.DataDirection = UfsDataOut;\r
- Packet.OutDataBuffer = Descriptor;\r
- Packet.OutTransferLength = DescSize;\r
- Packet.Opcode = UtpQueryFuncOpcodeWrDesc;\r
+ switch (Packet->Opcode) {\r
+ case UtpQueryFuncOpcodeRdDesc:\r
+ ReturnDataSize = QueryResp->Tsf.Length;\r
+ SwapLittleEndianToBigEndian ((UINT8*)&ReturnDataSize, sizeof (UINT16));\r
+ CopyMem (Packet->DataBuffer, (QueryResp + 1), ReturnDataSize);\r
+ Packet->TransferLength = ReturnDataSize;\r
+ break;\r
+ case UtpQueryFuncOpcodeWrDesc:\r
+ ReturnDataSize = QueryResp->Tsf.Length;\r
+ SwapLittleEndianToBigEndian ((UINT8*)&ReturnDataSize, sizeof (UINT16));\r
+ Packet->TransferLength = ReturnDataSize;\r
+ break;\r
+ case UtpQueryFuncOpcodeRdFlag:\r
+ case UtpQueryFuncOpcodeSetFlag:\r
+ case UtpQueryFuncOpcodeClrFlag:\r
+ case UtpQueryFuncOpcodeTogFlag:\r
+ CopyMem (Packet->DataBuffer, &QueryResp->Tsf.Value, sizeof (UINT8));\r
+ break;\r
+ case UtpQueryFuncOpcodeRdAttr:\r
+ case UtpQueryFuncOpcodeWrAttr:\r
+ ReturnData = QueryResp->Tsf.Value;\r
+ SwapLittleEndianToBigEndian ((UINT8*) &ReturnData, sizeof (UINT32));\r
+ CopyMem (Packet->DataBuffer, &ReturnData, sizeof (UINT32));\r
+ break;\r
+ default:\r
+ return EFI_INVALID_PARAMETER;\r
}\r
- Packet.DescId = DescId;\r
- Packet.Index = Index;\r
- Packet.Selector = Selector;\r
- Packet.Timeout = UFS_TIMEOUT;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Creates Transfer Request descriptor and sends Query Request to the device.\r
+\r
+ @param[in] Private Pointer to the UFS_PASS_THRU_PRIVATE_DATA.\r
+ @param[in] Packet Pointer to the UFS_DEVICE_MANAGEMENT_REQUEST_PACKET.\r
+\r
+ @retval EFI_SUCCESS The device descriptor was read/written successfully.\r
+ @retval EFI_INVALID_PARAMETER The DescId, Index and Selector fields in Packet are invalid\r
+ combination to point to a type of UFS device descriptor.\r
+ @retval EFI_DEVICE_ERROR A device error occurred while attempting to r/w the device descriptor.\r
+ @retval EFI_TIMEOUT A timeout occurred while waiting for the completion of r/w the device descriptor.\r
+\r
+**/\r
+EFI_STATUS\r
+UfsSendDmRequestRetry (\r
+ IN UFS_PASS_THRU_PRIVATE_DATA *Private,\r
+ IN UFS_DEVICE_MANAGEMENT_REQUEST_PACKET *Packet\r
+ )\r
+{\r
+ UINT8 Slot;\r
+ UTP_TRD *Trd;\r
+ VOID *CmdDescHost;\r
+ VOID *CmdDescMapping;\r
+ UINT32 CmdDescSize;\r
+ EDKII_UFS_HOST_CONTROLLER_PROTOCOL *UfsHc;\r
+ UTP_QUERY_RESP_UPIU *QueryResp;\r
+ EFI_STATUS Status;\r
\r
//\r
// Find out which slot of transfer request list is available.\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
//\r
- Status = UfsCreateDMCommandDesc (Private, &Packet, Trd, &CmdDescHost, &CmdDescMapping);\r
+ Status = UfsCreateDMCommandDesc (Private, Packet, Trd, &CmdDescHost, &CmdDescMapping);\r
if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "Failed to create DM command descriptor\n"));\r
return Status;\r
}\r
\r
- //\r
- // Check the transfer request result.\r
- //\r
UfsHc = Private->UfsHostController;\r
QueryResp = (UTP_QUERY_RESP_UPIU*)((UINT8*)CmdDescHost + Trd->RuO * sizeof (UINT32));\r
ASSERT (QueryResp != NULL);\r
\r
//\r
// Wait for the completion of the transfer request.\r
- // \r
- Status = UfsWaitMemSet (Private, UFS_HC_UTRLDBR_OFFSET, BIT0, 0, Packet.Timeout);\r
+ //\r
+ Status = UfsWaitMemSet (Private, UFS_HC_UTRLDBR_OFFSET, BIT0, 0, Packet->Timeout);\r
if (EFI_ERROR (Status)) {\r
goto Exit;\r
}\r
\r
- if (QueryResp->QueryResp != 0) {\r
+ if (Trd->Ocs != 0 || QueryResp->QueryResp != UfsUtpQueryResponseSuccess) {\r
+ DEBUG ((DEBUG_ERROR, "Failed to send query request, OCS = %X, QueryResp = %X\n", Trd->Ocs, QueryResp->QueryResp));\r
DumpQueryResponseResult (QueryResp->QueryResp);\r
- Status = EFI_DEVICE_ERROR;\r
- goto Exit;\r
- }\r
\r
- if (Trd->Ocs == 0) {\r
- ReturnDataSize = QueryResp->Tsf.Length;\r
- SwapLittleEndianToBigEndian ((UINT8*)&ReturnDataSize, sizeof (UINT16));\r
-\r
- if (Read) {\r
- CopyMem (Packet.InDataBuffer, (QueryResp + 1), ReturnDataSize);\r
- Packet.InTransferLength = ReturnDataSize;\r
+ if ((QueryResp->QueryResp == UfsUtpQueryResponseInvalidSelector) ||\r
+ (QueryResp->QueryResp == UfsUtpQueryResponseInvalidIndex) ||\r
+ (QueryResp->QueryResp == UfsUtpQueryResponseInvalidIdn)) {\r
+ Status = EFI_INVALID_PARAMETER;\r
} else {\r
- Packet.OutTransferLength = ReturnDataSize;\r
+ Status = EFI_DEVICE_ERROR;\r
}\r
- } else {\r
- Status = EFI_DEVICE_ERROR;\r
+ goto Exit;\r
+ }\r
+\r
+ Status = UfsGetReturnDataFromQueryResponse (Packet, QueryResp);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "Failed to get return data from query response\n"));\r
+ goto Exit;\r
}\r
\r
Exit:\r
return Status;\r
}\r
\r
+/**\r
+ Sends Query Request to the device. Query is sent until device responds correctly or counter runs out.\r
+\r
+ @param[in] Private Pointer to the UFS_PASS_THRU_PRIVATE_DATA.\r
+ @param[in] Packet Pointer to the UFS_DEVICE_MANAGEMENT_PACKET.\r
+\r
+ @retval EFI_SUCCESS The device responded correctly to the Query request.\r
+ @retval EFI_INVALID_PARAMETER The DescId, Index and Selector fields in Packet are invalid\r
+ combination to point to a type of UFS device descriptor.\r
+ @retval EFI_DEVICE_ERROR A device error occurred while waiting for the response from the device.\r
+ @retval EFI_TIMEOUT A timeout occurred while waiting for the completion of the operation.\r
+\r
+**/\r
+EFI_STATUS\r
+UfsSendDmRequest (\r
+ IN UFS_PASS_THRU_PRIVATE_DATA *Private,\r
+ IN UFS_DEVICE_MANAGEMENT_REQUEST_PACKET *Packet\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT8 Retry;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ for (Retry = 0; Retry < 5; Retry ++) {\r
+ Status = UfsSendDmRequestRetry (Private, Packet);\r
+ if (!EFI_ERROR (Status)) {\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+\r
+ DEBUG ((DEBUG_ERROR, "Failed to get response from the device after %d retries\n", Retry));\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Read or write specified device descriptor of a UFS device.\r
+\r
+ @param[in] Private The pointer to the UFS_PASS_THRU_PRIVATE_DATA data structure.\r
+ @param[in] Read The boolean variable to show r/w direction.\r
+ @param[in] DescId The ID of device descriptor.\r
+ @param[in] Index The Index of device descriptor.\r
+ @param[in] Selector The Selector of device descriptor.\r
+ @param[in, out] Descriptor The buffer of device descriptor to be read or written.\r
+ @param[in, out] DescSize The size of device descriptor buffer. On input, the size, in bytes,\r
+ of the data buffer specified by Descriptor. On output, the number\r
+ of bytes that were actually transferred.\r
+\r
+ @retval EFI_SUCCESS The device descriptor was read/written successfully.\r
+ @retval EFI_INVALID_PARAMETER DescId, Index and Selector are invalid combination to point to a\r
+ type of UFS device descriptor.\r
+ @retval EFI_DEVICE_ERROR A device error occurred while attempting to r/w the device descriptor.\r
+ @retval EFI_TIMEOUT A timeout occurred while waiting for the completion of r/w the device descriptor.\r
+\r
+**/\r
+EFI_STATUS\r
+UfsRwDeviceDesc (\r
+ IN UFS_PASS_THRU_PRIVATE_DATA *Private,\r
+ IN BOOLEAN Read,\r
+ IN UINT8 DescId,\r
+ IN UINT8 Index,\r
+ IN UINT8 Selector,\r
+ IN OUT VOID *Descriptor,\r
+ IN OUT UINT32 *DescSize\r
+ )\r
+{\r
+ UFS_DEVICE_MANAGEMENT_REQUEST_PACKET Packet;\r
+ EFI_STATUS Status;\r
+\r
+ if (DescSize == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ ZeroMem (&Packet, sizeof (UFS_DEVICE_MANAGEMENT_REQUEST_PACKET));\r
+\r
+ if (Read) {\r
+ Packet.DataDirection = UfsDataIn;\r
+ Packet.Opcode = UtpQueryFuncOpcodeRdDesc;\r
+ } else {\r
+ Packet.DataDirection = UfsDataOut;\r
+ Packet.Opcode = UtpQueryFuncOpcodeWrDesc;\r
+ }\r
+ Packet.DataBuffer = Descriptor;\r
+ Packet.TransferLength = *DescSize;\r
+ Packet.DescId = DescId;\r
+ Packet.Index = Index;\r
+ Packet.Selector = Selector;\r
+ Packet.Timeout = UFS_TIMEOUT;\r
+\r
+ Status = UfsSendDmRequest (Private, &Packet);\r
+ if (EFI_ERROR (Status)) {\r
+ *DescSize = 0;\r
+ } else {\r
+ *DescSize = Packet.TransferLength;\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
/**\r
Read or write specified attribute of a UFS device.\r
\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_INVALID_PARAMETER AttrId, Index and Selector are invalid combination to point to a\r
+ type of UFS device descriptor.\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
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
- UTP_QUERY_RESP_UPIU *QueryResp;\r
- UINT32 CmdDescSize;\r
- UINT32 ReturnData;\r
- VOID *CmdDescHost;\r
- VOID *CmdDescMapping;\r
- EDKII_UFS_HOST_CONTROLLER_PROTOCOL *UfsHc;\r
\r
ZeroMem (&Packet, sizeof (UFS_DEVICE_MANAGEMENT_REQUEST_PACKET));\r
\r
Packet.DataDirection = UfsDataOut;\r
Packet.Opcode = UtpQueryFuncOpcodeWrAttr;\r
}\r
+ Packet.DataBuffer = Attributes;\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, &CmdDescHost, &CmdDescMapping);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Check the transfer request result.\r
- //\r
- UfsHc = Private->UfsHostController;\r
- QueryResp = (UTP_QUERY_RESP_UPIU*)((UINT8*)CmdDescHost + Trd->RuO * sizeof (UINT32));\r
- ASSERT (QueryResp != NULL);\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
- Status = UfsWaitMemSet (Private, UFS_HC_UTRLDBR_OFFSET, BIT0, 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
- UfsHc->Flush (UfsHc);\r
-\r
- UfsStopExecCmd (Private, Slot);\r
-\r
- if (CmdDescMapping != NULL) {\r
- UfsHc->Unmap (UfsHc, CmdDescMapping);\r
- }\r
-\r
- if (CmdDescHost != NULL) {\r
- UfsHc->FreeBuffer (UfsHc, EFI_SIZE_TO_PAGES (CmdDescSize), CmdDescHost);\r
- }\r
-\r
- return Status;\r
+ return UfsSendDmRequest (Private, &Packet);\r
}\r
\r
/**\r
@param[in, out] Value The value to set or clear flag.\r
\r
@retval EFI_SUCCESS The flag was read/written successfully.\r
+ @retval EFI_INVALID_PARAMETER FlagId is an invalid UFS flag ID.\r
@retval EFI_DEVICE_ERROR A device error occurred while attempting to r/w the flag.\r
@retval EFI_TIMEOUT A timeout occurred while waiting for the completion of r/w the flag.\r
\r
IN OUT UINT8 *Value\r
)\r
{\r
- EFI_STATUS Status;\r
UFS_DEVICE_MANAGEMENT_REQUEST_PACKET Packet;\r
- UINT8 Slot;\r
- UTP_TRD *Trd;\r
- UTP_QUERY_RESP_UPIU *QueryResp;\r
- UINT32 CmdDescSize;\r
- VOID *CmdDescHost;\r
- VOID *CmdDescMapping;\r
- EDKII_UFS_HOST_CONTROLLER_PROTOCOL *UfsHc;\r
\r
if (Value == NULL) {\r
return EFI_INVALID_PARAMETER;\r
return EFI_INVALID_PARAMETER;\r
}\r
}\r
+ Packet.DataBuffer = Value;\r
Packet.DescId = FlagId;\r
Packet.Index = 0;\r
Packet.Selector = 0;\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
- //\r
- // Fill transfer request descriptor to this slot.\r
- //\r
- Trd = ((UTP_TRD*)Private->UtpTrlBase) + Slot;\r
- Status = UfsCreateDMCommandDesc (Private, &Packet, Trd, &CmdDescHost, &CmdDescMapping);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Check the transfer request result.\r
- //\r
- UfsHc = Private->UfsHostController;\r
- QueryResp = (UTP_QUERY_RESP_UPIU*)((UINT8*)CmdDescHost + Trd->RuO * sizeof (UINT32));\r
- ASSERT (QueryResp != NULL);\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
- Status = UfsWaitMemSet (Private, UFS_HC_UTRLDBR_OFFSET, BIT0, 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
- *Value = (UINT8)QueryResp->Tsf.Value;\r
- } else {\r
- Status = EFI_DEVICE_ERROR;\r
- }\r
-\r
-Exit:\r
- UfsHc->Flush (UfsHc);\r
-\r
- UfsStopExecCmd (Private, Slot);\r
-\r
- if (CmdDescMapping != NULL) {\r
- UfsHc->Unmap (UfsHc, CmdDescMapping);\r
- }\r
- if (CmdDescHost != NULL) {\r
- UfsHc->FreeBuffer (UfsHc, EFI_SIZE_TO_PAGES (CmdDescSize), CmdDescHost);\r
- }\r
-\r
- return Status;\r
+ return UfsSendDmRequest (Private, &Packet);\r
}\r
\r
/**\r
\r
//\r
// Wait for the completion of the transfer request.\r
- // \r
- Status = UfsWaitMemSet (Private, UFS_HC_UTRLDBR_OFFSET, BIT0, 0, UFS_TIMEOUT);\r
+ //\r
+ Status = UfsWaitMemSet (Private, UFS_HC_UTRLDBR_OFFSET, BIT0 << Slot, 0, UFS_TIMEOUT);\r
if (EFI_ERROR (Status)) {\r
goto Exit;\r
}\r
UINTN MapLength;\r
EDKII_UFS_HOST_CONTROLLER_PROTOCOL *UfsHc;\r
EDKII_UFS_HOST_CONTROLLER_OPERATION Flag;\r
- UFS_DATA_DIRECTION DataDirection;\r
UTP_TR_PRD *PrdtBase;\r
EFI_TPL OldTpl;\r
UFS_PASS_THRU_TRANS_REQ *TransReq;\r
if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {\r
DataBuf = Packet->InDataBuffer;\r
DataLen = Packet->InTransferLength;\r
- DataDirection = UfsDataIn;\r
Flag = EdkiiUfsHcOperationBusMasterWrite;\r
} else {\r
DataBuf = Packet->OutDataBuffer;\r
DataLen = Packet->OutTransferLength;\r
- DataDirection = UfsDataOut;\r
Flag = EdkiiUfsHcOperationBusMasterRead;\r
}\r
\r
- if (DataLen == 0) {\r
- DataDirection = UfsNoData;\r
- } else {\r
+ if (DataLen != 0) {\r
MapLength = DataLen;\r
Status = UfsHc->Map (\r
UfsHc,\r
\r
//\r
// Wait for the completion of the transfer request.\r
- // \r
- Status = UfsWaitMemSet (Private, UFS_HC_UTRLDBR_OFFSET, BIT0, 0, Packet->Timeout);\r
+ //\r
+ Status = UfsWaitMemSet (Private, UFS_HC_UTRLDBR_OFFSET, BIT0 << TransReq->Slot, 0, Packet->Timeout);\r
if (EFI_ERROR (Status)) {\r
goto Exit;\r
}\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
Packet->TargetStatus = Response->Status;\r
if (Response->Response != 0) {\r
- DEBUG ((EFI_D_ERROR, "UfsExecScsiCmds() fails with Target Failure\n"));\r
+ DEBUG ((DEBUG_ERROR, "UfsExecScsiCmds() fails with Target Failure\n"));\r
Status = EFI_DEVICE_ERROR;\r
goto Exit;\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
return EFI_NOT_FOUND;\r
}\r
\r
- DEBUG ((EFI_D_INFO, "UfsPassThruDxe: found a attached UFS device\n"));\r
+ DEBUG ((DEBUG_INFO, "UfsPassThruDxe: found a attached UFS device\n"));\r
\r
return EFI_SUCCESS;\r
}\r
EDKII_UFS_HOST_CONTROLLER_PROTOCOL *UfsHc;\r
\r
if ((Private->Capabilities & UFS_HC_CAP_64ADDR) == UFS_HC_CAP_64ADDR) {\r
- Is32BitAddr = TRUE;\r
- } else {\r
Is32BitAddr = FALSE;\r
+ } else {\r
+ Is32BitAddr = TRUE;\r
}\r
\r
UfsHc = Private->UfsHostController;\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
\r
Status = UfsEnableHostController (Private);\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "UfsControllerInit: Enable Host Controller Fails, Status = %r\n", Status));\r
+ DEBUG ((DEBUG_ERROR, "UfsControllerInit: Enable Host Controller Fails, Status = %r\n", Status));\r
return Status;\r
}\r
\r
Status = UfsDeviceDetection (Private);\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "UfsControllerInit: Device Detection Fails, Status = %r\n", Status));\r
+ DEBUG ((DEBUG_ERROR, "UfsControllerInit: Device Detection Fails, Status = %r\n", Status));\r
return Status;\r
}\r
\r
Status = UfsInitTaskManagementRequestList (Private);\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "UfsControllerInit: Task management list initialization Fails, Status = %r\n", Status));\r
+ DEBUG ((DEBUG_ERROR, "UfsControllerInit: Task management list initialization Fails, Status = %r\n", Status));\r
return Status;\r
}\r
\r
Status = UfsInitTransferRequestList (Private);\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "UfsControllerInit: Transfer list initialization Fails, Status = %r\n", Status));\r
+ DEBUG ((DEBUG_ERROR, "UfsControllerInit: Transfer list initialization Fails, Status = %r\n", Status));\r
return Status;\r
}\r
\r
- DEBUG ((EFI_D_INFO, "UfsControllerInit Finished\n"));\r
+ DEBUG ((DEBUG_INFO, "UfsControllerInit Finished\n"));\r
return EFI_SUCCESS;\r
}\r
\r
return EFI_DEVICE_ERROR;\r
}\r
\r
- DEBUG ((EFI_D_INFO, "UfsController is stopped\n"));\r
+ DEBUG ((DEBUG_INFO, "UfsController is stopped\n"));\r
\r
return EFI_SUCCESS;\r
}\r
// case.\r
//\r
Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_PHASE_ERROR;\r
- DEBUG ((EFI_D_VERBOSE, "ProcessAsyncTaskList(): Signal Event %p UfsMmioRead32() Error.\n", TransReq->CallerEvent));\r
+ DEBUG ((DEBUG_VERBOSE, "ProcessAsyncTaskList(): Signal Event %p UfsMmioRead32() Error.\n", TransReq->CallerEvent));\r
SignalCallerEvent (Private, TransReq);\r
continue;\r
}\r
// Timeout occurs.\r
//\r
Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_TIMEOUT_COMMAND;\r
- DEBUG ((EFI_D_VERBOSE, "ProcessAsyncTaskList(): Signal Event %p EFI_TIMEOUT.\n", TransReq->CallerEvent));\r
+ DEBUG ((DEBUG_VERBOSE, "ProcessAsyncTaskList(): Signal Event %p EFI_TIMEOUT.\n", TransReq->CallerEvent));\r
SignalCallerEvent (Private, TransReq);\r
continue;\r
}\r
//\r
Packet->TargetStatus = Response->Status;\r
if (Response->Response != 0) {\r
- DEBUG ((EFI_D_VERBOSE, "ProcessAsyncTaskList(): Signal Event %p Target Failure.\n", TransReq->CallerEvent));\r
+ DEBUG ((DEBUG_VERBOSE, "ProcessAsyncTaskList(): Signal Event %p Target Failure.\n", TransReq->CallerEvent));\r
SignalCallerEvent (Private, TransReq);\r
continue;\r
}\r
}\r
}\r
} else {\r
- DEBUG ((EFI_D_VERBOSE, "ProcessAsyncTaskList(): Signal Event %p Target Device Error.\n", TransReq->CallerEvent));\r
+ DEBUG ((DEBUG_VERBOSE, "ProcessAsyncTaskList(): Signal Event %p Target Device Error.\n", TransReq->CallerEvent));\r
SignalCallerEvent (Private, TransReq);\r
continue;\r
}\r
\r
- DEBUG ((EFI_D_VERBOSE, "ProcessAsyncTaskList(): Signal Event %p Success.\n", TransReq->CallerEvent));\r
+ DEBUG ((DEBUG_VERBOSE, "ProcessAsyncTaskList(): Signal Event %p Success.\n", TransReq->CallerEvent));\r
SignalCallerEvent (Private, TransReq);\r
}\r
}\r