Fix a bug that usb keybarod can not work well when it is inserted at a usb 2.0 hub.

It's due to AsyncInterruptList does not update the corresponding QTDHw->Data with pci bus master address.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10286 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
erictian 2010-03-19 06:54:35 +00:00
parent 33f30f1ee3
commit aa91de055c
8 changed files with 124 additions and 144 deletions

View File

@ -904,7 +904,12 @@ EhcUpdateAsyncRequest (
QtdHw->ErrCnt = QTD_MAX_ERR; QtdHw->ErrCnt = QTD_MAX_ERR;
QtdHw->CurPage = 0; QtdHw->CurPage = 0;
QtdHw->TotalBytes = (UINT32) Qtd->DataLen; QtdHw->TotalBytes = (UINT32) Qtd->DataLen;
QtdHw->Page[0] = EHC_LOW_32BIT (Qtd->Data); //
// calculate physical address by offset.
//
PciAddr = (UINTN)Urb->DataPhy + ((UINTN)Qtd->Data - (UINTN)Urb->Data);
QtdHw->Page[0] = EHC_LOW_32BIT (PciAddr);
QtdHw->PageHigh[0]= EHC_HIGH_32BIT (PciAddr);
} }
// //

View File

@ -949,7 +949,6 @@ Uhci2AsyncInterruptTransfer (
EFI_STATUS Status; EFI_STATUS Status;
UINT8 *DataPtr; UINT8 *DataPtr;
UINT8 *DataPhy; UINT8 *DataPhy;
VOID *DataMap;
UINT8 PktId; UINT8 PktId;
Uhc = UHC_FROM_USB2_HC_PROTO (This); Uhc = UHC_FROM_USB2_HC_PROTO (This);
@ -957,7 +956,6 @@ Uhci2AsyncInterruptTransfer (
IntTds = NULL; IntTds = NULL;
DataPtr = NULL; DataPtr = NULL;
DataPhy = NULL; DataPhy = NULL;
DataMap = NULL;
IsSlowDevice = (BOOLEAN) ((EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE); IsSlowDevice = (BOOLEAN) ((EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE);
@ -998,6 +996,12 @@ Uhci2AsyncInterruptTransfer (
return EFI_DEVICE_ERROR; return EFI_DEVICE_ERROR;
} }
if ((EndPointAddress & 0x80) == 0) {
PktId = OUTPUT_PACKET_ID;
} else {
PktId = INPUT_PACKET_ID;
}
// //
// Allocate and map source data buffer for bus master access. // Allocate and map source data buffer for bus master access.
// //
@ -1007,31 +1011,15 @@ Uhci2AsyncInterruptTransfer (
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }
DataPhy = (UINT8 *)UsbHcGetPciAddressForHostMem (Uhc->MemPool, DataPtr, DataLength);
OldTpl = gBS->RaiseTPL (UHCI_TPL); OldTpl = gBS->RaiseTPL (UHCI_TPL);
//
// Map the user data then create a queue head and
// list of TD for it.
//
Status = UhciMapUserData (
Uhc,
EfiUsbDataIn,
DataPtr,
&DataLength,
&PktId,
&DataPhy,
&DataMap
);
if (EFI_ERROR (Status)) {
goto FREE_DATA;
}
Qh = UhciCreateQh (Uhc, PollingInterval); Qh = UhciCreateQh (Uhc, PollingInterval);
if (Qh == NULL) { if (Qh == NULL) {
Status = EFI_OUT_OF_RESOURCES; Status = EFI_OUT_OF_RESOURCES;
goto UNMAP_DATA; goto FREE_DATA;
} }
IntTds = UhciCreateBulkOrIntTds ( IntTds = UhciCreateBulkOrIntTds (
@ -1066,7 +1054,6 @@ Uhci2AsyncInterruptTransfer (
EndPointAddress, EndPointAddress,
DataLength, DataLength,
PollingInterval, PollingInterval,
DataMap,
DataPtr, DataPtr,
CallBackFunction, CallBackFunction,
Context, Context,
@ -1085,11 +1072,8 @@ Uhci2AsyncInterruptTransfer (
DESTORY_QH: DESTORY_QH:
UsbHcFreeMem (Uhc->MemPool, Qh, sizeof (UHCI_QH_SW)); UsbHcFreeMem (Uhc->MemPool, Qh, sizeof (UHCI_QH_SW));
UNMAP_DATA:
Uhc->PciIo->Unmap (Uhc->PciIo, DataMap);
FREE_DATA: FREE_DATA:
gBS->FreePool (DataPtr); UsbHcFreeMem (Uhc->MemPool, DataPtr, DataLength);
Uhc->PciIo->Flush (Uhc->PciIo); Uhc->PciIo->Flush (Uhc->PciIo);
gBS->RestoreTPL (OldTpl); gBS->RestoreTPL (OldTpl);

View File

@ -117,8 +117,8 @@ struct _USB_HC_DEV {
// //
// Schedule data structures // Schedule data structures
// //
UINT32 *FrameBase; UINT32 *FrameBase; // the buffer pointed by this pointer is used to store pci bus address of the QH descriptor.
UINT32 *FrameBasePciMemAddr; UINT32 *FrameBaseHostAddr; // the buffer pointed by this pointer is used to store host memory address of the QH descriptor.
UHCI_QH_SW *SyncIntQh; UHCI_QH_SW *SyncIntQh;
UHCI_QH_SW *CtrlQh; UHCI_QH_SW *CtrlQh;
UHCI_QH_SW *BulkQh; UHCI_QH_SW *BulkQh;

View File

@ -2,7 +2,7 @@
The UHCI register operation routines. The UHCI register operation routines.
Copyright (c) 2007 - 2008, Intel Corporation Copyright (c) 2007 - 2010, Intel Corporation
All rights reserved. This program and the accompanying materials All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -164,22 +164,11 @@ UhciLinkTdToQh (
IN UHCI_TD_SW *Td IN UHCI_TD_SW *Td
) )
{ {
EFI_STATUS Status;
UINTN Len;
EFI_PHYSICAL_ADDRESS PhyAddr; EFI_PHYSICAL_ADDRESS PhyAddr;
VOID* Map;
Len = sizeof (UHCI_TD_HW); PhyAddr = UsbHcGetPciAddressForHostMem (Uhc->MemPool, Td, sizeof (UHCI_TD_HW));
Status = Uhc->PciIo->Map (
Uhc->PciIo,
EfiPciIoOperationBusMasterRead,
Td,
&Len,
&PhyAddr,
&Map
);
ASSERT (!EFI_ERROR (Status) && (Qh != NULL) && (Td != NULL)); ASSERT ((Qh != NULL) && (Td != NULL));
Qh->QhHw.VerticalLink = QH_VLINK (PhyAddr, FALSE); Qh->QhHw.VerticalLink = QH_VLINK (PhyAddr, FALSE);
Qh->TDs = (VOID *) Td; Qh->TDs = (VOID *) Td;
@ -221,22 +210,11 @@ UhciAppendTd (
IN UHCI_TD_SW *ThisTd IN UHCI_TD_SW *ThisTd
) )
{ {
EFI_STATUS Status;
UINTN Len;
EFI_PHYSICAL_ADDRESS PhyAddr; EFI_PHYSICAL_ADDRESS PhyAddr;
VOID* Map;
Len = sizeof (UHCI_TD_HW); PhyAddr = UsbHcGetPciAddressForHostMem (Uhc->MemPool, ThisTd, sizeof (UHCI_TD_HW));
Status = Uhc->PciIo->Map (
Uhc->PciIo,
EfiPciIoOperationBusMasterRead,
ThisTd,
&Len,
&PhyAddr,
&Map
);
ASSERT (!EFI_ERROR (Status) && (PrevTd != NULL) && (ThisTd != NULL)); ASSERT ((PrevTd != NULL) && (ThisTd != NULL));
PrevTd->TdHw.NextLink = TD_LINK (PhyAddr, TRUE, FALSE); PrevTd->TdHw.NextLink = TD_LINK (PhyAddr, TRUE, FALSE);
PrevTd->NextTd = (VOID *) ThisTd; PrevTd->NextTd = (VOID *) ThisTd;
@ -324,6 +302,7 @@ UhciCreateTd (
return NULL; return NULL;
} }
Td->TdHw.NextLink = TD_LINK (NULL, FALSE, TRUE);
Td->NextTd = NULL; Td->NextTd = NULL;
Td->Data = NULL; Td->Data = NULL;
Td->DataLen = 0; Td->DataLen = 0;
@ -428,7 +407,7 @@ UhciCreateDataTd (
Td->TdHw.ShortPacket = FALSE; Td->TdHw.ShortPacket = FALSE;
Td->TdHw.IsIsoch = FALSE; Td->TdHw.IsIsoch = FALSE;
Td->TdHw.IntOnCpl = FALSE; Td->TdHw.IntOnCpl = FALSE;
Td->TdHw.ErrorCount = 0X03; Td->TdHw.ErrorCount = 0x03;
Td->TdHw.Status = USBTD_ACTIVE; Td->TdHw.Status = USBTD_ACTIVE;
Td->TdHw.LowSpeed = IsLow ? 1 : 0; Td->TdHw.LowSpeed = IsLow ? 1 : 0;
Td->TdHw.DataToggle = Toggle & 0x01; Td->TdHw.DataToggle = Toggle & 0x01;

View File

@ -2,7 +2,7 @@
The EHCI register operation routines. The EHCI register operation routines.
Copyright (c) 2007 - 2009, Intel Corporation Copyright (c) 2007 - 2010, Intel Corporation
All rights reserved. This program and the accompanying materials All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -38,7 +38,6 @@ UhciInitFrameList (
UINTN Pages; UINTN Pages;
UINTN Bytes; UINTN Bytes;
UINTN Index; UINTN Index;
UINTN Len;
EFI_PHYSICAL_ADDRESS PhyAddr; EFI_PHYSICAL_ADDRESS PhyAddr;
// //
@ -77,10 +76,15 @@ UhciInitFrameList (
goto ON_ERROR; goto ON_ERROR;
} }
Uhc->FrameBase = (UINT32 *) (UINTN) Buffer; // Cpu memory address Uhc->FrameBase = (UINT32 *) (UINTN) Buffer;
Uhc->FrameBasePciMemAddr = (UINT32 *) (UINTN) MappedAddr; // Pci memory address
Uhc->FrameMapping = Mapping; Uhc->FrameMapping = Mapping;
//
// Tell the Host Controller where the Frame List lies,
// by set the Frame List Base Address Register.
//
UhciSetFrameListBaseAddr (Uhc->PciIo, (VOID *) MappedAddr);
// //
// Allocate the QH used by sync interrupt/control/bulk transfer. // Allocate the QH used by sync interrupt/control/bulk transfer.
// FS ctrl/bulk queue head is set to loopback so additional BW // FS ctrl/bulk queue head is set to loopback so additional BW
@ -104,30 +108,11 @@ UhciInitFrameList (
// Each frame entry is linked to this sequence of QH. These QH // Each frame entry is linked to this sequence of QH. These QH
// will remain on the schedul, never got removed // will remain on the schedul, never got removed
// //
Len = sizeof (UHCI_QH_HW); PhyAddr = UsbHcGetPciAddressForHostMem (Uhc->MemPool, Uhc->CtrlQh, sizeof (UHCI_QH_HW));
Status = Uhc->PciIo->Map (
Uhc->PciIo,
EfiPciIoOperationBusMasterRead,
Uhc->CtrlQh,
&Len,
&PhyAddr,
&Mapping
);
ASSERT (!EFI_ERROR (Status));
Uhc->SyncIntQh->QhHw.HorizonLink = QH_HLINK (PhyAddr, FALSE); Uhc->SyncIntQh->QhHw.HorizonLink = QH_HLINK (PhyAddr, FALSE);
Uhc->SyncIntQh->NextQh = Uhc->CtrlQh; Uhc->SyncIntQh->NextQh = Uhc->CtrlQh;
Status = Uhc->PciIo->Map ( PhyAddr = UsbHcGetPciAddressForHostMem (Uhc->MemPool, Uhc->BulkQh, sizeof (UHCI_QH_HW));
Uhc->PciIo,
EfiPciIoOperationBusMasterRead,
Uhc->BulkQh,
&Len,
&PhyAddr,
&Mapping
);
ASSERT (!EFI_ERROR (Status));
Uhc->CtrlQh->QhHw.HorizonLink = QH_HLINK (PhyAddr, FALSE); Uhc->CtrlQh->QhHw.HorizonLink = QH_HLINK (PhyAddr, FALSE);
Uhc->CtrlQh->NextQh = Uhc->BulkQh; Uhc->CtrlQh->NextQh = Uhc->BulkQh;
@ -140,27 +125,18 @@ UhciInitFrameList (
Uhc->BulkQh->NextQh = NULL; Uhc->BulkQh->NextQh = NULL;
Len = sizeof (UHCI_QH_HW); Uhc->FrameBaseHostAddr = AllocateZeroPool (4096);
Status = Uhc->PciIo->Map ( if (Uhc->FrameBaseHostAddr == NULL) {
Uhc->PciIo, Status = EFI_OUT_OF_RESOURCES;
EfiPciIoOperationBusMasterRead, goto ON_ERROR;
Uhc->SyncIntQh, }
&Len,
&PhyAddr, PhyAddr = UsbHcGetPciAddressForHostMem (Uhc->MemPool, Uhc->SyncIntQh, sizeof (UHCI_QH_HW));
&Mapping for (Index = 0; Index < UHCI_FRAME_NUM; Index++) {
); Uhc->FrameBase[Index] = QH_HLINK (PhyAddr, FALSE);
ASSERT (!EFI_ERROR (Status)); Uhc->FrameBaseHostAddr[Index] = (UINT32)(UINTN)Uhc->SyncIntQh;
for (Index = 0; Index < UHCI_FRAME_NUM; Index++) {
Uhc->FrameBase[Index] = QH_HLINK (Uhc->SyncIntQh, FALSE);
Uhc->FrameBasePciMemAddr[Index] = QH_HLINK (PhyAddr, FALSE);
} }
//
// Tell the Host Controller where the Frame List lies,
// by set the Frame List Base Address Register.
//
UhciSetFrameListBaseAddr (Uhc->PciIo, (VOID *) (Uhc->FrameBasePciMemAddr));
return EFI_SUCCESS; return EFI_SUCCESS;
ON_ERROR: ON_ERROR:
@ -205,6 +181,10 @@ UhciDestoryFrameList (
(VOID *) Uhc->FrameBase (VOID *) Uhc->FrameBase
); );
if (Uhc->FrameBaseHostAddr != NULL) {
FreePool (Uhc->FrameBaseHostAddr);
}
if (Uhc->SyncIntQh != NULL) { if (Uhc->SyncIntQh != NULL) {
UsbHcFreeMem (Uhc->MemPool, Uhc->SyncIntQh, sizeof (UHCI_QH_SW)); UsbHcFreeMem (Uhc->MemPool, Uhc->SyncIntQh, sizeof (UHCI_QH_SW));
} }
@ -218,7 +198,7 @@ UhciDestoryFrameList (
} }
Uhc->FrameBase = NULL; Uhc->FrameBase = NULL;
Uhc->FrameBasePciMemAddr = NULL; Uhc->FrameBaseHostAddr = NULL;
Uhc->SyncIntQh = NULL; Uhc->SyncIntQh = NULL;
Uhc->CtrlQh = NULL; Uhc->CtrlQh = NULL;
Uhc->BulkQh = NULL; Uhc->BulkQh = NULL;
@ -274,24 +254,12 @@ UhciLinkQhToFrameList (
UINTN Index; UINTN Index;
UHCI_QH_SW *Prev; UHCI_QH_SW *Prev;
UHCI_QH_SW *Next; UHCI_QH_SW *Next;
UINTN Len;
EFI_PHYSICAL_ADDRESS PhyAddr; EFI_PHYSICAL_ADDRESS PhyAddr;
EFI_PHYSICAL_ADDRESS QhPciAddr; EFI_PHYSICAL_ADDRESS QhPciAddr;
VOID* Map;
EFI_STATUS Status;
ASSERT ((Uhc->FrameBase != NULL) && (Qh != NULL)); ASSERT ((Uhc->FrameBase != NULL) && (Qh != NULL));
Len = sizeof (UHCI_QH_HW); QhPciAddr = UsbHcGetPciAddressForHostMem (Uhc->MemPool, Qh, sizeof (UHCI_QH_HW));
Status = Uhc->PciIo->Map (
Uhc->PciIo,
EfiPciIoOperationBusMasterRead,
Qh,
&Len,
&QhPciAddr,
&Map
);
ASSERT (!EFI_ERROR (Status));
for (Index = 0; Index < UHCI_FRAME_NUM; Index += Qh->Interval) { for (Index = 0; Index < UHCI_FRAME_NUM; Index += Qh->Interval) {
// //
@ -299,7 +267,7 @@ UhciLinkQhToFrameList (
// heads on the frame list // heads on the frame list
// //
ASSERT (!LINK_TERMINATED (Uhc->FrameBase[Index])); ASSERT (!LINK_TERMINATED (Uhc->FrameBase[Index]));
Next = UHCI_ADDR (Uhc->FrameBase[Index]); Next = (UHCI_QH_SW*)(UINTN)Uhc->FrameBaseHostAddr[Index];
Prev = NULL; Prev = NULL;
// //
@ -362,24 +330,13 @@ UhciLinkQhToFrameList (
// //
if (Qh->NextQh == NULL) { if (Qh->NextQh == NULL) {
Qh->NextQh = Next; Qh->NextQh = Next;
PhyAddr = UsbHcGetPciAddressForHostMem (Uhc->MemPool, Next, sizeof (UHCI_QH_HW));
Len = sizeof (UHCI_QH_HW);
Status = Uhc->PciIo->Map (
Uhc->PciIo,
EfiPciIoOperationBusMasterRead,
Next,
&Len,
&PhyAddr,
&Map
);
ASSERT (!EFI_ERROR (Status));
Qh->QhHw.HorizonLink = QH_HLINK (PhyAddr, FALSE); Qh->QhHw.HorizonLink = QH_HLINK (PhyAddr, FALSE);
} }
if (Prev == NULL) { if (Prev == NULL) {
Uhc->FrameBase[Index] = QH_HLINK (Qh, FALSE); Uhc->FrameBase[Index] = QH_HLINK (QhPciAddr, FALSE);
Uhc->FrameBasePciMemAddr[Index] = QH_HLINK (QhPciAddr, FALSE); Uhc->FrameBaseHostAddr[Index] = (UINT32)(UINTN)Qh;
} else { } else {
Prev->NextQh = Qh; Prev->NextQh = Qh;
Prev->QhHw.HorizonLink = QH_HLINK (QhPciAddr, FALSE); Prev->QhHw.HorizonLink = QH_HLINK (QhPciAddr, FALSE);
@ -415,7 +372,7 @@ UhciUnlinkQhFromFrameList (
// queue heads on the frame list // queue heads on the frame list
// //
ASSERT (!LINK_TERMINATED (Uhc->FrameBase[Index])); ASSERT (!LINK_TERMINATED (Uhc->FrameBase[Index]));
This = UHCI_ADDR (Uhc->FrameBase[Index]); This = (UHCI_QH_SW*)(UINTN)Uhc->FrameBaseHostAddr[Index];
Prev = NULL; Prev = NULL;
// //
@ -439,8 +396,8 @@ UhciUnlinkQhFromFrameList (
// //
// Qh is the first entry in the frame // Qh is the first entry in the frame
// //
Uhc->FrameBase[Index] = (UINT32)(UINTN)Qh->NextQh; Uhc->FrameBase[Index] = Qh->QhHw.HorizonLink;
Uhc->FrameBasePciMemAddr[Index] = Qh->QhHw.HorizonLink; Uhc->FrameBaseHostAddr[Index] = (UINT32)(UINTN)Qh->NextQh;
} else { } else {
Prev->NextQh = Qh->NextQh; Prev->NextQh = Qh->NextQh;
Prev->QhHw.HorizonLink = Qh->QhHw.HorizonLink; Prev->QhHw.HorizonLink = Qh->QhHw.HorizonLink;
@ -712,7 +669,6 @@ UhciUpdateAsyncReq (
@param EndPoint EndPoint Address. @param EndPoint EndPoint Address.
@param DataLen Data length. @param DataLen Data length.
@param Interval Polling Interval when inserted to frame list. @param Interval Polling Interval when inserted to frame list.
@param Mapping Mapping value.
@param Data Data buffer, unmapped. @param Data Data buffer, unmapped.
@param Callback Callback after interrupt transfeer. @param Callback Callback after interrupt transfeer.
@param Context Callback Context passed as function parameter. @param Context Callback Context passed as function parameter.
@ -732,7 +688,6 @@ UhciCreateAsyncReq (
IN UINT8 EndPoint, IN UINT8 EndPoint,
IN UINTN DataLen, IN UINTN DataLen,
IN UINTN Interval, IN UINTN Interval,
IN VOID *Mapping,
IN UINT8 *Data, IN UINT8 *Data,
IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback, IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback,
IN VOID *Context, IN VOID *Context,
@ -755,7 +710,6 @@ UhciCreateAsyncReq (
AsyncReq->EndPoint = EndPoint; AsyncReq->EndPoint = EndPoint;
AsyncReq->DataLen = DataLen; AsyncReq->DataLen = DataLen;
AsyncReq->Interval = UhciConvertPollRate(Interval); AsyncReq->Interval = UhciConvertPollRate(Interval);
AsyncReq->Mapping = Mapping;
AsyncReq->Data = Data; AsyncReq->Data = Data;
AsyncReq->Callback = Callback; AsyncReq->Callback = Callback;
AsyncReq->Context = Context; AsyncReq->Context = Context;
@ -793,10 +747,6 @@ UhciFreeAsyncReq (
UhciDestoryTds (Uhc, AsyncReq->FirstTd); UhciDestoryTds (Uhc, AsyncReq->FirstTd);
UsbHcFreeMem (Uhc->MemPool, AsyncReq->QhSw, sizeof (UHCI_QH_SW)); UsbHcFreeMem (Uhc->MemPool, AsyncReq->QhSw, sizeof (UHCI_QH_SW));
if (AsyncReq->Mapping != NULL) {
Uhc->PciIo->Unmap (Uhc->PciIo, AsyncReq->Mapping);
}
if (AsyncReq->Data != NULL) { if (AsyncReq->Data != NULL) {
UsbHcFreeMem (Uhc->MemPool, AsyncReq->Data, AsyncReq->DataLen); UsbHcFreeMem (Uhc->MemPool, AsyncReq->Data, AsyncReq->DataLen);
} }

View File

@ -190,7 +190,6 @@ UhciExecuteTransfer (
@param EndPoint EndPoint Address. @param EndPoint EndPoint Address.
@param DataLen Data length. @param DataLen Data length.
@param Interval Polling Interval when inserted to frame list. @param Interval Polling Interval when inserted to frame list.
@param Mapping Mapping value.
@param Data Data buffer, unmapped. @param Data Data buffer, unmapped.
@param Callback Callback after interrupt transfeer. @param Callback Callback after interrupt transfeer.
@param Context Callback Context passed as function parameter. @param Context Callback Context passed as function parameter.
@ -210,7 +209,6 @@ UhciCreateAsyncReq (
IN UINT8 EndPoint, IN UINT8 EndPoint,
IN UINTN DataLen, IN UINTN DataLen,
IN UINTN Interval, IN UINTN Interval,
IN VOID *Mapping,
IN UINT8 *Data, IN UINT8 *Data,
IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback, IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback,
IN VOID *Context, IN VOID *Context,

View File

@ -2,7 +2,7 @@
The routine procedure for uhci memory allocate/free. The routine procedure for uhci memory allocate/free.
Copyright (c) 2007, Intel Corporation Copyright (c) 2007 - 2010, Intel Corporation
All rights reserved. This program and the accompanying materials All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -220,6 +220,53 @@ UsbHcAllocMemFromBlock (
return Block->Buf + (StartByte * 8 + StartBit) * USBHC_MEM_UNIT; return Block->Buf + (StartByte * 8 + StartBit) * USBHC_MEM_UNIT;
} }
/**
Calculate the corresponding pci bus address according to the Mem parameter.
@param Pool The memory pool of the host controller.
@param Mem The pointer to host memory.
@param Size The size of the memory region.
@return the pci memory address
**/
EFI_PHYSICAL_ADDRESS
UsbHcGetPciAddressForHostMem (
IN USBHC_MEM_POOL *Pool,
IN VOID *Mem,
IN UINTN Size
)
{
USBHC_MEM_BLOCK *Head;
USBHC_MEM_BLOCK *Block;
UINTN AllocSize;
EFI_PHYSICAL_ADDRESS PhyAddr;
UINTN Offset;
Head = Pool->Head;
AllocSize = USBHC_MEM_ROUND (Size);
if (Mem == NULL) {
return 0;
}
for (Block = Head; Block != NULL; Block = Block->Next) {
//
// scan the memory block list for the memory block that
// completely contains the allocated memory.
//
if ((Block->BufHost <= (UINT8 *) Mem) && (((UINT8 *) Mem + AllocSize) <= (Block->BufHost + Block->BufLen))) {
break;
}
}
ASSERT ((Block != NULL));
//
// calculate the pci memory address for host memory address.
//
Offset = (UINT8 *)Mem - Block->BufHost;
PhyAddr = (EFI_PHYSICAL_ADDRESS)(UINTN) (Block->Buf + Offset);
return PhyAddr;
}
/** /**
Insert the memory block to the pool's list of the blocks. Insert the memory block to the pool's list of the blocks.

View File

@ -141,4 +141,21 @@ UsbHcFreeMem (
IN VOID *Mem, IN VOID *Mem,
IN UINTN Size IN UINTN Size
); );
/**
Calculate the corresponding pci bus address according to the Mem parameter.
@param Pool The memory pool of the host controller.
@param Mem The pointer to host memory.
@param Size The size of the memory region.
@return the pci memory address
**/
EFI_PHYSICAL_ADDRESS
UsbHcGetPciAddressForHostMem (
IN USBHC_MEM_POOL *Pool,
IN VOID *Mem,
IN UINTN Size
);
#endif #endif