MdeModulePkg UhciPei: Support IoMmu
Update the UhciPei driver to consume IOMMU_PPI to allocate DMA buffer. If no IOMMU_PPI exists, this driver still calls PEI service to allocate DMA buffer, with assumption that DRAM==DMA. Cc: Jiewen Yao <jiewen.yao@intel.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Star Zeng <star.zeng@intel.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
PEIM to produce gPeiUsbHostControllerPpiGuid based on gPeiUsbControllerPpiGuid
|
||||
which is used to enable recovery function from USB Drivers.
|
||||
|
||||
Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved. <BR>
|
||||
Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved. <BR>
|
||||
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions
|
||||
@@ -17,6 +17,78 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
#include "UhcPeim.h"
|
||||
|
||||
/**
|
||||
Stop the host controller.
|
||||
|
||||
@param Uhc The UHCI device.
|
||||
@param Timeout Max time allowed.
|
||||
|
||||
@retval EFI_SUCCESS The host controller is stopped.
|
||||
@retval EFI_TIMEOUT Failed to stop the host controller.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
UhciStopHc (
|
||||
IN USB_UHC_DEV *Uhc,
|
||||
IN UINTN Timeout
|
||||
)
|
||||
{
|
||||
UINT16 CommandContent;
|
||||
UINT16 UsbSts;
|
||||
UINTN Index;
|
||||
|
||||
CommandContent = USBReadPortW (Uhc, Uhc->UsbHostControllerBaseAddress + USBCMD);
|
||||
CommandContent &= USBCMD_RS;
|
||||
USBWritePortW (Uhc, Uhc->UsbHostControllerBaseAddress + USBCMD, CommandContent);
|
||||
|
||||
//
|
||||
// ensure the HC is in halt status after send the stop command
|
||||
// Timeout is in us unit.
|
||||
//
|
||||
for (Index = 0; Index < (Timeout / 50) + 1; Index++) {
|
||||
UsbSts = USBReadPortW (Uhc, Uhc->UsbHostControllerBaseAddress + USBSTS);
|
||||
|
||||
if ((UsbSts & USBSTS_HCH) == USBSTS_HCH) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
MicroSecondDelay (50);
|
||||
}
|
||||
|
||||
return EFI_TIMEOUT;
|
||||
}
|
||||
|
||||
/**
|
||||
One notified function to stop the Host Controller at the end of PEI
|
||||
|
||||
@param[in] PeiServices Pointer to PEI Services Table.
|
||||
@param[in] NotifyDescriptor Pointer to the descriptor for the Notification event that
|
||||
caused this function to execute.
|
||||
@param[in] Ppi Pointer to the PPI data associated with this function.
|
||||
|
||||
@retval EFI_SUCCESS The function completes successfully
|
||||
@retval others
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
UhcEndOfPei (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
|
||||
IN VOID *Ppi
|
||||
)
|
||||
{
|
||||
USB_UHC_DEV *Uhc;
|
||||
|
||||
Uhc = PEI_RECOVERY_USB_UHC_DEV_FROM_THIS_NOTIFY (NotifyDescriptor);
|
||||
|
||||
//
|
||||
// Stop the Host Controller
|
||||
//
|
||||
UhciStopHc (Uhc, 1000 * 1000);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Initializes Usb Host Controller.
|
||||
|
||||
@@ -98,6 +170,7 @@ UhcPeimEntry (
|
||||
|
||||
UhcDev = (USB_UHC_DEV *) ((UINTN) TempPtr);
|
||||
UhcDev->Signature = USB_UHC_DEV_SIGNATURE;
|
||||
IoMmuInit (&UhcDev->IoMmu);
|
||||
UhcDev->UsbHostControllerBaseAddress = (UINT32) BaseAddress;
|
||||
|
||||
//
|
||||
@@ -133,6 +206,12 @@ UhcPeimEntry (
|
||||
continue;
|
||||
}
|
||||
|
||||
UhcDev->EndOfPeiNotifyList.Flags = (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
|
||||
UhcDev->EndOfPeiNotifyList.Guid = &gEfiEndOfPeiSignalPpiGuid;
|
||||
UhcDev->EndOfPeiNotifyList.Notify = UhcEndOfPei;
|
||||
|
||||
PeiServicesNotifyPpi (&UhcDev->EndOfPeiNotifyList);
|
||||
|
||||
Index++;
|
||||
}
|
||||
|
||||
@@ -190,9 +269,11 @@ UhcControlTransfer (
|
||||
TD_STRUCT *PtrStatusTD;
|
||||
EFI_STATUS Status;
|
||||
UINT32 DataLen;
|
||||
UINT8 *PtrDataSource;
|
||||
UINT8 *Ptr;
|
||||
UINT8 DataToggle;
|
||||
UINT8 *RequestPhy;
|
||||
VOID *RequestMap;
|
||||
UINT8 *DataPhy;
|
||||
VOID *DataMap;
|
||||
|
||||
UhcDev = PEI_RECOVERY_USB_UHC_DEV_FROM_UHCI_THIS (This);
|
||||
|
||||
@@ -216,6 +297,24 @@ UhcControlTransfer (
|
||||
|
||||
ClearStatusReg (UhcDev, StatusReg);
|
||||
|
||||
//
|
||||
// Map the Request and data for bus master access,
|
||||
// then create a list of TD for this transfer
|
||||
//
|
||||
Status = UhciMapUserRequest (UhcDev, Request, &RequestPhy, &RequestMap);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = UhciMapUserData (UhcDev, TransferDirection, Data, DataLength, &PktID, &DataPhy, &DataMap);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
if (RequestMap != NULL) {
|
||||
IoMmuUnmap (UhcDev->IoMmu, RequestMap);
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// generate Setup Stage TD
|
||||
//
|
||||
@@ -228,6 +327,7 @@ UhcControlTransfer (
|
||||
0,
|
||||
DeviceSpeed,
|
||||
(UINT8 *) Request,
|
||||
RequestPhy,
|
||||
(UINT8) sizeof (EFI_USB_DEVICE_REQUEST),
|
||||
&PtrSetupTD
|
||||
);
|
||||
@@ -242,38 +342,11 @@ UhcControlTransfer (
|
||||
//
|
||||
// Data Stage of Control Transfer
|
||||
//
|
||||
switch (TransferDirection) {
|
||||
|
||||
case EfiUsbDataIn:
|
||||
PktID = INPUT_PACKET_ID;
|
||||
PtrDataSource = Data;
|
||||
DataLen = (UINT32) *DataLength;
|
||||
Ptr = PtrDataSource;
|
||||
break;
|
||||
|
||||
case EfiUsbDataOut:
|
||||
PktID = OUTPUT_PACKET_ID;
|
||||
PtrDataSource = Data;
|
||||
DataLen = (UINT32) *DataLength;
|
||||
Ptr = PtrDataSource;
|
||||
break;
|
||||
|
||||
//
|
||||
// no data stage
|
||||
//
|
||||
case EfiUsbNoData:
|
||||
if (*DataLength != 0) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
PktID = OUTPUT_PACKET_ID;
|
||||
PtrDataSource = NULL;
|
||||
DataLen = 0;
|
||||
Ptr = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
if (TransferDirection == EfiUsbNoData) {
|
||||
DataLen = 0;
|
||||
} else {
|
||||
DataLen = (UINT32) *DataLength;
|
||||
}
|
||||
|
||||
DataToggle = 1;
|
||||
@@ -297,7 +370,8 @@ UhcControlTransfer (
|
||||
UhcDev,
|
||||
DeviceAddress,
|
||||
0,
|
||||
Ptr,
|
||||
Data,
|
||||
DataPhy,
|
||||
PacketSize,
|
||||
PktID,
|
||||
DataToggle,
|
||||
@@ -312,7 +386,8 @@ UhcControlTransfer (
|
||||
PtrPreTD = PtrTD;
|
||||
|
||||
DataToggle ^= 1;
|
||||
Ptr += PacketSize;
|
||||
Data = (VOID *) ((UINT8 *) Data + PacketSize);
|
||||
DataPhy += PacketSize;
|
||||
DataLen -= PacketSize;
|
||||
}
|
||||
|
||||
@@ -365,14 +440,19 @@ UhcControlTransfer (
|
||||
// if has errors that cause host controller halt, then return EFI_DEVICE_ERROR directly.
|
||||
//
|
||||
if (!IsStatusOK (UhcDev, StatusReg)) {
|
||||
|
||||
ClearStatusReg (UhcDev, StatusReg);
|
||||
*TransferResult |= EFI_USB_ERR_SYSTEM;
|
||||
return EFI_DEVICE_ERROR;
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
ClearStatusReg (UhcDev, StatusReg);
|
||||
|
||||
if (DataMap != NULL) {
|
||||
IoMmuUnmap (UhcDev->IoMmu, DataMap);
|
||||
}
|
||||
if (RequestMap != NULL) {
|
||||
IoMmuUnmap (UhcDev->IoMmu, RequestMap);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
@@ -431,8 +511,6 @@ UhcBulkTransfer (
|
||||
TD_STRUCT *PtrPreTD;
|
||||
|
||||
UINT8 PktID;
|
||||
UINT8 *PtrDataSource;
|
||||
UINT8 *Ptr;
|
||||
|
||||
BOOLEAN IsFirstTD;
|
||||
|
||||
@@ -444,6 +522,9 @@ UhcBulkTransfer (
|
||||
|
||||
UINT16 CommandContent;
|
||||
|
||||
UINT8 *DataPhy;
|
||||
VOID *DataMap;
|
||||
|
||||
UhcDev = PEI_RECOVERY_USB_UHC_DEV_FROM_UHCI_THIS (This);
|
||||
|
||||
//
|
||||
@@ -467,7 +548,6 @@ UhcBulkTransfer (
|
||||
PtrFirstTD = NULL;
|
||||
PtrPreTD = NULL;
|
||||
DataLen = 0;
|
||||
Ptr = NULL;
|
||||
|
||||
ShortPacketEnable = FALSE;
|
||||
|
||||
@@ -495,33 +575,24 @@ UhcBulkTransfer (
|
||||
|
||||
ClearStatusReg (UhcDev, StatusReg);
|
||||
|
||||
//
|
||||
// Map the source data buffer for bus master access,
|
||||
// then create a list of TDs
|
||||
//
|
||||
if ((EndPointAddress & 0x80) != 0) {
|
||||
TransferDirection = EfiUsbDataIn;
|
||||
} else {
|
||||
TransferDirection = EfiUsbDataOut;
|
||||
}
|
||||
|
||||
switch (TransferDirection) {
|
||||
Status = UhciMapUserData (UhcDev, TransferDirection, Data, DataLength, &PktID, &DataPhy, &DataMap);
|
||||
|
||||
case EfiUsbDataIn:
|
||||
ShortPacketEnable = TRUE;
|
||||
PktID = INPUT_PACKET_ID;
|
||||
PtrDataSource = Data;
|
||||
DataLen = (UINT32) *DataLength;
|
||||
Ptr = PtrDataSource;
|
||||
break;
|
||||
|
||||
case EfiUsbDataOut:
|
||||
PktID = OUTPUT_PACKET_ID;
|
||||
PtrDataSource = Data;
|
||||
DataLen = (UINT32) *DataLength;
|
||||
Ptr = PtrDataSource;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
DataLen = (UINT32) *DataLength;
|
||||
|
||||
PtrQH = UhcDev->BulkQH;
|
||||
|
||||
IsFirstTD = TRUE;
|
||||
@@ -540,7 +611,8 @@ UhcBulkTransfer (
|
||||
UhcDev,
|
||||
DeviceAddress,
|
||||
EndPointAddress,
|
||||
Ptr,
|
||||
Data,
|
||||
DataPhy,
|
||||
PacketSize,
|
||||
PktID,
|
||||
*DataToggle,
|
||||
@@ -570,7 +642,8 @@ UhcBulkTransfer (
|
||||
PtrPreTD = PtrTD;
|
||||
|
||||
*DataToggle ^= 1;
|
||||
Ptr += PacketSize;
|
||||
Data = (VOID *) ((UINT8 *) Data + PacketSize);
|
||||
DataPhy += PacketSize;
|
||||
DataLen -= PacketSize;
|
||||
}
|
||||
//
|
||||
@@ -604,14 +677,16 @@ UhcBulkTransfer (
|
||||
// if has errors that cause host controller halt, then return EFI_DEVICE_ERROR directly.
|
||||
//
|
||||
if (!IsStatusOK (UhcDev, StatusReg)) {
|
||||
|
||||
ClearStatusReg (UhcDev, StatusReg);
|
||||
*TransferResult |= EFI_USB_ERR_SYSTEM;
|
||||
return EFI_DEVICE_ERROR;
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
ClearStatusReg (UhcDev, StatusReg);
|
||||
|
||||
if (DataMap != NULL) {
|
||||
IoMmuUnmap (UhcDev->IoMmu, DataMap);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
@@ -1492,7 +1567,8 @@ CreateTD (
|
||||
@param DevAddr Device address.
|
||||
@param Endpoint Endpoint number.
|
||||
@param DeviceSpeed Device Speed.
|
||||
@param DevRequest Device reuquest.
|
||||
@param DevRequest CPU memory address of request structure buffer to transfer.
|
||||
@param RequestPhy PCI memory address of request structure buffer to transfer.
|
||||
@param RequestLen Request length.
|
||||
@param PtrTD TD_STRUCT generated.
|
||||
|
||||
@@ -1507,6 +1583,7 @@ GenSetupStageTD (
|
||||
IN UINT8 Endpoint,
|
||||
IN UINT8 DeviceSpeed,
|
||||
IN UINT8 *DevRequest,
|
||||
IN UINT8 *RequestPhy,
|
||||
IN UINT8 RequestLen,
|
||||
OUT TD_STRUCT **PtrTD
|
||||
)
|
||||
@@ -1583,7 +1660,11 @@ GenSetupStageTD (
|
||||
|
||||
TdStruct->PtrTDBuffer = (UINT8 *) DevRequest;
|
||||
TdStruct->TDBufferLength = RequestLen;
|
||||
SetTDDataBuffer (TdStruct);
|
||||
//
|
||||
// Set the beginning address of the buffer that will be used
|
||||
// during the transaction.
|
||||
//
|
||||
TdStruct->TDData.TDBufferPtr = (UINT32) (UINTN) RequestPhy;
|
||||
|
||||
*PtrTD = TdStruct;
|
||||
|
||||
@@ -1596,7 +1677,8 @@ GenSetupStageTD (
|
||||
@param UhcDev The UHCI device.
|
||||
@param DevAddr Device address.
|
||||
@param Endpoint Endpoint number.
|
||||
@param PtrData Data buffer.
|
||||
@param PtrData CPU memory address of user data buffer to transfer.
|
||||
@param DataPhy PCI memory address of user data buffer to transfer.
|
||||
@param Len Data length.
|
||||
@param PktID PacketID.
|
||||
@param Toggle Data toggle value.
|
||||
@@ -1613,6 +1695,7 @@ GenDataTD (
|
||||
IN UINT8 DevAddr,
|
||||
IN UINT8 Endpoint,
|
||||
IN UINT8 *PtrData,
|
||||
IN UINT8 *DataPhy,
|
||||
IN UINT8 Len,
|
||||
IN UINT8 PktID,
|
||||
IN UINT8 Toggle,
|
||||
@@ -1700,7 +1783,11 @@ GenDataTD (
|
||||
|
||||
TdStruct->PtrTDBuffer = (UINT8 *) PtrData;
|
||||
TdStruct->TDBufferLength = Len;
|
||||
SetTDDataBuffer (TdStruct);
|
||||
//
|
||||
// Set the beginning address of the buffer that will be used
|
||||
// during the transaction.
|
||||
//
|
||||
TdStruct->TDData.TDBufferPtr = (UINT32) (UINTN) DataPhy;
|
||||
|
||||
*PtrTD = TdStruct;
|
||||
|
||||
@@ -1803,7 +1890,11 @@ CreateStatusTD (
|
||||
|
||||
PtrTDStruct->PtrTDBuffer = NULL;
|
||||
PtrTDStruct->TDBufferLength = 0;
|
||||
SetTDDataBuffer (PtrTDStruct);
|
||||
//
|
||||
// Set the beginning address of the buffer that will be used
|
||||
// during the transaction.
|
||||
//
|
||||
PtrTDStruct->TDData.TDBufferPtr = 0;
|
||||
|
||||
*PtrTD = PtrTDStruct;
|
||||
|
||||
@@ -2173,25 +2264,6 @@ SetTDTokenPacketID (
|
||||
PtrTDStruct->TDData.TDTokenPID = PacketID;
|
||||
}
|
||||
|
||||
/**
|
||||
Set the beginning address of the data buffer that will be used
|
||||
during the transaction.
|
||||
|
||||
@param PtrTDStruct Place to store TD_STRUCT pointer.
|
||||
|
||||
**/
|
||||
VOID
|
||||
SetTDDataBuffer (
|
||||
IN TD_STRUCT *PtrTDStruct
|
||||
)
|
||||
{
|
||||
//
|
||||
// Set the beginning address of the data buffer that will be used
|
||||
// during the transaction.
|
||||
//
|
||||
PtrTDStruct->TDData.TDBufferPtr = (UINT32) (UINTN) (PtrTDStruct->PtrTDBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
Detect whether the TD is active.
|
||||
|
||||
@@ -2773,25 +2845,29 @@ CreateMemoryBlock (
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_PHYSICAL_ADDRESS TempPtr;
|
||||
UINT8 *TempPtr;
|
||||
UINTN MemPages;
|
||||
UINT8 *Ptr;
|
||||
VOID *Mapping;
|
||||
EFI_PHYSICAL_ADDRESS MappedAddr;
|
||||
|
||||
//
|
||||
// Memory Block uses MemoryBlockSizeInPages pages,
|
||||
// memory management header and bit array use 1 page
|
||||
//
|
||||
MemPages = MemoryBlockSizeInPages + 1;
|
||||
Status = PeiServicesAllocatePages (
|
||||
EfiBootServicesData,
|
||||
Status = IoMmuAllocateBuffer (
|
||||
UhcDev->IoMmu,
|
||||
MemPages,
|
||||
&TempPtr
|
||||
(VOID **) &TempPtr,
|
||||
&MappedAddr,
|
||||
&Mapping
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Ptr = (UINT8 *) ((UINTN) TempPtr);
|
||||
Ptr = TempPtr;
|
||||
|
||||
ZeroMem (Ptr, MemPages * EFI_PAGE_SIZE);
|
||||
|
||||
@@ -2810,7 +2886,7 @@ CreateMemoryBlock (
|
||||
//
|
||||
// Memory block initial address
|
||||
//
|
||||
Ptr = (UINT8 *) ((UINTN) TempPtr);
|
||||
Ptr = TempPtr;
|
||||
Ptr += EFI_PAGE_SIZE;
|
||||
(*MemoryHeader)->MemoryBlockPtr = Ptr;
|
||||
//
|
||||
@@ -3217,3 +3293,135 @@ DelinkMemoryBlock (
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Map address of request structure buffer.
|
||||
|
||||
@param Uhc The UHCI device.
|
||||
@param Request The user request buffer.
|
||||
@param MappedAddr Mapped address of request.
|
||||
@param Map Identificaion of this mapping to return.
|
||||
|
||||
@return EFI_SUCCESS Success.
|
||||
@return EFI_DEVICE_ERROR Fail to map the user request.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
UhciMapUserRequest (
|
||||
IN USB_UHC_DEV *Uhc,
|
||||
IN OUT VOID *Request,
|
||||
OUT UINT8 **MappedAddr,
|
||||
OUT VOID **Map
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN Len;
|
||||
EFI_PHYSICAL_ADDRESS PhyAddr;
|
||||
|
||||
Len = sizeof (EFI_USB_DEVICE_REQUEST);
|
||||
Status = IoMmuMap (
|
||||
Uhc->IoMmu,
|
||||
EdkiiIoMmuOperationBusMasterRead,
|
||||
Request,
|
||||
&Len,
|
||||
&PhyAddr,
|
||||
Map
|
||||
);
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
*MappedAddr = (UINT8 *) (UINTN) PhyAddr;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Map address of user data buffer.
|
||||
|
||||
@param Uhc The UHCI device.
|
||||
@param Direction Direction of the data transfer.
|
||||
@param Data The user data buffer.
|
||||
@param Len Length of the user data.
|
||||
@param PktId Packet identificaion.
|
||||
@param MappedAddr Mapped address to return.
|
||||
@param Map Identificaion of this mapping to return.
|
||||
|
||||
@return EFI_SUCCESS Success.
|
||||
@return EFI_DEVICE_ERROR Fail to map the user data.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
UhciMapUserData (
|
||||
IN USB_UHC_DEV *Uhc,
|
||||
IN EFI_USB_DATA_DIRECTION Direction,
|
||||
IN VOID *Data,
|
||||
IN OUT UINTN *Len,
|
||||
OUT UINT8 *PktId,
|
||||
OUT UINT8 **MappedAddr,
|
||||
OUT VOID **Map
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_PHYSICAL_ADDRESS PhyAddr;
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
|
||||
switch (Direction) {
|
||||
case EfiUsbDataIn:
|
||||
//
|
||||
// BusMasterWrite means cpu read
|
||||
//
|
||||
*PktId = INPUT_PACKET_ID;
|
||||
Status = IoMmuMap (
|
||||
Uhc->IoMmu,
|
||||
EdkiiIoMmuOperationBusMasterWrite,
|
||||
Data,
|
||||
Len,
|
||||
&PhyAddr,
|
||||
Map
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
*MappedAddr = (UINT8 *) (UINTN) PhyAddr;
|
||||
break;
|
||||
|
||||
case EfiUsbDataOut:
|
||||
*PktId = OUTPUT_PACKET_ID;
|
||||
Status = IoMmuMap (
|
||||
Uhc->IoMmu,
|
||||
EdkiiIoMmuOperationBusMasterRead,
|
||||
Data,
|
||||
Len,
|
||||
&PhyAddr,
|
||||
Map
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
*MappedAddr = (UINT8 *) (UINTN) PhyAddr;
|
||||
break;
|
||||
|
||||
case EfiUsbNoData:
|
||||
if ((Len != NULL) && (*Len != 0)) {
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
*PktId = OUTPUT_PACKET_ID;
|
||||
*MappedAddr = NULL;
|
||||
*Map = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
EXIT:
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user