QhHw->HorizonLink = QH_LINK (PciAddr + OFFSET_OF(EHC_QH, QhHw), EHC_TYPE_QH, FALSE);\r
QhHw->Status = QTD_STAT_HALTED;\r
QhHw->ReclaimHead = 1;\r
+ Qh->NextQh = Qh;\r
Ehc->ReclaimHead = Qh;\r
\r
//\r
UINTN Pages;\r
UINTN Bytes;\r
UINTN Index;\r
- UINT32 *Desc;\r
EFI_STATUS Status;\r
EFI_PHYSICAL_ADDRESS PciAddr;\r
\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
- Ehc->PeriodFrameHost = Buf;\r
- Ehc->PeriodFrame = (VOID *) ((UINTN) PhyAddr);\r
+ Ehc->PeriodFrame = Buf;\r
Ehc->PeriodFrameMap = Map;\r
- Ehc->High32bitAddr = EHC_HIGH_32BIT (PhyAddr);\r
+\r
+ //\r
+ // Program the FRAMELISTBASE register with the low 32 bit addr\r
+ //\r
+ EhcWriteOpReg (Ehc, EHC_FRAME_BASE_OFFSET, EHC_LOW_32BIT (PhyAddr));\r
+ //\r
+ // Program the CTRLDSSEGMENT register with the high 32 bit addr\r
+ //\r
+ EhcWriteOpReg (Ehc, EHC_CTRLDSSEG_OFFSET, EHC_HIGH_32BIT (PhyAddr));\r
\r
//\r
// Init memory pool management then create the helper\r
Ehc->MemPool = UsbHcInitMemPool (\r
PciIo,\r
EHC_BIT_IS_SET (Ehc->HcCapParams, HCCP_64BIT),\r
- Ehc->High32bitAddr\r
+ EHC_HIGH_32BIT (PhyAddr)\r
);\r
\r
if (Ehc->MemPool == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ErrorExit1;\r
}\r
\r
Status = EhcCreateHelpQ (Ehc);\r
\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ goto ErrorExit;\r
}\r
\r
//\r
// Initialize the frame list entries then set the registers\r
//\r
- Desc = (UINT32 *) Ehc->PeriodFrameHost;\r
+ Ehc->PeriodFrameHost = AllocateZeroPool (EHC_FRAME_LEN * sizeof (UINTN));\r
+ if (Ehc->PeriodFrameHost == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ErrorExit;\r
+ }\r
+\r
+ PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Ehc->PeriodOne, sizeof (EHC_QH));\r
\r
for (Index = 0; Index < EHC_FRAME_LEN; Index++) {\r
- PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Ehc->PeriodOne, sizeof (EHC_QH));\r
- Desc[Index] = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);\r
+ //\r
+ // Store the pci bus address of the QH in period frame list which will be accessed by pci bus master.\r
+ //\r
+ ((UINT32 *)(Ehc->PeriodFrame))[Index] = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);\r
+ //\r
+ // Store the host address of the QH in period frame list which will be accessed by host.\r
+ //\r
+ ((UINTN *)(Ehc->PeriodFrameHost))[Index] = (UINTN)Ehc->PeriodOne;\r
}\r
\r
- EhcWriteOpReg (Ehc, EHC_FRAME_BASE_OFFSET, EHC_LOW_32BIT (Ehc->PeriodFrame));\r
-\r
//\r
// Second initialize the asynchronous schedule:\r
// Only need to set the AsynListAddr register to\r
PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Ehc->ReclaimHead, sizeof (EHC_QH));\r
EhcWriteOpReg (Ehc, EHC_ASYNC_HEAD_OFFSET, EHC_LOW_32BIT (PciAddr));\r
return EFI_SUCCESS;\r
+\r
+ErrorExit:\r
+ if (Ehc->PeriodOne != NULL) {\r
+ UsbHcFreeMem (Ehc->MemPool, Ehc->PeriodOne, sizeof (EHC_QH));\r
+ Ehc->PeriodOne = NULL;\r
+ }\r
+\r
+ if (Ehc->ReclaimHead != NULL) {\r
+ UsbHcFreeMem (Ehc->MemPool, Ehc->ReclaimHead, sizeof (EHC_QH));\r
+ Ehc->ReclaimHead = NULL;\r
+ }\r
+\r
+ if (Ehc->ShortReadStop != NULL) {\r
+ UsbHcFreeMem (Ehc->MemPool, Ehc->ShortReadStop, sizeof (EHC_QTD));\r
+ Ehc->ShortReadStop = NULL;\r
+ }\r
+\r
+ErrorExit1:\r
+ PciIo->FreeBuffer (PciIo, Pages, Buf);\r
+ PciIo->Unmap (PciIo, Map);\r
+\r
+ return Status;\r
}\r
\r
\r
Ehc->MemPool = NULL;\r
}\r
\r
- if (Ehc->PeriodFrameHost != NULL) {\r
+ if (Ehc->PeriodFrame != NULL) {\r
PciIo = Ehc->PciIo;\r
ASSERT (PciIo != NULL);\r
\r
PciIo->FreeBuffer (\r
PciIo,\r
EFI_SIZE_TO_PAGES (EFI_PAGE_SIZE),\r
- Ehc->PeriodFrameHost\r
+ Ehc->PeriodFrame\r
);\r
\r
+ Ehc->PeriodFrame = NULL;\r
+ }\r
+\r
+ if (Ehc->PeriodFrameHost != NULL) {\r
+ FreePool (Ehc->PeriodFrameHost);\r
Ehc->PeriodFrameHost = NULL;\r
- Ehc->PeriodFrame = NULL;\r
}\r
}\r
\r
Qh->NextQh = Head->NextQh;\r
Head->NextQh = Qh;\r
\r
- PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Head, sizeof (EHC_QH));\r
- Qh->QhHw.HorizonLink = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);;\r
- PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Qh, sizeof (EHC_QH));\r
+ PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Qh->NextQh, sizeof (EHC_QH));\r
+ Qh->QhHw.HorizonLink = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);\r
+ PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Head->NextQh, sizeof (EHC_QH));\r
Head->QhHw.HorizonLink = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);\r
}\r
\r
Head->NextQh = Qh->NextQh;\r
Qh->NextQh = NULL;\r
\r
- PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Head, sizeof (EHC_QH));\r
+ PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Head->NextQh, sizeof (EHC_QH));\r
Head->QhHw.HorizonLink = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);\r
\r
//\r
IN EHC_QH *Qh\r
)\r
{\r
- UINT32 *Frames;\r
UINTN Index;\r
EHC_QH *Prev;\r
EHC_QH *Next;\r
EFI_PHYSICAL_ADDRESS PciAddr;\r
\r
- Frames = Ehc->PeriodFrameHost;\r
-\r
for (Index = 0; Index < EHC_FRAME_LEN; Index += Qh->Interval) {\r
//\r
// First QH can't be NULL because we always keep PeriodOne\r
// heads on the frame list\r
//\r
- ASSERT (!EHC_LINK_TERMINATED (Frames[Index]));\r
- Next = EHC_ADDR (Ehc->High32bitAddr, Frames[Index]);\r
+ ASSERT (!EHC_LINK_TERMINATED (((UINT32*)Ehc->PeriodFrame)[Index]));\r
+ Next = (EHC_QH*)((UINTN*)Ehc->PeriodFrameHost)[Index];\r
Prev = NULL;\r
\r
//\r
PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Qh, sizeof (EHC_QH));\r
\r
if (Prev == NULL) {\r
- Frames[Index] = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);\r
+ ((UINT32*)Ehc->PeriodFrame)[Index] = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);\r
+ ((UINTN*)Ehc->PeriodFrameHost)[Index] = (UINTN)Qh;\r
} else {\r
Prev->NextQh = Qh;\r
Prev->QhHw.HorizonLink = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);\r
IN EHC_QH *Qh\r
)\r
{\r
- UINT32 *Frames;\r
UINTN Index;\r
EHC_QH *Prev;\r
EHC_QH *This;\r
\r
- Frames = Ehc->PeriodFrameHost;\r
-\r
for (Index = 0; Index < EHC_FRAME_LEN; Index += Qh->Interval) {\r
//\r
// Frame link can't be NULL because we always keep PeroidOne\r
// on the frame list\r
//\r
- ASSERT (!EHC_LINK_TERMINATED (Frames[Index]));\r
- This = EHC_ADDR (Ehc->High32bitAddr, Frames[Index]);\r
+ ASSERT (!EHC_LINK_TERMINATED (((UINT32*)Ehc->PeriodFrame)[Index]));\r
+ This = (EHC_QH*)((UINTN*)Ehc->PeriodFrameHost)[Index];\r
Prev = NULL;\r
\r
//\r
//\r
// Qh is the first entry in the frame\r
//\r
- Frames[Index] = Qh->QhHw.HorizonLink;\r
+ ((UINT32*)Ehc->PeriodFrame)[Index] = Qh->QhHw.HorizonLink;\r
+ ((UINTN*)Ehc->PeriodFrameHost)[Index] = (UINTN)Qh->NextQh;\r
} else {\r
Prev->NextQh = Qh->NextQh;\r
Prev->QhHw.HorizonLink = Qh->QhHw.HorizonLink;\r