PEIM to produce gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid\r
which is used to enable recovery function from USB Drivers.\r
\r
-Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>\r
\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions\r
)\r
{\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
- EFI_PHYSICAL_ADDRESS PhyAddr;\r
\r
Status = EFI_SUCCESS;\r
SlotId = XhcPeiBusDevAddrToSlotId (Xhc, Urb->Ep.BusAddr);\r
//\r
// 1) Send Reset endpoint command to transit from halt to stop state\r
//\r
- ZeroMem (&CmdTrbResetED, sizeof (CmdTrbResetED));\r
- CmdTrbResetED.CycleBit = 1;\r
- CmdTrbResetED.Type = TRB_TYPE_RESET_ENDPOINT;\r
- CmdTrbResetED.EDID = Dci;\r
- CmdTrbResetED.SlotId = SlotId;\r
- Status = XhcPeiCmdTransfer (\r
- Xhc,\r
- (TRB_TEMPLATE *) (UINTN) &CmdTrbResetED,\r
- XHC_GENERIC_TIMEOUT,\r
- (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
- );\r
+ Status = XhcPeiResetEndpoint (Xhc, SlotId, Dci);\r
if (EFI_ERROR(Status)) {\r
DEBUG ((EFI_D_ERROR, "XhcPeiRecoverHaltedEndpoint: Reset Endpoint Failed, Status = %r\n", Status));\r
goto Done;\r
//\r
// 2) Set dequeue pointer\r
//\r
- ZeroMem (&CmdSetTRDeq, sizeof (CmdSetTRDeq));\r
- PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Urb->Ring->RingEnqueue, sizeof (CMD_SET_TR_DEQ_POINTER));\r
- CmdSetTRDeq.PtrLo = XHC_LOW_32BIT (PhyAddr) | Urb->Ring->RingPCS;\r
- CmdSetTRDeq.PtrHi = XHC_HIGH_32BIT (PhyAddr);\r
- CmdSetTRDeq.CycleBit = 1;\r
- CmdSetTRDeq.Type = TRB_TYPE_SET_TR_DEQUE;\r
- CmdSetTRDeq.Endpoint = Dci;\r
- CmdSetTRDeq.SlotId = SlotId;\r
- Status = XhcPeiCmdTransfer (\r
- Xhc,\r
- (TRB_TEMPLATE *) (UINTN) &CmdSetTRDeq,\r
- XHC_GENERIC_TIMEOUT,\r
- (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
- );\r
+ Status = XhcPeiSetTrDequeuePointer (Xhc, SlotId, Dci, Urb);\r
if (EFI_ERROR(Status)) {\r
DEBUG ((EFI_D_ERROR, "XhcPeiRecoverHaltedEndpoint: Set Dequeue Pointer Failed, Status = %r\n", Status));\r
goto Done;\r
return Status;\r
}\r
\r
+/**\r
+ System software shall use a Stop Endpoint Command (section 4.6.9) and the Set TR Dequeue Pointer\r
+ Command (section 4.6.10) to remove the timed-out TDs from the xHC transfer ring. The next write to\r
+ the Doorbell of the Endpoint will transition the Endpoint Context from the Stopped to the Running\r
+ state.\r
+\r
+ @param Xhc The XHCI device.\r
+ @param Urb The urb which doesn't get completed in a specified timeout range.\r
+\r
+ @retval EFI_SUCCESS The dequeuing of the TDs is successful.\r
+ @retval Others Failed to stop the endpoint and dequeue the TDs.\r
+\r
+**/\r
+EFI_STATUS\r
+XhcPeiDequeueTrbFromEndpoint (\r
+ IN PEI_XHC_DEV *Xhc,\r
+ IN URB *Urb\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT8 Dci;\r
+ UINT8 SlotId;\r
+\r
+ Status = EFI_SUCCESS;\r
+ SlotId = XhcPeiBusDevAddrToSlotId (Xhc, Urb->Ep.BusAddr);\r
+ if (SlotId == 0) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+ Dci = XhcPeiEndpointToDci (Urb->Ep.EpAddr, (UINT8) (Urb->Ep.Direction));\r
+\r
+ DEBUG ((EFI_D_INFO, "XhcPeiDequeueTrbFromEndpoint: Stop Slot = %x, Dci = %x\n", SlotId, Dci));\r
+\r
+ //\r
+ // 1) Send Stop endpoint command to stop endpoint.\r
+ //\r
+ Status = XhcPeiStopEndpoint (Xhc, SlotId, Dci);\r
+ if (EFI_ERROR(Status)) {\r
+ DEBUG ((EFI_D_ERROR, "XhcPeiDequeueTrbFromEndpoint: Stop Endpoint Failed, Status = %r\n", Status));\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // 2) Set dequeue pointer\r
+ //\r
+ Status = XhcPeiSetTrDequeuePointer (Xhc, SlotId, Dci, Urb);\r
+ if (EFI_ERROR(Status)) {\r
+ DEBUG ((EFI_D_ERROR, "XhcPeiDequeueTrbFromEndpoint: Set Dequeue Pointer Failed, Status = %r\n", Status));\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // 3) Ring the doorbell to transit from stop to active\r
+ //\r
+ XhcPeiRingDoorBell (Xhc, SlotId, Dci);\r
+\r
+Done:\r
+ return Status;\r
+}\r
+\r
/**\r
Check if the Trb is a transaction of the URB.\r
\r
@return Whether the result of URB transfer is finialized.\r
\r
**/\r
-EFI_STATUS\r
+BOOLEAN\r
XhcPeiCheckUrbResult (\r
IN PEI_XHC_DEV *Xhc,\r
IN URB *Urb\r
\r
if (XhcPeiIsHalt (Xhc) || XhcPeiIsSysError (Xhc)) {\r
Urb->Result |= EFI_USB_ERR_SYSTEM;\r
- Status = EFI_DEVICE_ERROR;\r
goto EXIT;\r
}\r
\r
case TRB_COMPLETION_SHORT_PACKET:\r
case TRB_COMPLETION_SUCCESS:\r
if (EvtTrb->Completecode == TRB_COMPLETION_SHORT_PACKET) {\r
- DEBUG ((EFI_D_ERROR, "XhcPeiCheckUrbResult: short packet happens!\n"));\r
+ DEBUG ((EFI_D_VERBOSE, "XhcPeiCheckUrbResult: 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
- CheckedUrb->Completed += (CheckedUrb->DataLen - EvtTrb->Length);\r
+ CheckedUrb->Completed += (((TRANSFER_TRB_NORMAL*)TRBPtr)->Length - EvtTrb->Length);\r
}\r
\r
break;\r
XhcPeiWriteRuntimeReg (Xhc, XHC_ERDP_OFFSET + 4, XHC_HIGH_32BIT (PhyAddr));\r
}\r
\r
- return Status;\r
+ return Urb->Finished;\r
}\r
\r
/**\r
{\r
EFI_STATUS Status;\r
UINTN Index;\r
- UINTN Loop;\r
+ UINT64 Loop;\r
UINT8 SlotId;\r
UINT8 Dci;\r
+ BOOLEAN Finished;\r
\r
if (CmdTransfer) {\r
SlotId = 0;\r
XhcPeiRingDoorBell (Xhc, SlotId, Dci);\r
\r
for (Index = 0; Index < Loop; Index++) {\r
- Status = XhcPeiCheckUrbResult (Xhc, Urb);\r
- if (Urb->Finished) {\r
+ Finished = XhcPeiCheckUrbResult (Xhc, Urb);\r
+ if (Finished) {\r
break;\r
}\r
MicroSecondDelay (XHC_1_MICROSECOND);\r
\r
if (Index == Loop) {\r
Urb->Result = EFI_USB_ERR_TIMEOUT;\r
+ Status = EFI_TIMEOUT;\r
+ } else if (Urb->Result != EFI_USB_NOERROR) {\r
+ Status = EFI_DEVICE_ERROR;\r
}\r
\r
return Status;\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
+ // Delay 10ms to meet TRSTRCY delay requirement in usb 2.0 spec chapter 7.1.7.5 before sending SetAddress() request\r
+ // to device.\r
+ //\r
+ MicroSecondDelay (XHC_RESET_RECOVERY_DELAY);\r
ZeroMem (&CmdTrbAddr, sizeof (CmdTrbAddr));\r
PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Xhc->UsbDevContext[SlotId].InputContext, sizeof (INPUT_CONTEXT));\r
CmdTrbAddr.PtrLo = XHC_LOW_32BIT (PhyAddr);\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
+ // Delay 10ms to meet TRSTRCY delay requirement in usb 2.0 spec chapter 7.1.7.5 before sending SetAddress() request\r
+ // to device.\r
+ //\r
+ MicroSecondDelay (XHC_RESET_RECOVERY_DELAY);\r
ZeroMem (&CmdTrbAddr, sizeof (CmdTrbAddr));\r
PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Xhc->UsbDevContext[SlotId].InputContext, sizeof (INPUT_CONTEXT_64));\r
CmdTrbAddr.PtrLo = XHC_LOW_32BIT (PhyAddr);\r
InputContext->EP[Dci-1].CErr = 0;\r
InputContext->EP[Dci-1].EPType = ED_ISOCH_OUT;\r
}\r
- break;\r
+ //\r
+ // Get the bInterval from descriptor and init the the interval field of endpoint context.\r
+ // Refer to XHCI 1.1 spec section 6.2.3.6.\r
+ //\r
+ if (DeviceSpeed == EFI_USB_SPEED_FULL) {\r
+ Interval = EpDesc->Interval;\r
+ ASSERT (Interval >= 1 && Interval <= 16);\r
+ InputContext->EP[Dci-1].Interval = Interval + 2;\r
+ } else if ((DeviceSpeed == EFI_USB_SPEED_HIGH) || (DeviceSpeed == EFI_USB_SPEED_SUPER)) {\r
+ Interval = EpDesc->Interval;\r
+ ASSERT (Interval >= 1 && Interval <= 16);\r
+ InputContext->EP[Dci-1].Interval = Interval - 1;\r
+ }\r
+\r
+ //\r
+ // Do not support isochronous transfer now.\r
+ //\r
+ DEBUG ((EFI_D_INFO, "XhcPeiSetConfigCmd: Unsupport ISO EP found, Transfer ring is not allocated.\n"));\r
+ EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);\r
+ continue;\r
case USB_ENDPOINT_INTERRUPT:\r
if (Direction == EfiUsbDataIn) {\r
InputContext->EP[Dci-1].CErr = 3;\r
break;\r
\r
case USB_ENDPOINT_CONTROL:\r
+ //\r
+ // Do not support control transfer now.\r
+ //\r
+ DEBUG ((EFI_D_INFO, "XhcPeiSetConfigCmd: Unsupport Control EP found, Transfer ring is not allocated.\n"));\r
default:\r
- ASSERT (FALSE);\r
- break;\r
+ DEBUG ((EFI_D_INFO, "XhcPeiSetConfigCmd: Unknown EP found, Transfer ring is not allocated.\n"));\r
+ EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);\r
+ continue;\r
}\r
\r
PhyAddr = UsbHcGetPciAddrForHostAddr (\r
((TRANSFER_RING *) (UINTN) Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0,\r
sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER\r
);\r
- PhyAddr &= ~(0x0F);\r
- PhyAddr |= ((TRANSFER_RING *) (UINTN) Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingPCS;\r
+ PhyAddr &= ~((EFI_PHYSICAL_ADDRESS)0x0F);\r
+ PhyAddr |= (EFI_PHYSICAL_ADDRESS)((TRANSFER_RING *) (UINTN) Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingPCS;\r
InputContext->EP[Dci-1].PtrLo = XHC_LOW_32BIT (PhyAddr);\r
InputContext->EP[Dci-1].PtrHi = XHC_HIGH_32BIT (PhyAddr);\r
\r
InputContext->EP[Dci-1].CErr = 0;\r
InputContext->EP[Dci-1].EPType = ED_ISOCH_OUT;\r
}\r
- break;\r
+ //\r
+ // Get the bInterval from descriptor and init the the interval field of endpoint context.\r
+ // Refer to XHCI 1.1 spec section 6.2.3.6.\r
+ //\r
+ if (DeviceSpeed == EFI_USB_SPEED_FULL) {\r
+ Interval = EpDesc->Interval;\r
+ ASSERT (Interval >= 1 && Interval <= 16);\r
+ InputContext->EP[Dci-1].Interval = Interval + 2;\r
+ } else if ((DeviceSpeed == EFI_USB_SPEED_HIGH) || (DeviceSpeed == EFI_USB_SPEED_SUPER)) {\r
+ Interval = EpDesc->Interval;\r
+ ASSERT (Interval >= 1 && Interval <= 16);\r
+ InputContext->EP[Dci-1].Interval = Interval - 1;\r
+ }\r
+\r
+ //\r
+ // Do not support isochronous transfer now.\r
+ //\r
+ DEBUG ((EFI_D_INFO, "XhcPeiSetConfigCmd64: Unsupport ISO EP found, Transfer ring is not allocated.\n"));\r
+ EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);\r
+ continue;\r
case USB_ENDPOINT_INTERRUPT:\r
if (Direction == EfiUsbDataIn) {\r
InputContext->EP[Dci-1].CErr = 3;\r
break;\r
\r
case USB_ENDPOINT_CONTROL:\r
+ //\r
+ // Do not support control transfer now.\r
+ //\r
+ DEBUG ((EFI_D_INFO, "XhcPeiSetConfigCmd64: Unsupport Control EP found, Transfer ring is not allocated.\n"));\r
default:\r
- ASSERT (0);\r
- break;\r
+ DEBUG ((EFI_D_INFO, "XhcPeiSetConfigCmd64: Unknown EP found, Transfer ring is not allocated.\n"));\r
+ EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);\r
+ continue;\r
}\r
\r
PhyAddr = UsbHcGetPciAddrForHostAddr (\r
sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER\r
);\r
\r
- PhyAddr &= ~(0x0F);\r
- PhyAddr |= ((TRANSFER_RING *) (UINTN) Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingPCS;\r
+ PhyAddr &= ~((EFI_PHYSICAL_ADDRESS)0x0F);\r
+ PhyAddr |= (EFI_PHYSICAL_ADDRESS)((TRANSFER_RING *) (UINTN) Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingPCS;\r
\r
InputContext->EP[Dci-1].PtrLo = XHC_LOW_32BIT (PhyAddr);\r
InputContext->EP[Dci-1].PtrHi = XHC_HIGH_32BIT (PhyAddr);\r
return Status;\r
}\r
\r
+/**\r
+ Stop endpoint through XHCI's Stop_Endpoint cmd.\r
+\r
+ @param Xhc The XHCI device.\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
+ @retval EFI_SUCCESS Stop endpoint successfully.\r
+ @retval Others Failed to stop endpoint.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+XhcPeiStopEndpoint (\r
+ IN PEI_XHC_DEV *Xhc,\r
+ IN UINT8 SlotId,\r
+ IN UINT8 Dci\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EVT_TRB_COMMAND_COMPLETION *EvtTrb;\r
+ CMD_TRB_STOP_ENDPOINT CmdTrbStopED;\r
+\r
+ DEBUG ((EFI_D_INFO, "XhcPeiStopEndpoint: Slot = 0x%x, Dci = 0x%x\n", SlotId, Dci));\r
+\r
+ //\r
+ // Send stop endpoint command to transit Endpoint from running to stop state\r
+ //\r
+ ZeroMem (&CmdTrbStopED, sizeof (CmdTrbStopED));\r
+ CmdTrbStopED.CycleBit = 1;\r
+ CmdTrbStopED.Type = TRB_TYPE_STOP_ENDPOINT;\r
+ CmdTrbStopED.EDID = Dci;\r
+ CmdTrbStopED.SlotId = SlotId;\r
+ Status = XhcPeiCmdTransfer (\r
+ Xhc,\r
+ (TRB_TEMPLATE *) (UINTN) &CmdTrbStopED,\r
+ XHC_GENERIC_TIMEOUT,\r
+ (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
+ );\r
+ if (EFI_ERROR(Status)) {\r
+ DEBUG ((EFI_D_ERROR, "XhcPeiStopEndpoint: Stop Endpoint Failed, Status = %r\n", Status));\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Reset endpoint through XHCI's Reset_Endpoint cmd.\r
+\r
+ @param Xhc The XHCI device.\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
+ @retval EFI_SUCCESS Reset endpoint successfully.\r
+ @retval Others Failed to reset endpoint.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+XhcPeiResetEndpoint (\r
+ IN PEI_XHC_DEV *Xhc,\r
+ IN UINT8 SlotId,\r
+ IN UINT8 Dci\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EVT_TRB_COMMAND_COMPLETION *EvtTrb;\r
+ CMD_TRB_RESET_ENDPOINT CmdTrbResetED;\r
+\r
+ DEBUG ((EFI_D_INFO, "XhcPeiResetEndpoint: Slot = 0x%x, Dci = 0x%x\n", SlotId, Dci));\r
+\r
+ //\r
+ // Send stop endpoint command to transit Endpoint from running to stop state\r
+ //\r
+ ZeroMem (&CmdTrbResetED, sizeof (CmdTrbResetED));\r
+ CmdTrbResetED.CycleBit = 1;\r
+ CmdTrbResetED.Type = TRB_TYPE_RESET_ENDPOINT;\r
+ CmdTrbResetED.EDID = Dci;\r
+ CmdTrbResetED.SlotId = SlotId;\r
+ Status = XhcPeiCmdTransfer (\r
+ Xhc,\r
+ (TRB_TEMPLATE *) (UINTN) &CmdTrbResetED,\r
+ XHC_GENERIC_TIMEOUT,\r
+ (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
+ );\r
+ if (EFI_ERROR(Status)) {\r
+ DEBUG ((EFI_D_ERROR, "XhcPeiResetEndpoint: Reset Endpoint Failed, Status = %r\n", Status));\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Set transfer ring dequeue pointer through XHCI's Set_Tr_Dequeue_Pointer cmd.\r
+\r
+ @param Xhc The XHCI device.\r
+ @param SlotId The slot id of the target device.\r
+ @param Dci The device context index of the target slot or endpoint.\r
+ @param Urb The dequeue pointer of the transfer ring specified\r
+ by the urb to be updated.\r
+\r
+ @retval EFI_SUCCESS Set transfer ring dequeue pointer succeeds.\r
+ @retval Others Failed to set transfer ring dequeue pointer.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+XhcPeiSetTrDequeuePointer (\r
+ IN PEI_XHC_DEV *Xhc,\r
+ IN UINT8 SlotId,\r
+ IN UINT8 Dci,\r
+ IN URB *Urb\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EVT_TRB_COMMAND_COMPLETION *EvtTrb;\r
+ CMD_SET_TR_DEQ_POINTER CmdSetTRDeq;\r
+ EFI_PHYSICAL_ADDRESS PhyAddr;\r
+\r
+ DEBUG ((EFI_D_INFO, "XhcPeiSetTrDequeuePointer: Slot = 0x%x, Dci = 0x%x, Urb = 0x%x\n", SlotId, Dci, Urb));\r
+\r
+ //\r
+ // Send stop endpoint command to transit Endpoint from running to stop state\r
+ //\r
+ ZeroMem (&CmdSetTRDeq, sizeof (CmdSetTRDeq));\r
+ PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Urb->Ring->RingEnqueue, sizeof (CMD_SET_TR_DEQ_POINTER));\r
+ CmdSetTRDeq.PtrLo = XHC_LOW_32BIT (PhyAddr) | Urb->Ring->RingPCS;\r
+ CmdSetTRDeq.PtrHi = XHC_HIGH_32BIT (PhyAddr);\r
+ CmdSetTRDeq.CycleBit = 1;\r
+ CmdSetTRDeq.Type = TRB_TYPE_SET_TR_DEQUE;\r
+ CmdSetTRDeq.Endpoint = Dci;\r
+ CmdSetTRDeq.SlotId = SlotId;\r
+ Status = XhcPeiCmdTransfer (\r
+ Xhc,\r
+ (TRB_TEMPLATE *) (UINTN) &CmdSetTRDeq,\r
+ XHC_GENERIC_TIMEOUT,\r
+ (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
+ );\r
+ if (EFI_ERROR(Status)) {\r
+ DEBUG ((EFI_D_ERROR, "XhcPeiSetTrDequeuePointer: Set TR Dequeue Pointer Failed, Status = %r\n", Status));\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
/**\r
Check if there is a new generated event.\r
\r
ASSERT (ScratchEntry != NULL);\r
Xhc->ScratchEntry = ScratchEntry;\r
\r
+ ScratchPhy = 0;\r
Status = UsbHcAllocateAlignedPages (\r
EFI_SIZE_TO_PAGES (MaxScratchpadBufs * sizeof (UINT64)),\r
Xhc->PageSize,\r
// Allocate each scratch buffer\r
//\r
for (Index = 0; Index < MaxScratchpadBufs; Index++) {\r
+ ScratchEntryPhy = 0;\r
Status = UsbHcAllocateAlignedPages (\r
EFI_SIZE_TO_PAGES (Xhc->PageSize),\r
Xhc->PageSize,\r