\r
#include "Xhci.h"\r
\r
-/**\r
- Allocates a buffer of a certain pool type at a specified alignment.\r
-\r
- Allocates the number bytes specified by AllocationSize of a certain pool type with an alignment\r
- specified by Alignment. The allocated buffer is returned. If AllocationSize is 0, then a valid\r
- buffer of 0 size is returned. If there is not enough memory at the specified alignment remaining\r
- to satisfy the request, then NULL is returned.\r
- If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
-\r
- @param PoolType The type of pool to allocate.\r
- @param AllocationSize The number of bytes to allocate.\r
- @param Alignment The requested alignment of the allocation. Must be a power of two.\r
- If Alignment is zero, then byte alignment is used.\r
-\r
- @return A pointer to the allocated buffer or NULL if allocation fails.\r
-\r
-**/\r
-VOID *\r
-InternalAllocateAlignedPool (\r
- IN EFI_MEMORY_TYPE PoolType,\r
- IN UINTN AllocationSize,\r
- IN UINTN Alignment\r
- )\r
-{\r
- VOID *RawAddress;\r
- UINTN AlignedAddress;\r
- UINTN AlignmentMask;\r
- UINTN OverAllocationSize;\r
- UINTN RealAllocationSize;\r
- VOID **FreePointer;\r
-\r
- //\r
- // Alignment must be a power of two or zero.\r
- //\r
- ASSERT ((Alignment & (Alignment - 1)) == 0);\r
-\r
- if (Alignment == 0) {\r
- AlignmentMask = Alignment;\r
- } else {\r
- AlignmentMask = Alignment - 1;\r
- }\r
- //\r
- // Calculate the extra memory size, over-allocate memory pool and get the aligned memory address.\r
- //\r
- OverAllocationSize = sizeof (RawAddress) + AlignmentMask;\r
- RealAllocationSize = AllocationSize + OverAllocationSize;\r
- //\r
- // Make sure that AllocationSize plus OverAllocationSize does not overflow.\r
- //\r
- ASSERT (RealAllocationSize > AllocationSize);\r
-\r
- RawAddress = NULL;\r
- gBS->AllocatePool (PoolType, RealAllocationSize, &RawAddress);\r
- if (RawAddress == NULL) {\r
- return NULL;\r
- }\r
- AlignedAddress = ((UINTN) RawAddress + OverAllocationSize) & ~AlignmentMask;\r
- //\r
- // Save the original memory address just before the aligned address.\r
- //\r
- FreePointer = (VOID **)(AlignedAddress - sizeof (RawAddress));\r
- *FreePointer = RawAddress;\r
-\r
- return (VOID *) AlignedAddress;\r
-}\r
-\r
-/**\r
- Allocates and zeros a buffer of a certain pool type at a specified alignment.\r
-\r
- Allocates the number bytes specified by AllocationSize of a certain pool type with an alignment\r
- specified by Alignment, clears the buffer with zeros, and returns a pointer to the allocated\r
- buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is not\r
- enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.\r
- If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
-\r
- @param PoolType The type of pool to allocate.\r
- @param AllocationSize The number of bytes to allocate.\r
- @param Alignment The requested alignment of the allocation. Must be a power of two.\r
- If Alignment is zero, then byte alignment is used.\r
-\r
- @return A pointer to the allocated buffer or NULL if allocation fails.\r
-\r
-**/\r
-VOID *\r
-InternalAllocateAlignedZeroPool (\r
- IN EFI_MEMORY_TYPE PoolType,\r
- IN UINTN AllocationSize,\r
- IN UINTN Alignment\r
- )\r
-{\r
- VOID *Memory;\r
- Memory = InternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);\r
- if (Memory != NULL) {\r
- ZeroMem (Memory, AllocationSize);\r
- }\r
- return Memory;\r
-}\r
-\r
-/**\r
- Allocates and zeros a buffer of type EfiBootServicesData at a specified alignment.\r
-\r
- Allocates the number bytes specified by AllocationSize of type EfiBootServicesData with an\r
- alignment specified by Alignment, clears the buffer with zeros, and returns a pointer to the\r
- allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there\r
- is not enough memory at the specified alignment remaining to satisfy the request, then NULL is\r
- returned.\r
- If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
-\r
- @param AllocationSize The number of bytes to allocate.\r
- @param Alignment The requested alignment of the allocation. Must be a power of two.\r
- If Alignment is zero, then byte alignment is used.\r
-\r
- @return A pointer to the allocated buffer or NULL if allocation fails.\r
-\r
-**/\r
-VOID *\r
-EFIAPI\r
-AllocateAlignedZeroPool (\r
- IN UINTN AllocationSize,\r
- IN UINTN Alignment\r
- )\r
-{\r
- return InternalAllocateAlignedZeroPool (EfiBootServicesData, AllocationSize, Alignment);\r
-}\r
-\r
-/**\r
- Frees a buffer that was previously allocated with one of the aligned pool allocation functions\r
- in the Memory Allocation Library.\r
-\r
- Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the\r
- aligned pool allocation services of the Memory Allocation Library.\r
- If Buffer was not allocated with an aligned pool allocation function in the Memory Allocation\r
- Library, then ASSERT().\r
-\r
- @param Buffer Pointer to the buffer to free.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-FreeAlignedPool (\r
- IN VOID *Buffer\r
- )\r
-{\r
- VOID *RawAddress;\r
- VOID **FreePointer;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Get the pre-saved original address in the over-allocate pool.\r
- //\r
- FreePointer = (VOID **)((UINTN) Buffer - sizeof (RawAddress));\r
- RawAddress = *FreePointer;\r
-\r
- Status = gBS->FreePool (RawAddress);\r
- ASSERT_EFI_ERROR (Status);\r
-}\r
-\r
/**\r
Create a command transfer TRB to support XHCI command interfaces.\r
\r
- @param Xhc The XHCI device.\r
+ @param Xhc The XHCI Instance.\r
@param CmdTrb The cmd TRB to be executed.\r
\r
@return Created URB or NULL.\r
**/\r
URB*\r
XhcCreateCmdTrb (\r
- IN USB_XHCI_DEV *Xhc,\r
- IN TRB *CmdTrb\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN TRB_TEMPLATE *CmdTrb\r
)\r
{\r
URB *Urb;\r
XhcSyncTrsRing (Xhc, Urb->Ring);\r
Urb->TrbNum = 1;\r
Urb->TrbStart = Urb->Ring->RingEnqueue;\r
- CopyMem (Urb->TrbStart, CmdTrb, sizeof (TRB));\r
+ CopyMem (Urb->TrbStart, CmdTrb, sizeof (TRB_TEMPLATE));\r
Urb->TrbStart->CycleBit = Urb->Ring->RingPCS & BIT0;\r
Urb->TrbEnd = Urb->TrbStart;\r
\r
- Urb->EvtRing = &Xhc->CmdEventRing;\r
+ Urb->EvtRing = &Xhc->EventRing;\r
XhcSyncEventRing (Xhc, Urb->EvtRing);\r
Urb->EvtTrbStart = Urb->EvtRing->EventRingEnqueue;\r
\r
/**\r
Execute a XHCI cmd TRB pointed by CmdTrb.\r
\r
- @param Xhc The XHCI device.\r
+ @param Xhc The XHCI Instance.\r
@param CmdTrb The cmd TRB to be executed.\r
- @param TimeOut Indicates the maximum time, in millisecond, which the\r
+ @param Timeout Indicates the maximum time, in millisecond, which the\r
transfer is allowed to complete.\r
@param EvtTrb The event TRB corresponding to the cmd TRB.\r
\r
EFI_STATUS\r
EFIAPI\r
XhcCmdTransfer (\r
- IN USB_XHCI_DEV *Xhc,\r
- IN TRB *CmdTrb,\r
- IN UINTN TimeOut,\r
- OUT TRB **EvtTrb\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN TRB_TEMPLATE *CmdTrb,\r
+ IN UINTN Timeout,\r
+ OUT TRB_TEMPLATE **EvtTrb\r
)\r
{\r
EFI_STATUS Status;\r
goto ON_EXIT;\r
}\r
\r
- ASSERT (Urb->EvtRing == &Xhc->CmdEventRing);\r
+ ASSERT (Urb->EvtRing == &Xhc->EventRing);\r
\r
- Status = XhcExecTransfer (Xhc, TRUE, Urb, TimeOut);\r
+ Status = XhcExecTransfer (Xhc, TRUE, Urb, Timeout);\r
*EvtTrb = Urb->EvtTrbStart;\r
\r
if (Urb->Result == EFI_USB_NOERROR) {\r
/**\r
Create a new URB for a new transaction.\r
\r
- @param Xhc The XHCI device\r
- @param DevAddr The device address\r
+ @param Xhc The XHCI Instance\r
+ @param BusAddr The logical device address assigned by UsbBus driver\r
@param EpAddr Endpoint addrress\r
@param DevSpeed The device speed\r
@param MaxPacket The max packet length of the endpoint\r
**/\r
URB*\r
XhcCreateUrb (\r
- IN USB_XHCI_DEV *Xhc,\r
- IN UINT8 DevAddr,\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT8 BusAddr,\r
IN UINT8 EpAddr,\r
IN UINT8 DevSpeed,\r
IN UINTN MaxPacket,\r
InitializeListHead (&Urb->UrbList);\r
\r
Ep = &Urb->Ep;\r
- Ep->DevAddr = DevAddr;\r
- Ep->EpAddr = EpAddr & 0x0F;\r
+ Ep->BusAddr = BusAddr;\r
+ Ep->EpAddr = (UINT8)(EpAddr & 0x0F);\r
Ep->Direction = ((EpAddr & 0x80) != 0) ? EfiUsbDataIn : EfiUsbDataOut;\r
Ep->DevSpeed = DevSpeed;\r
Ep->MaxPacket = MaxPacket;\r
Urb->Context = Context;\r
\r
Status = XhcCreateTransferTrb (Xhc, Urb);\r
+ ASSERT_EFI_ERROR (Status);\r
\r
return Urb;\r
}\r
/**\r
Create a transfer TRB.\r
\r
- @param Xhc The XHCI device\r
+ @param Xhc The XHCI Instance\r
@param Urb The urb used to construct the transfer TRB.\r
\r
@return Created TRB or NULL\r
\r
**/\r
EFI_STATUS\r
-EFIAPI\r
XhcCreateTransferTrb (\r
- IN USB_XHCI_DEV *Xhc,\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
IN URB *Urb\r
)\r
{\r
- DEVICE_CONTEXT *OutputDevContxt;\r
+ VOID *OutputContext;\r
TRANSFER_RING *EPRing;\r
UINT8 EPType;\r
UINT8 SlotId;\r
UINTN Len;\r
UINTN TrbNum;\r
\r
- SlotId = XhcDevAddrToSlotId(Urb->Ep.DevAddr);\r
- Dci = XhcEndpointToDci (Urb->Ep.EpAddr, Urb->Ep.Direction);\r
- EPRing = (TRANSFER_RING *)(UINTN) UsbDevContext[SlotId].EndpointTransferRing[Dci-1];\r
+ SlotId = XhcBusDevAddrToSlotId (Xhc, Urb->Ep.BusAddr);\r
+ if (SlotId == 0) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ Dci = XhcEndpointToDci (Urb->Ep.EpAddr, (UINT8)(Urb->Ep.Direction));\r
+ ASSERT (Dci < 32);\r
+ EPRing = (TRANSFER_RING *)(UINTN) Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1];\r
Urb->Ring = EPRing;\r
- OutputDevContxt = (DEVICE_CONTEXT *)(UINTN) Xhc->DCBAA[SlotId];\r
- EPType = (UINT8) OutputDevContxt->EP[Dci-1].EPType;\r
+ OutputContext = (VOID *)(UINTN)Xhc->DCBAA[SlotId];\r
+ if (Xhc->HcCParams.Data.Csz == 0) {\r
+ EPType = (UINT8) ((DEVICE_CONTEXT *)OutputContext)->EP[Dci-1].EPType;\r
+ } else {\r
+ EPType = (UINT8) ((DEVICE_CONTEXT_64 *)OutputContext)->EP[Dci-1].EPType;\r
+ }\r
\r
//\r
// Construct the TRB\r
Urb->TrbStart = EPRing->RingEnqueue;\r
switch (EPType) {\r
case ED_CONTROL_BIDIR:\r
- Urb->EvtRing = &Xhc->CtrlTrEventRing;\r
+ Urb->EvtRing = &Xhc->EventRing;\r
XhcSyncEventRing (Xhc, Urb->EvtRing);\r
Urb->EvtTrbStart = Urb->EvtRing->EventRingEnqueue;\r
//\r
// For control transfer, create SETUP_STAGE_TRB first.\r
//\r
- TrbStart = EPRing->RingEnqueue;\r
- ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->bmRequestType = Urb->Request->RequestType;\r
- ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->bRequest = Urb->Request->Request;\r
- ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->wValue = Urb->Request->Value;\r
- ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->wIndex = Urb->Request->Index;\r
- ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->wLength = Urb->Request->Length;\r
- ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->Lenth = 8;\r
- ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->IntTarget = Urb->EvtRing->EventInterrupter;\r
- ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->IOC = 1;\r
- ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->IDT = 1;\r
- ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->Type = TRB_TYPE_SETUP_STAGE;\r
+ TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue;\r
+ TrbStart->TrbCtrSetup.bmRequestType = Urb->Request->RequestType;\r
+ TrbStart->TrbCtrSetup.bRequest = Urb->Request->Request;\r
+ TrbStart->TrbCtrSetup.wValue = Urb->Request->Value;\r
+ TrbStart->TrbCtrSetup.wIndex = Urb->Request->Index;\r
+ TrbStart->TrbCtrSetup.wLength = Urb->Request->Length;\r
+ TrbStart->TrbCtrSetup.Lenth = 8;\r
+ TrbStart->TrbCtrSetup.IntTarget = 0;\r
+ TrbStart->TrbCtrSetup.IOC = 1;\r
+ TrbStart->TrbCtrSetup.IDT = 1;\r
+ TrbStart->TrbCtrSetup.Type = TRB_TYPE_SETUP_STAGE;\r
if (Urb->Ep.Direction == EfiUsbDataIn) {\r
- ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->TRT = 3;\r
+ TrbStart->TrbCtrSetup.TRT = 3;\r
} else if (Urb->Ep.Direction == EfiUsbDataOut) {\r
- ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->TRT = 2;\r
+ TrbStart->TrbCtrSetup.TRT = 2;\r
} else {\r
- ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->TRT = 0;\r
+ TrbStart->TrbCtrSetup.TRT = 0;\r
}\r
//\r
// Update the cycle bit\r
//\r
- ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->CycleBit = EPRing->RingPCS & BIT0;\r
+ TrbStart->TrbCtrSetup.CycleBit = EPRing->RingPCS & BIT0;\r
Urb->TrbNum++;\r
\r
//\r
//\r
if (Urb->DataLen > 0) {\r
XhcSyncTrsRing (Xhc, EPRing);\r
- TrbStart = EPRing->RingEnqueue;\r
- ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->TRBPtrLo = XHC_LOW_32BIT(Urb->Data);\r
- ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->TRBPtrHi = XHC_HIGH_32BIT(Urb->Data);\r
- ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->Lenth = (UINT32) Urb->DataLen;\r
- ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->TDSize = 0;\r
- ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->IntTarget = Urb->EvtRing->EventInterrupter;\r
- ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->ISP = 1;\r
- ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->IOC = 1;\r
- ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->IDT = 0;\r
- ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->CH = 0;\r
- ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->Type = TRB_TYPE_DATA_STAGE;\r
+ TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue;\r
+ TrbStart->TrbCtrData.TRBPtrLo = XHC_LOW_32BIT(Urb->Data);\r
+ TrbStart->TrbCtrData.TRBPtrHi = XHC_HIGH_32BIT(Urb->Data);\r
+ TrbStart->TrbCtrData.Lenth = (UINT32) Urb->DataLen;\r
+ TrbStart->TrbCtrData.TDSize = 0;\r
+ TrbStart->TrbCtrData.IntTarget = 0;\r
+ TrbStart->TrbCtrData.ISP = 1;\r
+ TrbStart->TrbCtrData.IOC = 1;\r
+ TrbStart->TrbCtrData.IDT = 0;\r
+ TrbStart->TrbCtrData.CH = 0;\r
+ TrbStart->TrbCtrData.Type = TRB_TYPE_DATA_STAGE;\r
if (Urb->Ep.Direction == EfiUsbDataIn) {\r
- ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->DIR = 1;\r
+ TrbStart->TrbCtrData.DIR = 1;\r
} else if (Urb->Ep.Direction == EfiUsbDataOut) {\r
- ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->DIR = 0;\r
+ TrbStart->TrbCtrData.DIR = 0;\r
} else {\r
- ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->DIR = 0;\r
+ TrbStart->TrbCtrData.DIR = 0;\r
}\r
//\r
// Update the cycle bit\r
//\r
- ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->CycleBit = EPRing->RingPCS & BIT0;\r
+ TrbStart->TrbCtrData.CycleBit = EPRing->RingPCS & BIT0;\r
Urb->TrbNum++;\r
}\r
//\r
// Get the pointer to next TRB for status stage use\r
//\r
XhcSyncTrsRing (Xhc, EPRing);\r
- TrbStart = EPRing->RingEnqueue;\r
- ((TRANSFER_TRB_CONTROL_STATUS *) TrbStart)->IntTarget = Urb->EvtRing->EventInterrupter;\r
- ((TRANSFER_TRB_CONTROL_STATUS *) TrbStart)->IOC = 1;\r
- ((TRANSFER_TRB_CONTROL_STATUS *) TrbStart)->CH = 0;\r
- ((TRANSFER_TRB_CONTROL_STATUS *) TrbStart)->Type = TRB_TYPE_STATUS_STAGE;\r
+ TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue;\r
+ TrbStart->TrbCtrStatus.IntTarget = 0;\r
+ TrbStart->TrbCtrStatus.IOC = 1;\r
+ TrbStart->TrbCtrStatus.CH = 0;\r
+ TrbStart->TrbCtrStatus.Type = TRB_TYPE_STATUS_STAGE;\r
if (Urb->Ep.Direction == EfiUsbDataIn) {\r
- ((TRANSFER_TRB_CONTROL_STATUS *) TrbStart)->DIR = 0;\r
+ TrbStart->TrbCtrStatus.DIR = 0;\r
} else if (Urb->Ep.Direction == EfiUsbDataOut) {\r
- ((TRANSFER_TRB_CONTROL_STATUS *) TrbStart)->DIR = 1;\r
+ TrbStart->TrbCtrStatus.DIR = 1;\r
} else {\r
- ((TRANSFER_TRB_CONTROL_STATUS *) TrbStart)->DIR = 0;\r
+ TrbStart->TrbCtrStatus.DIR = 0;\r
}\r
//\r
// Update the cycle bit\r
//\r
- ((TRANSFER_TRB_CONTROL_STATUS *) TrbStart)->CycleBit = EPRing->RingPCS & BIT0;\r
+ TrbStart->TrbCtrStatus.CycleBit = EPRing->RingPCS & BIT0;\r
//\r
// Update the enqueue pointer\r
//\r
XhcSyncTrsRing (Xhc, EPRing);\r
Urb->TrbNum++;\r
- Urb->TrbEnd = TrbStart;\r
+ Urb->TrbEnd = (TRB_TEMPLATE *)(UINTN)TrbStart;\r
\r
break;\r
\r
case ED_BULK_OUT:\r
case ED_BULK_IN:\r
- Urb->EvtRing = &Xhc->BulkTrEventRing;\r
+ Urb->EvtRing = &Xhc->EventRing;\r
XhcSyncEventRing (Xhc, Urb->EvtRing);\r
Urb->EvtTrbStart = Urb->EvtRing->EventRingEnqueue;\r
\r
TotalLen = 0;\r
Len = 0;\r
TrbNum = 0;\r
- TrbStart = EPRing->RingEnqueue;\r
+ TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue;\r
while (TotalLen < Urb->DataLen) {\r
if ((TotalLen + 0x10000) >= Urb->DataLen) {\r
Len = Urb->DataLen - TotalLen;\r
} else {\r
Len = 0x10000;\r
}\r
- TrbStart = EPRing->RingEnqueue;\r
- ((TRANSFER_TRB_NORMAL *) TrbStart)->TRBPtrLo = XHC_LOW_32BIT((UINT8 *) Urb->Data + TotalLen);\r
- ((TRANSFER_TRB_NORMAL *) TrbStart)->TRBPtrHi = XHC_HIGH_32BIT((UINT8 *) Urb->Data + TotalLen);\r
- ((TRANSFER_TRB_NORMAL *) TrbStart)->Lenth = (UINT32) Len;\r
- ((TRANSFER_TRB_NORMAL *) TrbStart)->TDSize = 0;\r
- ((TRANSFER_TRB_NORMAL *) TrbStart)->IntTarget = Urb->EvtRing->EventInterrupter;\r
- ((TRANSFER_TRB_NORMAL *) TrbStart)->ISP = 1;\r
- ((TRANSFER_TRB_NORMAL *) TrbStart)->IOC = 1;\r
- ((TRANSFER_TRB_NORMAL *) TrbStart)->Type = TRB_TYPE_NORMAL;\r
+ TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue;\r
+ TrbStart->TrbNormal.TRBPtrLo = XHC_LOW_32BIT((UINT8 *) Urb->Data + TotalLen);\r
+ TrbStart->TrbNormal.TRBPtrHi = XHC_HIGH_32BIT((UINT8 *) Urb->Data + TotalLen);\r
+ TrbStart->TrbNormal.Lenth = (UINT32) Len;\r
+ TrbStart->TrbNormal.TDSize = 0;\r
+ TrbStart->TrbNormal.IntTarget = 0;\r
+ TrbStart->TrbNormal.ISP = 1;\r
+ TrbStart->TrbNormal.IOC = 1;\r
+ TrbStart->TrbNormal.Type = TRB_TYPE_NORMAL;\r
//\r
// Update the cycle bit\r
//\r
- ((TRANSFER_TRB_NORMAL *) TrbStart)->CycleBit = EPRing->RingPCS & BIT0;\r
+ TrbStart->TrbNormal.CycleBit = EPRing->RingPCS & BIT0;\r
\r
XhcSyncTrsRing (Xhc, EPRing);\r
TrbNum++;\r
}\r
\r
Urb->TrbNum = TrbNum;\r
- Urb->TrbEnd = TrbStart;\r
+ Urb->TrbEnd = (TRB_TEMPLATE *)(UINTN)TrbStart;\r
break;\r
\r
case ED_INTERRUPT_OUT:\r
case ED_INTERRUPT_IN:\r
- if (Urb->Ep.Type == XHC_INT_TRANSFER_ASYNC) {\r
- Urb->EvtRing = &Xhc->AsynIntTrEventRing;\r
- } else if(Urb->Ep.Type == XHC_INT_TRANSFER_SYNC){\r
- Urb->EvtRing = &Xhc->IntTrEventRing;\r
- } else {\r
- DEBUG ((EFI_D_ERROR, "EP Interrupt type error!\n"));\r
- ASSERT(FALSE);\r
- }\r
+ Urb->EvtRing = &Xhc->EventRing;\r
XhcSyncEventRing (Xhc, Urb->EvtRing);\r
Urb->EvtTrbStart = Urb->EvtRing->EventRingEnqueue;\r
\r
TotalLen = 0;\r
Len = 0;\r
TrbNum = 0;\r
- TrbStart = EPRing->RingEnqueue;\r
+ TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue;\r
while (TotalLen < Urb->DataLen) {\r
if ((TotalLen + 0x10000) >= Urb->DataLen) {\r
Len = Urb->DataLen - TotalLen;\r
} else {\r
Len = 0x10000;\r
}\r
- TrbStart = EPRing->RingEnqueue;\r
- ((TRANSFER_TRB_NORMAL *) TrbStart)->TRBPtrLo = XHC_LOW_32BIT((UINT8 *) Urb->Data + TotalLen);\r
- ((TRANSFER_TRB_NORMAL *) TrbStart)->TRBPtrHi = XHC_HIGH_32BIT((UINT8 *) Urb->Data + TotalLen);\r
- ((TRANSFER_TRB_NORMAL *) TrbStart)->Lenth = (UINT32) Len;\r
- ((TRANSFER_TRB_NORMAL *) TrbStart)->TDSize = 0;\r
- ((TRANSFER_TRB_NORMAL *) TrbStart)->IntTarget = Urb->EvtRing->EventInterrupter;\r
- ((TRANSFER_TRB_NORMAL *) TrbStart)->ISP = 1;\r
- ((TRANSFER_TRB_NORMAL *) TrbStart)->IOC = 1;\r
- ((TRANSFER_TRB_NORMAL *) TrbStart)->Type = TRB_TYPE_NORMAL;\r
+ TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue;\r
+ TrbStart->TrbNormal.TRBPtrLo = XHC_LOW_32BIT((UINT8 *) Urb->Data + TotalLen);\r
+ TrbStart->TrbNormal.TRBPtrHi = XHC_HIGH_32BIT((UINT8 *) Urb->Data + TotalLen);\r
+ TrbStart->TrbNormal.Lenth = (UINT32) Len;\r
+ TrbStart->TrbNormal.TDSize = 0;\r
+ TrbStart->TrbNormal.IntTarget = 0;\r
+ TrbStart->TrbNormal.ISP = 1;\r
+ TrbStart->TrbNormal.IOC = 1;\r
+ TrbStart->TrbNormal.Type = TRB_TYPE_NORMAL;\r
//\r
// Update the cycle bit\r
//\r
- ((TRANSFER_TRB_NORMAL *) TrbStart)->CycleBit = EPRing->RingPCS & BIT0;\r
+ TrbStart->TrbNormal.CycleBit = EPRing->RingPCS & BIT0;\r
\r
XhcSyncTrsRing (Xhc, EPRing);\r
TrbNum++;\r
}\r
\r
Urb->TrbNum = TrbNum;\r
- Urb->TrbEnd = TrbStart;\r
+ Urb->TrbEnd = (TRB_TEMPLATE *)(UINTN)TrbStart;\r
break;\r
\r
default:\r
/**\r
Initialize the XHCI host controller for schedule.\r
\r
- @param Xhc The XHCI device to be initialized.\r
+ @param Xhc The XHCI Instance to be initialized.\r
\r
**/\r
VOID\r
XhcInitSched (\r
- IN USB_XHCI_DEV *Xhc\r
+ IN USB_XHCI_INSTANCE *Xhc\r
)\r
{\r
VOID *Dcbaa;\r
// Software shall set Device Context Base Address Array entries for unallocated Device Slots to '0'.\r
//\r
Entries = (Xhc->MaxSlotsEn + 1) * sizeof(UINT64);\r
- Dcbaa = AllocateAlignedZeroPool(Entries, 64);\r
+ Dcbaa = AllocatePages (EFI_SIZE_TO_PAGES (Entries));\r
ASSERT (Dcbaa != NULL);\r
+ ZeroMem (Dcbaa, Entries);\r
\r
//\r
// A Scratchpad Buffer is a PAGESIZE block of system memory located on a PAGESIZE boundary.\r
//\r
MaxScratchpadBufs = ((Xhc->HcSParams2.Data.ScratchBufHi) << 5) | (Xhc->HcSParams2.Data.ScratchBufLo);\r
Xhc->MaxScratchpadBufs = MaxScratchpadBufs;\r
- ASSERT (MaxScratchpadBufs >= 0 && MaxScratchpadBufs <= 1023);\r
+ ASSERT (MaxScratchpadBufs <= 1023);\r
if (MaxScratchpadBufs != 0) {\r
- ScratchBuf = AllocateAlignedZeroPool(MaxScratchpadBufs * sizeof (UINT64), Xhc->PageSize);\r
+ ScratchBuf = AllocateAlignedPages (EFI_SIZE_TO_PAGES (MaxScratchpadBufs * sizeof (UINT64)), Xhc->PageSize);\r
ASSERT (ScratchBuf != NULL);\r
+ ZeroMem (ScratchBuf, MaxScratchpadBufs * sizeof (UINT64));\r
Xhc->ScratchBuf = ScratchBuf;\r
\r
for (Index = 0; Index < MaxScratchpadBufs; Index++) {\r
- ScratchEntryBuf = AllocateAlignedZeroPool(Xhc->PageSize, Xhc->PageSize);\r
+ ScratchEntryBuf = AllocateAlignedPages (EFI_SIZE_TO_PAGES (Xhc->PageSize), Xhc->PageSize);\r
+ ASSERT (ScratchEntryBuf != NULL);\r
+ ZeroMem (ScratchEntryBuf, Xhc->PageSize);\r
*ScratchBuf++ = (UINT64)(UINTN)ScratchEntryBuf;\r
}\r
\r
// Program the Device Context Base Address Array Pointer (DCBAAP) register (5.4.6) with\r
// a 64-bit address pointing to where the Device Context Base Address Array is located.\r
//\r
- Xhc->DCBAA = (UINT64 *)(UINTN)Dcbaa;\r
- XhcWriteOpReg64 (Xhc, XHC_DCBAAP_OFFSET, (UINT64)Xhc->DCBAA);\r
- DEBUG ((EFI_D_INFO, "XhcInitSched:DCBAA=0x%x\n", (UINT64)Xhc->DCBAA));\r
+ Xhc->DCBAA = (UINT64 *)(UINTN)Dcbaa;\r
+ //\r
+ // Some 3rd party XHCI external cards don't support single 64-bytes width register access,\r
+ // So divide it to two 32-bytes width register access.\r
+ //\r
+ XhcWriteOpReg (Xhc, XHC_DCBAAP_OFFSET, XHC_LOW_32BIT(Xhc->DCBAA));\r
+ XhcWriteOpReg (Xhc, XHC_DCBAAP_OFFSET + 4, XHC_HIGH_32BIT (Xhc->DCBAA));\r
+ DEBUG ((EFI_D_INFO, "XhcInitSched:DCBAA=0x%x\n", (UINT64)(UINTN)Xhc->DCBAA));\r
\r
//\r
// Define the Command Ring Dequeue Pointer by programming the Command Ring Control Register\r
CmdRing = (UINT64)(UINTN)Xhc->CmdRing.RingSeg0;\r
ASSERT ((CmdRing & 0x3F) == 0);\r
CmdRing |= XHC_CRCR_RCS;\r
- XhcWriteOpReg64 (Xhc, XHC_CRCR_OFFSET, CmdRing);\r
+ //\r
+ // Some 3rd party XHCI external cards don't support single 64-bytes width register access,\r
+ // So divide it to two 32-bytes width register access.\r
+ //\r
+ XhcWriteOpReg (Xhc, XHC_CRCR_OFFSET, XHC_LOW_32BIT(CmdRing));\r
+ XhcWriteOpReg (Xhc, XHC_CRCR_OFFSET + 4, XHC_HIGH_32BIT (CmdRing));\r
\r
DEBUG ((EFI_D_INFO, "XhcInitSched:XHC_CRCR=0x%x\n", Xhc->CmdRing.RingSeg0));\r
\r
//\r
// Allocate EventRing for Cmd, Ctrl, Bulk, Interrupt, AsynInterrupt transfer\r
//\r
- CreateEventRing (Xhc, CMD_INTER, &Xhc->CmdEventRing);\r
- CreateEventRing (Xhc, CTRL_INTER, &Xhc->CtrlTrEventRing);\r
- CreateEventRing (Xhc, BULK_INTER, &Xhc->BulkTrEventRing);\r
- CreateEventRing (Xhc, INT_INTER, &Xhc->IntTrEventRing);\r
- CreateEventRing (Xhc, INT_INTER_ASYNC, &Xhc->AsynIntTrEventRing);\r
+ CreateEventRing (Xhc, &Xhc->EventRing);\r
+ DEBUG ((EFI_D_INFO, "XhcInitSched:XHC_EVENTRING=0x%x\n", Xhc->EventRing.EventRingSeg0));\r
}\r
\r
/**\r
reenabled. The next write to the Doorbell of the Endpoint will transition the Endpoint Context from the\r
Stopped to the Running state.\r
\r
- @param Xhc The XHCI device.\r
+ @param Xhc The XHCI Instance.\r
@param Urb The urb which makes the endpoint halted.\r
\r
@retval EFI_SUCCESS The recovery is successful.\r
EFI_STATUS\r
EFIAPI\r
XhcRecoverHaltedEndpoint (\r
- IN USB_XHCI_DEV *Xhc,\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
IN URB *Urb\r
)\r
{\r
- EFI_STATUS Status;\r
- EVT_TRB_COMMAND *EvtTrb;\r
- CMD_TRB_RESET_ED CmdTrbResetED;\r
- CMD_SET_TR_DEQ CmdSetTRDeq;\r
- UINT8 Dci;\r
- UINT8 SlotId;\r
-\r
- Status = EFI_SUCCESS;\r
- SlotId = XhcDevAddrToSlotId(Urb->Ep.DevAddr);\r
- Dci = XhcEndpointToDci(Urb->Ep.EpAddr, Urb->Ep.Direction);\r
+ EFI_STATUS Status;\r
+ EVT_TRB_COMMAND_COMPLETION *EvtTrb;\r
+ CMD_TRB_RESET_ENDPOINT CmdTrbResetED;\r
+ CMD_SET_TR_DEQ_POINTER CmdSetTRDeq;\r
+ UINT8 Dci;\r
+ UINT8 SlotId;\r
\r
+ Status = EFI_SUCCESS;\r
+ SlotId = XhcBusDevAddrToSlotId (Xhc, Urb->Ep.BusAddr);\r
+ if (SlotId == 0) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+ Dci = XhcEndpointToDci (Urb->Ep.EpAddr, (UINT8)(Urb->Ep.Direction));\r
+ ASSERT (Dci < 32);\r
+ \r
DEBUG ((EFI_D_INFO, "Recovery Halted Slot = %x,Dci = %x\n", SlotId, Dci));\r
\r
//\r
CmdTrbResetED.SlotId = SlotId;\r
Status = XhcCmdTransfer (\r
Xhc,\r
- (TRB *) (UINTN) &CmdTrbResetED,\r
+ (TRB_TEMPLATE *) (UINTN) &CmdTrbResetED,\r
XHC_GENERIC_TIMEOUT,\r
- (TRB **) (UINTN) &EvtTrb\r
+ (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
);\r
ASSERT (!EFI_ERROR(Status));\r
\r
CmdSetTRDeq.SlotId = SlotId;\r
Status = XhcCmdTransfer (\r
Xhc,\r
- (TRB *) (UINTN) &CmdSetTRDeq,\r
+ (TRB_TEMPLATE *) (UINTN) &CmdSetTRDeq,\r
XHC_GENERIC_TIMEOUT,\r
- (TRB **) (UINTN) &EvtTrb\r
+ (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
);\r
ASSERT (!EFI_ERROR(Status));\r
\r
/**\r
Create XHCI event ring.\r
\r
- @param Xhc The XHCI device.\r
- @param EventInterrupter The interrupter of event.\r
+ @param Xhc The XHCI Instance.\r
@param EventRing The created event ring.\r
\r
**/\r
VOID\r
-EFIAPI\r
CreateEventRing (\r
- IN USB_XHCI_DEV *Xhc,\r
- IN UINT8 EventInterrupter,\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
OUT EVENT_RING *EventRing\r
)\r
{\r
\r
ASSERT (EventRing != NULL);\r
\r
- Buf = AllocateAlignedZeroPool(sizeof (TRB) * EVENT_RING_TRB_NUMBER, 64);\r
+ Buf = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER));\r
ASSERT (Buf != NULL);\r
ASSERT (((UINTN) Buf & 0x3F) == 0);\r
+ ZeroMem (Buf, sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER);\r
\r
EventRing->EventRingSeg0 = Buf;\r
- EventRing->EventInterrupter = EventInterrupter;\r
EventRing->TrbNumber = EVENT_RING_TRB_NUMBER;\r
- EventRing->EventRingDequeue = (TRB *) EventRing->EventRingSeg0;\r
- EventRing->EventRingEnqueue = (TRB *) EventRing->EventRingSeg0;\r
+ EventRing->EventRingDequeue = (TRB_TEMPLATE *) EventRing->EventRingSeg0;\r
+ EventRing->EventRingEnqueue = (TRB_TEMPLATE *) EventRing->EventRingSeg0;\r
//\r
// Software maintains an Event Ring Consumer Cycle State (CCS) bit, initializing it to '1'\r
// and toggling it every time the Event Ring Dequeue Pointer wraps back to the beginning of the Event Ring.\r
//\r
EventRing->EventRingCCS = 1;\r
\r
- Buf = AllocateAlignedZeroPool(sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER, 64);\r
+ Buf = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER));\r
ASSERT (Buf != NULL);\r
ASSERT (((UINTN) Buf & 0x3F) == 0);\r
+ ZeroMem (Buf, sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER);\r
\r
ERSTBase = (EVENT_RING_SEG_TABLE_ENTRY *) Buf;\r
EventRing->ERSTBase = ERSTBase;\r
//\r
XhcWriteRuntimeReg (\r
Xhc,\r
- XHC_ERSTSZ_OFFSET + (32 * EventRing->EventInterrupter),\r
+ XHC_ERSTSZ_OFFSET,\r
ERST_NUMBER\r
);\r
//\r
// Program the Interrupter Event Ring Dequeue Pointer (ERDP) register (5.5.2.3.3)\r
//\r
- XhcWriteRuntimeReg64 (\r
+ // Some 3rd party XHCI external cards don't support single 64-bytes width register access,\r
+ // So divide it to two 32-bytes width register access.\r
+ //\r
+ XhcWriteRuntimeReg (\r
+ Xhc,\r
+ XHC_ERDP_OFFSET,\r
+ XHC_LOW_32BIT((UINT64)(UINTN)EventRing->EventRingDequeue)\r
+ );\r
+ XhcWriteRuntimeReg (\r
Xhc,\r
- XHC_ERDP_OFFSET + (32 * EventRing->EventInterrupter),\r
- (UINT64)EventRing->EventRingDequeue\r
+ XHC_ERDP_OFFSET + 4,\r
+ XHC_HIGH_32BIT((UINT64)(UINTN)EventRing->EventRingDequeue)\r
);\r
//\r
// Program the Interrupter Event Ring Segment Table Base Address (ERSTBA) register(5.5.2.3.2)\r
//\r
- XhcWriteRuntimeReg64 (\r
+ // Some 3rd party XHCI external cards don't support single 64-bytes width register access,\r
+ // So divide it to two 32-bytes width register access.\r
+ //\r
+ XhcWriteRuntimeReg (\r
+ Xhc,\r
+ XHC_ERSTBA_OFFSET,\r
+ XHC_LOW_32BIT((UINT64)(UINTN)ERSTBase)\r
+ );\r
+ XhcWriteRuntimeReg (\r
Xhc,\r
- XHC_ERSTBA_OFFSET + (32 * EventRing->EventInterrupter),\r
- (UINT64) ERSTBase\r
+ XHC_ERSTBA_OFFSET + 4,\r
+ XHC_HIGH_32BIT((UINT64)(UINTN)ERSTBase)\r
);\r
//\r
// Need set IMAN IE bit to enble the ring interrupt\r
//\r
- XhcSetRuntimeRegBit (Xhc, XHC_IMAN_OFFSET + (32 * EventRing->EventInterrupter), XHC_IMAN_IE);\r
+ XhcSetRuntimeRegBit (Xhc, XHC_IMAN_OFFSET, XHC_IMAN_IE);\r
}\r
\r
/**\r
Create XHCI transfer ring.\r
\r
- @param Xhc The XHCI device.\r
+ @param Xhc The XHCI Instance.\r
@param TrbNum The number of TRB in the ring.\r
@param TransferRing The created transfer ring.\r
\r
**/\r
VOID\r
-EFIAPI\r
CreateTransferRing (\r
- IN USB_XHCI_DEV *Xhc,\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
IN UINTN TrbNum,\r
OUT TRANSFER_RING *TransferRing\r
)\r
{\r
VOID *Buf;\r
- LNK_TRB *EndTrb;\r
+ LINK_TRB *EndTrb;\r
\r
- Buf = AllocateAlignedZeroPool(sizeof (TRB) * TrbNum, 64);\r
+ Buf = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (TRB_TEMPLATE) * TrbNum));\r
ASSERT (Buf != NULL);\r
ASSERT (((UINTN) Buf & 0x3F) == 0);\r
+ ZeroMem (Buf, sizeof (TRB_TEMPLATE) * TrbNum);\r
\r
TransferRing->RingSeg0 = Buf;\r
TransferRing->TrbNumber = TrbNum;\r
- TransferRing->RingEnqueue = (TRB *) TransferRing->RingSeg0;\r
- TransferRing->RingDequeue = (TRB *) TransferRing->RingSeg0;\r
+ TransferRing->RingEnqueue = (TRB_TEMPLATE *) TransferRing->RingSeg0;\r
+ TransferRing->RingDequeue = (TRB_TEMPLATE *) TransferRing->RingSeg0;\r
TransferRing->RingPCS = 1;\r
//\r
// 4.9.2 Transfer Ring Management\r
// To form a ring (or circular queue) a Link TRB may be inserted at the end of a ring to\r
// point to the first TRB in the ring.\r
//\r
- EndTrb = (LNK_TRB*) ((UINTN)Buf + sizeof (TRB) * (TrbNum - 1));\r
+ EndTrb = (LINK_TRB *) ((UINTN)Buf + sizeof (TRB_TEMPLATE) * (TrbNum - 1));\r
EndTrb->Type = TRB_TYPE_LINK;\r
EndTrb->PtrLo = XHC_LOW_32BIT (Buf);\r
EndTrb->PtrHi = XHC_HIGH_32BIT (Buf);\r
/**\r
Free XHCI event ring.\r
\r
- @param Xhc The XHCI device.\r
+ @param Xhc The XHCI Instance.\r
@param EventRing The event ring to be freed.\r
\r
**/\r
EFI_STATUS\r
EFIAPI\r
XhcFreeEventRing (\r
- IN USB_XHCI_DEV *Xhc,\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
IN EVENT_RING *EventRing\r
)\r
{\r
EVENT_RING_SEG_TABLE_ENTRY *TablePtr;\r
VOID *RingBuf;\r
EVENT_RING_SEG_TABLE_ENTRY *EventRingPtr;\r
- UINTN InterrupterTarget;\r
\r
if(EventRing->EventRingSeg0 == NULL) {\r
return EFI_SUCCESS;\r
}\r
\r
- InterrupterTarget = EventRing->EventInterrupter;\r
//\r
// Get the Event Ring Segment Table base address\r
//\r
//\r
for (Index = 0; Index < ERST_NUMBER; Index++) {\r
EventRingPtr = TablePtr + Index;\r
- RingBuf = (VOID *)(UINTN)(EventRingPtr->PtrLo | ((UINT64)EventRingPtr->PtrHi << 32));\r
+ RingBuf = (VOID *)(UINTN)(EventRingPtr->PtrLo | LShiftU64 ((UINT64)EventRingPtr->PtrHi, 32));\r
\r
if(RingBuf != NULL) {\r
- FreeAlignedPool (RingBuf);\r
+ FreePages (RingBuf, EFI_SIZE_TO_PAGES (sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER));\r
ZeroMem (EventRingPtr, sizeof (EVENT_RING_SEG_TABLE_ENTRY));\r
}\r
}\r
\r
- FreeAlignedPool (TablePtr);\r
+ FreePages (TablePtr, EFI_SIZE_TO_PAGES (sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER));\r
return EFI_SUCCESS;\r
}\r
\r
/**\r
Free the resouce allocated at initializing schedule.\r
\r
- @param Xhc The XHCI device.\r
+ @param Xhc The XHCI Instance.\r
\r
**/\r
VOID\r
XhcFreeSched (\r
- IN USB_XHCI_DEV *Xhc\r
+ IN USB_XHCI_INSTANCE *Xhc\r
)\r
{\r
UINT32 Index;\r
+ UINT64 *ScratchBuf;\r
\r
if (Xhc->ScratchBuf != NULL) {\r
+ ScratchBuf = Xhc->ScratchBuf;\r
for (Index = 0; Index < Xhc->MaxScratchpadBufs; Index++) {\r
- FreeAlignedPool ((VOID*)(UINTN)*Xhc->ScratchBuf++);\r
+ FreeAlignedPages ((VOID*)(UINTN)*ScratchBuf++, EFI_SIZE_TO_PAGES (Xhc->PageSize));\r
}\r
+ FreeAlignedPages (Xhc->ScratchBuf, EFI_SIZE_TO_PAGES (Xhc->MaxScratchpadBufs * sizeof (UINT64)));\r
}\r
\r
if (Xhc->DCBAA != NULL) {\r
- FreeAlignedPool (Xhc->DCBAA);\r
+ FreePages (Xhc->DCBAA, EFI_SIZE_TO_PAGES((Xhc->MaxSlotsEn + 1) * sizeof(UINT64)));\r
Xhc->DCBAA = NULL;\r
}\r
\r
if (Xhc->CmdRing.RingSeg0 != NULL){\r
- FreeAlignedPool (Xhc->CmdRing.RingSeg0);\r
+ FreePages (Xhc->CmdRing.RingSeg0, EFI_SIZE_TO_PAGES (sizeof (TRB_TEMPLATE) * CMD_RING_TRB_NUMBER));\r
Xhc->CmdRing.RingSeg0 = NULL;\r
}\r
- XhcFreeEventRing (Xhc,&Xhc->CmdEventRing);\r
- XhcFreeEventRing (Xhc,&Xhc->CtrlTrEventRing);\r
- XhcFreeEventRing (Xhc,&Xhc->BulkTrEventRing);\r
- XhcFreeEventRing (Xhc,&Xhc->AsynIntTrEventRing);\r
- XhcFreeEventRing (Xhc,&Xhc->IntTrEventRing);\r
+\r
+ XhcFreeEventRing (Xhc,&Xhc->EventRing);\r
}\r
\r
/**\r
BOOLEAN\r
IsTransferRingTrb (\r
IN TRANSFER_RING *Ring,\r
- IN TRB *Trb\r
+ IN TRB_TEMPLATE *Trb\r
)\r
{\r
BOOLEAN Flag;\r
- TRB *Trb1;\r
+ TRB_TEMPLATE *Trb1;\r
UINTN Index;\r
\r
Trb1 = Ring->RingSeg0;\r
Check the URB's execution result and update the URB's\r
result accordingly.\r
\r
- @param Xhc The XHCI device.\r
+ @param Xhc The XHCI Instance.\r
@param Urb The URB to check result.\r
\r
@return Whether the result of URB transfer is finialized.\r
**/\r
EFI_STATUS\r
XhcCheckUrbResult (\r
- IN USB_XHCI_DEV *Xhc,\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
IN URB *Urb\r
)\r
{\r
BOOLEAN StartDone;\r
BOOLEAN EndDone;\r
EVT_TRB_TRANSFER *EvtTrb;\r
- TRB *TRBPtr;\r
+ TRB_TEMPLATE *TRBPtr;\r
UINTN Index;\r
UINT8 TRBType;\r
EFI_STATUS Status;\r
Urb->EvtRing->EventRingDequeue = Urb->EvtTrbStart;\r
for (Index = 0; Index < Urb->EvtRing->TrbNumber; Index++) {\r
XhcSyncEventRing (Xhc, Urb->EvtRing);\r
- Status = XhcCheckNewEvent (Xhc, Urb->EvtRing, &(TRB *)EvtTrb);\r
+ Status = XhcCheckNewEvent (Xhc, Urb->EvtRing, ((TRB_TEMPLATE **)&EvtTrb));\r
if (Status == EFI_NOT_READY) {\r
Urb->Result |= EFI_USB_ERR_TIMEOUT;\r
goto EXIT;\r
}\r
\r
- TRBPtr = (TRB *)(UINTN)(EvtTrb->TRBPtrLo | (UINT64) EvtTrb->TRBPtrHi << 32);\r
+ //\r
+ // Only handle COMMAND_COMPLETETION_EVENT and TRANSFER_EVENT.\r
+ //\r
+ if ((EvtTrb->Type != TRB_TYPE_COMMAND_COMPLT_EVENT) && (EvtTrb->Type != TRB_TYPE_TRANS_EVENT)) {\r
+ continue;\r
+ }\r
\r
- switch (EvtTrb->Completcode) {\r
- case TRB_COMPLETION_STALL_ERROR:\r
- Urb->Result |= EFI_USB_ERR_STALL;\r
- Status = EFI_DEVICE_ERROR;\r
- DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: STALL_ERROR! Completcode = %x\n",EvtTrb->Completcode));\r
- goto EXIT;\r
- break;\r
+ TRBPtr = (TRB_TEMPLATE *)(UINTN)(EvtTrb->TRBPtrLo | LShiftU64 ((UINT64) EvtTrb->TRBPtrHi, 32));\r
+ if (IsTransferRingTrb (Urb->Ring, TRBPtr)) {\r
+ switch (EvtTrb->Completecode) {\r
+ case TRB_COMPLETION_STALL_ERROR:\r
+ Urb->Result |= EFI_USB_ERR_STALL;\r
+ Status = EFI_DEVICE_ERROR;\r
+ DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: STALL_ERROR! Completecode = %x\n",EvtTrb->Completecode));\r
+ goto EXIT;\r
+ break;\r
\r
- case TRB_COMPLETION_BABBLE_ERROR:\r
- Urb->Result |= EFI_USB_ERR_BABBLE;\r
- Status = EFI_DEVICE_ERROR;\r
- DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: BABBLE_ERROR! Completcode = %x\n",EvtTrb->Completcode));\r
- goto EXIT;\r
- break;\r
+ case TRB_COMPLETION_BABBLE_ERROR:\r
+ Urb->Result |= EFI_USB_ERR_BABBLE;\r
+ Status = EFI_DEVICE_ERROR;\r
+ DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: BABBLE_ERROR! Completecode = %x\n",EvtTrb->Completecode));\r
+ goto EXIT;\r
+ break;\r
\r
- case TRB_COMPLETION_DATA_BUFFER_ERROR:\r
- Urb->Result |= EFI_USB_ERR_BUFFER;\r
- Status = EFI_DEVICE_ERROR;\r
- DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: ERR_BUFFER! Completcode = %x\n",EvtTrb->Completcode));\r
- goto EXIT;\r
- break;\r
+ case TRB_COMPLETION_DATA_BUFFER_ERROR:\r
+ Urb->Result |= EFI_USB_ERR_BUFFER;\r
+ Status = EFI_DEVICE_ERROR;\r
+ DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: ERR_BUFFER! Completecode = %x\n",EvtTrb->Completecode));\r
+ goto EXIT;\r
+ break;\r
\r
- case TRB_COMPLETION_USB_TRANSACTION_ERROR:\r
- Urb->Result |= EFI_USB_ERR_TIMEOUT;\r
- Status = EFI_DEVICE_ERROR;\r
- DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: TRANSACTION_ERROR! Completcode = %x\n",EvtTrb->Completcode));\r
- goto EXIT;\r
- break;\r
+ case TRB_COMPLETION_USB_TRANSACTION_ERROR:\r
+ Urb->Result |= EFI_USB_ERR_TIMEOUT;\r
+ Status = EFI_DEVICE_ERROR;\r
+ DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: TRANSACTION_ERROR! Completecode = %x\n",EvtTrb->Completecode));\r
+ goto EXIT;\r
+ break;\r
\r
- case TRB_COMPLETION_SHORT_PACKET:\r
- case TRB_COMPLETION_SUCCESS:\r
- if (IsTransferRingTrb (Urb->Ring, TRBPtr)) {\r
- if (EvtTrb->Completcode == TRB_COMPLETION_SHORT_PACKET) {\r
+ case TRB_COMPLETION_SHORT_PACKET:\r
+ case TRB_COMPLETION_SUCCESS:\r
+ if (EvtTrb->Completecode == TRB_COMPLETION_SHORT_PACKET) {\r
DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: short packet happens!\n"));\r
}\r
+\r
TRBType = (UINT8) (TRBPtr->Type);\r
if ((TRBType == TRB_TYPE_DATA_STAGE) ||\r
(TRBType == TRB_TYPE_NORMAL) ||\r
(TRBType == TRB_TYPE_ISOCH)) {\r
Urb->Completed += (Urb->DataLen - EvtTrb->Lenth);\r
}\r
- }\r
- Status = EFI_SUCCESS;\r
- break;\r
\r
- default:\r
- DEBUG ((EFI_D_ERROR, "Transfer Default Error Occur! Completcode = 0x%x!\n",EvtTrb->Completcode));\r
- Urb->Result |= EFI_USB_ERR_TIMEOUT;\r
- Status = EFI_DEVICE_ERROR;\r
- goto EXIT;\r
- break;\r
- }\r
+ Status = EFI_SUCCESS;\r
+ break;\r
\r
- //\r
- // Only check first and end Trb event address\r
- //\r
- if (TRBPtr == Urb->TrbStart) {\r
- StartDone = TRUE;\r
- }\r
+ default:\r
+ DEBUG ((EFI_D_ERROR, "Transfer Default Error Occur! Completecode = 0x%x!\n",EvtTrb->Completecode));\r
+ Urb->Result |= EFI_USB_ERR_TIMEOUT;\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto EXIT;\r
+ break;\r
+ }\r
\r
- if (TRBPtr == Urb->TrbEnd) {\r
- EndDone = TRUE;\r
- }\r
+ //\r
+ // Only check first and end Trb event address\r
+ //\r
+ if (TRBPtr == Urb->TrbStart) {\r
+ StartDone = TRUE;\r
+ }\r
\r
- if (StartDone && EndDone) {\r
- break;\r
+ if (TRBPtr == Urb->TrbEnd) {\r
+ EndDone = TRUE;\r
+ }\r
+\r
+ if (StartDone && EndDone) {\r
+ break;\r
+ }\r
}\r
}\r
\r
/**\r
Execute the transfer by polling the URB. This is a synchronous operation.\r
\r
- @param Xhc The XHCI device.\r
+ @param Xhc The XHCI Instance.\r
@param CmdTransfer The executed URB is for cmd transfer or not.\r
@param Urb The URB to execute.\r
- @param TimeOut The time to wait before abort, in millisecond.\r
+ @param Timeout The time to wait before abort, in millisecond.\r
\r
@return EFI_DEVICE_ERROR The transfer failed due to transfer error.\r
@return EFI_TIMEOUT The transfer failed due to time out.\r
**/\r
EFI_STATUS\r
XhcExecTransfer (\r
- IN USB_XHCI_DEV *Xhc,\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
IN BOOLEAN CmdTransfer,\r
IN URB *Urb,\r
- IN UINTN TimeOut\r
+ IN UINTN Timeout\r
)\r
{\r
EFI_STATUS Status;\r
SlotId = 0;\r
Dci = 0;\r
} else {\r
- SlotId = XhcDevAddrToSlotId(Urb->Ep.DevAddr);\r
- Dci = XhcEndpointToDci(Urb->Ep.EpAddr, Urb->Ep.Direction);\r
+ SlotId = XhcBusDevAddrToSlotId (Xhc, Urb->Ep.BusAddr);\r
+ if (SlotId == 0) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+ Dci = XhcEndpointToDci (Urb->Ep.EpAddr, (UINT8)(Urb->Ep.Direction));\r
+ ASSERT (Dci < 32);\r
}\r
\r
Status = EFI_SUCCESS;\r
- Loop = (TimeOut * XHC_1_MILLISECOND / XHC_SYNC_POLL_INTERVAL) + 1;\r
- if (TimeOut == 0) {\r
+ Loop = (Timeout * XHC_1_MILLISECOND / XHC_POLL_DELAY) + 1;\r
+ if (Timeout == 0) {\r
Loop = 0xFFFFFFFF;\r
}\r
\r
if ((Status != EFI_NOT_READY)) {\r
break;\r
}\r
- gBS->Stall (XHC_SYNC_POLL_INTERVAL);\r
+ gBS->Stall (XHC_POLL_DELAY);\r
}\r
\r
return Status;\r
Delete a single asynchronous interrupt transfer for\r
the device and endpoint.\r
\r
- @param Xhc The XHCI device.\r
- @param DevAddr The address of the target device.\r
+ @param Xhc The XHCI Instance.\r
+ @param BusAddr The logical device address assigned by UsbBus driver.\r
@param EpNum The endpoint of the target.\r
\r
@retval EFI_SUCCESS An asynchronous transfer is removed.\r
**/\r
EFI_STATUS\r
XhciDelAsyncIntTransfer (\r
- IN USB_XHCI_DEV *Xhc,\r
- IN UINT8 DevAddr,\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT8 BusAddr,\r
IN UINT8 EpNum\r
)\r
{\r
LIST_ENTRY *Next;\r
URB *Urb;\r
EFI_USB_DATA_DIRECTION Direction;\r
- BOOLEAN Found;\r
\r
Direction = ((EpNum & 0x80) != 0) ? EfiUsbDataIn : EfiUsbDataOut;\r
EpNum &= 0x0F;\r
\r
- Found = FALSE;\r
- Urb = NULL;\r
+ Urb = NULL;\r
\r
EFI_LIST_FOR_EACH_SAFE (Entry, Next, &Xhc->AsyncIntTransfers) {\r
Urb = EFI_LIST_CONTAINER (Entry, URB, UrbList);\r
- if ((Urb->Ep.DevAddr == DevAddr) &&\r
+ if ((Urb->Ep.BusAddr == BusAddr) &&\r
(Urb->Ep.EpAddr == EpNum) &&\r
(Urb->Ep.Direction == Direction)) {\r
RemoveEntryList (&Urb->UrbList);\r
/**\r
Remove all the asynchronous interrutp transfers.\r
\r
- @param Xhc The XHCI device.\r
+ @param Xhc The XHCI Instance.\r
\r
**/\r
VOID\r
XhciDelAllAsyncIntTransfers (\r
- IN USB_XHCI_DEV *Xhc\r
+ IN USB_XHCI_INSTANCE *Xhc\r
)\r
{\r
LIST_ENTRY *Entry;\r
/**\r
Update the queue head for next round of asynchronous transfer\r
\r
- @param Xhc The XHCI device.\r
+ @param Xhc The XHCI Instance.\r
@param Urb The URB to update\r
\r
**/\r
VOID\r
XhcUpdateAsyncRequest (\r
- IN USB_XHCI_DEV* Xhc,\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
IN URB *Urb\r
)\r
{\r
\r
if (Urb->Result == EFI_USB_NOERROR) {\r
Status = XhcCreateTransferTrb (Xhc, Urb);\r
- ASSERT_EFI_ERROR (Status);\r
+ if (EFI_ERROR (Status)) {\r
+ return;\r
+ }\r
Status = RingIntTransferDoorBell (Xhc, Urb);\r
- ASSERT_EFI_ERROR (Status);\r
+ if (EFI_ERROR (Status)) {\r
+ return;\r
+ }\r
}\r
}\r
\r
Interrupt transfer periodic check handler.\r
\r
@param Event Interrupt event.\r
- @param Context Pointer to USB_XHCI_DEV.\r
+ @param Context Pointer to USB_XHCI_INSTANCE.\r
\r
**/\r
VOID\r
IN VOID *Context\r
)\r
{\r
- USB_XHCI_DEV *Xhc;\r
+ USB_XHCI_INSTANCE *Xhc;\r
LIST_ENTRY *Entry;\r
LIST_ENTRY *Next;\r
UINT8 *ProcBuf;\r
\r
OldTpl = gBS->RaiseTPL (XHC_TPL);\r
\r
- Xhc = (USB_XHCI_DEV*) Context;\r
+ Xhc = (USB_XHCI_INSTANCE*) Context;\r
\r
EFI_LIST_FOR_EACH_SAFE (Entry, Next, &Xhc->AsyncIntTransfers) {\r
Urb = EFI_LIST_CONTAINER (Entry, URB, UrbList);\r
//\r
// Make sure that the device is available before every check.\r
//\r
- SlotId = XhcDevAddrToSlotId(Urb->Ep.DevAddr);\r
+ SlotId = XhcBusDevAddrToSlotId (Xhc, Urb->Ep.BusAddr);\r
if (SlotId == 0) {\r
continue;\r
}\r
if (Urb->Result == EFI_USB_NOERROR) {\r
ASSERT (Urb->Completed <= Urb->DataLen);\r
\r
- ProcBuf = AllocatePool (Urb->Completed);\r
+ ProcBuf = AllocateZeroPool (Urb->Completed);\r
\r
if (ProcBuf == NULL) {\r
XhcUpdateAsyncRequest (Xhc, Urb);\r
/**\r
Monitor the port status change. Enable/Disable device slot if there is a device attached/detached.\r
\r
- @param Xhc The XHCI device.\r
+ @param Xhc The XHCI Instance.\r
@param ParentRouteChart The route string pointed to the parent device if it exists.\r
@param Port The port to be polled.\r
@param PortState The port state.\r
EFI_STATUS\r
EFIAPI\r
XhcPollPortStatusChange (\r
- IN USB_XHCI_DEV* Xhc,\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
IN USB_DEV_ROUTE ParentRouteChart,\r
IN UINT8 Port,\r
IN EFI_USB_PORT_STATUS *PortState\r
Status = EFI_SUCCESS;\r
\r
if (ParentRouteChart.Dword == 0) {\r
- RouteChart.Field.RouteString = 0;\r
- RouteChart.Field.RootPortNum = Port + 1;\r
- RouteChart.Field.TierNum = 1;\r
+ RouteChart.Route.RouteString = 0;\r
+ RouteChart.Route.RootPortNum = Port + 1;\r
+ RouteChart.Route.TierNum = 1;\r
} else {\r
if(Port < 14) {\r
- RouteChart.Field.RouteString = ParentRouteChart.Field.RouteString | (Port << (4 * (ParentRouteChart.Field.TierNum - 1)));\r
+ RouteChart.Route.RouteString = ParentRouteChart.Route.RouteString | (Port << (4 * (ParentRouteChart.Route.TierNum - 1)));\r
} else {\r
- RouteChart.Field.RouteString = ParentRouteChart.Field.RouteString | (15 << (4 * (ParentRouteChart.Field.TierNum - 1)));\r
+ RouteChart.Route.RouteString = ParentRouteChart.Route.RouteString | (15 << (4 * (ParentRouteChart.Route.TierNum - 1)));\r
}\r
- RouteChart.Field.RootPortNum = ParentRouteChart.Field.RootPortNum;\r
- RouteChart.Field.TierNum = ParentRouteChart.Field.TierNum + 1;\r
+ RouteChart.Route.RootPortNum = ParentRouteChart.Route.RootPortNum;\r
+ RouteChart.Route.TierNum = ParentRouteChart.Route.TierNum + 1;\r
}\r
\r
if (((PortState->PortStatus & USB_PORT_STAT_ENABLE) != 0) &&\r
//\r
// Execute Enable_Slot cmd for attached device, initialize device context and assign device address.\r
//\r
- SlotId = XhcRouteStringToSlotId (RouteChart);\r
+ SlotId = XhcRouteStringToSlotId (Xhc, RouteChart);\r
if (SlotId == 0) {\r
- Status = XhcInitializeDeviceSlot (Xhc, ParentRouteChart, Port, RouteChart, Speed);\r
+ if (Xhc->HcCParams.Data.Csz == 0) {\r
+ Status = XhcInitializeDeviceSlot (Xhc, ParentRouteChart, Port, RouteChart, Speed);\r
+ } else {\r
+ Status = XhcInitializeDeviceSlot64 (Xhc, ParentRouteChart, Port, RouteChart, Speed);\r
+ }\r
ASSERT_EFI_ERROR (Status);\r
}\r
} else if ((PortState->PortStatus & USB_PORT_STAT_CONNECTION) == 0) {\r
//\r
// Device is detached. Disable the allocated device slot and release resource.\r
//\r
- SlotId = XhcRouteStringToSlotId (RouteChart);\r
+ SlotId = XhcRouteStringToSlotId (Xhc, RouteChart);\r
if (SlotId != 0) {\r
- Status = XhcDisableSlotCmd (Xhc, SlotId);\r
+ if (Xhc->HcCParams.Data.Csz == 0) {\r
+ Status = XhcDisableSlotCmd (Xhc, SlotId);\r
+ } else {\r
+ Status = XhcDisableSlotCmd64 (Xhc, SlotId);\r
+ }\r
ASSERT_EFI_ERROR (Status);\r
}\r
}\r
if (EpAddr == 0) {\r
return 1;\r
} else {\r
- Index = 2 * EpAddr;\r
+ Index = (UINT8) (2 * EpAddr);\r
if (Direction == EfiUsbDataIn) {\r
Index += 1;\r
}\r
}\r
}\r
\r
-/**\r
- Find out the slot id according to device address assigned by XHCI's Address_Device cmd.\r
-\r
- @param DevAddr The device address of the target device.\r
-\r
- @return The slot id used by the device.\r
-\r
-**/\r
-UINT8\r
-EFIAPI\r
-XhcDevAddrToSlotId (\r
- IN UINT8 DevAddr\r
- )\r
-{\r
- UINT8 Index;\r
-\r
- for (Index = 0; Index < 255; Index++) {\r
- if (UsbDevContext[Index + 1].Enabled &&\r
- (UsbDevContext[Index + 1].SlotId != 0) &&\r
- (UsbDevContext[Index + 1].XhciDevAddr == DevAddr)) {\r
- break;\r
- }\r
- }\r
-\r
- if (Index == 255) {\r
- return 0;\r
- }\r
-\r
- return UsbDevContext[Index + 1].SlotId;\r
-}\r
-\r
/**\r
Find out the actual device address according to the requested device address from UsbBus.\r
\r
- @param BusDevAddr The requested device address by UsbBus upper driver.\r
+ @param Xhc The XHCI Instance.\r
+ @param BusDevAddr The requested device address by UsbBus upper driver.\r
\r
@return The actual device address assigned to the device.\r
\r
UINT8\r
EFIAPI\r
XhcBusDevAddrToSlotId (\r
- IN UINT8 BusDevAddr\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT8 BusDevAddr\r
)\r
{\r
UINT8 Index;\r
\r
for (Index = 0; Index < 255; Index++) {\r
- if (UsbDevContext[Index + 1].Enabled &&\r
- (UsbDevContext[Index + 1].SlotId != 0) &&\r
- (UsbDevContext[Index + 1].BusDevAddr == BusDevAddr)) {\r
+ if (Xhc->UsbDevContext[Index + 1].Enabled &&\r
+ (Xhc->UsbDevContext[Index + 1].SlotId != 0) &&\r
+ (Xhc->UsbDevContext[Index + 1].BusDevAddr == BusDevAddr)) {\r
break;\r
}\r
}\r
return 0;\r
}\r
\r
- return UsbDevContext[Index + 1].SlotId;\r
+ return Xhc->UsbDevContext[Index + 1].SlotId;\r
}\r
\r
/**\r
Find out the slot id according to the device's route string.\r
\r
- @param RouteString The route string described the device location.\r
+ @param Xhc The XHCI Instance.\r
+ @param RouteString The route string described the device location.\r
\r
@return The slot id used by the device.\r
\r
UINT8\r
EFIAPI\r
XhcRouteStringToSlotId (\r
- IN USB_DEV_ROUTE RouteString\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN USB_DEV_ROUTE RouteString\r
)\r
{\r
UINT8 Index;\r
\r
for (Index = 0; Index < 255; Index++) {\r
- if (UsbDevContext[Index + 1].Enabled &&\r
- (UsbDevContext[Index + 1].SlotId != 0) &&\r
- (UsbDevContext[Index + 1].RouteString.Dword == RouteString.Dword)) {\r
+ if (Xhc->UsbDevContext[Index + 1].Enabled &&\r
+ (Xhc->UsbDevContext[Index + 1].SlotId != 0) &&\r
+ (Xhc->UsbDevContext[Index + 1].RouteString.Dword == RouteString.Dword)) {\r
break;\r
}\r
}\r
return 0;\r
}\r
\r
- return UsbDevContext[Index + 1].SlotId;\r
+ return Xhc->UsbDevContext[Index + 1].SlotId;\r
}\r
\r
/**\r
Synchronize the specified event ring to update the enqueue and dequeue pointer.\r
\r
- @param Xhc The XHCI device.\r
+ @param Xhc The XHCI Instance.\r
@param EvtRing The event ring to sync.\r
\r
@retval EFI_SUCCESS The event ring is synchronized successfully.\r
EFI_STATUS\r
EFIAPI\r
XhcSyncEventRing (\r
- IN USB_XHCI_DEV *Xhc,\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
IN EVENT_RING *EvtRing\r
)\r
{\r
UINTN Index;\r
- TRB *EvtTrb1;\r
- TRB *EvtTrb2;\r
- TRB *XhcDequeue;\r
+ TRB_TEMPLATE *EvtTrb1;\r
+ TRB_TEMPLATE *EvtTrb2;\r
+ UINT64 XhcDequeue;\r
+ UINT32 High;\r
+ UINT32 Low;\r
\r
ASSERT (EvtRing != NULL);\r
\r
//\r
// Apply the EventRingDequeue to Xhc\r
//\r
- XhcDequeue = (TRB *)(UINTN) XhcReadRuntimeReg64 (\r
- Xhc,\r
- XHC_ERDP_OFFSET + (32 * EvtRing->EventInterrupter)\r
- );\r
-\r
- if (((UINT64) XhcDequeue & (~0x0F)) != ((UINT64) EvtRing->EventRingDequeue & (~0x0F))) {\r
- XhcWriteRuntimeReg64 (\r
- Xhc,\r
- XHC_ERDP_OFFSET + (32 * EvtRing->EventInterrupter),\r
- (UINT64)EvtRing->EventRingDequeue | BIT3\r
- );\r
+ // Some 3rd party XHCI external cards don't support single 64-bytes width register access,\r
+ // So divide it to two 32-bytes width register access.\r
+ //\r
+ Low = XhcReadRuntimeReg (Xhc, XHC_ERDP_OFFSET);\r
+ High = XhcReadRuntimeReg (Xhc, XHC_ERDP_OFFSET + 4);\r
+ XhcDequeue = (UINT64)(LShiftU64((UINT64)High, 32) | Low);\r
+\r
+ if ((XhcDequeue & (~0x0F)) != ((UINT64)(UINTN)EvtRing->EventRingDequeue & (~0x0F))) {\r
+ //\r
+ // Some 3rd party XHCI external cards don't support single 64-bytes width register access,\r
+ // So divide it to two 32-bytes width register access.\r
+ //\r
+ XhcWriteRuntimeReg (Xhc, XHC_ERDP_OFFSET, Low | BIT3);\r
+ XhcWriteRuntimeReg (Xhc, XHC_ERDP_OFFSET + 4, High);\r
}\r
\r
return EFI_SUCCESS;\r
/**\r
Synchronize the specified transfer ring to update the enqueue and dequeue pointer.\r
\r
- @param Xhc The XHCI device.\r
+ @param Xhc The XHCI Instance.\r
@param TrsRing The transfer ring to sync.\r
\r
@retval EFI_SUCCESS The transfer ring is synchronized successfully.\r
EFI_STATUS\r
EFIAPI\r
XhcSyncTrsRing (\r
- IN USB_XHCI_DEV *Xhc,\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
IN TRANSFER_RING *TrsRing\r
)\r
{\r
UINTN Index;\r
- TRB *TrsTrb;\r
+ TRB_TEMPLATE *TrsTrb;\r
\r
ASSERT (TrsRing != NULL);\r
//\r
}\r
TrsTrb++;\r
if ((UINT8) TrsTrb->Type == TRB_TYPE_LINK) {\r
- ASSERT (((LNK_TRB*)TrsTrb)->TC != 0);\r
+ ASSERT (((LINK_TRB*)TrsTrb)->TC != 0);\r
//\r
// set cycle bit in Link TRB as normal\r
//\r
- ((LNK_TRB*)TrsTrb)->CycleBit = TrsRing->RingPCS & BIT0;\r
+ ((LINK_TRB*)TrsTrb)->CycleBit = TrsRing->RingPCS & BIT0;\r
//\r
// Toggle PCS maintained by software\r
//\r
TrsRing->RingPCS = (TrsRing->RingPCS & BIT0) ? 0 : 1;\r
- TrsTrb = (TRB*)(UINTN)((TrsTrb->Dword1 | ((UINT64)TrsTrb->Dword2 << 32)) & ~0x0F);\r
+ TrsTrb = (TRB_TEMPLATE *)(UINTN)((TrsTrb->Parameter1 | LShiftU64 ((UINT64)TrsTrb->Parameter2, 32)) & ~0x0F);\r
}\r
}\r
\r
//\r
// Clear the Trb context for enqueue, but reserve the PCS bit\r
//\r
- TrsTrb->Dword1 = 0;\r
- TrsTrb->Dword2 = 0;\r
- TrsTrb->Dword3 = 0;\r
- TrsTrb->RsvdZ1 = 0;\r
- TrsTrb->Type = 0;\r
- TrsTrb->RsvdZ2 = 0;\r
+ TrsTrb->Parameter1 = 0;\r
+ TrsTrb->Parameter2 = 0;\r
+ TrsTrb->Status = 0;\r
+ TrsTrb->RsvdZ1 = 0;\r
+ TrsTrb->Type = 0;\r
+ TrsTrb->Control = 0;\r
\r
return EFI_SUCCESS;\r
}\r
/**\r
Check if there is a new generated event.\r
\r
- @param Xhc The XHCI device.\r
+ @param Xhc The XHCI Instance.\r
@param EvtRing The event ring to check.\r
@param NewEvtTrb The new event TRB found.\r
\r
EFI_STATUS\r
EFIAPI\r
XhcCheckNewEvent (\r
- IN USB_XHCI_DEV *Xhc,\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
IN EVENT_RING *EvtRing,\r
- OUT TRB **NewEvtTrb\r
+ OUT TRB_TEMPLATE **NewEvtTrb\r
)\r
{\r
EFI_STATUS Status;\r
- TRB *EvtTrb;\r
+ TRB_TEMPLATE*EvtTrb;\r
\r
ASSERT (EvtRing != NULL);\r
\r
\r
Status = EFI_SUCCESS;\r
\r
- if (((EvtTrb->Dword3 >> 24) & 0xFF) != TRB_COMPLETION_SUCCESS) {\r
+ if (((EvtTrb->Status >> 24) & 0xFF) != TRB_COMPLETION_SUCCESS) {\r
Status = EFI_DEVICE_ERROR;\r
}\r
\r
//\r
// If the dequeue pointer is beyond the ring, then roll-back it to the begining of the ring.\r
//\r
- if ((UINTN)EvtRing->EventRingDequeue >= ((UINTN) EvtRing->EventRingSeg0 + sizeof (TRB) * EvtRing->TrbNumber)) {\r
+ if ((UINTN)EvtRing->EventRingDequeue >= ((UINTN) EvtRing->EventRingSeg0 + sizeof (TRB_TEMPLATE) * EvtRing->TrbNumber)) {\r
EvtRing->EventRingDequeue = EvtRing->EventRingSeg0;\r
}\r
\r
/**\r
Ring the door bell to notify XHCI there is a transaction to be executed.\r
\r
- @param Xhc The XHCI device.\r
+ @param Xhc The XHCI Instance.\r
@param SlotId The slot id of the target device.\r
@param Dci The device context index of the target slot or endpoint.\r
\r
EFI_STATUS\r
EFIAPI\r
XhcRingDoorBell (\r
- IN USB_XHCI_DEV *Xhc,\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
IN UINT8 SlotId,\r
IN UINT8 Dci\r
)\r
/**\r
Ring the door bell to notify XHCI there is a transaction to be executed through URB.\r
\r
- @param Xhc The XHCI device.\r
+ @param Xhc The XHCI Instance.\r
@param Urb The URB to be rung.\r
\r
@retval EFI_SUCCESS Successfully ring the door bell.\r
**/\r
EFI_STATUS\r
RingIntTransferDoorBell (\r
- IN USB_XHCI_DEV *Xhc,\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
IN URB *Urb\r
)\r
{\r
UINT8 SlotId;\r
UINT8 Dci;\r
\r
- SlotId = XhcDevAddrToSlotId(Urb->Ep.DevAddr);\r
- Dci = XhcEndpointToDci(Urb->Ep.EpAddr, Urb->Ep.Direction);\r
+ SlotId = XhcBusDevAddrToSlotId (Xhc, Urb->Ep.BusAddr);\r
+ Dci = XhcEndpointToDci (Urb->Ep.EpAddr, (UINT8)(Urb->Ep.Direction));\r
XhcRingDoorBell (Xhc, SlotId, Dci);\r
return EFI_SUCCESS;\r
}\r
/**\r
Assign and initialize the device slot for a new device.\r
\r
- @param Xhc The XHCI device.\r
+ @param Xhc The XHCI Instance.\r
@param ParentRouteChart The route string pointed to the parent device.\r
@param ParentPort The port at which the device is located.\r
@param RouteChart The route string pointed to the device.\r
EFI_STATUS\r
EFIAPI\r
XhcInitializeDeviceSlot (\r
- IN USB_XHCI_DEV *Xhc,\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
IN USB_DEV_ROUTE ParentRouteChart,\r
IN UINT16 ParentPort,\r
IN USB_DEV_ROUTE RouteChart,\r
IN UINT8 DeviceSpeed\r
)\r
{\r
- EFI_STATUS Status;\r
- EVT_TRB_COMMAND *EvtTrb;\r
- INPUT_CONTEXT *InputContext;\r
- DEVICE_CONTEXT *OutputDevContxt;\r
- TRANSFER_RING *EndpointTransferRing;\r
- CMD_TRB_ADDR_DEV CmdTrbAddr;\r
- UINT8 DeviceAddress;\r
- CMD_TRB_EN_SLOT CmdTrb;\r
- UINT8 SlotId;\r
- UINT8 ParentSlotId;\r
- DEVICE_CONTEXT *ParentDeviceContext;\r
-\r
- ZeroMem (&CmdTrb, sizeof (CMD_TRB_EN_SLOT));\r
+ EFI_STATUS Status;\r
+ EVT_TRB_COMMAND_COMPLETION *EvtTrb;\r
+ INPUT_CONTEXT *InputContext;\r
+ DEVICE_CONTEXT *OutputContext;\r
+ TRANSFER_RING *EndpointTransferRing;\r
+ CMD_TRB_ADDRESS_DEVICE CmdTrbAddr;\r
+ UINT8 DeviceAddress;\r
+ CMD_TRB_ENABLE_SLOT CmdTrb;\r
+ UINT8 SlotId;\r
+ UINT8 ParentSlotId;\r
+ DEVICE_CONTEXT *ParentDeviceContext;\r
+\r
+ ZeroMem (&CmdTrb, sizeof (CMD_TRB_ENABLE_SLOT));\r
CmdTrb.CycleBit = 1;\r
CmdTrb.Type = TRB_TYPE_EN_SLOT;\r
\r
Status = XhcCmdTransfer (\r
Xhc,\r
- (TRB *) (UINTN) &CmdTrb,\r
+ (TRB_TEMPLATE *) (UINTN) &CmdTrb,\r
XHC_GENERIC_TIMEOUT,\r
- (TRB **) (UINTN) &EvtTrb\r
+ (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
);\r
ASSERT_EFI_ERROR (Status);\r
ASSERT (EvtTrb->SlotId <= Xhc->MaxSlotsEn);\r
SlotId = (UINT8)EvtTrb->SlotId;\r
ASSERT (SlotId != 0);\r
\r
- ZeroMem (&UsbDevContext[SlotId], sizeof (USB_DEV_CONTEXT));\r
- UsbDevContext[SlotId].Enabled = TRUE;\r
- UsbDevContext[SlotId].SlotId = SlotId;\r
- UsbDevContext[SlotId].RouteString.Dword = RouteChart.Dword;\r
- UsbDevContext[SlotId].ParentRouteString.Dword = ParentRouteChart.Dword;\r
+ ZeroMem (&Xhc->UsbDevContext[SlotId], sizeof (USB_DEV_CONTEXT));\r
+ Xhc->UsbDevContext[SlotId].Enabled = TRUE;\r
+ Xhc->UsbDevContext[SlotId].SlotId = SlotId;\r
+ Xhc->UsbDevContext[SlotId].RouteString.Dword = RouteChart.Dword;\r
+ Xhc->UsbDevContext[SlotId].ParentRouteString.Dword = ParentRouteChart.Dword;\r
\r
//\r
// 4.3.3 Device Slot Initialization\r
// 1) Allocate an Input Context data structure (6.2.5) and initialize all fields to '0'.\r
//\r
- InputContext = AllocateAlignedZeroPool(sizeof (INPUT_CONTEXT), 64);\r
+ InputContext = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (INPUT_CONTEXT)));\r
ASSERT (InputContext != NULL);\r
ASSERT (((UINTN) InputContext & 0x3F) == 0);\r
+ ZeroMem (InputContext, sizeof (INPUT_CONTEXT));\r
\r
- UsbDevContext[SlotId].InputContext = (VOID *) InputContext;\r
+ Xhc->UsbDevContext[SlotId].InputContext = (VOID *) InputContext;\r
\r
//\r
// 2) Initialize the Input Control Context (6.2.5.1) of the Input Context by setting the A0 and A1\r
//\r
// 3) Initialize the Input Slot Context data structure\r
//\r
- InputContext->Slot.RouteStr = RouteChart.Field.RouteString;\r
+ InputContext->Slot.RouteString = RouteChart.Route.RouteString;\r
InputContext->Slot.Speed = DeviceSpeed + 1;\r
InputContext->Slot.ContextEntries = 1;\r
- InputContext->Slot.RootHubPortNum = RouteChart.Field.RootPortNum;\r
+ InputContext->Slot.RootHubPortNum = RouteChart.Route.RootPortNum;\r
\r
- if (RouteChart.Field.RouteString) {\r
+ if (RouteChart.Route.RouteString) {\r
//\r
// The device is behind of hub device.\r
//\r
- ParentSlotId = XhcRouteStringToSlotId(ParentRouteChart);\r
+ ParentSlotId = XhcRouteStringToSlotId(Xhc, ParentRouteChart);\r
ASSERT (ParentSlotId != 0);\r
//\r
//if the Full/Low device attached to a High Speed Hub, Init the TTPortNum and TTHubSlotId field of slot context\r
//\r
- ParentDeviceContext = (DEVICE_CONTEXT *)UsbDevContext[ParentSlotId].OutputDevContxt;\r
+ ParentDeviceContext = (DEVICE_CONTEXT *)Xhc->UsbDevContext[ParentSlotId].OutputContext;\r
if ((ParentDeviceContext->Slot.TTPortNum == 0) &&\r
(ParentDeviceContext->Slot.TTHubSlotId == 0)) {\r
if ((ParentDeviceContext->Slot.Speed == (EFI_USB_SPEED_HIGH + 1)) && (DeviceSpeed < EFI_USB_SPEED_HIGH)) {\r
//\r
// 4) Allocate and initialize the Transfer Ring for the Default Control Endpoint.\r
//\r
- EndpointTransferRing = AllocateAlignedZeroPool(sizeof (TRANSFER_RING), 64);\r
- UsbDevContext[SlotId].EndpointTransferRing[0] = EndpointTransferRing;\r
- CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)UsbDevContext[SlotId].EndpointTransferRing[0]);\r
+ EndpointTransferRing = AllocateZeroPool (sizeof (TRANSFER_RING));\r
+ Xhc->UsbDevContext[SlotId].EndpointTransferRing[0] = EndpointTransferRing;\r
+ CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[0]);\r
//\r
// 5) Initialize the Input default control Endpoint 0 Context (6.2.3).\r
//\r
//\r
// Init the DCS(dequeue cycle state) as the transfer ring's CCS\r
//\r
- InputContext->EP[0].PtrLo = XHC_LOW_32BIT (((TRANSFER_RING *)(UINTN)UsbDevContext[SlotId].EndpointTransferRing[0])->RingSeg0) | BIT0;\r
- InputContext->EP[0].PtrHi = XHC_HIGH_32BIT (((TRANSFER_RING *)(UINTN)UsbDevContext[SlotId].EndpointTransferRing[0])->RingSeg0);\r
+ InputContext->EP[0].PtrLo = XHC_LOW_32BIT (((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[0])->RingSeg0) | BIT0;\r
+ InputContext->EP[0].PtrHi = XHC_HIGH_32BIT (((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[0])->RingSeg0);\r
\r
//\r
// 6) Allocate the Output Device Context data structure (6.2.1) and initialize it to '0'.\r
//\r
- OutputDevContxt = AllocateAlignedZeroPool(sizeof (DEVICE_CONTEXT), 64);\r
- ASSERT (OutputDevContxt != NULL);\r
- ASSERT (((UINTN) OutputDevContxt & 0x3F) == 0);\r
+ OutputContext = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (DEVICE_CONTEXT)));\r
+ ASSERT (OutputContext != NULL);\r
+ ASSERT (((UINTN) OutputContext & 0x3F) == 0);\r
+ ZeroMem (OutputContext, sizeof (DEVICE_CONTEXT));\r
\r
- UsbDevContext[SlotId].OutputDevContxt = OutputDevContxt;\r
+ Xhc->UsbDevContext[SlotId].OutputContext = OutputContext;\r
//\r
// 7) Load the appropriate (Device Slot ID) entry in the Device Context Base Address Array (5.4.6) with\r
// a pointer to the Output Device Context data structure (6.2.1).\r
//\r
- Xhc->DCBAA[SlotId] = (UINT64) (UINTN) OutputDevContxt;\r
+ Xhc->DCBAA[SlotId] = (UINT64) (UINTN) OutputContext;\r
\r
//\r
// 8) Issue an Address Device Command for the Device Slot, where the command points to the Input\r
// Context data structure described above.\r
//\r
ZeroMem (&CmdTrbAddr, sizeof (CmdTrbAddr));\r
- CmdTrbAddr.PtrLo = XHC_LOW_32BIT (UsbDevContext[SlotId].InputContext);\r
- CmdTrbAddr.PtrHi = XHC_HIGH_32BIT (UsbDevContext[SlotId].InputContext);\r
+ CmdTrbAddr.PtrLo = XHC_LOW_32BIT (Xhc->UsbDevContext[SlotId].InputContext);\r
+ CmdTrbAddr.PtrHi = XHC_HIGH_32BIT (Xhc->UsbDevContext[SlotId].InputContext);\r
CmdTrbAddr.CycleBit = 1;\r
CmdTrbAddr.Type = TRB_TYPE_ADDRESS_DEV;\r
- CmdTrbAddr.SlotId = UsbDevContext[SlotId].SlotId;\r
+ CmdTrbAddr.SlotId = Xhc->UsbDevContext[SlotId].SlotId;\r
Status = XhcCmdTransfer (\r
Xhc,\r
- (TRB *) (UINTN) &CmdTrbAddr,\r
+ (TRB_TEMPLATE *) (UINTN) &CmdTrbAddr,\r
XHC_GENERIC_TIMEOUT,\r
- (TRB **) (UINTN) &EvtTrb\r
+ (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
);\r
ASSERT (!EFI_ERROR(Status));\r
\r
- DeviceAddress = (UINT8) ((DEVICE_CONTEXT *) OutputDevContxt)->Slot.DeviceAddress;\r
+ DeviceAddress = (UINT8) ((DEVICE_CONTEXT *) OutputContext)->Slot.DeviceAddress;\r
DEBUG ((EFI_D_INFO, " Address %d assigned succeefully\n", DeviceAddress));\r
\r
- UsbDevContext[SlotId].XhciDevAddr = DeviceAddress;\r
+ Xhc->UsbDevContext[SlotId].XhciDevAddr = DeviceAddress;\r
\r
return Status;\r
}\r
\r
/**\r
- Disable the specified device slot.\r
+ Assign and initialize the device slot for a new device.\r
\r
- @param Xhc The XHCI device.\r
- @param SlotId The slot id to be disabled.\r
+ @param Xhc The XHCI Instance.\r
+ @param ParentRouteChart The route string pointed to the parent device.\r
+ @param ParentPort The port at which the device is located.\r
+ @param RouteChart The route string pointed to the device.\r
+ @param DeviceSpeed The device speed.\r
\r
- @retval EFI_SUCCESS Successfully disable the device slot.\r
+ @retval EFI_SUCCESS Successfully assign a slot to the device and assign an address to it.\r
\r
**/\r
EFI_STATUS\r
EFIAPI\r
-XhcDisableSlotCmd (\r
- IN USB_XHCI_DEV *Xhc,\r
- IN UINT8 SlotId\r
+XhcInitializeDeviceSlot64 (\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN USB_DEV_ROUTE ParentRouteChart,\r
+ IN UINT16 ParentPort,\r
+ IN USB_DEV_ROUTE RouteChart,\r
+ IN UINT8 DeviceSpeed\r
)\r
{\r
- EFI_STATUS Status;\r
- TRB *EvtTrb;\r
- CMD_TRB_DIS_SLOT CmdTrbDisSlot;\r
- UINT8 Index;\r
- VOID *RingSeg;\r
-\r
- //\r
- // Disable the device slots occupied by these devices on its downstream ports.\r
- // Entry 0 is reserved.\r
- //\r
- for (Index = 0; Index < 255; Index++) {\r
- if (!UsbDevContext[Index + 1].Enabled ||\r
- (UsbDevContext[Index + 1].SlotId == 0) ||\r
- (UsbDevContext[Index + 1].ParentRouteString.Dword != UsbDevContext[SlotId].RouteString.Dword)) {\r
- continue;\r
- }\r
+ EFI_STATUS Status;\r
+ EVT_TRB_COMMAND_COMPLETION *EvtTrb;\r
+ INPUT_CONTEXT_64 *InputContext;\r
+ DEVICE_CONTEXT_64 *OutputContext;\r
+ TRANSFER_RING *EndpointTransferRing;\r
+ CMD_TRB_ADDRESS_DEVICE CmdTrbAddr;\r
+ UINT8 DeviceAddress;\r
+ CMD_TRB_ENABLE_SLOT CmdTrb;\r
+ UINT8 SlotId;\r
+ UINT8 ParentSlotId;\r
+ DEVICE_CONTEXT_64 *ParentDeviceContext;\r
+\r
+ ZeroMem (&CmdTrb, sizeof (CMD_TRB_ENABLE_SLOT));\r
+ CmdTrb.CycleBit = 1;\r
+ CmdTrb.Type = TRB_TYPE_EN_SLOT;\r
\r
- Status = XhcDisableSlotCmd (Xhc, UsbDevContext[Index + 1].SlotId);\r
+ Status = XhcCmdTransfer (\r
+ Xhc,\r
+ (TRB_TEMPLATE *) (UINTN) &CmdTrb,\r
+ XHC_GENERIC_TIMEOUT,\r
+ (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ ASSERT (EvtTrb->SlotId <= Xhc->MaxSlotsEn);\r
+ DEBUG ((EFI_D_INFO, "Enable Slot Successfully, The Slot ID = 0x%x\n", EvtTrb->SlotId));\r
+ SlotId = (UINT8)EvtTrb->SlotId;\r
+ ASSERT (SlotId != 0);\r
\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "XhcDisableSlotCmd: failed to disable child, ignore error\n"));\r
- UsbDevContext[Index + 1].SlotId = 0;\r
- }\r
- }\r
+ ZeroMem (&Xhc->UsbDevContext[SlotId], sizeof (USB_DEV_CONTEXT));\r
+ Xhc->UsbDevContext[SlotId].Enabled = TRUE;\r
+ Xhc->UsbDevContext[SlotId].SlotId = SlotId;\r
+ Xhc->UsbDevContext[SlotId].RouteString.Dword = RouteChart.Dword;\r
+ Xhc->UsbDevContext[SlotId].ParentRouteString.Dword = ParentRouteChart.Dword;\r
\r
//\r
- // Construct the disable slot command\r
+ // 4.3.3 Device Slot Initialization\r
+ // 1) Allocate an Input Context data structure (6.2.5) and initialize all fields to '0'.\r
//\r
- DEBUG ((EFI_D_INFO, "Disable device slot %d!\n", SlotId));\r
+ InputContext = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (INPUT_CONTEXT_64)));\r
+ ASSERT (InputContext != NULL);\r
+ ASSERT (((UINTN) InputContext & 0x3F) == 0);\r
+ ZeroMem (InputContext, sizeof (INPUT_CONTEXT_64));\r
\r
- ZeroMem (&CmdTrbDisSlot, sizeof (CmdTrbDisSlot));\r
- CmdTrbDisSlot.CycleBit = 1;\r
- CmdTrbDisSlot.Type = TRB_TYPE_DIS_SLOT;\r
- CmdTrbDisSlot.SlotId = SlotId;\r
- Status = XhcCmdTransfer (\r
- Xhc,\r
- (TRB *) (UINTN) &CmdTrbDisSlot,\r
- XHC_GENERIC_TIMEOUT,\r
- (TRB **) (UINTN) &EvtTrb\r
- );\r
- ASSERT_EFI_ERROR(Status);\r
- //\r
- // Free the slot's device context entry\r
- //\r
- Xhc->DCBAA[SlotId] = 0;\r
+ Xhc->UsbDevContext[SlotId].InputContext = (VOID *) InputContext;\r
\r
//\r
- // Free the slot related data structure\r
+ // 2) Initialize the Input Control Context (6.2.5.1) of the Input Context by setting the A0 and A1\r
+ // flags to '1'. These flags indicate that the Slot Context and the Endpoint 0 Context of the Input\r
+ // Context are affected by the command.\r
//\r
- for (Index = 0; Index < 31; Index++) {\r
- if (UsbDevContext[SlotId].EndpointTransferRing[Index] != NULL) {\r
- RingSeg = ((TRANSFER_RING *)(UINTN)UsbDevContext[SlotId].EndpointTransferRing[Index])->RingSeg0;\r
- if (RingSeg != NULL) {\r
- FreeAlignedPool(RingSeg);\r
- }\r
- FreeAlignedPool(UsbDevContext[SlotId].EndpointTransferRing[Index]);\r
- }\r
- }\r
-\r
- for (Index = 0; Index < UsbDevContext[SlotId].DevDesc.NumConfigurations; Index++) {\r
- if (UsbDevContext[SlotId].ConfDesc[Index] != NULL) {\r
- FreePool (UsbDevContext[SlotId].ConfDesc[Index]);\r
- }\r
- }\r
-\r
- if (UsbDevContext[SlotId].InputContext != NULL) {\r
- FreeAlignedPool (UsbDevContext[SlotId].InputContext);\r
- }\r
+ InputContext->InputControlContext.Dword2 |= (BIT0 | BIT1);\r
\r
- if (UsbDevContext[SlotId].OutputDevContxt != NULL) {\r
- FreeAlignedPool (UsbDevContext[SlotId].OutputDevContxt);\r
- }\r
//\r
- // Doesn't zero the entry because XhcAsyncInterruptTransfer() may be invoked to remove the established\r
- // asynchronous interrupt pipe after the device is disabled. It needs the device address mapping info to\r
- // remove urb from XHCI's asynchronous transfer list.\r
+ // 3) Initialize the Input Slot Context data structure\r
//\r
- UsbDevContext[SlotId].Enabled = FALSE;\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Configure all the device endpoints through XHCI's Configure_Endpoint cmd.\r
+ InputContext->Slot.RouteString = RouteChart.Route.RouteString;\r
+ InputContext->Slot.Speed = DeviceSpeed + 1;\r
+ InputContext->Slot.ContextEntries = 1;\r
+ InputContext->Slot.RootHubPortNum = RouteChart.Route.RootPortNum;\r
\r
- @param Xhc The XHCI device.\r
- @param SlotId The slot id to be configured.\r
+ if (RouteChart.Route.RouteString) {\r
+ //\r
+ // The device is behind of hub device.\r
+ //\r
+ ParentSlotId = XhcRouteStringToSlotId(Xhc, ParentRouteChart);\r
+ ASSERT (ParentSlotId != 0);\r
+ //\r
+ //if the Full/Low device attached to a High Speed Hub, Init the TTPortNum and TTHubSlotId field of slot context\r
+ //\r
+ ParentDeviceContext = (DEVICE_CONTEXT_64 *)Xhc->UsbDevContext[ParentSlotId].OutputContext;\r
+ if ((ParentDeviceContext->Slot.TTPortNum == 0) &&\r
+ (ParentDeviceContext->Slot.TTHubSlotId == 0)) {\r
+ if ((ParentDeviceContext->Slot.Speed == (EFI_USB_SPEED_HIGH + 1)) && (DeviceSpeed < EFI_USB_SPEED_HIGH)) {\r
+ //\r
+ // Full/Low device attached to High speed hub port that isolates the high speed signaling\r
+ // environment from Full/Low speed signaling environment for a device\r
+ //\r
+ InputContext->Slot.TTPortNum = ParentPort;\r
+ InputContext->Slot.TTHubSlotId = ParentSlotId;\r
+ }\r
+ } else {\r
+ //\r
+ // Inherit the TT parameters from parent device.\r
+ //\r
+ InputContext->Slot.TTPortNum = ParentDeviceContext->Slot.TTPortNum;\r
+ InputContext->Slot.TTHubSlotId = ParentDeviceContext->Slot.TTHubSlotId;\r
+ //\r
+ // If the device is a High speed device then down the speed to be the same as its parent Hub\r
+ //\r
+ if (DeviceSpeed == EFI_USB_SPEED_HIGH) {\r
+ InputContext->Slot.Speed = ParentDeviceContext->Slot.Speed;\r
+ }\r
+ }\r
+ }\r
+\r
+ //\r
+ // 4) Allocate and initialize the Transfer Ring for the Default Control Endpoint.\r
+ //\r
+ EndpointTransferRing = AllocateZeroPool (sizeof (TRANSFER_RING));\r
+ Xhc->UsbDevContext[SlotId].EndpointTransferRing[0] = EndpointTransferRing;\r
+ CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[0]);\r
+ //\r
+ // 5) Initialize the Input default control Endpoint 0 Context (6.2.3).\r
+ //\r
+ InputContext->EP[0].EPType = ED_CONTROL_BIDIR;\r
+\r
+ if (DeviceSpeed == EFI_USB_SPEED_SUPER) {\r
+ InputContext->EP[0].MaxPacketSize = 512;\r
+ } else if (DeviceSpeed == EFI_USB_SPEED_HIGH) {\r
+ InputContext->EP[0].MaxPacketSize = 64;\r
+ } else {\r
+ InputContext->EP[0].MaxPacketSize = 8;\r
+ }\r
+ //\r
+ // Initial value of Average TRB Length for Control endpoints would be 8B, Interrupt endpoints\r
+ // 1KB, and Bulk and Isoch endpoints 3KB.\r
+ //\r
+ InputContext->EP[0].AverageTRBLength = 8;\r
+ InputContext->EP[0].MaxBurstSize = 0;\r
+ InputContext->EP[0].Interval = 0;\r
+ InputContext->EP[0].MaxPStreams = 0;\r
+ InputContext->EP[0].Mult = 0;\r
+ InputContext->EP[0].CErr = 3;\r
+\r
+ //\r
+ // Init the DCS(dequeue cycle state) as the transfer ring's CCS\r
+ //\r
+ InputContext->EP[0].PtrLo = XHC_LOW_32BIT (((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[0])->RingSeg0) | BIT0;\r
+ InputContext->EP[0].PtrHi = XHC_HIGH_32BIT (((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[0])->RingSeg0);\r
+\r
+ //\r
+ // 6) Allocate the Output Device Context data structure (6.2.1) and initialize it to '0'.\r
+ //\r
+ OutputContext = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (DEVICE_CONTEXT_64)));\r
+ ASSERT (OutputContext != NULL);\r
+ ASSERT (((UINTN) OutputContext & 0x3F) == 0);\r
+ ZeroMem (OutputContext, sizeof (DEVICE_CONTEXT_64));\r
+\r
+ Xhc->UsbDevContext[SlotId].OutputContext = OutputContext;\r
+ //\r
+ // 7) Load the appropriate (Device Slot ID) entry in the Device Context Base Address Array (5.4.6) with\r
+ // a pointer to the Output Device Context data structure (6.2.1).\r
+ //\r
+ Xhc->DCBAA[SlotId] = (UINT64) (UINTN) OutputContext;\r
+\r
+ //\r
+ // 8) Issue an Address Device Command for the Device Slot, where the command points to the Input\r
+ // Context data structure described above.\r
+ //\r
+ ZeroMem (&CmdTrbAddr, sizeof (CmdTrbAddr));\r
+ CmdTrbAddr.PtrLo = XHC_LOW_32BIT (Xhc->UsbDevContext[SlotId].InputContext);\r
+ CmdTrbAddr.PtrHi = XHC_HIGH_32BIT (Xhc->UsbDevContext[SlotId].InputContext);\r
+ CmdTrbAddr.CycleBit = 1;\r
+ CmdTrbAddr.Type = TRB_TYPE_ADDRESS_DEV;\r
+ CmdTrbAddr.SlotId = Xhc->UsbDevContext[SlotId].SlotId;\r
+ Status = XhcCmdTransfer (\r
+ Xhc,\r
+ (TRB_TEMPLATE *) (UINTN) &CmdTrbAddr,\r
+ XHC_GENERIC_TIMEOUT,\r
+ (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
+ );\r
+ ASSERT (!EFI_ERROR(Status));\r
+\r
+ DeviceAddress = (UINT8) ((DEVICE_CONTEXT_64 *) OutputContext)->Slot.DeviceAddress;\r
+ DEBUG ((EFI_D_INFO, " Address %d assigned succeefully\n", DeviceAddress));\r
+\r
+ Xhc->UsbDevContext[SlotId].XhciDevAddr = DeviceAddress;\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ Disable the specified device slot.\r
+\r
+ @param Xhc The XHCI Instance.\r
+ @param SlotId The slot id to be disabled.\r
+\r
+ @retval EFI_SUCCESS Successfully disable the device slot.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+XhcDisableSlotCmd (\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT8 SlotId\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ TRB_TEMPLATE *EvtTrb;\r
+ CMD_TRB_DISABLE_SLOT CmdTrbDisSlot;\r
+ UINT8 Index;\r
+ VOID *RingSeg;\r
+\r
+ //\r
+ // Disable the device slots occupied by these devices on its downstream ports.\r
+ // Entry 0 is reserved.\r
+ //\r
+ for (Index = 0; Index < 255; Index++) {\r
+ if (!Xhc->UsbDevContext[Index + 1].Enabled ||\r
+ (Xhc->UsbDevContext[Index + 1].SlotId == 0) ||\r
+ (Xhc->UsbDevContext[Index + 1].ParentRouteString.Dword != Xhc->UsbDevContext[SlotId].RouteString.Dword)) {\r
+ continue;\r
+ }\r
+\r
+ Status = XhcDisableSlotCmd (Xhc, Xhc->UsbDevContext[Index + 1].SlotId);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "XhcDisableSlotCmd: failed to disable child, ignore error\n"));\r
+ Xhc->UsbDevContext[Index + 1].SlotId = 0;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Construct the disable slot command\r
+ //\r
+ DEBUG ((EFI_D_INFO, "Disable device slot %d!\n", SlotId));\r
+\r
+ ZeroMem (&CmdTrbDisSlot, sizeof (CmdTrbDisSlot));\r
+ CmdTrbDisSlot.CycleBit = 1;\r
+ CmdTrbDisSlot.Type = TRB_TYPE_DIS_SLOT;\r
+ CmdTrbDisSlot.SlotId = SlotId;\r
+ Status = XhcCmdTransfer (\r
+ Xhc,\r
+ (TRB_TEMPLATE *) (UINTN) &CmdTrbDisSlot,\r
+ XHC_GENERIC_TIMEOUT,\r
+ (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
+ );\r
+ ASSERT_EFI_ERROR(Status);\r
+ //\r
+ // Free the slot's device context entry\r
+ //\r
+ Xhc->DCBAA[SlotId] = 0;\r
+\r
+ //\r
+ // Free the slot related data structure\r
+ //\r
+ for (Index = 0; Index < 31; Index++) {\r
+ if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index] != NULL) {\r
+ RingSeg = ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index])->RingSeg0;\r
+ if (RingSeg != NULL) {\r
+ FreePages (RingSeg, EFI_SIZE_TO_PAGES (sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER));\r
+ }\r
+ FreePool (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index]);\r
+ }\r
+ }\r
+\r
+ for (Index = 0; Index < Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations; Index++) {\r
+ if (Xhc->UsbDevContext[SlotId].ConfDesc[Index] != NULL) {\r
+ FreePool (Xhc->UsbDevContext[SlotId].ConfDesc[Index]);\r
+ }\r
+ }\r
+\r
+ if (Xhc->UsbDevContext[SlotId].InputContext != NULL) {\r
+ FreePages (Xhc->UsbDevContext[SlotId].InputContext, EFI_SIZE_TO_PAGES (sizeof (INPUT_CONTEXT)));\r
+ }\r
+\r
+ if (Xhc->UsbDevContext[SlotId].OutputContext != NULL) {\r
+ FreePages (Xhc->UsbDevContext[SlotId].OutputContext, EFI_SIZE_TO_PAGES (sizeof (DEVICE_CONTEXT)));\r
+ }\r
+ //\r
+ // Doesn't zero the entry because XhcAsyncInterruptTransfer() may be invoked to remove the established\r
+ // asynchronous interrupt pipe after the device is disabled. It needs the device address mapping info to\r
+ // remove urb from XHCI's asynchronous transfer list.\r
+ //\r
+ Xhc->UsbDevContext[SlotId].Enabled = FALSE;\r
+ Xhc->UsbDevContext[SlotId].SlotId = 0;\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Disable the specified device slot.\r
+\r
+ @param Xhc The XHCI Instance.\r
+ @param SlotId The slot id to be disabled.\r
+\r
+ @retval EFI_SUCCESS Successfully disable the device slot.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+XhcDisableSlotCmd64 (\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT8 SlotId\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ TRB_TEMPLATE *EvtTrb;\r
+ CMD_TRB_DISABLE_SLOT CmdTrbDisSlot;\r
+ UINT8 Index;\r
+ VOID *RingSeg;\r
+\r
+ //\r
+ // Disable the device slots occupied by these devices on its downstream ports.\r
+ // Entry 0 is reserved.\r
+ //\r
+ for (Index = 0; Index < 255; Index++) {\r
+ if (!Xhc->UsbDevContext[Index + 1].Enabled ||\r
+ (Xhc->UsbDevContext[Index + 1].SlotId == 0) ||\r
+ (Xhc->UsbDevContext[Index + 1].ParentRouteString.Dword != Xhc->UsbDevContext[SlotId].RouteString.Dword)) {\r
+ continue;\r
+ }\r
+\r
+ Status = XhcDisableSlotCmd64 (Xhc, Xhc->UsbDevContext[Index + 1].SlotId);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "XhcDisableSlotCmd: failed to disable child, ignore error\n"));\r
+ Xhc->UsbDevContext[Index + 1].SlotId = 0;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Construct the disable slot command\r
+ //\r
+ DEBUG ((EFI_D_INFO, "Disable device slot %d!\n", SlotId));\r
+\r
+ ZeroMem (&CmdTrbDisSlot, sizeof (CmdTrbDisSlot));\r
+ CmdTrbDisSlot.CycleBit = 1;\r
+ CmdTrbDisSlot.Type = TRB_TYPE_DIS_SLOT;\r
+ CmdTrbDisSlot.SlotId = SlotId;\r
+ Status = XhcCmdTransfer (\r
+ Xhc,\r
+ (TRB_TEMPLATE *) (UINTN) &CmdTrbDisSlot,\r
+ XHC_GENERIC_TIMEOUT,\r
+ (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
+ );\r
+ ASSERT_EFI_ERROR(Status);\r
+ //\r
+ // Free the slot's device context entry\r
+ //\r
+ Xhc->DCBAA[SlotId] = 0;\r
+\r
+ //\r
+ // Free the slot related data structure\r
+ //\r
+ for (Index = 0; Index < 31; Index++) {\r
+ if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index] != NULL) {\r
+ RingSeg = ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index])->RingSeg0;\r
+ if (RingSeg != NULL) {\r
+ FreePages (RingSeg, EFI_SIZE_TO_PAGES (sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER));\r
+ }\r
+ FreePool (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index]);\r
+ }\r
+ }\r
+\r
+ for (Index = 0; Index < Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations; Index++) {\r
+ if (Xhc->UsbDevContext[SlotId].ConfDesc[Index] != NULL) {\r
+ FreePool (Xhc->UsbDevContext[SlotId].ConfDesc[Index]);\r
+ }\r
+ }\r
+\r
+ if (Xhc->UsbDevContext[SlotId].InputContext != NULL) {\r
+ FreePages (Xhc->UsbDevContext[SlotId].InputContext, EFI_SIZE_TO_PAGES (sizeof (INPUT_CONTEXT_64)));\r
+ }\r
+\r
+ if (Xhc->UsbDevContext[SlotId].OutputContext != NULL) {\r
+ FreePages (Xhc->UsbDevContext[SlotId].OutputContext, EFI_SIZE_TO_PAGES (sizeof (DEVICE_CONTEXT_64)));\r
+ }\r
+ //\r
+ // Doesn't zero the entry because XhcAsyncInterruptTransfer() may be invoked to remove the established\r
+ // asynchronous interrupt pipe after the device is disabled. It needs the device address mapping info to\r
+ // remove urb from XHCI's asynchronous transfer list.\r
+ //\r
+ Xhc->UsbDevContext[SlotId].Enabled = FALSE;\r
+ Xhc->UsbDevContext[SlotId].SlotId = 0;\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ Configure all the device endpoints through XHCI's Configure_Endpoint cmd.\r
+\r
+ @param Xhc The XHCI Instance.\r
+ @param SlotId The slot id to be configured.\r
@param DeviceSpeed The device's speed.\r
@param ConfigDesc The pointer to the usb device configuration descriptor.\r
\r
EFI_STATUS\r
EFIAPI\r
XhcSetConfigCmd (\r
- IN USB_XHCI_DEV *Xhc,\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
IN UINT8 SlotId,\r
- IN UINT8 DeviceSpeed,\r
+ IN UINT8 DeviceSpeed,\r
IN USB_CONFIG_DESCRIPTOR *ConfigDesc\r
)\r
{\r
- EFI_STATUS Status;\r
-\r
- USB_INTERFACE_DESCRIPTOR *IfDesc;\r
- USB_ENDPOINT_DESCRIPTOR *EpDesc;\r
- UINT8 Index;\r
- UINTN NumEp;\r
- UINTN EpIndex;\r
- UINT8 EpAddr;\r
- UINT8 Direction;\r
- UINT8 Dci;\r
- UINT8 MaxDci;\r
- UINT32 PhyAddr;\r
- UINT8 Interval;\r
-\r
- TRANSFER_RING *EndpointTransferRing;\r
- CMD_CFG_ED CmdTrbCfgEP;\r
- INPUT_CONTEXT *InputContext;\r
- DEVICE_CONTEXT *OutputDevContxt;\r
- EVT_TRB_COMMAND *EvtTrb;\r
+ EFI_STATUS Status;\r
+\r
+ USB_INTERFACE_DESCRIPTOR *IfDesc;\r
+ USB_ENDPOINT_DESCRIPTOR *EpDesc;\r
+ UINT8 Index;\r
+ UINTN NumEp;\r
+ UINTN EpIndex;\r
+ UINT8 EpAddr;\r
+ UINT8 Direction;\r
+ UINT8 Dci;\r
+ UINT8 MaxDci;\r
+ UINT32 PhyAddr;\r
+ UINT8 Interval;\r
+\r
+ TRANSFER_RING *EndpointTransferRing;\r
+ CMD_TRB_CONFIG_ENDPOINT CmdTrbCfgEP;\r
+ INPUT_CONTEXT *InputContext;\r
+ DEVICE_CONTEXT *OutputContext;\r
+ EVT_TRB_COMMAND_COMPLETION *EvtTrb;\r
//\r
// 4.6.6 Configure Endpoint\r
//\r
- InputContext = UsbDevContext[SlotId].InputContext;\r
- OutputDevContxt = UsbDevContext[SlotId].OutputDevContxt;\r
+ InputContext = Xhc->UsbDevContext[SlotId].InputContext;\r
+ OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;\r
ZeroMem (InputContext, sizeof (INPUT_CONTEXT));\r
- CopyMem (&InputContext->Slot, &OutputDevContxt->Slot, sizeof (SLOT_CONTEXT));\r
+ CopyMem (&InputContext->Slot, &OutputContext->Slot, sizeof (SLOT_CONTEXT));\r
+\r
+ ASSERT (ConfigDesc != NULL);\r
+\r
+ MaxDci = 0;\r
+\r
+ IfDesc = (USB_INTERFACE_DESCRIPTOR *)(ConfigDesc + 1);\r
+ for (Index = 0; Index < ConfigDesc->NumInterfaces; Index++) {\r
+ while (IfDesc->DescriptorType != USB_DESC_TYPE_INTERFACE) {\r
+ IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length);\r
+ }\r
+\r
+ NumEp = IfDesc->NumEndpoints;\r
+\r
+ EpDesc = (USB_ENDPOINT_DESCRIPTOR *)(IfDesc + 1);\r
+ for (EpIndex = 0; EpIndex < NumEp; EpIndex++) {\r
+ while (EpDesc->DescriptorType != USB_DESC_TYPE_ENDPOINT) {\r
+ EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);\r
+ }\r
+\r
+ EpAddr = (UINT8)(EpDesc->EndpointAddress & 0x0F);\r
+ Direction = (UINT8)((EpDesc->EndpointAddress & 0x80) ? EfiUsbDataIn : EfiUsbDataOut);\r
+\r
+ Dci = XhcEndpointToDci (EpAddr, Direction);\r
+ ASSERT (Dci < 32);\r
+ if (Dci > MaxDci) {\r
+ MaxDci = Dci;\r
+ }\r
+\r
+ InputContext->InputControlContext.Dword2 |= (BIT0 << Dci);\r
+ InputContext->EP[Dci-1].MaxPacketSize = EpDesc->MaxPacketSize;\r
+\r
+ if (DeviceSpeed == EFI_USB_SPEED_SUPER) {\r
+ //\r
+ // 6.2.3.4, shall be set to the value defined in the bMaxBurst field of the SuperSpeed Endpoint Companion Descriptor.\r
+ //\r
+ InputContext->EP[Dci-1].MaxBurstSize = 0x0;\r
+ } else {\r
+ InputContext->EP[Dci-1].MaxBurstSize = 0x0;\r
+ }\r
+\r
+ switch (EpDesc->Attributes & USB_ENDPOINT_TYPE_MASK) {\r
+ case USB_ENDPOINT_BULK:\r
+ if (Direction == EfiUsbDataIn) {\r
+ InputContext->EP[Dci-1].CErr = 3;\r
+ InputContext->EP[Dci-1].EPType = ED_BULK_IN;\r
+ } else {\r
+ InputContext->EP[Dci-1].CErr = 3;\r
+ InputContext->EP[Dci-1].EPType = ED_BULK_OUT;\r
+ }\r
+\r
+ InputContext->EP[Dci-1].AverageTRBLength = 0x1000;\r
+ if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] == NULL) {\r
+ EndpointTransferRing = AllocateZeroPool(sizeof (TRANSFER_RING));\r
+ Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing;\r
+ CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]);\r
+ }\r
+\r
+ break;\r
+ case USB_ENDPOINT_ISO:\r
+ if (Direction == EfiUsbDataIn) {\r
+ InputContext->EP[Dci-1].CErr = 0;\r
+ InputContext->EP[Dci-1].EPType = ED_ISOCH_IN;\r
+ } else {\r
+ InputContext->EP[Dci-1].CErr = 0;\r
+ InputContext->EP[Dci-1].EPType = ED_ISOCH_OUT;\r
+ }\r
+ break;\r
+ case USB_ENDPOINT_INTERRUPT:\r
+ if (Direction == EfiUsbDataIn) {\r
+ InputContext->EP[Dci-1].CErr = 3;\r
+ InputContext->EP[Dci-1].EPType = ED_INTERRUPT_IN;\r
+ } else {\r
+ InputContext->EP[Dci-1].CErr = 3;\r
+ InputContext->EP[Dci-1].EPType = ED_INTERRUPT_OUT;\r
+ }\r
+ InputContext->EP[Dci-1].AverageTRBLength = 0x1000;\r
+ InputContext->EP[Dci-1].MaxESITPayload = EpDesc->MaxPacketSize;\r
+ //\r
+ // Get the bInterval from descriptor and init the the interval field of endpoint context\r
+ //\r
+ if ((DeviceSpeed == EFI_USB_SPEED_FULL) || (DeviceSpeed == EFI_USB_SPEED_LOW)) {\r
+ Interval = EpDesc->Interval;\r
+ //\r
+ // Hard code the interval to MAX first, need calculate through the bInterval field of Endpoint descriptor.\r
+ //\r
+ InputContext->EP[Dci-1].Interval = 6;\r
+ } else if ((DeviceSpeed == EFI_USB_SPEED_HIGH) || (DeviceSpeed == EFI_USB_SPEED_SUPER)) {\r
+ Interval = EpDesc->Interval;\r
+ ASSERT (Interval >= 1 && Interval <= 16);\r
+ //\r
+ // Refer to XHCI 1.0 spec section 6.2.3.6, table 61\r
+ //\r
+ InputContext->EP[Dci-1].Interval = Interval - 1;\r
+ InputContext->EP[Dci-1].AverageTRBLength = 0x1000;\r
+ InputContext->EP[Dci-1].MaxESITPayload = 0x0002;\r
+ InputContext->EP[Dci-1].MaxBurstSize = 0x0;\r
+ InputContext->EP[Dci-1].CErr = 3;\r
+ }\r
+\r
+ if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] == NULL) {\r
+ EndpointTransferRing = AllocateZeroPool(sizeof (TRANSFER_RING));\r
+ Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing;\r
+ CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]);\r
+ }\r
+ break;\r
+\r
+ case USB_ENDPOINT_CONTROL:\r
+ default:\r
+ ASSERT (0);\r
+ break;\r
+ }\r
+\r
+ PhyAddr = XHC_LOW_32BIT (((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0);\r
+ PhyAddr &= ~(0x0F);\r
+ PhyAddr |= ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingPCS;\r
+ InputContext->EP[Dci-1].PtrLo = PhyAddr;\r
+ InputContext->EP[Dci-1].PtrHi = XHC_HIGH_32BIT (((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0);\r
+\r
+ EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);\r
+ }\r
+ IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length);\r
+ }\r
+\r
+ InputContext->InputControlContext.Dword2 |= BIT0;\r
+ InputContext->Slot.ContextEntries = MaxDci;\r
+ //\r
+ // configure endpoint\r
+ //\r
+ ZeroMem (&CmdTrbCfgEP, sizeof (CmdTrbCfgEP));\r
+ CmdTrbCfgEP.PtrLo = XHC_LOW_32BIT (InputContext);\r
+ CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (InputContext);\r
+ CmdTrbCfgEP.CycleBit = 1;\r
+ CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT;\r
+ CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId;\r
+ DEBUG ((EFI_D_INFO, "Configure Endpoint\n"));\r
+ Status = XhcCmdTransfer (\r
+ Xhc,\r
+ (TRB_TEMPLATE *) (UINTN) &CmdTrbCfgEP,\r
+ XHC_GENERIC_TIMEOUT,\r
+ (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
+ );\r
+ ASSERT_EFI_ERROR(Status);\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Configure all the device endpoints through XHCI's Configure_Endpoint cmd.\r
+\r
+ @param Xhc The XHCI Instance.\r
+ @param SlotId The slot id to be configured.\r
+ @param DeviceSpeed The device's speed.\r
+ @param ConfigDesc The pointer to the usb device configuration descriptor.\r
+\r
+ @retval EFI_SUCCESS Successfully configure all the device endpoints.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+XhcSetConfigCmd64 (\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT8 SlotId,\r
+ IN UINT8 DeviceSpeed,\r
+ IN USB_CONFIG_DESCRIPTOR *ConfigDesc\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ USB_INTERFACE_DESCRIPTOR *IfDesc;\r
+ USB_ENDPOINT_DESCRIPTOR *EpDesc;\r
+ UINT8 Index;\r
+ UINTN NumEp;\r
+ UINTN EpIndex;\r
+ UINT8 EpAddr;\r
+ UINT8 Direction;\r
+ UINT8 Dci;\r
+ UINT8 MaxDci;\r
+ UINT32 PhyAddr;\r
+ UINT8 Interval;\r
+\r
+ TRANSFER_RING *EndpointTransferRing;\r
+ CMD_TRB_CONFIG_ENDPOINT CmdTrbCfgEP;\r
+ INPUT_CONTEXT_64 *InputContext;\r
+ DEVICE_CONTEXT_64 *OutputContext;\r
+ EVT_TRB_COMMAND_COMPLETION *EvtTrb;\r
+ //\r
+ // 4.6.6 Configure Endpoint\r
+ //\r
+ InputContext = Xhc->UsbDevContext[SlotId].InputContext;\r
+ OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;\r
+ ZeroMem (InputContext, sizeof (INPUT_CONTEXT_64));\r
+ CopyMem (&InputContext->Slot, &OutputContext->Slot, sizeof (SLOT_CONTEXT_64));\r
\r
ASSERT (ConfigDesc != NULL);\r
\r
EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);\r
}\r
\r
- EpAddr = EpDesc->EndpointAddress & 0x0F;\r
+ EpAddr = (UINT8)(EpDesc->EndpointAddress & 0x0F);\r
Direction = (UINT8)((EpDesc->EndpointAddress & 0x80) ? EfiUsbDataIn : EfiUsbDataOut);\r
\r
Dci = XhcEndpointToDci (EpAddr, Direction);\r
+ ASSERT (Dci < 32);\r
if (Dci > MaxDci) {\r
MaxDci = Dci;\r
}\r
}\r
\r
InputContext->EP[Dci-1].AverageTRBLength = 0x1000;\r
- if (UsbDevContext[SlotId].EndpointTransferRing[Dci-1] == NULL) {\r
- EndpointTransferRing = AllocateAlignedZeroPool(sizeof (TRANSFER_RING), 64);\r
- UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing;\r
- CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)UsbDevContext[SlotId].EndpointTransferRing[Dci-1]);\r
+ if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] == NULL) {\r
+ EndpointTransferRing = AllocateZeroPool(sizeof (TRANSFER_RING));\r
+ Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing;\r
+ CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]);\r
}\r
\r
break;\r
if ((DeviceSpeed == EFI_USB_SPEED_FULL) || (DeviceSpeed == EFI_USB_SPEED_LOW)) {\r
Interval = EpDesc->Interval;\r
//\r
- // BUGBUG: Hard code the interval to MAX\r
+ // Hard code the interval to MAX first, need calculate through the bInterval field of Endpoint descriptor.\r
//\r
InputContext->EP[Dci-1].Interval = 6;\r
- } else if (DeviceSpeed == EFI_USB_SPEED_SUPER) {\r
+ } else if ((DeviceSpeed == EFI_USB_SPEED_HIGH) || (DeviceSpeed == EFI_USB_SPEED_SUPER)) {\r
Interval = EpDesc->Interval;\r
- InputContext->EP[Dci-1].Interval = 0x0F;\r
+ ASSERT (Interval >= 1 && Interval <= 16);\r
+ //\r
+ // Refer to XHCI 1.0 spec section 6.2.3.6, table 61\r
+ //\r
+ InputContext->EP[Dci-1].Interval = Interval - 1;\r
InputContext->EP[Dci-1].AverageTRBLength = 0x1000;\r
InputContext->EP[Dci-1].MaxESITPayload = 0x0002;\r
InputContext->EP[Dci-1].MaxBurstSize = 0x0;\r
InputContext->EP[Dci-1].CErr = 3;\r
}\r
\r
- if (UsbDevContext[SlotId].EndpointTransferRing[Dci-1] == NULL) {\r
- EndpointTransferRing = AllocateAlignedZeroPool(sizeof (TRANSFER_RING), 64);\r
- UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing;\r
- CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)UsbDevContext[SlotId].EndpointTransferRing[Dci-1]);\r
+ if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] == NULL) {\r
+ EndpointTransferRing = AllocateZeroPool(sizeof (TRANSFER_RING));\r
+ Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing;\r
+ CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]);\r
}\r
break;\r
\r
break;\r
}\r
\r
- PhyAddr = XHC_LOW_32BIT (((TRANSFER_RING *)(UINTN)UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0);\r
+ PhyAddr = XHC_LOW_32BIT (((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0);\r
PhyAddr &= ~(0x0F);\r
- PhyAddr |= ((TRANSFER_RING *)(UINTN)UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingPCS;\r
+ PhyAddr |= ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingPCS;\r
InputContext->EP[Dci-1].PtrLo = PhyAddr;\r
- InputContext->EP[Dci-1].PtrHi = XHC_HIGH_32BIT (((TRANSFER_RING *)(UINTN)UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0);\r
+ InputContext->EP[Dci-1].PtrHi = XHC_HIGH_32BIT (((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0);\r
\r
EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);\r
}\r
CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (InputContext);\r
CmdTrbCfgEP.CycleBit = 1;\r
CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT;\r
- CmdTrbCfgEP.SlotId = UsbDevContext[SlotId].SlotId;\r
+ CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId;\r
DEBUG ((EFI_D_INFO, "Configure Endpoint\n"));\r
Status = XhcCmdTransfer (\r
Xhc,\r
- (TRB *) (UINTN) &CmdTrbCfgEP,\r
+ (TRB_TEMPLATE *) (UINTN) &CmdTrbCfgEP,\r
XHC_GENERIC_TIMEOUT,\r
- (TRB **) (UINTN) &EvtTrb\r
+ (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
);\r
ASSERT_EFI_ERROR(Status);\r
\r
return Status;\r
}\r
\r
+\r
/**\r
Evaluate the endpoint 0 context through XHCI's Evaluate_Context cmd.\r
\r
- @param Xhc The XHCI device.\r
+ @param Xhc The XHCI Instance.\r
@param SlotId The slot id to be evaluated.\r
@param MaxPacketSize The max packet size supported by the device control transfer.\r
\r
EFI_STATUS\r
EFIAPI\r
XhcEvaluateContext (\r
- IN USB_XHCI_DEV *Xhc,\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
IN UINT8 SlotId,\r
IN UINT32 MaxPacketSize\r
)\r
{\r
- EFI_STATUS Status;\r
- CMD_TRB_EVALU_CONTX CmdTrbEvalu;\r
- EVT_TRB_COMMAND *EvtTrb;\r
- INPUT_CONTEXT *InputContext;\r
+ EFI_STATUS Status;\r
+ CMD_TRB_EVALUATE_CONTEXT CmdTrbEvalu;\r
+ EVT_TRB_COMMAND_COMPLETION *EvtTrb;\r
+ INPUT_CONTEXT *InputContext;\r
\r
- ASSERT (UsbDevContext[SlotId].SlotId != 0);\r
+ ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0);\r
\r
//\r
// 4.6.7 Evaluate Context\r
//\r
- InputContext = UsbDevContext[SlotId].InputContext;\r
+ InputContext = Xhc->UsbDevContext[SlotId].InputContext;\r
ZeroMem (InputContext, sizeof (INPUT_CONTEXT));\r
\r
InputContext->InputControlContext.Dword2 |= BIT1;\r
CmdTrbEvalu.PtrHi = XHC_HIGH_32BIT (InputContext);\r
CmdTrbEvalu.CycleBit = 1;\r
CmdTrbEvalu.Type = TRB_TYPE_EVALU_CONTXT;\r
- CmdTrbEvalu.SlotId = UsbDevContext[SlotId].SlotId;\r
+ CmdTrbEvalu.SlotId = Xhc->UsbDevContext[SlotId].SlotId;\r
DEBUG ((EFI_D_INFO, "Evaluate context\n"));\r
Status = XhcCmdTransfer (\r
Xhc,\r
- (TRB *) (UINTN) &CmdTrbEvalu,\r
+ (TRB_TEMPLATE *) (UINTN) &CmdTrbEvalu,\r
XHC_GENERIC_TIMEOUT,\r
- (TRB **) (UINTN) &EvtTrb\r
+ (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
);\r
ASSERT (!EFI_ERROR(Status));\r
\r
return Status;\r
}\r
\r
+/**\r
+ Evaluate the endpoint 0 context through XHCI's Evaluate_Context cmd.\r
+\r
+ @param Xhc The XHCI Instance.\r
+ @param SlotId The slot id to be evaluated.\r
+ @param MaxPacketSize The max packet size supported by the device control transfer.\r
+\r
+ @retval EFI_SUCCESS Successfully evaluate the device endpoint 0.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+XhcEvaluateContext64 (\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT8 SlotId,\r
+ IN UINT32 MaxPacketSize\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ CMD_TRB_EVALUATE_CONTEXT CmdTrbEvalu;\r
+ EVT_TRB_COMMAND_COMPLETION *EvtTrb;\r
+ INPUT_CONTEXT_64 *InputContext;\r
+\r
+ ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0);\r
+\r
+ //\r
+ // 4.6.7 Evaluate Context\r
+ //\r
+ InputContext = Xhc->UsbDevContext[SlotId].InputContext;\r
+ ZeroMem (InputContext, sizeof (INPUT_CONTEXT_64));\r
+\r
+ InputContext->InputControlContext.Dword2 |= BIT1;\r
+ InputContext->EP[0].MaxPacketSize = MaxPacketSize;\r
+\r
+ ZeroMem (&CmdTrbEvalu, sizeof (CmdTrbEvalu));\r
+ CmdTrbEvalu.PtrLo = XHC_LOW_32BIT (InputContext);\r
+ CmdTrbEvalu.PtrHi = XHC_HIGH_32BIT (InputContext);\r
+ CmdTrbEvalu.CycleBit = 1;\r
+ CmdTrbEvalu.Type = TRB_TYPE_EVALU_CONTXT;\r
+ CmdTrbEvalu.SlotId = Xhc->UsbDevContext[SlotId].SlotId;\r
+ DEBUG ((EFI_D_INFO, "Evaluate context\n"));\r
+ Status = XhcCmdTransfer (\r
+ Xhc,\r
+ (TRB_TEMPLATE *) (UINTN) &CmdTrbEvalu,\r
+ XHC_GENERIC_TIMEOUT,\r
+ (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
+ );\r
+ ASSERT (!EFI_ERROR(Status));\r
+\r
+ return Status;\r
+}\r
+\r
+\r
/**\r
Evaluate the slot context for hub device through XHCI's Configure_Endpoint cmd.\r
\r
- @param Xhc The XHCI device.\r
+ @param Xhc The XHCI Instance.\r
@param SlotId The slot id to be configured.\r
@param PortNum The total number of downstream port supported by the hub.\r
@param TTT The TT think time of the hub device.\r
**/\r
EFI_STATUS\r
XhcConfigHubContext (\r
- IN USB_XHCI_DEV *Xhc,\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
IN UINT8 SlotId,\r
IN UINT8 PortNum,\r
IN UINT8 TTT,\r
IN UINT8 MTT\r
)\r
{\r
- EFI_STATUS Status;\r
+ EFI_STATUS Status;\r
\r
- EVT_TRB_COMMAND *EvtTrb;\r
- INPUT_CONTEXT *InputContext;\r
- DEVICE_CONTEXT *OutputDevContxt;\r
- CMD_CFG_ED CmdTrbCfgEP;\r
+ EVT_TRB_COMMAND_COMPLETION *EvtTrb;\r
+ INPUT_CONTEXT *InputContext;\r
+ DEVICE_CONTEXT *OutputContext;\r
+ CMD_TRB_CONFIG_ENDPOINT CmdTrbCfgEP;\r
\r
- ASSERT (UsbDevContext[SlotId].SlotId != 0);\r
- InputContext = UsbDevContext[SlotId].InputContext;\r
- OutputDevContxt = UsbDevContext[SlotId].OutputDevContxt;\r
+ ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0);\r
+ InputContext = Xhc->UsbDevContext[SlotId].InputContext;\r
+ OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;\r
\r
//\r
// 4.6.7 Evaluate Context\r
//\r
// Copy the slot context from OutputContext to Input context\r
//\r
- CopyMem(&(InputContext->Slot), &(OutputDevContxt->Slot), sizeof (SLOT_CONTEXT));\r
+ CopyMem(&(InputContext->Slot), &(OutputContext->Slot), sizeof (SLOT_CONTEXT));\r
+ InputContext->Slot.Hub = 1;\r
+ InputContext->Slot.PortNum = PortNum;\r
+ InputContext->Slot.TTT = TTT;\r
+ InputContext->Slot.MTT = MTT;\r
+\r
+ ZeroMem (&CmdTrbCfgEP, sizeof (CmdTrbCfgEP));\r
+ CmdTrbCfgEP.PtrLo = XHC_LOW_32BIT (InputContext);\r
+ CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (InputContext);\r
+ CmdTrbCfgEP.CycleBit = 1;\r
+ CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT;\r
+ CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId;\r
+ DEBUG ((EFI_D_INFO, "Configure Hub Slot Context\n"));\r
+ Status = XhcCmdTransfer (\r
+ Xhc,\r
+ (TRB_TEMPLATE *) (UINTN) &CmdTrbCfgEP,\r
+ XHC_GENERIC_TIMEOUT,\r
+ (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
+ );\r
+ ASSERT (!EFI_ERROR(Status));\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Evaluate the slot context for hub device through XHCI's Configure_Endpoint cmd.\r
+\r
+ @param Xhc The XHCI Instance.\r
+ @param SlotId The slot id to be configured.\r
+ @param PortNum The total number of downstream port supported by the hub.\r
+ @param TTT The TT think time of the hub device.\r
+ @param MTT The multi-TT of the hub device.\r
+\r
+ @retval EFI_SUCCESS Successfully configure the hub device's slot context.\r
+\r
+**/\r
+EFI_STATUS\r
+XhcConfigHubContext64 (\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT8 SlotId,\r
+ IN UINT8 PortNum,\r
+ IN UINT8 TTT,\r
+ IN UINT8 MTT\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ EVT_TRB_COMMAND_COMPLETION *EvtTrb;\r
+ INPUT_CONTEXT_64 *InputContext;\r
+ DEVICE_CONTEXT_64 *OutputContext;\r
+ CMD_TRB_CONFIG_ENDPOINT CmdTrbCfgEP;\r
+\r
+ ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0);\r
+ InputContext = Xhc->UsbDevContext[SlotId].InputContext;\r
+ OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;\r
+\r
+ //\r
+ // 4.6.7 Evaluate Context\r
+ //\r
+ ZeroMem (InputContext, sizeof (INPUT_CONTEXT_64));\r
+\r
+ InputContext->InputControlContext.Dword2 |= BIT0;\r
+\r
+ //\r
+ // Copy the slot context from OutputContext to Input context\r
+ //\r
+ CopyMem(&(InputContext->Slot), &(OutputContext->Slot), sizeof (SLOT_CONTEXT_64));\r
InputContext->Slot.Hub = 1;\r
InputContext->Slot.PortNum = PortNum;\r
InputContext->Slot.TTT = TTT;\r
CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (InputContext);\r
CmdTrbCfgEP.CycleBit = 1;\r
CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT;\r
- CmdTrbCfgEP.SlotId = UsbDevContext[SlotId].SlotId;\r
+ CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId;\r
DEBUG ((EFI_D_INFO, "Configure Hub Slot Context\n"));\r
Status = XhcCmdTransfer (\r
Xhc,\r
- (TRB *) (UINTN) &CmdTrbCfgEP,\r
+ (TRB_TEMPLATE *) (UINTN) &CmdTrbCfgEP,\r
XHC_GENERIC_TIMEOUT,\r
- (TRB **) (UINTN) &EvtTrb\r
+ (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
);\r
ASSERT (!EFI_ERROR(Status));\r
\r
return Status;\r
}\r
\r
+\r