\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
@param[in] Lun The Lun on which the SCSI command is executed.\r
@param[in] Packet The pointer to the UFS_SCSI_REQUEST_PACKET data structure.\r
@param[in] Trd The pointer to the UTP Transfer Request Descriptor.\r
+ @param[out] BufferMap A resulting value, if not NULL, to pass to IoMmuUnmap().\r
\r
@retval EFI_SUCCESS The creation succeed.\r
@retval EFI_DEVICE_ERROR The creation failed.\r
**/\r
EFI_STATUS\r
UfsCreateScsiCommandDesc (\r
- IN UFS_PEIM_HC_PRIVATE_DATA *Private,\r
- IN UINT8 Lun,\r
- IN UFS_SCSI_REQUEST_PACKET *Packet,\r
- IN UTP_TRD *Trd\r
+ IN UFS_PEIM_HC_PRIVATE_DATA *Private,\r
+ IN UINT8 Lun,\r
+ IN UFS_SCSI_REQUEST_PACKET *Packet,\r
+ IN UTP_TRD *Trd,\r
+ OUT VOID **BufferMap\r
)\r
{\r
UINT8 *CommandDesc;\r
UTP_COMMAND_UPIU *CommandUpiu;\r
UTP_TR_PRD *PrdtBase;\r
UFS_DATA_DIRECTION DataDirection;\r
+ EFI_STATUS Status;\r
+ EDKII_IOMMU_OPERATION MapOp;\r
+ UINTN MapLength;\r
+ EFI_PHYSICAL_ADDRESS BufferPhyAddr;\r
\r
ASSERT ((Private != NULL) && (Packet != NULL) && (Trd != NULL));\r
\r
+ BufferPhyAddr = 0;\r
+\r
if (Packet->DataDirection == UfsDataIn) {\r
- Buffer = Packet->InDataBuffer;\r
- Length = Packet->InTransferLength;\r
+ Buffer = Packet->InDataBuffer;\r
+ Length = Packet->InTransferLength;\r
DataDirection = UfsDataIn;\r
+ MapOp = EdkiiIoMmuOperationBusMasterWrite;\r
} else {\r
Buffer = Packet->OutDataBuffer;\r
Length = Packet->OutTransferLength;\r
DataDirection = UfsDataOut;\r
+ MapOp = EdkiiIoMmuOperationBusMasterRead;\r
}\r
\r
if (Length == 0) {\r
DataDirection = UfsNoData;\r
+ } else {\r
+ MapLength = Length;\r
+ Status = IoMmuMap (MapOp, Buffer, &MapLength, &BufferPhyAddr, BufferMap);\r
+\r
+ if (EFI_ERROR (Status) || (MapLength != Length)) {\r
+ DEBUG ((DEBUG_ERROR, "UfsCreateScsiCommandDesc: Fail to map data buffer.\n"));\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
}\r
\r
PrdtNumber = (UINTN)DivU64x32 ((UINT64)Length + UFS_MAX_DATA_LEN_PER_PRD - 1, UFS_MAX_DATA_LEN_PER_PRD);\r
PrdtBase = (UTP_TR_PRD*)(CommandDesc + ROUNDUP8 (sizeof (UTP_COMMAND_UPIU)) + ROUNDUP8 (sizeof (UTP_RESPONSE_UPIU)));\r
\r
UfsInitCommandUpiu (CommandUpiu, Lun, Private->TaskTag++, Packet->Cdb, Packet->CdbLength, DataDirection, Length);\r
- UfsInitUtpPrdt (PrdtBase, Buffer, Length);\r
+ UfsInitUtpPrdt (PrdtBase, (VOID*)(UINTN)BufferPhyAddr, Length);\r
\r
//\r
// Fill UTP_TRD associated fields\r
UTP_RESPONSE_UPIU *Response;\r
UINT16 SenseDataLen;\r
UINT32 ResTranCount;\r
+ VOID *PacketBufferMap;\r
\r
//\r
// Find out which slot of transfer request list is available.\r
}\r
\r
Trd = ((UTP_TRD*)Private->UtpTrlBase) + Slot;\r
+ PacketBufferMap = NULL;\r
\r
//\r
// Fill transfer request descriptor to this slot.\r
//\r
- Status = UfsCreateScsiCommandDesc (Private, Lun, Packet, Trd);\r
+ Status = UfsCreateScsiCommandDesc (Private, Lun, Packet, Trd, &PacketBufferMap);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
}\r
\r
Exit:\r
+ if (PacketBufferMap != NULL) {\r
+ IoMmuUnmap (PacketBufferMap);\r
+ }\r
UfsStopExecCmd (Private, Slot);\r
UfsPeimFreeMem (Private->Pool, CmdDescBase, CmdDescSize);\r
\r
UINTN Address;\r
UINT32 Data;\r
UINT8 Nutmrs;\r
- EFI_PHYSICAL_ADDRESS Buffer;\r
+ VOID *CmdDescHost;\r
+ EFI_PHYSICAL_ADDRESS CmdDescPhyAddr;\r
+ VOID *CmdDescMapping;\r
EFI_STATUS Status;\r
\r
//\r
// Allocate and initialize UTP Task Management Request List.\r
//\r
Nutmrs = (UINT8) (RShiftU64 ((Private->Capabilities & UFS_HC_CAP_NUTMRS), 16) + 1);\r
- Status = PeiServicesAllocatePages (\r
- EfiBootServicesCode,\r
+ Status = IoMmuAllocateBuffer (\r
EFI_SIZE_TO_PAGES (Nutmrs * sizeof (UTP_TMRD)),\r
- &Buffer\r
+ &CmdDescHost,\r
+ &CmdDescPhyAddr,\r
+ &CmdDescMapping\r
);\r
-\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
}\r
\r
- ZeroMem ((VOID*)(UINTN)Buffer, EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (Nutmrs * sizeof (UTP_TMRD))));\r
+ ZeroMem (CmdDescHost, EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (Nutmrs * sizeof (UTP_TMRD))));\r
\r
//\r
// Program the UTP Task Management Request List Base Address and UTP Task Management\r
// Request List Base Address with a 64-bit address allocated at step 6.\r
//\r
Address = Private->UfsHcBase + UFS_HC_UTMRLBA_OFFSET; \r
- MmioWrite32 (Address, (UINT32)(UINTN)Buffer);\r
+ MmioWrite32 (Address, (UINT32)(UINTN)CmdDescPhyAddr);\r
Address = Private->UfsHcBase + UFS_HC_UTMRLBAU_OFFSET; \r
- MmioWrite32 (Address, (UINT32)RShiftU64 ((UINT64)Buffer, 32));\r
- Private->UtpTmrlBase = (VOID*)(UINTN)Buffer;\r
+ MmioWrite32 (Address, (UINT32)RShiftU64 ((UINT64)CmdDescPhyAddr, 32));\r
+ Private->UtpTmrlBase = (VOID*)(UINTN)CmdDescHost;\r
Private->Nutmrs = Nutmrs;\r
+ Private->TmrlMapping = CmdDescMapping;\r
\r
//\r
// Enable the UTP Task Management Request List by setting the UTP Task Management\r
UINTN Address;\r
UINT32 Data;\r
UINT8 Nutrs;\r
- EFI_PHYSICAL_ADDRESS Buffer;\r
+ VOID *CmdDescHost;\r
+ EFI_PHYSICAL_ADDRESS CmdDescPhyAddr;\r
+ VOID *CmdDescMapping;\r
EFI_STATUS Status;\r
\r
//\r
// Allocate and initialize UTP Transfer Request List.\r
//\r
Nutrs = (UINT8)((Private->Capabilities & UFS_HC_CAP_NUTRS) + 1);\r
- Status = PeiServicesAllocatePages (\r
- EfiBootServicesCode,\r
+ Status = IoMmuAllocateBuffer (\r
EFI_SIZE_TO_PAGES (Nutrs * sizeof (UTP_TRD)),\r
- &Buffer\r
+ &CmdDescHost,\r
+ &CmdDescPhyAddr,\r
+ &CmdDescMapping\r
);\r
-\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
}\r
\r
- ZeroMem ((VOID*)(UINTN)Buffer, EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (Nutrs * sizeof (UTP_TRD))));\r
+ ZeroMem (CmdDescHost, EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (Nutrs * sizeof (UTP_TRD))));\r
\r
//\r
// Program the UTP Transfer Request List Base Address and UTP Transfer Request List\r
// Base Address with a 64-bit address allocated at step 8.\r
//\r
Address = Private->UfsHcBase + UFS_HC_UTRLBA_OFFSET; \r
- MmioWrite32 (Address, (UINT32)(UINTN)Buffer);\r
+ MmioWrite32 (Address, (UINT32)(UINTN)CmdDescPhyAddr);\r
Address = Private->UfsHcBase + UFS_HC_UTRLBAU_OFFSET; \r
- MmioWrite32 (Address, (UINT32)RShiftU64 ((UINT64)Buffer, 32));\r
- Private->UtpTrlBase = (VOID*)(UINTN)Buffer;\r
+ MmioWrite32 (Address, (UINT32)RShiftU64 ((UINT64)CmdDescPhyAddr, 32));\r
+ Private->UtpTrlBase = (VOID*)(UINTN)CmdDescHost;\r
Private->Nutrs = Nutrs;\r
+ Private->TrlMapping = CmdDescMapping;\r
\r
//\r
// Enable the UTP Transfer Request List by setting the UTP Transfer Request List\r
Status = UfsInitTransferRequestList (Private);\r
if (EFI_ERROR (Status)) {\r
DEBUG ((EFI_D_ERROR, "UfsDevicePei: Transfer list initialization Fails, Status = %r\n", Status));\r
+\r
+ if (Private->TmrlMapping != NULL) {\r
+ IoMmuFreeBuffer (\r
+ EFI_SIZE_TO_PAGES (Private->Nutmrs * sizeof (UTP_TMRD)),\r
+ Private->UtpTmrlBase,\r
+ Private->TmrlMapping\r
+ );\r
+ Private->TmrlMapping = NULL;\r
+ }\r
+\r
return Status;\r
}\r
\r