// Allocate the periodic frame and associated memeory\r
// management facilities if not already done.\r
//\r
- if (Ehc->PeriodFrameHost != NULL) {\r
+ if (Ehc->PeriodFrame != NULL) {\r
EhcFreeSched (Ehc);\r
}\r
\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- //\r
- // 1. Program the CTRLDSSEGMENT register with the high 32 bit addr\r
- //\r
- EhcWriteOpReg (Ehc, EHC_CTRLDSSEG_OFFSET, Ehc->High32bitAddr);\r
\r
//\r
- // 2. Clear USBINTR to disable all the interrupt. UEFI works by polling\r
+ // 1. Clear USBINTR to disable all the interrupt. UEFI works by polling\r
//\r
EhcWriteOpReg (Ehc, EHC_USBINTR_OFFSET, 0);\r
\r
//\r
- // 3. Program periodic frame list, already done in EhcInitSched\r
- // 4. Start the Host Controller\r
+ // 2. Program periodic frame list, already done in EhcInitSched\r
+ // 3. Start the Host Controller\r
//\r
EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_RUN);\r
\r
//\r
- // 5. Set all ports routing to EHC\r
+ // 4. Set all ports routing to EHC\r
//\r
EhcSetOpRegBit (Ehc, EHC_CONFIG_FLAG_OFFSET, CONFIGFLAG_ROUTE_EHC);\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
+ goto ErrorExit;\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
+ PciIo->FreeBuffer (PciIo, Pages, Buf);\r
+ PciIo->Unmap (PciIo, Map);\r
+\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
+ 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
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
+ Qh->QhHw.HorizonLink = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);\r
PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Qh, sizeof (EHC_QH));\r
Head->QhHw.HorizonLink = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);\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
NEXT_BIT (Byte, Bit);\r
}\r
\r
- return Block->Buf + (StartByte * 8 + StartBit) * USBHC_MEM_UNIT;\r
+ return Block->BufHost + (StartByte * 8 + StartBit) * USBHC_MEM_UNIT;\r
}\r
\r
/**\r
- Get the pci memory address according to the allocated host memory address.\r
+ Calculate the corresponding pci bus address according to the Mem parameter.\r
\r
@param Pool The memory pool of the host controller.\r
- @param Mem The memory to free.\r
- @param Size The size of the memory to free.\r
+ @param Mem The pointer to host memory.\r
+ @param Size The size of the memory region.\r
\r
@return the pci memory address\r
**/\r
// scan the memory block list for the memory block that\r
// completely contains the allocated memory.\r
//\r
- if ((Block->Buf <= (UINT8 *) Mem) && (((UINT8 *) Mem + AllocSize) <= (Block->Buf + Block->BufLen))) {\r
+ if ((Block->BufHost <= (UINT8 *) Mem) && (((UINT8 *) Mem + AllocSize) <= (Block->BufHost + Block->BufLen))) {\r
break;\r
}\r
}\r
// scan the memory block list for the memory block that\r
// completely contains the memory to free.\r
//\r
- if ((Block->Buf <= ToFree) && ((ToFree + AllocSize) <= (Block->Buf + Block->BufLen))) {\r
+ if ((Block->BufHost <= ToFree) && ((ToFree + AllocSize) <= (Block->BufHost + Block->BufLen))) {\r
//\r
// compute the start byte and bit in the bit array\r
//\r
- Byte = ((ToFree - Block->Buf) / USBHC_MEM_UNIT) / 8;\r
- Bit = ((ToFree - Block->Buf) / USBHC_MEM_UNIT) % 8;\r
+ Byte = ((ToFree - Block->BufHost) / USBHC_MEM_UNIT) / 8;\r
+ Bit = ((ToFree - Block->BufHost) / USBHC_MEM_UNIT) % 8;\r
\r
//\r
// reset associated bits in bit arry\r