\r
The EHCI register operation routines.\r
\r
-Copyright (c) 2007 - 2008, Intel Corporation\r
+Copyright (c) 2007 - 2010, Intel Corporation\r
All rights reserved. This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
UINTN Pages;\r
UINTN Bytes;\r
UINTN Index;\r
+ EFI_PHYSICAL_ADDRESS PhyAddr;\r
\r
//\r
// The Frame List is a common buffer that will be\r
goto ON_ERROR;\r
}\r
\r
- Uhc->FrameBase = (UINT32 *) (UINTN) MappedAddr;\r
- Uhc->FrameMapping = Mapping;\r
+ Uhc->FrameBase = (UINT32 *) (UINTN) Buffer;\r
+ Uhc->FrameMapping = Mapping;\r
+\r
+ //\r
+ // Tell the Host Controller where the Frame List lies,\r
+ // by set the Frame List Base Address Register.\r
+ //\r
+ UhciSetFrameListBaseAddr (Uhc->PciIo, (VOID *) (UINTN) MappedAddr);\r
\r
//\r
// Allocate the QH used by sync interrupt/control/bulk transfer.\r
// Each frame entry is linked to this sequence of QH. These QH\r
// will remain on the schedul, never got removed\r
//\r
- Uhc->SyncIntQh->QhHw.HorizonLink = QH_HLINK (Uhc->CtrlQh, FALSE);\r
+ PhyAddr = UsbHcGetPciAddressForHostMem (Uhc->MemPool, Uhc->CtrlQh, sizeof (UHCI_QH_HW));\r
+ Uhc->SyncIntQh->QhHw.HorizonLink = QH_HLINK (PhyAddr, FALSE);\r
Uhc->SyncIntQh->NextQh = Uhc->CtrlQh;\r
\r
- Uhc->CtrlQh->QhHw.HorizonLink = QH_HLINK (Uhc->BulkQh, FALSE);\r
+ PhyAddr = UsbHcGetPciAddressForHostMem (Uhc->MemPool, Uhc->BulkQh, sizeof (UHCI_QH_HW));\r
+ Uhc->CtrlQh->QhHw.HorizonLink = QH_HLINK (PhyAddr, FALSE);\r
Uhc->CtrlQh->NextQh = Uhc->BulkQh;\r
\r
//\r
// in supporting the full speed bandwidth reclamation in the previous\r
// mentioned form. Most new platforms don't suffer it.\r
//\r
- Uhc->BulkQh->QhHw.HorizonLink = QH_HLINK (Uhc->BulkQh, FALSE);\r
+ Uhc->BulkQh->QhHw.HorizonLink = QH_HLINK (PhyAddr, FALSE);\r
\r
Uhc->BulkQh->NextQh = NULL;\r
\r
+ Uhc->FrameBaseHostAddr = AllocateZeroPool (4096);\r
+ if (Uhc->FrameBaseHostAddr == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_ERROR;\r
+ }\r
+\r
+ PhyAddr = UsbHcGetPciAddressForHostMem (Uhc->MemPool, Uhc->SyncIntQh, sizeof (UHCI_QH_HW));\r
for (Index = 0; Index < UHCI_FRAME_NUM; Index++) {\r
- Uhc->FrameBase[Index] = QH_HLINK (Uhc->SyncIntQh, FALSE);\r
+ Uhc->FrameBase[Index] = QH_HLINK (PhyAddr, FALSE);\r
+ Uhc->FrameBaseHostAddr[Index] = (UINT32)(UINTN)Uhc->SyncIntQh;\r
}\r
\r
- //\r
- // Tell the Host Controller where the Frame List lies,\r
- // by set the Frame List Base Address Register.\r
- //\r
- UhciSetFrameListBaseAddr (Uhc->PciIo, (VOID *) (Uhc->FrameBase));\r
return EFI_SUCCESS;\r
\r
ON_ERROR:\r
(VOID *) Uhc->FrameBase\r
);\r
\r
+ if (Uhc->FrameBaseHostAddr != NULL) {\r
+ FreePool (Uhc->FrameBaseHostAddr);\r
+ }\r
+\r
if (Uhc->SyncIntQh != NULL) {\r
UsbHcFreeMem (Uhc->MemPool, Uhc->SyncIntQh, sizeof (UHCI_QH_SW));\r
}\r
UsbHcFreeMem (Uhc->MemPool, Uhc->BulkQh, sizeof (UHCI_QH_SW));\r
}\r
\r
- Uhc->FrameBase = NULL;\r
- Uhc->SyncIntQh = NULL;\r
- Uhc->CtrlQh = NULL;\r
- Uhc->BulkQh = NULL;\r
+ Uhc->FrameBase = NULL;\r
+ Uhc->FrameBaseHostAddr = NULL;\r
+ Uhc->SyncIntQh = NULL;\r
+ Uhc->CtrlQh = NULL;\r
+ Uhc->BulkQh = NULL;\r
}\r
\r
\r
Link a queue head (for asynchronous interrupt transfer) to\r
the frame list.\r
\r
- @param FrameBase The base of the frame list.\r
+ @param Uhc The UHCI device.\r
@param Qh The queue head to link into.\r
\r
**/\r
VOID\r
UhciLinkQhToFrameList (\r
- UINT32 *FrameBase,\r
+ USB_HC_DEV *Uhc,\r
UHCI_QH_SW *Qh\r
)\r
{\r
UINTN Index;\r
UHCI_QH_SW *Prev;\r
UHCI_QH_SW *Next;\r
+ EFI_PHYSICAL_ADDRESS PhyAddr;\r
+ EFI_PHYSICAL_ADDRESS QhPciAddr;\r
+\r
+ ASSERT ((Uhc->FrameBase != NULL) && (Qh != NULL));\r
\r
- ASSERT ((FrameBase != NULL) && (Qh != NULL));\r
+ QhPciAddr = UsbHcGetPciAddressForHostMem (Uhc->MemPool, Qh, sizeof (UHCI_QH_HW));\r
\r
for (Index = 0; Index < UHCI_FRAME_NUM; Index += Qh->Interval) {\r
//\r
// First QH can't be NULL because we always keep static queue\r
// heads on the frame list\r
//\r
- ASSERT (!LINK_TERMINATED (FrameBase[Index]));\r
- Next = UHCI_ADDR (FrameBase[Index]);\r
+ ASSERT (!LINK_TERMINATED (Uhc->FrameBase[Index]));\r
+ Next = (UHCI_QH_SW*)(UINTN)Uhc->FrameBaseHostAddr[Index];\r
Prev = NULL;\r
\r
//\r
while (Next->Interval > Qh->Interval) {\r
Prev = Next;\r
Next = Next->NextQh;\r
+ ASSERT (Next != NULL);\r
}\r
\r
- ASSERT (Next != NULL);\r
-\r
//\r
// The entry may have been linked into the frame by early insertation.\r
// For example: if insert a Qh with Qh.Interval == 4, and there is a Qh\r
Prev->NextQh = Qh;\r
\r
Qh->QhHw.HorizonLink = Prev->QhHw.HorizonLink;\r
- Prev->QhHw.HorizonLink = QH_HLINK (Qh, FALSE);\r
+\r
+ Prev->QhHw.HorizonLink = QH_HLINK (QhPciAddr, FALSE);\r
break;\r
}\r
\r
//\r
if (Qh->NextQh == NULL) {\r
Qh->NextQh = Next;\r
- Qh->QhHw.HorizonLink = QH_HLINK (Next, FALSE);\r
+ PhyAddr = UsbHcGetPciAddressForHostMem (Uhc->MemPool, Next, sizeof (UHCI_QH_HW));\r
+ Qh->QhHw.HorizonLink = QH_HLINK (PhyAddr, FALSE);\r
}\r
\r
if (Prev == NULL) {\r
- FrameBase[Index] = QH_HLINK (Qh, FALSE);\r
+ Uhc->FrameBase[Index] = QH_HLINK (QhPciAddr, FALSE);\r
+ Uhc->FrameBaseHostAddr[Index] = (UINT32)(UINTN)Qh;\r
} else {\r
Prev->NextQh = Qh;\r
- Prev->QhHw.HorizonLink = QH_HLINK (Qh, FALSE);\r
+ Prev->QhHw.HorizonLink = QH_HLINK (QhPciAddr, FALSE);\r
}\r
}\r
}\r
the precedence node, and pointer there next to QhSw's\r
next.\r
\r
- @param FrameBase The base address of the frame list.\r
+ @param Uhc The UHCI device.\r
@param Qh The queue head to unlink.\r
\r
**/\r
VOID\r
UhciUnlinkQhFromFrameList (\r
- UINT32 *FrameBase,\r
- UHCI_QH_SW *Qh\r
+ USB_HC_DEV *Uhc,\r
+ UHCI_QH_SW *Qh\r
)\r
{\r
UINTN Index;\r
UHCI_QH_SW *Prev;\r
UHCI_QH_SW *This;\r
\r
- ASSERT ((FrameBase != NULL) && (Qh != NULL));\r
+ ASSERT ((Uhc->FrameBase != NULL) && (Qh != NULL));\r
\r
for (Index = 0; Index < UHCI_FRAME_NUM; Index += Qh->Interval) {\r
//\r
// Frame link can't be NULL because we always keep static\r
// queue heads on the frame list\r
//\r
- ASSERT (!LINK_TERMINATED (FrameBase[Index]));\r
- This = UHCI_ADDR (FrameBase[Index]);\r
+ ASSERT (!LINK_TERMINATED (Uhc->FrameBase[Index]));\r
+ This = (UHCI_QH_SW*)(UINTN)Uhc->FrameBaseHostAddr[Index];\r
Prev = NULL;\r
\r
//\r
//\r
// Qh is the first entry in the frame\r
//\r
- FrameBase[Index] = Qh->QhHw.HorizonLink;\r
+ Uhc->FrameBase[Index] = Qh->QhHw.HorizonLink;\r
+ Uhc->FrameBaseHostAddr[Index] = (UINT32)(UINTN)Qh->NextQh;\r
} else {\r
Prev->NextQh = Qh->NextQh;\r
Prev->QhHw.HorizonLink = Qh->QhHw.HorizonLink;\r
/**\r
Update Async Request, QH and TDs.\r
\r
+ @param Uhc The UHCI device.\r
@param AsyncReq The UHCI asynchronous transfer to update.\r
@param Result Transfer reslut.\r
@param NextToggle The toggle of next data.\r
**/\r
VOID\r
UhciUpdateAsyncReq (\r
+ IN USB_HC_DEV *Uhc,\r
IN UHCI_ASYNC_REQUEST *AsyncReq,\r
IN UINT32 Result,\r
IN UINT32 NextToggle\r
Td->TdHw.Status |= USBTD_ACTIVE;\r
}\r
\r
- UhciLinkTdToQh (Qh, FirstTd);\r
+ UhciLinkTdToQh (Uhc, Qh, FirstTd);\r
return ;\r
}\r
}\r
@param EndPoint EndPoint Address.\r
@param DataLen Data length.\r
@param Interval Polling Interval when inserted to frame list.\r
- @param Mapping Mapping value.\r
@param Data Data buffer, unmapped.\r
@param Callback Callback after interrupt transfeer.\r
@param Context Callback Context passed as function parameter.\r
IN UINT8 EndPoint,\r
IN UINTN DataLen,\r
IN UINTN Interval,\r
- IN VOID *Mapping,\r
IN UINT8 *Data,\r
IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback,\r
IN VOID *Context,\r
AsyncReq->EndPoint = EndPoint;\r
AsyncReq->DataLen = DataLen;\r
AsyncReq->Interval = UhciConvertPollRate(Interval);\r
- AsyncReq->Mapping = Mapping;\r
AsyncReq->Data = Data;\r
AsyncReq->Callback = Callback;\r
AsyncReq->Context = Context;\r
UhciDestoryTds (Uhc, AsyncReq->FirstTd);\r
UsbHcFreeMem (Uhc->MemPool, AsyncReq->QhSw, sizeof (UHCI_QH_SW));\r
\r
- if (AsyncReq->Mapping != NULL) {\r
- Uhc->PciIo->Unmap (Uhc->PciIo, AsyncReq->Mapping);\r
- }\r
-\r
if (AsyncReq->Data != NULL) {\r
- gBS->FreePool (AsyncReq->Data);\r
+ UsbHcFreeMem (Uhc->MemPool, AsyncReq->Data, AsyncReq->DataLen);\r
}\r
\r
gBS->FreePool (AsyncReq);\r
ASSERT ((Uhc != NULL) && (AsyncReq != NULL));\r
\r
RemoveEntryList (&(AsyncReq->Link));\r
- UhciUnlinkQhFromFrameList (Uhc->FrameBase, AsyncReq->QhSw);\r
+ UhciUnlinkQhFromFrameList (Uhc, AsyncReq->QhSw);\r
\r
if (FreeNow) {\r
UhciFreeAsyncReq (Uhc, AsyncReq);\r
\r
**/\r
VOID\r
+EFIAPI\r
UhciMonitorAsyncReqList (\r
IN EFI_EVENT Event,\r
IN VOID *Context\r
CopyMem (Data, AsyncReq->FirstTd->Data, QhResult.Complete);\r
}\r
\r
- UhciUpdateAsyncReq (AsyncReq, QhResult.Result, QhResult.NextToggle);\r
+ UhciUpdateAsyncReq (Uhc, AsyncReq, QhResult.Result, QhResult.NextToggle);\r
\r
//\r
// Now, either transfer is SUCCESS or met errors since\r