\r
XHCI transfer scheduling routines.\r
\r
-Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\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.Length = 8;\r
TrbStart->TrbCtrSetup.IntTarget = 0;\r
TrbStart->TrbCtrSetup.IOC = 1;\r
TrbStart->TrbCtrSetup.IDT = 1;\r
TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue;\r
TrbStart->TrbCtrData.TRBPtrLo = XHC_LOW_32BIT(Urb->DataPhy);\r
TrbStart->TrbCtrData.TRBPtrHi = XHC_HIGH_32BIT(Urb->DataPhy);\r
- TrbStart->TrbCtrData.Lenth = (UINT32) Urb->DataLen;\r
+ TrbStart->TrbCtrData.Length = (UINT32) Urb->DataLen;\r
TrbStart->TrbCtrData.TDSize = 0;\r
TrbStart->TrbCtrData.IntTarget = 0;\r
TrbStart->TrbCtrData.ISP = 1;\r
TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue;\r
TrbStart->TrbNormal.TRBPtrLo = XHC_LOW_32BIT((UINT8 *) Urb->DataPhy + TotalLen);\r
TrbStart->TrbNormal.TRBPtrHi = XHC_HIGH_32BIT((UINT8 *) Urb->DataPhy + TotalLen);\r
- TrbStart->TrbNormal.Lenth = (UINT32) Len;\r
+ TrbStart->TrbNormal.Length = (UINT32) Len;\r
TrbStart->TrbNormal.TDSize = 0;\r
TrbStart->TrbNormal.IntTarget = 0;\r
TrbStart->TrbNormal.ISP = 1;\r
TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue;\r
TrbStart->TrbNormal.TRBPtrLo = XHC_LOW_32BIT((UINT8 *) Urb->DataPhy + TotalLen);\r
TrbStart->TrbNormal.TRBPtrHi = XHC_HIGH_32BIT((UINT8 *) Urb->DataPhy + TotalLen);\r
- TrbStart->TrbNormal.Lenth = (UINT32) Len;\r
+ TrbStart->TrbNormal.Length = (UINT32) Len;\r
TrbStart->TrbNormal.TDSize = 0;\r
TrbStart->TrbNormal.IntTarget = 0;\r
TrbStart->TrbNormal.ISP = 1;\r
ASSERT (ScratchEntry != NULL);\r
Xhc->ScratchEntry = ScratchEntry;\r
\r
+ ScratchPhy = 0;\r
Status = UsbHcAllocateAlignedPages (\r
Xhc->PciIo,\r
EFI_SIZE_TO_PAGES (MaxScratchpadBufs * sizeof (UINT64)),\r
// Allocate each scratch buffer\r
//\r
for (Index = 0; Index < MaxScratchpadBufs; Index++) {\r
+ ScratchEntryPhy = 0;\r
Status = UsbHcAllocateAlignedPages (\r
Xhc->PciIo,\r
EFI_SIZE_TO_PAGES (Xhc->PageSize),\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 = XhcBusDevAddrToSlotId (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 = XhcCmdTransfer (\r
- Xhc,\r
- (TRB_TEMPLATE *) (UINTN) &CmdTrbResetED,\r
- XHC_GENERIC_TIMEOUT,\r
- (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
- );\r
+ Status = XhcResetEndpoint(Xhc, SlotId, Dci);\r
if (EFI_ERROR(Status)) {\r
DEBUG ((EFI_D_ERROR, "XhcRecoverHaltedEndpoint: 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 = XhcCmdTransfer (\r
- Xhc,\r
- (TRB_TEMPLATE *) (UINTN) &CmdSetTRDeq,\r
- XHC_GENERIC_TIMEOUT,\r
- (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
- );\r
+ Status = XhcSetTrDequeuePointer(Xhc, SlotId, Dci, Urb);\r
+ if (EFI_ERROR(Status)) {\r
+ DEBUG ((EFI_D_ERROR, "XhcRecoverHaltedEndpoint: Set Transfer Ring 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
+ XhcRingDoorBell (Xhc, SlotId, Dci);\r
+\r
+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 Instance.\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
+EFIAPI\r
+XhcDequeueTrbFromEndpoint (\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN URB *Urb\r
+ )\r
+{\r
+ EFI_STATUS Status;\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, "Stop Slot = %x,Dci = %x\n", SlotId, Dci));\r
+\r
+ //\r
+ // 1) Send Stop endpoint command to stop xHC from executing of the TDs on the endpoint\r
+ //\r
+ Status = XhcStopEndpoint(Xhc, SlotId, Dci);\r
if (EFI_ERROR(Status)) {\r
- DEBUG ((EFI_D_ERROR, "XhcRecoverHaltedEndpoint: Set Dequeue Pointer Failed, Status = %r\n", Status));\r
+ DEBUG ((EFI_D_ERROR, "XhcDequeueTrbFromEndpoint: Stop Endpoint Failed, Status = %r\n", Status));\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // 2)Set dequeue pointer\r
+ //\r
+ Status = XhcSetTrDequeuePointer(Xhc, SlotId, Dci, Urb);\r
+ if (EFI_ERROR(Status)) {\r
+ DEBUG ((EFI_D_ERROR, "XhcDequeueTrbFromEndpoint: Set Transfer Ring Dequeue Pointer Failed, Status = %r\n", Status));\r
goto Done;\r
}\r
\r
return TRUE;\r
}\r
CheckedTrb++;\r
- if ((UINTN)CheckedTrb >= ((UINTN) CheckedUrb->Ring->RingSeg0 + sizeof (TRB_TEMPLATE) * CheckedUrb->Ring->TrbNumber)) {\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
}\r
@return Whether the result of URB transfer is finialized.\r
\r
**/\r
-EFI_STATUS\r
+BOOLEAN\r
XhcCheckUrbResult (\r
IN USB_XHCI_INSTANCE *Xhc,\r
IN URB *Urb\r
\r
if (XhcIsHalt (Xhc) || XhcIsSysError (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, "XhcCheckUrbResult: short packet happens!\n"));\r
+ DEBUG ((EFI_D_VERBOSE, "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
- CheckedUrb->Completed += (CheckedUrb->DataLen - EvtTrb->Lenth);\r
+ CheckedUrb->Completed += (((TRANSFER_TRB_NORMAL*)TRBPtr)->Length - EvtTrb->Length);\r
}\r
\r
break;\r
XhcWriteRuntimeReg (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
XhcRingDoorBell (Xhc, SlotId, Dci);\r
\r
for (Index = 0; Index < Loop; Index++) {\r
- Status = XhcCheckUrbResult (Xhc, Urb);\r
- if (Urb->Finished) {\r
+ Finished = XhcCheckUrbResult (Xhc, Urb);\r
+ if (Finished) {\r
break;\r
}\r
gBS->Stall (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
EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);\r
}\r
\r
+ if (EpDesc->Length < sizeof (USB_ENDPOINT_DESCRIPTOR)) {\r
+ EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);\r
+ continue;\r
+ }\r
+\r
EpAddr = (UINT8)(EpDesc->EndpointAddress & 0x0F);\r
Direction = (UINT8)((EpDesc->EndpointAddress & 0x80) ? EfiUsbDataIn : EfiUsbDataOut);\r
\r
InputContext->EP[Dci-1].CErr = 0;\r
InputContext->EP[Dci-1].EPType = ED_ISOCH_OUT;\r
}\r
- break;\r
+ //\r
+ // Do not support isochronous transfer now.\r
+ //\r
+ DEBUG ((EFI_D_INFO, "XhcInitializeEndpointContext: 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, "XhcInitializeEndpointContext: Unsupport Control EP found, Transfer ring is not allocated.\n"));\r
default:\r
- ASSERT (0);\r
- break;\r
+ DEBUG ((EFI_D_INFO, "XhcInitializeEndpointContext: 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
EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);\r
}\r
\r
+ if (EpDesc->Length < sizeof (USB_ENDPOINT_DESCRIPTOR)) {\r
+ EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);\r
+ continue;\r
+ }\r
+\r
EpAddr = (UINT8)(EpDesc->EndpointAddress & 0x0F);\r
Direction = (UINT8)((EpDesc->EndpointAddress & 0x80) ? EfiUsbDataIn : EfiUsbDataOut);\r
\r
InputContext->EP[Dci-1].CErr = 0;\r
InputContext->EP[Dci-1].EPType = ED_ISOCH_OUT;\r
}\r
- break;\r
+ //\r
+ // Do not support isochronous transfer now.\r
+ //\r
+ DEBUG ((EFI_D_INFO, "XhcInitializeEndpointContext64: 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, "XhcInitializeEndpointContext64: Unsupport Control EP found, Transfer ring is not allocated.\n"));\r
default:\r
- ASSERT (0);\r
- break;\r
+ DEBUG ((EFI_D_INFO, "XhcInitializeEndpointContext64: 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
IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length);\r
}\r
\r
+ if (IfDesc->Length < sizeof (USB_INTERFACE_DESCRIPTOR)) {\r
+ IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length);\r
+ continue;\r
+ }\r
+\r
Dci = XhcInitializeEndpointContext (Xhc, SlotId, DeviceSpeed, InputContext, IfDesc);\r
if (Dci > MaxDci) {\r
MaxDci = Dci;\r
IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length);\r
}\r
\r
+ if (IfDesc->Length < sizeof (USB_INTERFACE_DESCRIPTOR)) {\r
+ IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length);\r
+ continue;\r
+ }\r
+\r
Dci = XhcInitializeEndpointContext64 (Xhc, SlotId, DeviceSpeed, InputContext, IfDesc);\r
if (Dci > MaxDci) {\r
MaxDci = Dci;\r
return Status;\r
}\r
\r
+/**\r
+ Reset endpoint through XHCI's Reset_Endpoint cmd.\r
+\r
+ @param Xhc The XHCI Instance.\r
+ @param SlotId The slot id to be configured.\r
+ @param Dci The device context index of endpoint.\r
+\r
+ @retval EFI_SUCCESS Reset endpoint successfully.\r
+ @retval Others Failed to reset endpoint.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+XhcResetEndpoint (\r
+ IN USB_XHCI_INSTANCE *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, "XhcResetEndpoint: 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 = XhcCmdTransfer (\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, "XhcResetEndpoint: 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 Instance.\r
+ @param SlotId The slot id to be configured.\r
+ @param Dci The device context index of 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
+XhcSetTrDequeuePointer (\r
+ IN USB_XHCI_INSTANCE *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, "XhcSetTrDequeuePointer: 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 = XhcCmdTransfer (\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, "XhcSetTrDequeuePointer: Set TR Dequeue Pointer Failed, Status = %r\n", Status));\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
/**\r
Set interface through XHCI's Configure_Endpoint cmd.\r
\r
\r
IfDesc = (USB_INTERFACE_DESCRIPTOR *)(ConfigDesc + 1);\r
while ((UINTN) IfDesc < ((UINTN) ConfigDesc + ConfigDesc->TotalLength)) {\r
- if (IfDesc->DescriptorType == USB_DESC_TYPE_INTERFACE) {\r
+ if ((IfDesc->DescriptorType == USB_DESC_TYPE_INTERFACE) && (IfDesc->Length >= sizeof (USB_INTERFACE_DESCRIPTOR))) {\r
if (IfDesc->InterfaceNumber == (UINT8) Request->Index) {\r
if (IfDesc->AlternateSetting == Xhc->UsbDevContext[SlotId].ActiveAlternateSetting[IfDesc->InterfaceNumber]) {\r
//\r
EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);\r
}\r
\r
+ if (EpDesc->Length < sizeof (USB_ENDPOINT_DESCRIPTOR)) {\r
+ EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);\r
+ continue;\r
+ }\r
+\r
EpAddr = (UINT8) (EpDesc->EndpointAddress & 0x0F);\r
Direction = (UINT8) ((EpDesc->EndpointAddress & 0x80) ? EfiUsbDataIn : EfiUsbDataOut);\r
\r
\r
IfDesc = (USB_INTERFACE_DESCRIPTOR *)(ConfigDesc + 1);\r
while ((UINTN) IfDesc < ((UINTN) ConfigDesc + ConfigDesc->TotalLength)) {\r
- if (IfDesc->DescriptorType == USB_DESC_TYPE_INTERFACE) {\r
+ if ((IfDesc->DescriptorType == USB_DESC_TYPE_INTERFACE) && (IfDesc->Length >= sizeof (USB_INTERFACE_DESCRIPTOR))) {\r
if (IfDesc->InterfaceNumber == (UINT8) Request->Index) {\r
if (IfDesc->AlternateSetting == Xhc->UsbDevContext[SlotId].ActiveAlternateSetting[IfDesc->InterfaceNumber]) {\r
//\r
EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);\r
}\r
\r
+ if (EpDesc->Length < sizeof (USB_ENDPOINT_DESCRIPTOR)) {\r
+ EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);\r
+ continue;\r
+ }\r
+\r
EpAddr = (UINT8) (EpDesc->EndpointAddress & 0x0F);\r
Direction = (UINT8) ((EpDesc->EndpointAddress & 0x80) ? EfiUsbDataIn : EfiUsbDataOut);\r
\r