36 UfsHc = Private->UfsHostController;
38 Status = UfsHc->Read (UfsHc, EfiUfsHcWidthUint32, Offset, 1, Value);
66 UfsHc = Private->UfsHostController;
68 Status = UfsHc->Write (UfsHc, EfiUfsHcWidthUint32, Offset, 1, &Value);
105 InfiniteWait =
FALSE;
115 if (EFI_ERROR (Status)) {
121 if (Value == TestValue) {
131 }
while (InfiniteWait || (Delay > 0));
149 if (UicOpcode <= UfsUicDmePeerSet) {
154 DEBUG ((DEBUG_VERBOSE,
"UIC configuration command fails - INVALID_MIB_ATTRIBUTE\n"));
157 DEBUG ((DEBUG_VERBOSE,
"UIC configuration command fails - INVALID_MIB_ATTRIBUTE_VALUE\n"));
160 DEBUG ((DEBUG_VERBOSE,
"UIC configuration command fails - READ_ONLY_MIB_ATTRIBUTE\n"));
163 DEBUG ((DEBUG_VERBOSE,
"UIC configuration command fails - WRITE_ONLY_MIB_ATTRIBUTE\n"));
166 DEBUG ((DEBUG_VERBOSE,
"UIC configuration command fails - BAD_INDEX\n"));
169 DEBUG ((DEBUG_VERBOSE,
"UIC configuration command fails - LOCKED_MIB_ATTRIBUTE\n"));
172 DEBUG ((DEBUG_VERBOSE,
"UIC configuration command fails - BAD_TEST_FEATURE_INDEX\n"));
175 DEBUG ((DEBUG_VERBOSE,
"UIC configuration command fails - PEER_COMMUNICATION_FAILURE\n"));
178 DEBUG ((DEBUG_VERBOSE,
"UIC configuration command fails - BUSY\n"));
181 DEBUG ((DEBUG_VERBOSE,
"UIC configuration command fails - DME_FAILURE\n"));
192 DEBUG ((DEBUG_VERBOSE,
"UIC control command fails - FAILURE\n"));
214 DEBUG ((DEBUG_VERBOSE,
"Query Response with Parameter Not Readable\n"));
217 DEBUG ((DEBUG_VERBOSE,
"Query Response with Parameter Not Writeable\n"));
220 DEBUG ((DEBUG_VERBOSE,
"Query Response with Parameter Already Written\n"));
223 DEBUG ((DEBUG_VERBOSE,
"Query Response with Invalid Length\n"));
226 DEBUG ((DEBUG_VERBOSE,
"Query Response with Invalid Value\n"));
229 DEBUG ((DEBUG_VERBOSE,
"Query Response with Invalid Selector\n"));
232 DEBUG ((DEBUG_VERBOSE,
"Query Response with Invalid Index\n"));
235 DEBUG ((DEBUG_VERBOSE,
"Query Response with Invalid Idn\n"));
238 DEBUG ((DEBUG_VERBOSE,
"Query Response with Invalid Opcode\n"));
241 DEBUG ((DEBUG_VERBOSE,
"Query Response with General Failure\n"));
259 IN OUT UINT8 *Buffer,
267 SwapCount = BufferSize / 2;
268 for (Index = 0; Index < SwapCount; Index++) {
269 Temp = Buffer[Index];
270 Buffer[Index] = Buffer[BufferSize - 1 - Index];
271 Buffer[BufferSize - 1 - Index] = Temp;
291 IN UINT8 DescId OPTIONAL,
292 IN UINT8 Index OPTIONAL,
293 IN UINT8 Selector OPTIONAL,
294 IN UINT16 Length OPTIONAL,
295 IN UINT32 Value OPTIONAL
298 ASSERT (TsfBase !=
NULL);
299 ASSERT (Opcode <= UtpQueryFuncOpcodeTogFlag);
301 TsfBase->Opcode = Opcode;
302 if (Opcode != UtpQueryFuncOpcodeNop) {
303 TsfBase->DescId = DescId;
304 TsfBase->Index = Index;
305 TsfBase->Selector = Selector;
307 if ((Opcode == UtpQueryFuncOpcodeRdDesc) || (Opcode == UtpQueryFuncOpcodeWrDesc)) {
309 TsfBase->Length = Length;
312 if (Opcode == UtpQueryFuncOpcodeWrAttr) {
314 TsfBase->Value = Value;
340 IN UFS_DATA_DIRECTION DataDirection,
341 IN UINT32 ExpDataTranLen
346 ASSERT ((Command !=
NULL) && (Cdb !=
NULL));
351 if (DataDirection == UfsDataIn) {
353 }
else if (DataDirection == UfsDataOut) {
362 Command->TransCode = 0x01;
363 Command->Flags = Flags;
365 Command->TaskTag = TaskTag;
366 Command->CmdSet = 0x00;
368 Command->ExpDataTranLen = ExpDataTranLen;
370 CopyMem (Command->Cdb, Cdb, CdbLength);
397 ASSERT (((
UINTN)Buffer & (BIT0 | BIT1)) == 0);
398 ASSERT ((BufferSize & (BIT1 | BIT0)) == 0);
400 if (BufferSize == 0) {
404 RemainingLen = BufferSize;
406 PrdtNumber = (
UINTN)
DivU64x32 ((UINT64)BufferSize + UFS_MAX_DATA_LEN_PER_PRD - 1, UFS_MAX_DATA_LEN_PER_PRD);
408 for (PrdtIndex = 0; PrdtIndex < PrdtNumber; PrdtIndex++) {
409 if (RemainingLen < UFS_MAX_DATA_LEN_PER_PRD) {
410 Prdt[PrdtIndex].DbCount = (UINT32)RemainingLen - 1;
412 Prdt[PrdtIndex].DbCount = UFS_MAX_DATA_LEN_PER_PRD - 1;
415 Prdt[PrdtIndex].DbAddr = (UINT32)
RShiftU64 ((UINT64)(
UINTN)Remaining, 2);
416 Prdt[PrdtIndex].DbAddrU = (UINT32)
RShiftU64 ((UINT64)(
UINTN)Remaining, 32);
417 RemainingLen -= UFS_MAX_DATA_LEN_PER_PRD;
418 Remaining += UFS_MAX_DATA_LEN_PER_PRD;
448 IN UINT8 *Data OPTIONAL
451 ASSERT (QueryReq !=
NULL);
453 QueryReq->TransCode = 0x16;
454 QueryReq->TaskTag = TaskTag;
455 if ((Opcode == UtpQueryFuncOpcodeRdDesc) || (Opcode == UtpQueryFuncOpcodeRdFlag) || (Opcode == UtpQueryFuncOpcodeRdAttr)) {
456 QueryReq->QueryFunc = QUERY_FUNC_STD_READ_REQ;
458 QueryReq->QueryFunc = QUERY_FUNC_STD_WRITE_REQ;
461 if (Opcode == UtpQueryFuncOpcodeWrAttr) {
463 }
else if ((Opcode == UtpQueryFuncOpcodeRdDesc) || (Opcode == UtpQueryFuncOpcodeWrDesc)) {
469 if (Opcode == UtpQueryFuncOpcodeWrDesc) {
470 CopyMem (QueryReq + 1, Data, DataSize);
473 QueryReq->DataSegLen = (UINT16)DataSize;
500 OUT VOID **CmdDescHost,
501 OUT VOID **CmdDescMapping
510 UFS_DATA_DIRECTION DataDirection;
512 ASSERT ((Private !=
NULL) && (Packet !=
NULL) && (Trd !=
NULL));
514 if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {
515 DataLen = Packet->InTransferLength;
516 DataDirection = UfsDataIn;
518 DataLen = Packet->OutTransferLength;
519 DataDirection = UfsDataOut;
523 DataDirection = UfsNoData;
526 PrdtNumber = (
UINTN)
DivU64x32 ((UINT64)DataLen + UFS_MAX_DATA_LEN_PER_PRD - 1, UFS_MAX_DATA_LEN_PER_PRD);
531 if (EFI_ERROR (Status)) {
537 UfsInitCommandUpiu (CommandUpiu, Lun, Private->TaskTag++, Packet->Cdb, Packet->CdbLength, DataDirection, DataLen);
544 Trd->Int = UFS_INTERRUPT_COMMAND;
545 Trd->Dd = DataDirection;
546 Trd->Ct = UFS_STORAGE_COMMAND_TYPE;
547 Trd->Ocs = UFS_HC_TRD_OCS_INIT_VALUE;
548 Trd->UcdBa = (UINT32)
RShiftU64 ((UINT64)CmdDescPhyAddr, 7);
549 Trd->UcdBaU = (UINT32)
RShiftU64 ((UINT64)CmdDescPhyAddr, 32);
552 Trd->PrdtL = (UINT16)PrdtNumber;
577 OUT VOID **CmdDescHost,
578 OUT VOID **CmdDescMapping
590 ASSERT ((Private !=
NULL) && (Packet !=
NULL) && (Trd !=
NULL));
592 Opcode = Packet->Opcode;
593 if ((Opcode > UtpQueryFuncOpcodeTogFlag) || (Opcode == UtpQueryFuncOpcodeNop)) {
594 return EFI_INVALID_PARAMETER;
597 DataDirection = Packet->DataDirection;
598 DataSize = Packet->TransferLength;
599 Data = Packet->DataBuffer;
601 if ((Opcode == UtpQueryFuncOpcodeWrDesc) || (Opcode == UtpQueryFuncOpcodeRdDesc)) {
602 if ((DataSize == 0) || (Data ==
NULL)) {
603 return EFI_INVALID_PARAMETER;
612 if (EFI_ERROR (Status)) {
620 ASSERT (QueryReqUpiu !=
NULL);
636 Trd->Int = UFS_INTERRUPT_COMMAND;
637 Trd->Dd = DataDirection;
638 Trd->Ct = UFS_STORAGE_COMMAND_TYPE;
639 Trd->Ocs = UFS_HC_TRD_OCS_INIT_VALUE;
640 Trd->UcdBa = (UINT32)
RShiftU64 ((UINT64)CmdDescPhyAddr, 7);
641 Trd->UcdBaU = (UINT32)
RShiftU64 ((UINT64)CmdDescPhyAddr, 32);
642 if (Opcode == UtpQueryFuncOpcodeWrDesc) {
670 OUT VOID **CmdDescHost,
671 OUT VOID **CmdDescMapping
679 ASSERT ((Private !=
NULL) && (Trd !=
NULL));
683 if (EFI_ERROR (Status)) {
688 ASSERT (NopOutUpiu !=
NULL);
689 NopOutUpiu->TaskTag = Private->TaskTag++;
695 Trd->Int = UFS_INTERRUPT_COMMAND;
697 Trd->Ct = UFS_STORAGE_COMMAND_TYPE;
698 Trd->Ocs = UFS_HC_TRD_OCS_INIT_VALUE;
699 Trd->UcdBa = (UINT32)
RShiftU64 ((UINT64)CmdDescPhyAddr, 7);
700 Trd->UcdBaU = (UINT32)
RShiftU64 ((UINT64)CmdDescPhyAddr, 32);
728 ASSERT ((Private !=
NULL) && (Slot !=
NULL));
730 Status =
UfsMmioRead32 (Private, UFS_HC_UTRLDBR_OFFSET, &Data);
731 if (EFI_ERROR (Status)) {
735 Nutrs = (UINT8)((Private->UfsHcInfo.Capabilities & UFS_HC_CAP_NUTRS) + 1);
737 for (Index = 0; Index < Nutrs; Index++) {
738 if ((Data & (BIT0 << Index)) == 0) {
744 return EFI_NOT_READY;
763 Status =
UfsMmioRead32 (Private, UFS_HC_UTRLRSR_OFFSET, &Data);
764 if (EFI_ERROR (Status)) {
768 if ((Data & UFS_HC_UTRLRSR) != UFS_HC_UTRLRSR) {
769 Status =
UfsMmioWrite32 (Private, UFS_HC_UTRLRSR_OFFSET, UFS_HC_UTRLRSR);
770 if (EFI_ERROR (Status)) {
775 Status =
UfsMmioWrite32 (Private, UFS_HC_UTRLDBR_OFFSET, BIT0 << Slot);
776 if (EFI_ERROR (Status)) {
799 Status =
UfsMmioRead32 (Private, UFS_HC_UTRLDBR_OFFSET, &Data);
800 if (EFI_ERROR (Status)) {
804 if ((Data & (BIT0 << Slot)) != 0) {
805 Status =
UfsMmioRead32 (Private, UFS_HC_UTRLCLR_OFFSET, &Data);
806 if (EFI_ERROR (Status)) {
810 Status =
UfsMmioWrite32 (Private, UFS_HC_UTRLCLR_OFFSET, Data & ~(BIT0 << Slot));
811 if (EFI_ERROR (Status)) {
836 UINT16 ReturnDataSize;
839 if ((Packet ==
NULL) || (QueryResp ==
NULL)) {
840 return EFI_INVALID_PARAMETER;
843 switch (Packet->Opcode) {
844 case UtpQueryFuncOpcodeRdDesc:
845 ReturnDataSize = QueryResp->Tsf.Length;
850 if (ReturnDataSize > Packet->TransferLength) {
851 return EFI_DEVICE_ERROR;
854 CopyMem (Packet->DataBuffer, (QueryResp + 1), ReturnDataSize);
855 Packet->TransferLength = ReturnDataSize;
857 case UtpQueryFuncOpcodeWrDesc:
858 ReturnDataSize = QueryResp->Tsf.Length;
860 Packet->TransferLength = ReturnDataSize;
862 case UtpQueryFuncOpcodeRdFlag:
863 case UtpQueryFuncOpcodeSetFlag:
864 case UtpQueryFuncOpcodeClrFlag:
865 case UtpQueryFuncOpcodeTogFlag:
869 *((UINT8 *)(Packet->DataBuffer)) = *((UINT8 *)&(QueryResp->Tsf.Value) + 3);
871 case UtpQueryFuncOpcodeRdAttr:
872 case UtpQueryFuncOpcodeWrAttr:
873 ReturnData = QueryResp->Tsf.Value;
875 CopyMem (Packet->DataBuffer, &ReturnData, sizeof (UINT32));
878 return EFI_INVALID_PARAMETER;
906 VOID *CmdDescMapping;
916 if (EFI_ERROR (Status)) {
920 Trd = ((
UTP_TRD *)Private->UtpTrlBase) + Slot;
925 if (EFI_ERROR (Status)) {
926 DEBUG ((DEBUG_ERROR,
"Failed to create DM command descriptor\n"));
930 UfsHc = Private->UfsHostController;
932 ASSERT (QueryResp !=
NULL);
933 CmdDescSize = Trd->RuO *
sizeof (UINT32) + Trd->RuL * sizeof (UINT32);
943 Status =
UfsWaitMemSet (Private, UFS_HC_UTRLDBR_OFFSET, BIT0, 0, Packet->Timeout);
944 if (EFI_ERROR (Status)) {
948 if ((Trd->Ocs != 0) || (QueryResp->QueryResp != UfsUtpQueryResponseSuccess)) {
949 DEBUG ((DEBUG_ERROR,
"Failed to send query request, OCS = %X, QueryResp = %X\n", Trd->Ocs, QueryResp->QueryResp));
952 if ((QueryResp->QueryResp == UfsUtpQueryResponseInvalidSelector) ||
953 (QueryResp->QueryResp == UfsUtpQueryResponseInvalidIndex) ||
954 (QueryResp->QueryResp == UfsUtpQueryResponseInvalidIdn))
956 Status = EFI_INVALID_PARAMETER;
958 Status = EFI_DEVICE_ERROR;
965 if (EFI_ERROR (Status)) {
966 DEBUG ((DEBUG_ERROR,
"Failed to get return data from query response\n"));
971 UfsHc->Flush (UfsHc);
975 if (CmdDescMapping !=
NULL) {
976 UfsHc->Unmap (UfsHc, CmdDescMapping);
979 if (CmdDescHost !=
NULL) {
1010 for (Retry = 0; Retry < 5; Retry++) {
1012 if (!EFI_ERROR (Status)) {
1017 DEBUG ((DEBUG_ERROR,
"Failed to get response from the device after %d retries\n", Retry));
1048 IN OUT VOID *Descriptor,
1049 IN OUT UINT32 *DescSize
1055 if (DescSize ==
NULL) {
1056 return EFI_INVALID_PARAMETER;
1062 Packet.DataDirection = UfsDataIn;
1063 Packet.Opcode = UtpQueryFuncOpcodeRdDesc;
1065 Packet.DataDirection = UfsDataOut;
1066 Packet.Opcode = UtpQueryFuncOpcodeWrDesc;
1069 Packet.DataBuffer = Descriptor;
1070 Packet.TransferLength = *DescSize;
1071 Packet.DescId = DescId;
1072 Packet.Index = Index;
1073 Packet.Selector = Selector;
1074 Packet.Timeout = UFS_TIMEOUT;
1077 if (EFI_ERROR (Status)) {
1080 *DescSize = Packet.TransferLength;
1110 IN OUT UINT32 *Attributes
1118 Packet.DataDirection = UfsDataIn;
1119 Packet.Opcode = UtpQueryFuncOpcodeRdAttr;
1121 Packet.DataDirection = UfsDataOut;
1122 Packet.Opcode = UtpQueryFuncOpcodeWrAttr;
1125 Packet.DataBuffer = Attributes;
1126 Packet.DescId = AttrId;
1127 Packet.Index = Index;
1128 Packet.Selector = Selector;
1129 Packet.Timeout = UFS_TIMEOUT;
1158 if (Value ==
NULL) {
1159 return EFI_INVALID_PARAMETER;
1165 ASSERT (Value !=
NULL);
1166 Packet.DataDirection = UfsDataIn;
1167 Packet.Opcode = UtpQueryFuncOpcodeRdFlag;
1169 Packet.DataDirection = UfsDataOut;
1171 Packet.Opcode = UtpQueryFuncOpcodeSetFlag;
1172 }
else if (*Value == 0) {
1173 Packet.Opcode = UtpQueryFuncOpcodeClrFlag;
1175 return EFI_INVALID_PARAMETER;
1179 Packet.DataBuffer = Value;
1180 Packet.DescId = FlagId;
1182 Packet.Selector = 0;
1183 Packet.Timeout = UFS_TIMEOUT;
1264 VOID *CmdDescMapping;
1271 if (EFI_ERROR (Status)) {
1275 Trd = ((
UTP_TRD *)Private->UtpTrlBase) + Slot;
1277 if (EFI_ERROR (Status)) {
1284 UfsHc = Private->UfsHostController;
1285 NopInUpiu = (
UTP_NOP_IN_UPIU *)((UINT8 *)CmdDescHost + Trd->RuO *
sizeof (UINT32));
1286 ASSERT (NopInUpiu !=
NULL);
1287 CmdDescSize = Trd->RuO *
sizeof (UINT32) + Trd->RuL * sizeof (UINT32);
1297 Status =
UfsWaitMemSet (Private, UFS_HC_UTRLDBR_OFFSET, BIT0 << Slot, 0, UFS_TIMEOUT);
1298 if (EFI_ERROR (Status)) {
1302 if (NopInUpiu->Resp != 0) {
1303 Status = EFI_DEVICE_ERROR;
1309 UfsHc->Flush (UfsHc);
1313 if (CmdDescMapping !=
NULL) {
1314 UfsHc->Unmap (UfsHc, CmdDescMapping);
1317 if (CmdDescHost !=
NULL) {
1338 if (TransReq->DataBufMapping !=
NULL) {
1339 Private->UfsHostController->Unmap (
1340 Private->UfsHostController,
1341 TransReq->DataBufMapping
1351 if (TransReq->AlignedDataBuf !=
NULL) {
1352 if (TransReq->Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {
1353 CopyMem (TransReq->Packet->InDataBuffer, TransReq->AlignedDataBuf, TransReq->Packet->InTransferLength);
1359 ZeroMem (TransReq->AlignedDataBuf, TransReq->AlignedDataBufSize);
1361 TransReq->AlignedDataBuf =
NULL;
1396 if (TransReq->Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {
1397 if (((
UINTN)TransReq->Packet->InDataBuffer % 4 != 0) || (TransReq->Packet->InTransferLength % 4 != 0)) {
1398 DataLen = TransReq->Packet->InTransferLength + (4 - (TransReq->Packet->InTransferLength % 4));
1400 if (DataBuf ==
NULL) {
1401 return EFI_DEVICE_ERROR;
1405 TransReq->AlignedDataBuf = DataBuf;
1406 TransReq->AlignedDataBufSize = DataLen;
1408 DataLen = TransReq->Packet->InTransferLength;
1409 DataBuf = TransReq->Packet->InDataBuffer;
1414 if (((
UINTN)TransReq->Packet->OutDataBuffer % 4 != 0) || (TransReq->Packet->OutTransferLength % 4 != 0)) {
1415 DataLen = TransReq->Packet->OutTransferLength + (4 - (TransReq->Packet->OutTransferLength % 4));
1417 if (DataBuf ==
NULL) {
1418 return EFI_DEVICE_ERROR;
1421 CopyMem (DataBuf, TransReq->Packet->OutDataBuffer, TransReq->Packet->OutTransferLength);
1422 TransReq->AlignedDataBuf = DataBuf;
1423 TransReq->AlignedDataBufSize = DataLen;
1425 DataLen = TransReq->Packet->OutTransferLength;
1426 DataBuf = TransReq->Packet->OutDataBuffer;
1433 MapLength = DataLen;
1434 Status = Private->UfsHostController->Map (
1435 Private->UfsHostController,
1440 &TransReq->DataBufMapping
1443 if (EFI_ERROR (Status) || (DataLen != MapLength)) {
1444 if (TransReq->AlignedDataBuf !=
NULL) {
1448 ZeroMem (TransReq->AlignedDataBuf, TransReq->AlignedDataBufSize);
1450 TransReq->AlignedDataBuf =
NULL;
1453 return EFI_DEVICE_ERROR;
1461 ASSERT (PrdtBase !=
NULL);
1501 UINT16 SenseDataLen;
1502 UINT32 ResTranCount;
1508 if (TransReq ==
NULL) {
1509 return EFI_OUT_OF_RESOURCES;
1512 TransReq->Signature = UFS_PASS_THRU_TRANS_REQ_SIG;
1513 TransReq->TimeoutRemain = Packet->Timeout;
1514 TransReq->Packet = Packet;
1516 UfsHc = Private->UfsHostController;
1521 if (EFI_ERROR (Status)) {
1525 TransReq->Trd = ((
UTP_TRD *)Private->UtpTrlBase) + TransReq->Slot;
1535 &TransReq->CmdDescHost,
1536 &TransReq->CmdDescMapping
1538 if (EFI_ERROR (Status)) {
1542 TransReq->CmdDescSize = TransReq->Trd->PrdtO *
sizeof (UINT32) + TransReq->Trd->PrdtL * sizeof (
UTP_TR_PRD);
1545 if (EFI_ERROR (Status)) {
1552 if (Event !=
NULL) {
1553 OldTpl =
gBS->RaiseTPL (TPL_NOTIFY);
1554 TransReq->CallerEvent = Event;
1556 gBS->RestoreTPL (OldTpl);
1567 if (Event !=
NULL) {
1574 Status =
UfsWaitMemSet (Private, UFS_HC_UTRLDBR_OFFSET, BIT0 << TransReq->Slot, 0, Packet->Timeout);
1575 if (EFI_ERROR (Status)) {
1582 Response = (
UTP_RESPONSE_UPIU *)((UINT8 *)TransReq->CmdDescHost + TransReq->Trd->RuO *
sizeof (UINT32));
1583 ASSERT (Response !=
NULL);
1584 SenseDataLen = Response->SenseDataLen;
1587 if ((Packet->SenseDataLength != 0) && (Packet->SenseData !=
NULL)) {
1591 if (SenseDataLen <= Packet->SenseDataLength) {
1592 CopyMem (Packet->SenseData, Response->SenseData, SenseDataLen);
1593 Packet->SenseDataLength = (UINT8)SenseDataLen;
1595 Packet->SenseDataLength = 0;
1602 Packet->TargetStatus = Response->Status;
1603 if (Response->Response != 0) {
1604 DEBUG ((DEBUG_ERROR,
"UfsExecScsiCmds() fails with Target Failure\n"));
1605 Status = EFI_DEVICE_ERROR;
1609 if (TransReq->Trd->Ocs == 0) {
1610 if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {
1611 if ((Response->Flags & BIT5) == BIT5) {
1612 ResTranCount = Response->ResTranCount;
1614 Packet->InTransferLength -= ResTranCount;
1617 if ((Response->Flags & BIT5) == BIT5) {
1618 ResTranCount = Response->ResTranCount;
1620 Packet->OutTransferLength -= ResTranCount;
1624 Status = EFI_DEVICE_ERROR;
1628 UfsHc->Flush (UfsHc);
1635 if (TransReq->CmdDescMapping !=
NULL) {
1636 UfsHc->Unmap (UfsHc, TransReq->CmdDescMapping);
1639 if (TransReq->CmdDescHost !=
NULL) {
1640 UfsHc->FreeBuffer (UfsHc,
EFI_SIZE_TO_PAGES (TransReq->CmdDescSize), TransReq->CmdDescHost);
1643 if (TransReq !=
NULL) {
1670 if (EFI_ERROR (Status)) {
1674 if ((Data & UFS_HC_IS_UCCS) == UFS_HC_IS_UCCS) {
1679 if (EFI_ERROR (Status)) {
1689 Status =
UfsMmioWrite32 (Private, UFS_HC_UCMD_ARG1_OFFSET, UicCommand->Arg1);
1690 if (EFI_ERROR (Status)) {
1694 Status =
UfsMmioWrite32 (Private, UFS_HC_UCMD_ARG2_OFFSET, UicCommand->Arg2);
1695 if (EFI_ERROR (Status)) {
1699 Status =
UfsMmioWrite32 (Private, UFS_HC_UCMD_ARG3_OFFSET, UicCommand->Arg3);
1700 if (EFI_ERROR (Status)) {
1707 Status =
UfsWaitMemSet (Private, UFS_HC_STATUS_OFFSET, UFS_HC_HCS_UCRDY, UFS_HC_HCS_UCRDY, UFS_TIMEOUT);
1708 if (EFI_ERROR (Status)) {
1712 Status =
UfsMmioWrite32 (Private, UFS_HC_UIC_CMD_OFFSET, UicCommand->Opcode);
1713 if (EFI_ERROR (Status)) {
1721 Status =
UfsWaitMemSet (Private, UFS_HC_IS_OFFSET, UFS_HC_IS_UCCS, UFS_HC_IS_UCCS, UFS_TIMEOUT);
1722 if (EFI_ERROR (Status)) {
1726 if (UicCommand->Opcode != UfsUicDmeReset) {
1727 Status =
UfsMmioRead32 (Private, UFS_HC_UCMD_ARG2_OFFSET, &UicCommand->Arg2);
1728 if (EFI_ERROR (Status)) {
1732 Status =
UfsMmioRead32 (Private, UFS_HC_UCMD_ARG3_OFFSET, &UicCommand->Arg3);
1733 if (EFI_ERROR (Status)) {
1737 if ((UicCommand->Arg2 & 0xFF) != 0) {
1741 return EFI_DEVICE_ERROR;
1766 OUT VOID **CmdDescHost,
1768 OUT VOID **CmdDescMapping
1773 BOOLEAN Is32BitAddr;
1776 if ((Private->UfsHcInfo.Capabilities & UFS_HC_CAP_64ADDR) == UFS_HC_CAP_64ADDR) {
1777 Is32BitAddr =
FALSE;
1782 UfsHc = Private->UfsHostController;
1783 Status = UfsHc->AllocateBuffer (
1791 if (EFI_ERROR (Status)) {
1792 *CmdDescMapping =
NULL;
1793 *CmdDescHost =
NULL;
1794 *CmdDescPhyAddr = 0;
1795 return EFI_OUT_OF_RESOURCES;
1799 Status = UfsHc->Map (
1814 *CmdDescHost =
NULL;
1815 return EFI_OUT_OF_RESOURCES;
1818 if (Is32BitAddr && ((*CmdDescPhyAddr) > 0x100000000ULL)) {
1831 *CmdDescMapping =
NULL;
1832 *CmdDescHost =
NULL;
1833 return EFI_DEVICE_ERROR;
1858 Status = mUfsHcPlatform->
Callback (Private->Handle, EdkiiUfsHcPreHce, &Private->UfsHcDriverInterface);
1859 if (EFI_ERROR (Status)) {
1860 DEBUG ((DEBUG_ERROR,
"Failure from platform driver during EdkiiUfsHcPreHce, Status = %r\n", Status));
1870 Status =
UfsMmioRead32 (Private, UFS_HC_ENABLE_OFFSET, &Data);
1871 if (EFI_ERROR (Status)) {
1875 if ((Data & UFS_HC_HCE_EN) == UFS_HC_HCE_EN) {
1880 if (EFI_ERROR (Status)) {
1887 Status =
UfsWaitMemSet (Private, UFS_HC_ENABLE_OFFSET, UFS_HC_HCE_EN, 0, UFS_TIMEOUT);
1888 if (EFI_ERROR (Status)) {
1889 return EFI_DEVICE_ERROR;
1896 Status =
UfsMmioWrite32 (Private, UFS_HC_ENABLE_OFFSET, UFS_HC_HCE_EN);
1897 if (EFI_ERROR (Status)) {
1904 Status =
UfsWaitMemSet (Private, UFS_HC_ENABLE_OFFSET, UFS_HC_HCE_EN, UFS_HC_HCE_EN, UFS_TIMEOUT);
1905 if (EFI_ERROR (Status)) {
1906 return EFI_DEVICE_ERROR;
1910 Status = mUfsHcPlatform->
Callback (Private->Handle, EdkiiUfsHcPostHce, &Private->UfsHcDriverInterface);
1911 if (EFI_ERROR (Status)) {
1912 DEBUG ((DEBUG_ERROR,
"Failure from platform driver during EdkiiUfsHcPostHce, Status = %r\n", Status));
1941 Status = mUfsHcPlatform->
Callback (Private->Handle, EdkiiUfsHcPreLinkStartup, &Private->UfsHcDriverInterface);
1942 if (EFI_ERROR (Status)) {
1943 DEBUG ((DEBUG_ERROR,
"Failure from platform driver during EdkiiUfsHcPreLinkStartup, Status = %r\n", Status));
1952 for (Retry = 0; Retry < 3; Retry++) {
1953 LinkStartupCommand.Opcode = UfsUicDmeLinkStartup;
1954 LinkStartupCommand.Arg1 = 0;
1955 LinkStartupCommand.Arg2 = 0;
1956 LinkStartupCommand.Arg3 = 0;
1958 if (EFI_ERROR (Status)) {
1959 return EFI_DEVICE_ERROR;
1962 Status =
UfsMmioRead32 (Private, UFS_HC_STATUS_OFFSET, &Data);
1963 if (EFI_ERROR (Status)) {
1964 return EFI_DEVICE_ERROR;
1967 if ((Data & UFS_HC_HCS_DP) == 0) {
1968 Status =
UfsWaitMemSet (Private, UFS_HC_IS_OFFSET, UFS_HC_IS_ULSS, UFS_HC_IS_ULSS, UFS_TIMEOUT);
1969 if (EFI_ERROR (Status)) {
1970 return EFI_DEVICE_ERROR;
1977 return EFI_NOT_FOUND;
1997 VOID *CmdDescMapping;
2004 CmdDescMapping =
NULL;
2010 Nutmrs = (UINT8)(
RShiftU64 ((Private->UfsHcInfo.Capabilities & UFS_HC_CAP_NUTMRS), 16) + 1);
2012 if (EFI_ERROR (Status)) {
2021 if (EFI_ERROR (Status)) {
2026 if (EFI_ERROR (Status)) {
2030 Private->UtpTmrlBase = CmdDescHost;
2031 Private->Nutmrs = Nutmrs;
2032 Private->TmrlMapping = CmdDescMapping;
2038 Status =
UfsMmioWrite32 (Private, UFS_HC_UTMRLRSR_OFFSET, UFS_HC_UTMRLRSR);
2039 if (EFI_ERROR (Status)) {
2063 VOID *CmdDescMapping;
2070 CmdDescMapping =
NULL;
2076 Nutrs = (UINT8)((Private->UfsHcInfo.Capabilities & UFS_HC_CAP_NUTRS) + 1);
2078 if (EFI_ERROR (Status)) {
2087 if (EFI_ERROR (Status)) {
2092 if (EFI_ERROR (Status)) {
2096 Private->UtpTrlBase = CmdDescHost;
2097 Private->Nutrs = Nutrs;
2098 Private->TrlMapping = CmdDescMapping;
2104 Status =
UfsMmioWrite32 (Private, UFS_HC_UTRLRSR_OFFSET, UFS_HC_UTRLRSR);
2105 if (EFI_ERROR (Status)) {
2129 if (EFI_ERROR (Status)) {
2130 DEBUG ((DEBUG_ERROR,
"UfsControllerInit: Enable Host Controller Fails, Status = %r\n", Status));
2135 if (EFI_ERROR (Status)) {
2136 DEBUG ((DEBUG_ERROR,
"UfsControllerInit: Device Detection Fails, Status = %r\n", Status));
2141 if (EFI_ERROR (Status)) {
2142 DEBUG ((DEBUG_ERROR,
"UfsControllerInit: Task management list initialization Fails, Status = %r\n", Status));
2147 if (EFI_ERROR (Status)) {
2148 DEBUG ((DEBUG_ERROR,
"UfsControllerInit: Transfer list initialization Fails, Status = %r\n", Status));
2152 DEBUG ((DEBUG_INFO,
"UfsControllerInit Finished\n"));
2178 if (EFI_ERROR (Status)) {
2187 if (EFI_ERROR (Status)) {
2194 Status =
UfsMmioRead32 (Private, UFS_HC_ENABLE_OFFSET, &Data);
2195 if (EFI_ERROR (Status)) {
2199 ASSERT ((Data & UFS_HC_HCE_EN) == UFS_HC_HCE_EN);
2202 if (EFI_ERROR (Status)) {
2209 Status =
UfsWaitMemSet (Private, UFS_HC_ENABLE_OFFSET, UFS_HC_HCE_EN, 0, UFS_TIMEOUT);
2210 if (EFI_ERROR (Status)) {
2211 return EFI_DEVICE_ERROR;
2214 DEBUG ((DEBUG_INFO,
"UfsController is stopped\n"));
2239 ASSERT ((Private !=
NULL) && (TransReq !=
NULL));
2241 UfsHc = Private->UfsHostController;
2242 CallerEvent = TransReq->CallerEvent;
2246 UfsHc->Flush (UfsHc);
2252 if (TransReq->CmdDescMapping !=
NULL) {
2253 UfsHc->Unmap (UfsHc, TransReq->CmdDescMapping);
2256 if (TransReq->CmdDescHost !=
NULL) {
2260 TransReq->CmdDescHost
2266 gBS->SignalEvent (CallerEvent);
2290 UINT16 SenseDataLen;
2291 UINT32 ResTranCount;
2304 TransReq = UFS_PASS_THRU_TRANS_REQ_FROM_THIS (Entry);
2305 Packet = TransReq->Packet;
2307 if ((SlotsMap & (BIT0 << TransReq->Slot)) != 0) {
2311 SlotsMap |= BIT0 << TransReq->Slot;
2313 Status =
UfsMmioRead32 (Private, UFS_HC_UTRLDBR_OFFSET, &Value);
2314 if (EFI_ERROR (Status)) {
2320 DEBUG ((DEBUG_VERBOSE,
"ProcessAsyncTaskList(): Signal Event %p UfsMmioRead32() Error.\n", TransReq->CallerEvent));
2325 if ((Value & (BIT0 << TransReq->Slot)) != 0) {
2329 if (TransReq->TimeoutRemain > UFS_HC_ASYNC_TIMER) {
2330 TransReq->TimeoutRemain -= UFS_HC_ASYNC_TIMER;
2337 DEBUG ((DEBUG_VERBOSE,
"ProcessAsyncTaskList(): Signal Event %p EFI_TIMEOUT.\n", TransReq->CallerEvent));
2347 Response = (
UTP_RESPONSE_UPIU *)((UINT8 *)TransReq->CmdDescHost + TransReq->Trd->RuO *
sizeof (UINT32));
2348 ASSERT (Response !=
NULL);
2349 SenseDataLen = Response->SenseDataLen;
2356 if (SenseDataLen <= Packet->SenseDataLength) {
2368 if (Response->Response != 0) {
2369 DEBUG ((DEBUG_VERBOSE,
"ProcessAsyncTaskList(): Signal Event %p Target Failure.\n", TransReq->CallerEvent));
2374 if (TransReq->Trd->Ocs == 0) {
2375 if (Packet->
DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {
2376 if ((Response->Flags & BIT5) == BIT5) {
2377 ResTranCount = Response->ResTranCount;
2382 if ((Response->Flags & BIT5) == BIT5) {
2383 ResTranCount = Response->ResTranCount;
2389 DEBUG ((DEBUG_VERBOSE,
"ProcessAsyncTaskList(): Signal Event %p Target Device Error.\n", TransReq->CallerEvent));
2394 DEBUG ((DEBUG_VERBOSE,
"ProcessAsyncTaskList(): Signal Event %p Success.\n", TransReq->CallerEvent));
2420 if ((This ==
NULL) || (UicCommand ==
NULL)) {
2421 return EFI_INVALID_PARAMETER;
2424 Private = UFS_PASS_THRU_PRIVATE_DATA_FROM_DRIVER_INTF (This);
2446 if (EFI_ERROR (Status)) {
2450 Private->UfsHcInfo.Version = Data;
2453 if (EFI_ERROR (Status)) {
2457 Private->UfsHcInfo.Capabilities = Data;
2460 Status = mUfsHcPlatform->
OverrideHcInfo (Private->Handle, &Private->UfsHcInfo);
2461 if (EFI_ERROR (Status)) {
2462 DEBUG ((DEBUG_ERROR,
"Failure from platform on OverrideHcInfo, Status = %r\n", Status));
UINTN EFIAPI MicroSecondDelay(IN UINTN MicroSeconds)
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
UINT64 EFIAPI DivU64x32(IN UINT64 Dividend, IN UINT32 Divisor)
#define BASE_LIST_FOR_EACH_SAFE(Entry, NextEntry, ListHead)
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID EFIAPI FreeAlignedPages(IN VOID *Buffer, IN UINTN Pages)
#define DEBUG_CODE_BEGIN()
#define DEBUG(Expression)
VOID *EFIAPI AllocateAlignedPages(IN UINTN Pages, IN UINTN Alignment)
EDKII_UFS_HOST_CONTROLLER_OPERATION
@ EdkiiUfsHcOperationBusMasterWrite
@ EdkiiUfsHcOperationBusMasterRead
@ EdkiiUfsHcOperationBusMasterCommonBuffer
VOID EFIAPI Exit(IN EFI_STATUS Status)
UINT64 EFI_PHYSICAL_ADDRESS
#define EFI_PAGES_TO_SIZE(Pages)
#define EFI_SIZE_TO_PAGES(Size)
EFI_STATUS UfsWaitMemSet(IN UFS_PASS_THRU_PRIVATE_DATA *Private, IN UINTN Offset, IN UINT32 MaskValue, IN UINT32 TestValue, IN UINT64 Timeout)
EFI_STATUS UfsGetReturnDataFromQueryResponse(IN UFS_DEVICE_MANAGEMENT_REQUEST_PACKET *Packet, IN UTP_QUERY_RESP_UPIU *QueryResp)
EFI_STATUS UfsMmioWrite32(IN UFS_PASS_THRU_PRIVATE_DATA *Private, IN UINTN Offset, IN UINT32 Value)
EFI_STATUS UfsInitTransferRequestList(IN UFS_PASS_THRU_PRIVATE_DATA *Private)
EFI_STATUS UfsExecScsiCmds(IN UFS_PASS_THRU_PRIVATE_DATA *Private, IN UINT8 Lun, IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet, IN EFI_EVENT Event OPTIONAL)
EFI_STATUS UfsEnableHostController(IN UFS_PASS_THRU_PRIVATE_DATA *Private)
EFI_STATUS UfsAllocateAlignCommonBuffer(IN UFS_PASS_THRU_PRIVATE_DATA *Private, IN UINTN Size, OUT VOID **CmdDescHost, OUT EFI_PHYSICAL_ADDRESS *CmdDescPhyAddr, OUT VOID **CmdDescMapping)
EFI_STATUS UfsSendDmRequest(IN UFS_PASS_THRU_PRIVATE_DATA *Private, IN UFS_DEVICE_MANAGEMENT_REQUEST_PACKET *Packet)
VOID SwapLittleEndianToBigEndian(IN OUT UINT8 *Buffer, IN UINT32 BufferSize)
VOID UfsReconcileDataTransferBuffer(IN UFS_PASS_THRU_PRIVATE_DATA *Private, IN UFS_PASS_THRU_TRANS_REQ *TransReq)
EFI_STATUS UfsSendDmRequestRetry(IN UFS_PASS_THRU_PRIVATE_DATA *Private, IN UFS_DEVICE_MANAGEMENT_REQUEST_PACKET *Packet)
EFI_STATUS UfsRwDeviceDesc(IN UFS_PASS_THRU_PRIVATE_DATA *Private, IN BOOLEAN Read, IN UINT8 DescId, IN UINT8 Index, IN UINT8 Selector, IN OUT VOID *Descriptor, IN OUT UINT32 *DescSize)
EFI_STATUS GetUfsHcInfo(IN UFS_PASS_THRU_PRIVATE_DATA *Private)
EFI_STATUS UfsExecNopCmds(IN UFS_PASS_THRU_PRIVATE_DATA *Private)
EFI_STATUS EFIAPI UfsHcDriverInterfaceExecUicCommand(IN EDKII_UFS_HC_DRIVER_INTERFACE *This, IN OUT EDKII_UIC_COMMAND *UicCommand)
EFI_STATUS UfsRwFlags(IN UFS_PASS_THRU_PRIVATE_DATA *Private, IN BOOLEAN Read, IN UINT8 FlagId, IN OUT UINT8 *Value)
EFI_STATUS UfsDeviceDetection(IN UFS_PASS_THRU_PRIVATE_DATA *Private)
EFI_STATUS UfsReadFlag(IN UFS_PASS_THRU_PRIVATE_DATA *Private, IN UINT8 FlagId, OUT UINT8 *Value)
VOID UfsFillTsfOfQueryReqUpiu(IN OUT UTP_UPIU_TSF *TsfBase, IN UINT8 Opcode, IN UINT8 DescId OPTIONAL, IN UINT8 Index OPTIONAL, IN UINT8 Selector OPTIONAL, IN UINT16 Length OPTIONAL, IN UINT32 Value OPTIONAL)
VOID DumpUicCmdExecResult(IN UINT8 UicOpcode, IN UINT8 Result)
VOID EFIAPI SignalCallerEvent(IN UFS_PASS_THRU_PRIVATE_DATA *Private, IN UFS_PASS_THRU_TRANS_REQ *TransReq)
EFI_STATUS UfsMmioRead32(IN UFS_PASS_THRU_PRIVATE_DATA *Private, IN UINTN Offset, OUT UINT32 *Value)
EFI_STATUS UfsInitUtpPrdt(IN UTP_TR_PRD *Prdt, IN VOID *Buffer, IN UINT32 BufferSize)
EFI_STATUS UfsStopExecCmd(IN UFS_PASS_THRU_PRIVATE_DATA *Private, IN UINT8 Slot)
EFI_STATUS UfsRwAttributes(IN UFS_PASS_THRU_PRIVATE_DATA *Private, IN BOOLEAN Read, IN UINT8 AttrId, IN UINT8 Index, IN UINT8 Selector, IN OUT UINT32 *Attributes)
VOID EFIAPI ProcessAsyncTaskList(IN EFI_EVENT Event, IN VOID *Context)
EFI_STATUS UfsStartExecCmd(IN UFS_PASS_THRU_PRIVATE_DATA *Private, IN UINT8 Slot)
EFI_STATUS UfsInitTaskManagementRequestList(IN UFS_PASS_THRU_PRIVATE_DATA *Private)
EFI_STATUS UfsCreateNopCommandDesc(IN UFS_PASS_THRU_PRIVATE_DATA *Private, IN UTP_TRD *Trd, OUT VOID **CmdDescHost, OUT VOID **CmdDescMapping)
EFI_STATUS UfsPrepareDataTransferBuffer(IN UFS_PASS_THRU_PRIVATE_DATA *Private, IN OUT UFS_PASS_THRU_TRANS_REQ *TransReq)
EFI_STATUS UfsExecUicCommands(IN UFS_PASS_THRU_PRIVATE_DATA *Private, IN OUT EDKII_UIC_COMMAND *UicCommand)
EFI_STATUS UfsInitCommandUpiu(IN OUT UTP_COMMAND_UPIU *Command, IN UINT8 Lun, IN UINT8 TaskTag, IN UINT8 *Cdb, IN UINT8 CdbLength, IN UFS_DATA_DIRECTION DataDirection, IN UINT32 ExpDataTranLen)
EFI_STATUS UfsControllerStop(IN UFS_PASS_THRU_PRIVATE_DATA *Private)
EFI_STATUS UfsFindAvailableSlotInTrl(IN UFS_PASS_THRU_PRIVATE_DATA *Private, OUT UINT8 *Slot)
EFI_STATUS UfsCreateScsiCommandDesc(IN UFS_PASS_THRU_PRIVATE_DATA *Private, IN UINT8 Lun, IN EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet, IN UTP_TRD *Trd, OUT VOID **CmdDescHost, OUT VOID **CmdDescMapping)
VOID DumpQueryResponseResult(IN UINT8 Result)
EFI_STATUS UfsCreateDMCommandDesc(IN UFS_PASS_THRU_PRIVATE_DATA *Private, IN UFS_DEVICE_MANAGEMENT_REQUEST_PACKET *Packet, IN UTP_TRD *Trd, OUT VOID **CmdDescHost, OUT VOID **CmdDescMapping)
EFI_STATUS UfsControllerInit(IN UFS_PASS_THRU_PRIVATE_DATA *Private)
EFI_STATUS UfsInitQueryRequestUpiu(IN OUT UTP_QUERY_REQ_UPIU *QueryReq, IN UINT8 TaskTag, IN UINT8 Opcode, IN UINT8 DescId, IN UINT8 Index, IN UINT8 Selector, IN UINTN DataSize OPTIONAL, IN UINT8 *Data OPTIONAL)
EFI_STATUS UfsSetFlag(IN UFS_PASS_THRU_PRIVATE_DATA *Private, IN UINT8 FlagId)
EDKII_UFS_HC_PLATFORM_OVERRIDE_HC_INFO OverrideHcInfo
EDKII_UFS_HC_PLATFORM_CALLBACK Callback