PEIM to produce gPeiUsbHostControllerPpiGuid based on gPeiUsbControllerPpiGuid\r
which is used to enable recovery function from USB Drivers.\r
\r
-Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved. <BR>\r
- \r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions\r
-of the BSD License which accompanies this distribution. The\r
-full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved. <BR>\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
#include "UhcPeim.h"\r
\r
+/**\r
+ Stop the host controller.\r
+\r
+ @param Uhc The UHCI device.\r
+ @param Timeout Max time allowed.\r
+\r
+ @retval EFI_SUCCESS The host controller is stopped.\r
+ @retval EFI_TIMEOUT Failed to stop the host controller.\r
+\r
+**/\r
+EFI_STATUS\r
+UhciStopHc (\r
+ IN USB_UHC_DEV *Uhc,\r
+ IN UINTN Timeout\r
+ )\r
+{\r
+ UINT16 CommandContent;\r
+ UINT16 UsbSts;\r
+ UINTN Index;\r
+\r
+ CommandContent = USBReadPortW (Uhc, Uhc->UsbHostControllerBaseAddress + USBCMD);\r
+ CommandContent &= USBCMD_RS;\r
+ USBWritePortW (Uhc, Uhc->UsbHostControllerBaseAddress + USBCMD, CommandContent);\r
+\r
+ //\r
+ // ensure the HC is in halt status after send the stop command\r
+ // Timeout is in us unit.\r
+ //\r
+ for (Index = 0; Index < (Timeout / 50) + 1; Index++) {\r
+ UsbSts = USBReadPortW (Uhc, Uhc->UsbHostControllerBaseAddress + USBSTS);\r
+\r
+ if ((UsbSts & USBSTS_HCH) == USBSTS_HCH) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ MicroSecondDelay (50);\r
+ }\r
+\r
+ return EFI_TIMEOUT;\r
+}\r
+\r
+/**\r
+ One notified function to stop the Host Controller at the end of PEI\r
+\r
+ @param[in] PeiServices Pointer to PEI Services Table.\r
+ @param[in] NotifyDescriptor Pointer to the descriptor for the Notification event that\r
+ caused this function to execute.\r
+ @param[in] Ppi Pointer to the PPI data associated with this function.\r
+\r
+ @retval EFI_SUCCESS The function completes successfully\r
+ @retval others\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UhcEndOfPei (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
+ IN VOID *Ppi\r
+ )\r
+{\r
+ USB_UHC_DEV *Uhc;\r
+\r
+ Uhc = PEI_RECOVERY_USB_UHC_DEV_FROM_THIS_NOTIFY (NotifyDescriptor);\r
+\r
+ //\r
+ // Stop the Host Controller\r
+ //\r
+ UhciStopHc (Uhc, 1000 * 1000);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
/**\r
Initializes Usb Host Controller.\r
\r
\r
UhcDev = (USB_UHC_DEV *) ((UINTN) TempPtr);\r
UhcDev->Signature = USB_UHC_DEV_SIGNATURE;\r
+ IoMmuInit (&UhcDev->IoMmu);\r
UhcDev->UsbHostControllerBaseAddress = (UINT32) BaseAddress;\r
\r
//\r
continue;\r
}\r
\r
+ UhcDev->EndOfPeiNotifyList.Flags = (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);\r
+ UhcDev->EndOfPeiNotifyList.Guid = &gEfiEndOfPeiSignalPpiGuid;\r
+ UhcDev->EndOfPeiNotifyList.Notify = UhcEndOfPei;\r
+\r
+ PeiServicesNotifyPpi (&UhcDev->EndOfPeiNotifyList);\r
+\r
Index++;\r
}\r
\r
\r
/**\r
Submits control transfer to a target USB device.\r
- \r
+\r
@param PeiServices The pointer of EFI_PEI_SERVICES.\r
@param This The pointer of PEI_USB_HOST_CONTROLLER_PPI.\r
@param DeviceAddress The target device address.\r
@param DeviceSpeed Target device speed.\r
- @param MaximumPacketLength Maximum packet size the default control transfer \r
+ @param MaximumPacketLength Maximum packet size the default control transfer\r
endpoint is capable of sending or receiving.\r
@param Request USB device request to send.\r
@param TransferDirection Specifies the data direction for the data stage.\r
TD_STRUCT *PtrStatusTD;\r
EFI_STATUS Status;\r
UINT32 DataLen;\r
- UINT8 *PtrDataSource;\r
- UINT8 *Ptr;\r
UINT8 DataToggle;\r
+ UINT8 *RequestPhy;\r
+ VOID *RequestMap;\r
+ UINT8 *DataPhy;\r
+ VOID *DataMap;\r
\r
UhcDev = PEI_RECOVERY_USB_UHC_DEV_FROM_UHCI_THIS (This);\r
\r
\r
ClearStatusReg (UhcDev, StatusReg);\r
\r
+ //\r
+ // Map the Request and data for bus master access,\r
+ // then create a list of TD for this transfer\r
+ //\r
+ Status = UhciMapUserRequest (UhcDev, Request, &RequestPhy, &RequestMap);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = UhciMapUserData (UhcDev, TransferDirection, Data, DataLength, &PktID, &DataPhy, &DataMap);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ if (RequestMap != NULL) {\r
+ IoMmuUnmap (UhcDev->IoMmu, RequestMap);\r
+ }\r
+ return Status;\r
+ }\r
+\r
//\r
// generate Setup Stage TD\r
//\r
0,\r
DeviceSpeed,\r
(UINT8 *) Request,\r
+ RequestPhy,\r
(UINT8) sizeof (EFI_USB_DEVICE_REQUEST),\r
&PtrSetupTD\r
);\r
//\r
// Data Stage of Control Transfer\r
//\r
- switch (TransferDirection) {\r
\r
- case EfiUsbDataIn:\r
- PktID = INPUT_PACKET_ID;\r
- PtrDataSource = Data;\r
- DataLen = (UINT32) *DataLength;\r
- Ptr = PtrDataSource;\r
- break;\r
-\r
- case EfiUsbDataOut:\r
- PktID = OUTPUT_PACKET_ID;\r
- PtrDataSource = Data;\r
- DataLen = (UINT32) *DataLength;\r
- Ptr = PtrDataSource;\r
- break;\r
-\r
- //\r
- // no data stage\r
- //\r
- case EfiUsbNoData:\r
- if (*DataLength != 0) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- PktID = OUTPUT_PACKET_ID;\r
- PtrDataSource = NULL;\r
- DataLen = 0;\r
- Ptr = NULL;\r
- break;\r
-\r
- default:\r
- return EFI_INVALID_PARAMETER;\r
+ if (TransferDirection == EfiUsbNoData) {\r
+ DataLen = 0;\r
+ } else {\r
+ DataLen = (UINT32) *DataLength;\r
}\r
\r
DataToggle = 1;\r
UhcDev,\r
DeviceAddress,\r
0,\r
- Ptr,\r
+ Data,\r
+ DataPhy,\r
PacketSize,\r
PktID,\r
DataToggle,\r
PtrPreTD = PtrTD;\r
\r
DataToggle ^= 1;\r
- Ptr += PacketSize;\r
+ Data = (VOID *) ((UINT8 *) Data + PacketSize);\r
+ DataPhy += PacketSize;\r
DataLen -= PacketSize;\r
}\r
\r
// if has errors that cause host controller halt, then return EFI_DEVICE_ERROR directly.\r
//\r
if (!IsStatusOK (UhcDev, StatusReg)) {\r
-\r
- ClearStatusReg (UhcDev, StatusReg);\r
*TransferResult |= EFI_USB_ERR_SYSTEM;\r
- return EFI_DEVICE_ERROR;\r
+ Status = EFI_DEVICE_ERROR;\r
}\r
\r
ClearStatusReg (UhcDev, StatusReg);\r
\r
+ if (DataMap != NULL) {\r
+ IoMmuUnmap (UhcDev->IoMmu, DataMap);\r
+ }\r
+ if (RequestMap != NULL) {\r
+ IoMmuUnmap (UhcDev->IoMmu, RequestMap);\r
+ }\r
+\r
return Status;\r
}\r
\r
/**\r
Submits bulk transfer to a bulk endpoint of a USB device.\r
- \r
+\r
@param PeiServices The pointer of EFI_PEI_SERVICES.\r
@param This The pointer of PEI_USB_HOST_CONTROLLER_PPI.\r
@param DeviceAddress Target device address.\r
@param EndPointAddress Endpoint number and its direction in bit 7.\r
- @param MaximumPacketLength Maximum packet size the endpoint is capable of \r
+ @param MaximumPacketLength Maximum packet size the endpoint is capable of\r
sending or receiving.\r
- @param Data Array of pointers to the buffers of data to transmit \r
+ @param Data Array of pointers to the buffers of data to transmit\r
from or receive into.\r
@param DataLength The lenght of the data buffer.\r
@param DataToggle On input, the initial data toggle for the transfer;\r
- On output, it is updated to to next data toggle to use of \r
+ On output, it is updated to to next data toggle to use of\r
the subsequent bulk transfer.\r
@param TimeOut Indicates the maximum time, in millisecond, which the\r
transfer is allowed to complete.\r
TD_STRUCT *PtrPreTD;\r
\r
UINT8 PktID;\r
- UINT8 *PtrDataSource;\r
- UINT8 *Ptr;\r
\r
BOOLEAN IsFirstTD;\r
\r
\r
UINT16 CommandContent;\r
\r
+ UINT8 *DataPhy;\r
+ VOID *DataMap;\r
+\r
UhcDev = PEI_RECOVERY_USB_UHC_DEV_FROM_UHCI_THIS (This);\r
\r
//\r
PtrFirstTD = NULL;\r
PtrPreTD = NULL;\r
DataLen = 0;\r
- Ptr = NULL;\r
\r
ShortPacketEnable = FALSE;\r
\r
\r
ClearStatusReg (UhcDev, StatusReg);\r
\r
+ //\r
+ // Map the source data buffer for bus master access,\r
+ // then create a list of TDs\r
+ //\r
if ((EndPointAddress & 0x80) != 0) {\r
TransferDirection = EfiUsbDataIn;\r
} else {\r
TransferDirection = EfiUsbDataOut;\r
}\r
\r
- switch (TransferDirection) {\r
-\r
- case EfiUsbDataIn:\r
- ShortPacketEnable = TRUE;\r
- PktID = INPUT_PACKET_ID;\r
- PtrDataSource = Data;\r
- DataLen = (UINT32) *DataLength;\r
- Ptr = PtrDataSource;\r
- break;\r
-\r
- case EfiUsbDataOut:\r
- PktID = OUTPUT_PACKET_ID;\r
- PtrDataSource = Data;\r
- DataLen = (UINT32) *DataLength;\r
- Ptr = PtrDataSource;\r
- break;\r
+ Status = UhciMapUserData (UhcDev, TransferDirection, Data, DataLength, &PktID, &DataPhy, &DataMap);\r
\r
- default:\r
- break;\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
}\r
\r
+ DataLen = (UINT32) *DataLength;\r
+\r
PtrQH = UhcDev->BulkQH;\r
\r
IsFirstTD = TRUE;\r
UhcDev,\r
DeviceAddress,\r
EndPointAddress,\r
- Ptr,\r
+ Data,\r
+ DataPhy,\r
PacketSize,\r
PktID,\r
*DataToggle,\r
PtrPreTD = PtrTD;\r
\r
*DataToggle ^= 1;\r
- Ptr += PacketSize;\r
+ Data = (VOID *) ((UINT8 *) Data + PacketSize);\r
+ DataPhy += PacketSize;\r
DataLen -= PacketSize;\r
}\r
//\r
// if has errors that cause host controller halt, then return EFI_DEVICE_ERROR directly.\r
//\r
if (!IsStatusOK (UhcDev, StatusReg)) {\r
-\r
- ClearStatusReg (UhcDev, StatusReg);\r
*TransferResult |= EFI_USB_ERR_SYSTEM;\r
- return EFI_DEVICE_ERROR;\r
+ Status = EFI_DEVICE_ERROR;\r
}\r
\r
ClearStatusReg (UhcDev, StatusReg);\r
\r
+ if (DataMap != NULL) {\r
+ IoMmuUnmap (UhcDev->IoMmu, DataMap);\r
+ }\r
+\r
return Status;\r
}\r
\r
Retrieves the number of root hub ports.\r
\r
@param[in] PeiServices The pointer to the PEI Services Table.\r
- @param[in] This The pointer to this instance of the \r
+ @param[in] This The pointer to this instance of the\r
PEI_USB_HOST_CONTROLLER_PPI.\r
- @param[out] PortNumber The pointer to the number of the root hub ports. \r
- \r
+ @param[out] PortNumber The pointer to the number of the root hub ports.\r
+\r
@retval EFI_SUCCESS The port number was retrieved successfully.\r
@retval EFI_INVALID_PARAMETER PortNumber is NULL.\r
\r
\r
/**\r
Retrieves the current status of a USB root hub port.\r
- \r
+\r
@param PeiServices The pointer of EFI_PEI_SERVICES.\r
@param This The pointer of PEI_USB_HOST_CONTROLLER_PPI.\r
- @param PortNumber The root hub port to retrieve the state from. \r
+ @param PortNumber The root hub port to retrieve the state from.\r
@param PortStatus Variable to receive the port state.\r
\r
@retval EFI_SUCCESS The status of the USB root hub port specified.\r
\r
/**\r
Sets a feature for the specified root hub port.\r
- \r
+\r
@param PeiServices The pointer of EFI_PEI_SERVICES\r
@param This The pointer of PEI_USB_HOST_CONTROLLER_PPI\r
@param PortNumber Root hub port to set.\r
\r
/**\r
Clears a feature for the specified root hub port.\r
- \r
+\r
@param PeiServices The pointer of EFI_PEI_SERVICES.\r
@param This The pointer of PEI_USB_HOST_CONTROLLER_PPI.\r
@param PortNumber Specifies the root hub port whose feature\r
@param PortFeature Indicates the feature selector associated with the\r
feature clear request.\r
\r
- @retval EFI_SUCCESS The feature specified by PortFeature was cleared \r
+ @retval EFI_SUCCESS The feature specified by PortFeature was cleared\r
for the USB root hub port specified by PortNumber.\r
@retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.\r
\r
ASSERT (UhcDev->BulkQH != NULL);\r
\r
//\r
- //Set the corresponding QH pointer \r
+ //Set the corresponding QH pointer\r
//\r
SetQHHorizontalLinkPtr(UhcDev->ConfigQH, UhcDev->BulkQH);\r
SetQHHorizontalQHorTDSelect (UhcDev->ConfigQH, TRUE);\r
\r
/**\r
Read a 16bit width data from Uhc HC IO space register.\r
- \r
+\r
@param UhcDev The UHCI device.\r
@param Port The IO space address of the register.\r
\r
\r
/**\r
Write a 16bit width data into Uhc HC IO space register.\r
- \r
+\r
@param UhcDev The UHCI device.\r
@param Port The IO space address of the register.\r
@param Data The data written into the register.\r
\r
/**\r
Write a 32bit width data into Uhc HC IO space register.\r
- \r
+\r
@param UhcDev The UHCI device.\r
@param Port The IO space address of the register.\r
@param Data The data written into the register.\r
\r
/**\r
Clear the content of UHCI's Status Register.\r
- \r
+\r
@param UhcDev The UHCI device.\r
@param StatusAddr The IO space address of the register.\r
\r
}\r
}\r
\r
-/**\r
- Get Current Frame Number.\r
-\r
- @param UhcDev The UHCI device.\r
- @param FrameNumberAddr The address of frame list register.\r
-\r
- @retval The content of the frame list register.\r
\r
-**/\r
-UINT16\r
-GetCurrentFrameNumber (\r
- IN USB_UHC_DEV *UhcDev,\r
- IN UINT32 FrameNumberAddr\r
- )\r
-{\r
- //\r
- // Gets value in the USB frame number register.\r
- //\r
- return (UINT16) (USBReadPortW (UhcDev, FrameNumberAddr) & 0x03FF);\r
-}\r
\r
/**\r
Set Frame List Base Address.\r
PtrQH->QueueHead.QHHorizontalPtr = (UINT32) (UINTN) PtrNext >> 4;\r
}\r
\r
-/**\r
- Get the horizontal link pointer in QH.\r
-\r
- @param PtrQH Place to store QH_STRUCT pointer.\r
\r
- @retval The horizontal link pointer in QH.\r
-\r
-**/\r
-VOID *\r
-GetQHHorizontalLinkPtr (\r
- IN QH_STRUCT *PtrQH\r
- )\r
-{\r
- //\r
- // Restore the 28bit address to 32bit address\r
- // (take 32bit address as an example)\r
- //\r
- return (VOID *) (UINTN) ((PtrQH->QueueHead.QHHorizontalPtr) << 4);\r
-}\r
\r
/**\r
Set a QH or TD horizontally to be connected with a specific QH.\r
PtrQH->QueueHead.QHVerticalTerminate = IsValid ? 0 : 1;\r
}\r
\r
-/**\r
- Get the vertical validor bit in QH.\r
-\r
- @param PtrQH Place to store QH_STRUCT pointer.\r
-\r
- @retval The vertical linker is valid or not.\r
\r
-**/\r
-BOOLEAN\r
-GetQHHorizontalValidorInvalid (\r
- IN QH_STRUCT *PtrQH\r
- )\r
-{\r
- //\r
- // If TRUE, meaning the Horizontal Link Pointer field is valid,\r
- // else, the field is invalid.\r
- //\r
- return (BOOLEAN) (!(PtrQH->QueueHead.QHHorizontalTerminate));\r
-}\r
\r
/**\r
Allocate TD or QH Struct.\r
@param DevAddr Device address.\r
@param Endpoint Endpoint number.\r
@param DeviceSpeed Device Speed.\r
- @param DevRequest Device reuquest.\r
+ @param DevRequest CPU memory address of request structure buffer to transfer.\r
+ @param RequestPhy PCI memory address of request structure buffer to transfer.\r
@param RequestLen Request length.\r
@param PtrTD TD_STRUCT generated.\r
\r
IN UINT8 Endpoint,\r
IN UINT8 DeviceSpeed,\r
IN UINT8 *DevRequest,\r
+ IN UINT8 *RequestPhy,\r
IN UINT8 RequestLen,\r
OUT TD_STRUCT **PtrTD\r
)\r
\r
TdStruct->PtrTDBuffer = (UINT8 *) DevRequest;\r
TdStruct->TDBufferLength = RequestLen;\r
- SetTDDataBuffer (TdStruct);\r
+ //\r
+ // Set the beginning address of the buffer that will be used\r
+ // during the transaction.\r
+ //\r
+ TdStruct->TDData.TDBufferPtr = (UINT32) (UINTN) RequestPhy;\r
\r
*PtrTD = TdStruct;\r
\r
@param UhcDev The UHCI device.\r
@param DevAddr Device address.\r
@param Endpoint Endpoint number.\r
- @param PtrData Data buffer.\r
+ @param PtrData CPU memory address of user data buffer to transfer.\r
+ @param DataPhy PCI memory address of user data buffer to transfer.\r
@param Len Data length.\r
@param PktID PacketID.\r
@param Toggle Data toggle value.\r
IN UINT8 DevAddr,\r
IN UINT8 Endpoint,\r
IN UINT8 *PtrData,\r
+ IN UINT8 *DataPhy,\r
IN UINT8 Len,\r
IN UINT8 PktID,\r
IN UINT8 Toggle,\r
\r
TdStruct->PtrTDBuffer = (UINT8 *) PtrData;\r
TdStruct->TDBufferLength = Len;\r
- SetTDDataBuffer (TdStruct);\r
+ //\r
+ // Set the beginning address of the buffer that will be used\r
+ // during the transaction.\r
+ //\r
+ TdStruct->TDData.TDBufferPtr = (UINT32) (UINTN) DataPhy;\r
\r
*PtrTD = TdStruct;\r
\r
\r
PtrTDStruct->PtrTDBuffer = NULL;\r
PtrTDStruct->TDBufferLength = 0;\r
- SetTDDataBuffer (PtrTDStruct);\r
+ //\r
+ // Set the beginning address of the buffer that will be used\r
+ // during the transaction.\r
+ //\r
+ PtrTDStruct->TDData.TDBufferPtr = 0;\r
\r
*PtrTD = PtrTDStruct;\r
\r
return (VOID *) (UINTN) ((PtrTDStruct->TDData.TDLinkPtr) << 4);\r
}\r
\r
-/**\r
- Get the information about whether the Link Pointer field pointing to\r
- a QH or a TD.\r
-\r
- @param PtrTDStruct Place to store TD_STRUCT pointer.\r
-\r
- @retval whether the Link Pointer field pointing to a QH or a TD.\r
\r
-**/\r
-BOOLEAN\r
-IsTDLinkPtrQHOrTD (\r
- IN TD_STRUCT *PtrTDStruct\r
- )\r
-{\r
- //\r
- // Get the information about whether the Link Pointer field pointing to\r
- // a QH or a TD.\r
- //\r
- return (BOOLEAN) (PtrTDStruct->TDData.TDLinkPtrQSelect);\r
-}\r
\r
/**\r
Enable/Disable short packet detection mechanism.\r
PtrTDStruct->TDData.TDTokenPID = PacketID;\r
}\r
\r
-/**\r
- Set the beginning address of the data buffer that will be used\r
- during the transaction.\r
-\r
- @param PtrTDStruct Place to store TD_STRUCT pointer.\r
-\r
-**/\r
-VOID\r
-SetTDDataBuffer (\r
- IN TD_STRUCT *PtrTDStruct\r
- )\r
-{\r
- //\r
- // Set the beginning address of the data buffer that will be used\r
- // during the transaction.\r
- //\r
- PtrTDStruct->TDData.TDBufferPtr = (UINT32) (UINTN) (PtrTDStruct->PtrTDBuffer);\r
-}\r
-\r
/**\r
Detect whether the TD is active.\r
\r
)\r
{\r
EFI_STATUS Status;\r
- EFI_PHYSICAL_ADDRESS TempPtr;\r
+ UINT8 *TempPtr;\r
UINTN MemPages;\r
UINT8 *Ptr;\r
+ VOID *Mapping;\r
+ EFI_PHYSICAL_ADDRESS MappedAddr;\r
\r
//\r
// Memory Block uses MemoryBlockSizeInPages pages,\r
// memory management header and bit array use 1 page\r
//\r
MemPages = MemoryBlockSizeInPages + 1;\r
- Status = PeiServicesAllocatePages (\r
- EfiBootServicesData,\r
+ Status = IoMmuAllocateBuffer (\r
+ UhcDev->IoMmu,\r
MemPages,\r
- &TempPtr\r
+ (VOID **) &TempPtr,\r
+ &MappedAddr,\r
+ &Mapping\r
);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
+ if (EFI_ERROR (Status) || (TempPtr == NULL)) {\r
+ return EFI_OUT_OF_RESOURCES;\r
}\r
\r
- Ptr = (UINT8 *) ((UINTN) TempPtr);\r
+ Ptr = TempPtr;\r
\r
ZeroMem (Ptr, MemPages * EFI_PAGE_SIZE);\r
\r
//\r
// Memory block initial address\r
//\r
- Ptr = (UINT8 *) ((UINTN) TempPtr);\r
+ Ptr = TempPtr;\r
Ptr += EFI_PAGE_SIZE;\r
(*MemoryHeader)->MemoryBlockPtr = Ptr;\r
//\r
StartBitPos = (UINT8) (((Pool - TempHeaderPtr->MemoryBlockPtr) / 32) % 8);\r
\r
//\r
- // reset associated bits in bit arry\r
+ // reset associated bits in bit array\r
//\r
for (Index = StartBytePos, Index2 = StartBitPos, Count = 0; Count < (RealAllocSize / 32); Count++) {\r
\r
}\r
}\r
\r
+\r
+\r
+\r
+\r
/**\r
- Judge the memory block in the memory header is empty or not.\r
+ Map address of request structure buffer.\r
\r
- @param MemoryHeaderPtr A pointer to the memory header list.\r
+ @param Uhc The UHCI device.\r
+ @param Request The user request buffer.\r
+ @param MappedAddr Mapped address of request.\r
+ @param Map Identificaion of this mapping to return.\r
\r
- @retval Whether the memory block in the memory header is empty or not.\r
+ @return EFI_SUCCESS Success.\r
+ @return EFI_DEVICE_ERROR Fail to map the user request.\r
\r
**/\r
-BOOLEAN\r
-IsMemoryBlockEmptied (\r
- IN MEMORY_MANAGE_HEADER *MemoryHeaderPtr\r
+EFI_STATUS\r
+UhciMapUserRequest (\r
+ IN USB_UHC_DEV *Uhc,\r
+ IN OUT VOID *Request,\r
+ OUT UINT8 **MappedAddr,\r
+ OUT VOID **Map\r
)\r
{\r
- UINTN Index;\r
+ EFI_STATUS Status;\r
+ UINTN Len;\r
+ EFI_PHYSICAL_ADDRESS PhyAddr;\r
+\r
+ Len = sizeof (EFI_USB_DEVICE_REQUEST);\r
+ Status = IoMmuMap (\r
+ Uhc->IoMmu,\r
+ EdkiiIoMmuOperationBusMasterRead,\r
+ Request,\r
+ &Len,\r
+ &PhyAddr,\r
+ Map\r
+ );\r
\r
- for (Index = 0; Index < MemoryHeaderPtr->BitArraySizeInBytes; Index++) {\r
- if (MemoryHeaderPtr->BitArrayPtr[Index] != 0) {\r
- return FALSE;\r
- }\r
+ if (!EFI_ERROR (Status)) {\r
+ *MappedAddr = (UINT8 *) (UINTN) PhyAddr;\r
}\r
\r
- return TRUE;\r
+ return Status;\r
}\r
\r
/**\r
- remove a memory header from list.\r
+ Map address of user data buffer.\r
+\r
+ @param Uhc The UHCI device.\r
+ @param Direction Direction of the data transfer.\r
+ @param Data The user data buffer.\r
+ @param Len Length of the user data.\r
+ @param PktId Packet identificaion.\r
+ @param MappedAddr Mapped address to return.\r
+ @param Map Identificaion of this mapping to return.\r
\r
- @param FirstMemoryHeader A pointer to the memory header list.\r
- @param FreeMemoryHeader A memory header to be removed into the list.\r
+ @return EFI_SUCCESS Success.\r
+ @return EFI_DEVICE_ERROR Fail to map the user data.\r
\r
**/\r
-VOID\r
-DelinkMemoryBlock (\r
- IN MEMORY_MANAGE_HEADER *FirstMemoryHeader,\r
- IN MEMORY_MANAGE_HEADER *FreeMemoryHeader\r
+EFI_STATUS\r
+UhciMapUserData (\r
+ IN USB_UHC_DEV *Uhc,\r
+ IN EFI_USB_DATA_DIRECTION Direction,\r
+ IN VOID *Data,\r
+ IN OUT UINTN *Len,\r
+ OUT UINT8 *PktId,\r
+ OUT UINT8 **MappedAddr,\r
+ OUT VOID **Map\r
)\r
{\r
- MEMORY_MANAGE_HEADER *TempHeaderPtr;\r
+ EFI_STATUS Status;\r
+ EFI_PHYSICAL_ADDRESS PhyAddr;\r
\r
- if ((FirstMemoryHeader == NULL) || (FreeMemoryHeader == NULL)) {\r
- return ;\r
- }\r
+ Status = EFI_SUCCESS;\r
\r
- for (TempHeaderPtr = FirstMemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) {\r
+ switch (Direction) {\r
+ case EfiUsbDataIn:\r
+ //\r
+ // BusMasterWrite means cpu read\r
+ //\r
+ *PktId = INPUT_PACKET_ID;\r
+ Status = IoMmuMap (\r
+ Uhc->IoMmu,\r
+ EdkiiIoMmuOperationBusMasterWrite,\r
+ Data,\r
+ Len,\r
+ &PhyAddr,\r
+ Map\r
+ );\r
\r
- if (TempHeaderPtr->Next == FreeMemoryHeader) {\r
- //\r
- // Link the before and after\r
- //\r
- TempHeaderPtr->Next = FreeMemoryHeader->Next;\r
- break;\r
+ if (EFI_ERROR (Status)) {\r
+ goto EXIT;\r
}\r
+\r
+ *MappedAddr = (UINT8 *) (UINTN) PhyAddr;\r
+ break;\r
+\r
+ case EfiUsbDataOut:\r
+ *PktId = OUTPUT_PACKET_ID;\r
+ Status = IoMmuMap (\r
+ Uhc->IoMmu,\r
+ EdkiiIoMmuOperationBusMasterRead,\r
+ Data,\r
+ Len,\r
+ &PhyAddr,\r
+ Map\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ goto EXIT;\r
+ }\r
+\r
+ *MappedAddr = (UINT8 *) (UINTN) PhyAddr;\r
+ break;\r
+\r
+ case EfiUsbNoData:\r
+ if ((Len != NULL) && (*Len != 0)) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto EXIT;\r
+ }\r
+\r
+ *PktId = OUTPUT_PACKET_ID;\r
+ *MappedAddr = NULL;\r
+ *Map = NULL;\r
+ break;\r
+\r
+ default:\r
+ Status = EFI_INVALID_PARAMETER;\r
}\r
+\r
+EXIT:\r
+ return Status;\r
}\r
+\r