XhcWriteOpReg (Xhc, XHC_CRCR_OFFSET, XHC_LOW_32BIT(CmdRingPhy));\r
XhcWriteOpReg (Xhc, XHC_CRCR_OFFSET + 4, XHC_HIGH_32BIT (CmdRingPhy));\r
\r
- DEBUG ((EFI_D_INFO, "XhcInitSched:XHC_CRCR=0x%x\n", Xhc->CmdRing.RingSeg0));\r
-\r
//\r
// Disable the 'interrupter enable' bit in USB_CMD\r
// and clear IE & IP bit in all Interrupter X Management Registers.\r
// Allocate EventRing for Cmd, Ctrl, Bulk, Interrupt, AsynInterrupt transfer\r
//\r
CreateEventRing (Xhc, &Xhc->EventRing);\r
- DEBUG ((EFI_D_INFO, "XhcInitSched:XHC_EVENTRING=0x%x\n", Xhc->EventRing.EventRingSeg0));\r
+ DEBUG ((DEBUG_INFO, "XhcInitSched: Created CMD ring [%p~%p) EVENT ring [%p~%p)\n",\r
+ Xhc->CmdRing.RingSeg0, (UINTN)Xhc->CmdRing.RingSeg0 + sizeof (TRB_TEMPLATE) * CMD_RING_TRB_NUMBER,\r
+ Xhc->EventRing.EventRingSeg0, (UINTN)Xhc->EventRing.EventRingSeg0 + sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER\r
+ ));\r
}\r
\r
/**\r
}\r
\r
/**\r
- Check if the Trb is a transaction of the URBs in XHCI's asynchronous transfer list.\r
+ Check if the Trb is a transaction of the URB.\r
\r
- @param Xhc The XHCI Instance.\r
- @param Trb The TRB to be checked.\r
- @param Urb The pointer to the matched Urb.\r
+ @param Trb The TRB to be checked\r
+ @param Urb The URB to be checked.\r
\r
- @retval TRUE The Trb is matched with a transaction of the URBs in the async list.\r
- @retval FALSE The Trb is not matched with any URBs in the async list.\r
+ @retval TRUE It is a transaction of the URB.\r
+ @retval FALSE It is not any transaction of the URB.\r
\r
**/\r
BOOLEAN\r
-IsAsyncIntTrb (\r
+IsTransferRingTrb (\r
IN USB_XHCI_INSTANCE *Xhc,\r
IN TRB_TEMPLATE *Trb,\r
- OUT URB **Urb\r
+ IN URB *Urb\r
)\r
{\r
- LIST_ENTRY *Entry;\r
- LIST_ENTRY *Next;\r
- TRB_TEMPLATE *CheckedTrb;\r
- URB *CheckedUrb;\r
- UINTN Index;\r
+ LINK_TRB *LinkTrb;\r
+ TRB_TEMPLATE *CheckedTrb;\r
+ UINTN Index;\r
+ EFI_PHYSICAL_ADDRESS PhyAddr;\r
\r
- EFI_LIST_FOR_EACH_SAFE (Entry, Next, &Xhc->AsyncIntTransfers) {\r
- CheckedUrb = EFI_LIST_CONTAINER (Entry, URB, UrbList);\r
- CheckedTrb = CheckedUrb->TrbStart;\r
- for (Index = 0; Index < CheckedUrb->TrbNum; Index++) {\r
- if (Trb == CheckedTrb) {\r
- *Urb = CheckedUrb;\r
- return TRUE;\r
- }\r
- CheckedTrb++;\r
- //\r
- // If the checked TRB is the link TRB at the end of the transfer ring,\r
- // recircle it to the head of the ring.\r
- //\r
- if (CheckedTrb->Type == TRB_TYPE_LINK) {\r
- CheckedTrb = (TRB_TEMPLATE*) CheckedUrb->Ring->RingSeg0;\r
- }\r
+ CheckedTrb = Urb->TrbStart;\r
+ for (Index = 0; Index < Urb->TrbNum; Index++) {\r
+ if (Trb == CheckedTrb) {\r
+ return TRUE;\r
+ }\r
+ CheckedTrb++;\r
+ //\r
+ // If the checked TRB is the link TRB at the end of the transfer ring,\r
+ // recircle it to the head of the ring.\r
+ //\r
+ if (CheckedTrb->Type == TRB_TYPE_LINK) {\r
+ LinkTrb = (LINK_TRB *) CheckedTrb;\r
+ PhyAddr = (EFI_PHYSICAL_ADDRESS)(LinkTrb->PtrLo | LShiftU64 ((UINT64) LinkTrb->PtrHi, 32));\r
+ CheckedTrb = (TRB_TEMPLATE *)(UINTN) UsbHcGetHostAddrForPciAddr (Xhc->MemPool, (VOID *)(UINTN) PhyAddr, sizeof (TRB_TEMPLATE));\r
+ ASSERT (CheckedTrb == Urb->Ring->RingSeg0);\r
}\r
}\r
\r
}\r
\r
/**\r
- Check if the Trb is a transaction of the URB.\r
+ Check if the Trb is a transaction of the URBs in XHCI's asynchronous transfer list.\r
\r
- @param Trb The TRB to be checked\r
- @param Urb The transfer ring to be checked.\r
+ @param Xhc The XHCI Instance.\r
+ @param Trb The TRB to be checked.\r
+ @param Urb The pointer to the matched Urb.\r
\r
- @retval TRUE It is a transaction of the URB.\r
- @retval FALSE It is not any transaction of the URB.\r
+ @retval TRUE The Trb is matched with a transaction of the URBs in the async list.\r
+ @retval FALSE The Trb is not matched with any URBs in the async list.\r
\r
**/\r
BOOLEAN\r
-IsTransferRingTrb (\r
+IsAsyncIntTrb (\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
IN TRB_TEMPLATE *Trb,\r
- IN URB *Urb\r
+ OUT URB **Urb\r
)\r
{\r
- TRB_TEMPLATE *CheckedTrb;\r
- UINTN Index;\r
-\r
- CheckedTrb = Urb->Ring->RingSeg0;\r
-\r
- ASSERT (Urb->Ring->TrbNumber == CMD_RING_TRB_NUMBER || Urb->Ring->TrbNumber == TR_RING_TRB_NUMBER);\r
+ LIST_ENTRY *Entry;\r
+ LIST_ENTRY *Next;\r
+ URB *CheckedUrb;\r
\r
- for (Index = 0; Index < Urb->Ring->TrbNumber; Index++) {\r
- if (Trb == CheckedTrb) {\r
+ EFI_LIST_FOR_EACH_SAFE (Entry, Next, &Xhc->AsyncIntTransfers) {\r
+ CheckedUrb = EFI_LIST_CONTAINER (Entry, URB, UrbList);\r
+ if (IsTransferRingTrb (Xhc, Trb, CheckedUrb)) {\r
+ *Urb = CheckedUrb;\r
return TRUE;\r
}\r
- CheckedTrb++;\r
}\r
\r
return FALSE;\r
}\r
\r
+\r
/**\r
Check the URB's execution result and update the URB's\r
result accordingly.\r
// This way is used to avoid that those completed async transfer events don't get\r
// handled in time and are flushed by newer coming events.\r
//\r
- if (IsTransferRingTrb (TRBPtr, Urb)) {\r
+ if (IsTransferRingTrb (Xhc, TRBPtr, Urb)) {\r
CheckedUrb = Urb;\r
} else if (IsAsyncIntTrb (Xhc, TRBPtr, &AsyncUrb)) { \r
CheckedUrb = AsyncUrb;\r
EFI_LIST_FOR_EACH_SAFE (Entry, Next, &Xhc->AsyncIntTransfers) {\r
Urb = EFI_LIST_CONTAINER (Entry, URB, UrbList);\r
\r
- //\r
- // Device doesn't finish the IntTransfer until real data comes\r
- // So the TRB should be removed as well.\r
- //\r
+ //\r
+ // Device doesn't finish the IntTransfer until real data comes\r
+ // So the TRB should be removed as well.\r
+ //\r
Status = XhcDequeueTrbFromEndpoint (Xhc, Urb);\r
if (EFI_ERROR (Status)) {\r
DEBUG ((EFI_D_ERROR, "XhciDelAllAsyncIntTransfers: XhcDequeueTrbFromEndpoint failed\n"));\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
+ DEBUG ((DEBUG_INFO, "Endpoint[%x]: Created BULK ring [%p~%p)\n",\r
+ EpDesc->EndpointAddress,\r
+ EndpointTransferRing->RingSeg0,\r
+ (UINTN) EndpointTransferRing->RingSeg0 + TR_RING_TRB_NUMBER * sizeof (TRB_TEMPLATE)\r
+ ));\r
}\r
\r
break;\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
+ DEBUG ((DEBUG_INFO, "Endpoint[%x]: Created INT ring [%p~%p)\n",\r
+ EpDesc->EndpointAddress,\r
+ EndpointTransferRing->RingSeg0,\r
+ (UINTN) EndpointTransferRing->RingSeg0 + TR_RING_TRB_NUMBER * sizeof (TRB_TEMPLATE)\r
+ ));\r
}\r
break;\r
\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
+ DEBUG ((DEBUG_INFO, "Endpoint64[%x]: Created BULK ring [%p~%p)\n",\r
+ EpDesc->EndpointAddress,\r
+ EndpointTransferRing->RingSeg0,\r
+ (UINTN) EndpointTransferRing->RingSeg0 + TR_RING_TRB_NUMBER * sizeof (TRB_TEMPLATE)\r
+ ));\r
}\r
\r
break;\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
+ DEBUG ((DEBUG_INFO, "Endpoint64[%x]: Created INT ring [%p~%p)\n",\r
+ EpDesc->EndpointAddress,\r
+ EndpointTransferRing->RingSeg0,\r
+ (UINTN) EndpointTransferRing->RingSeg0 + TR_RING_TRB_NUMBER * sizeof (TRB_TEMPLATE)\r
+ ));\r
}\r
break;\r
\r