X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=MdeModulePkg%2FBus%2FPci%2FXhciDxe%2FXhciSched.c;h=4b7462704a812ee2868123a8100ed63df7a64c22;hb=8147fe090fb566f9a1ed8fde24098bbe425026be;hp=58a2f984a9450a127e065f95fa8ec35580ef15c7;hpb=3719c2aa879bcbcf3f0ab1f710e81fe2dbc19d9a;p=mirror_edk2.git
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
index 58a2f984a9..4b7462704a 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
@@ -2,14 +2,10 @@
XHCI transfer scheduling routines.
-Copyright (c) 2011 - 2017, Intel Corporation. All rights reserved.
-This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution. The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+Copyright (c) 2011 - 2020, Intel Corporation. All rights reserved.
+Copyright (c) Microsoft Corporation.
+Copyright (C) 2022 Advanced Micro Devices, Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -24,25 +20,25 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
@return Created URB or NULL.
**/
-URB*
+URB *
XhcCreateCmdTrb (
IN USB_XHCI_INSTANCE *Xhc,
IN TRB_TEMPLATE *CmdTrb
)
{
- URB *Urb;
+ URB *Urb;
Urb = AllocateZeroPool (sizeof (URB));
if (Urb == NULL) {
return NULL;
}
- Urb->Signature = XHC_URB_SIG;
+ Urb->Signature = XHC_URB_SIG;
- Urb->Ring = &Xhc->CmdRing;
+ Urb->Ring = &Xhc->CmdRing;
XhcSyncTrsRing (Xhc, Urb->Ring);
- Urb->TrbNum = 1;
- Urb->TrbStart = Urb->Ring->RingEnqueue;
+ Urb->TrbNum = 1;
+ Urb->TrbStart = Urb->Ring->RingEnqueue;
CopyMem (Urb->TrbStart, CmdTrb, sizeof (TRB_TEMPLATE));
Urb->TrbStart->CycleBit = Urb->Ring->RingPCS & BIT0;
Urb->TrbEnd = Urb->TrbStart;
@@ -68,14 +64,14 @@ XhcCreateCmdTrb (
EFI_STATUS
EFIAPI
XhcCmdTransfer (
- IN USB_XHCI_INSTANCE *Xhc,
- IN TRB_TEMPLATE *CmdTrb,
- IN UINTN Timeout,
- OUT TRB_TEMPLATE **EvtTrb
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN TRB_TEMPLATE *CmdTrb,
+ IN UINTN Timeout,
+ OUT TRB_TEMPLATE **EvtTrb
)
{
- EFI_STATUS Status;
- URB *Urb;
+ EFI_STATUS Status;
+ URB *Urb;
//
// Validate the parameters
@@ -87,7 +83,7 @@ XhcCmdTransfer (
Status = EFI_DEVICE_ERROR;
if (XhcIsHalt (Xhc) || XhcIsSysError (Xhc)) {
- DEBUG ((EFI_D_ERROR, "XhcCmdTransfer: HC is halted\n"));
+ DEBUG ((DEBUG_ERROR, "XhcCmdTransfer: HC is halted\n"));
goto ON_EXIT;
}
@@ -97,7 +93,7 @@ XhcCmdTransfer (
Urb = XhcCreateCmdTrb (Xhc, CmdTrb);
if (Urb == NULL) {
- DEBUG ((EFI_D_ERROR, "XhcCmdTransfer: failed to create URB\n"));
+ DEBUG ((DEBUG_ERROR, "XhcCmdTransfer: failed to create URB\n"));
Status = EFI_OUT_OF_RESOURCES;
goto ON_EXIT;
}
@@ -133,24 +129,24 @@ ON_EXIT:
@return Created URB or NULL
**/
-URB*
+URB *
XhcCreateUrb (
- IN USB_XHCI_INSTANCE *Xhc,
- IN UINT8 BusAddr,
- IN UINT8 EpAddr,
- IN UINT8 DevSpeed,
- IN UINTN MaxPacket,
- IN UINTN Type,
- IN EFI_USB_DEVICE_REQUEST *Request,
- IN VOID *Data,
- IN UINTN DataLen,
- IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback,
- IN VOID *Context
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN UINT8 BusAddr,
+ IN UINT8 EpAddr,
+ IN UINT8 DevSpeed,
+ IN UINTN MaxPacket,
+ IN UINTN Type,
+ IN EFI_USB_DEVICE_REQUEST *Request,
+ IN VOID *Data,
+ IN UINTN DataLen,
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback,
+ IN VOID *Context
)
{
- USB_ENDPOINT *Ep;
- EFI_STATUS Status;
- URB *Urb;
+ USB_ENDPOINT *Ep;
+ EFI_STATUS Status;
+ URB *Urb;
Urb = AllocateZeroPool (sizeof (URB));
if (Urb == NULL) {
@@ -177,7 +173,7 @@ XhcCreateUrb (
Status = XhcCreateTransferTrb (Xhc, Urb);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "XhcCreateUrb: XhcCreateTransferTrb Failed, Status = %r\n", Status));
+ DEBUG ((DEBUG_ERROR, "XhcCreateUrb: XhcCreateTransferTrb Failed, Status = %r\n", Status));
FreePool (Urb);
Urb = NULL;
}
@@ -194,14 +190,14 @@ XhcCreateUrb (
**/
VOID
XhcFreeUrb (
- IN USB_XHCI_INSTANCE *Xhc,
- IN URB *Urb
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN URB *Urb
)
{
if ((Xhc == NULL) || (Urb == NULL)) {
return;
}
-
+
if (Urb->DataMap != NULL) {
Xhc->PciIo->Unmap (Xhc->PciIo, Urb->DataMap);
}
@@ -220,23 +216,23 @@ XhcFreeUrb (
**/
EFI_STATUS
XhcCreateTransferTrb (
- IN USB_XHCI_INSTANCE *Xhc,
- IN URB *Urb
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN URB *Urb
)
{
- VOID *OutputContext;
- TRANSFER_RING *EPRing;
- UINT8 EPType;
- UINT8 SlotId;
- UINT8 Dci;
- TRB *TrbStart;
- UINTN TotalLen;
- UINTN Len;
- UINTN TrbNum;
- EFI_PCI_IO_PROTOCOL_OPERATION MapOp;
- EFI_PHYSICAL_ADDRESS PhyAddr;
- VOID *Map;
- EFI_STATUS Status;
+ VOID *OutputContext;
+ TRANSFER_RING *EPRing;
+ UINT8 EPType;
+ UINT8 SlotId;
+ UINT8 Dci;
+ TRB *TrbStart;
+ UINTN TotalLen;
+ UINTN Len;
+ UINTN TrbNum;
+ EFI_PCI_IO_PROTOCOL_OPERATION MapOp;
+ EFI_PHYSICAL_ADDRESS PhyAddr;
+ VOID *Map;
+ EFI_STATUS Status;
SlotId = XhcBusDevAddrToSlotId (Xhc, Urb->Ep.BusAddr);
if (SlotId == 0) {
@@ -249,34 +245,37 @@ XhcCreateTransferTrb (
Urb->Completed = 0;
Urb->Result = EFI_USB_NOERROR;
- Dci = XhcEndpointToDci (Urb->Ep.EpAddr, (UINT8)(Urb->Ep.Direction));
+ Dci = XhcEndpointToDci (Urb->Ep.EpAddr, (UINT8)(Urb->Ep.Direction));
ASSERT (Dci < 32);
- EPRing = (TRANSFER_RING *)(UINTN) Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1];
- Urb->Ring = EPRing;
+ EPRing = (TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1];
+ Urb->Ring = EPRing;
OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;
if (Xhc->HcCParams.Data.Csz == 0) {
- EPType = (UINT8) ((DEVICE_CONTEXT *)OutputContext)->EP[Dci-1].EPType;
+ EPType = (UINT8)((DEVICE_CONTEXT *)OutputContext)->EP[Dci-1].EPType;
} else {
- EPType = (UINT8) ((DEVICE_CONTEXT_64 *)OutputContext)->EP[Dci-1].EPType;
+ EPType = (UINT8)((DEVICE_CONTEXT_64 *)OutputContext)->EP[Dci-1].EPType;
}
-
- if (Urb->Data != NULL) {
- if (((UINT8) (Urb->Ep.Direction)) == EfiUsbDataIn) {
+
+ //
+ // No need to remap.
+ //
+ if ((Urb->Data != NULL) && (Urb->DataMap == NULL)) {
+ if (((UINT8)(Urb->Ep.Direction)) == EfiUsbDataIn) {
MapOp = EfiPciIoOperationBusMasterWrite;
} else {
MapOp = EfiPciIoOperationBusMasterRead;
}
-
- Len = Urb->DataLen;
- Status = Xhc->PciIo->Map (Xhc->PciIo, MapOp, Urb->Data, &Len, &PhyAddr, &Map);
-
+
+ Len = Urb->DataLen;
+ Status = Xhc->PciIo->Map (Xhc->PciIo, MapOp, Urb->Data, &Len, &PhyAddr, &Map);
+
if (EFI_ERROR (Status) || (Len != Urb->DataLen)) {
- DEBUG ((EFI_D_ERROR, "XhcCreateTransferTrb: Fail to map Urb->Data.\n"));
+ DEBUG ((DEBUG_ERROR, "XhcCreateTransferTrb: Fail to map Urb->Data.\n"));
return EFI_OUT_OF_RESOURCES;
}
-
- Urb->DataPhy = (VOID *) ((UINTN) PhyAddr);
- Urb->DataMap = Map;
+
+ Urb->DataPhy = (VOID *)((UINTN)PhyAddr);
+ Urb->DataMap = Map;
}
//
@@ -289,7 +288,7 @@ XhcCreateTransferTrb (
//
// For control transfer, create SETUP_STAGE_TRB first.
//
- TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue;
+ TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue;
TrbStart->TrbCtrSetup.bmRequestType = Urb->Request->RequestType;
TrbStart->TrbCtrSetup.bRequest = Urb->Request->Request;
TrbStart->TrbCtrSetup.wValue = Urb->Request->Value;
@@ -300,13 +299,19 @@ XhcCreateTransferTrb (
TrbStart->TrbCtrSetup.IOC = 1;
TrbStart->TrbCtrSetup.IDT = 1;
TrbStart->TrbCtrSetup.Type = TRB_TYPE_SETUP_STAGE;
- if (Urb->Ep.Direction == EfiUsbDataIn) {
- TrbStart->TrbCtrSetup.TRT = 3;
- } else if (Urb->Ep.Direction == EfiUsbDataOut) {
- TrbStart->TrbCtrSetup.TRT = 2;
+ if (Urb->DataLen > 0) {
+ if (Urb->Ep.Direction == EfiUsbDataIn) {
+ TrbStart->TrbCtrSetup.TRT = 3;
+ } else if (Urb->Ep.Direction == EfiUsbDataOut) {
+ TrbStart->TrbCtrSetup.TRT = 2;
+ } else {
+ DEBUG ((DEBUG_ERROR, "XhcCreateTransferTrb: Direction sholud be IN or OUT when Data exists!\n"));
+ ASSERT (FALSE);
+ }
} else {
TrbStart->TrbCtrSetup.TRT = 0;
}
+
//
// Update the cycle bit
//
@@ -318,10 +323,10 @@ XhcCreateTransferTrb (
//
if (Urb->DataLen > 0) {
XhcSyncTrsRing (Xhc, EPRing);
- TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue;
- TrbStart->TrbCtrData.TRBPtrLo = XHC_LOW_32BIT(Urb->DataPhy);
- TrbStart->TrbCtrData.TRBPtrHi = XHC_HIGH_32BIT(Urb->DataPhy);
- TrbStart->TrbCtrData.Length = (UINT32) Urb->DataLen;
+ TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue;
+ TrbStart->TrbCtrData.TRBPtrLo = XHC_LOW_32BIT (Urb->DataPhy);
+ TrbStart->TrbCtrData.TRBPtrHi = XHC_HIGH_32BIT (Urb->DataPhy);
+ TrbStart->TrbCtrData.Length = (UINT32)Urb->DataLen;
TrbStart->TrbCtrData.TDSize = 0;
TrbStart->TrbCtrData.IntTarget = 0;
TrbStart->TrbCtrData.ISP = 1;
@@ -336,18 +341,20 @@ XhcCreateTransferTrb (
} else {
TrbStart->TrbCtrData.DIR = 0;
}
+
//
// Update the cycle bit
//
TrbStart->TrbCtrData.CycleBit = EPRing->RingPCS & BIT0;
Urb->TrbNum++;
}
+
//
// For control transfer, create STATUS_STAGE_TRB.
// Get the pointer to next TRB for status stage use
//
XhcSyncTrsRing (Xhc, EPRing);
- TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue;
+ TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue;
TrbStart->TrbCtrStatus.IntTarget = 0;
TrbStart->TrbCtrStatus.IOC = 1;
TrbStart->TrbCtrStatus.CH = 0;
@@ -359,6 +366,7 @@ XhcCreateTransferTrb (
} else {
TrbStart->TrbCtrStatus.DIR = 0;
}
+
//
// Update the cycle bit
//
@@ -384,10 +392,11 @@ XhcCreateTransferTrb (
} else {
Len = 0x10000;
}
- TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue;
- TrbStart->TrbNormal.TRBPtrLo = XHC_LOW_32BIT((UINT8 *) Urb->DataPhy + TotalLen);
- TrbStart->TrbNormal.TRBPtrHi = XHC_HIGH_32BIT((UINT8 *) Urb->DataPhy + TotalLen);
- TrbStart->TrbNormal.Length = (UINT32) Len;
+
+ TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue;
+ TrbStart->TrbNormal.TRBPtrLo = XHC_LOW_32BIT ((UINT8 *)Urb->DataPhy + TotalLen);
+ TrbStart->TrbNormal.TRBPtrHi = XHC_HIGH_32BIT ((UINT8 *)Urb->DataPhy + TotalLen);
+ TrbStart->TrbNormal.Length = (UINT32)Len;
TrbStart->TrbNormal.TDSize = 0;
TrbStart->TrbNormal.IntTarget = 0;
TrbStart->TrbNormal.ISP = 1;
@@ -419,10 +428,11 @@ XhcCreateTransferTrb (
} else {
Len = 0x10000;
}
- TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue;
- TrbStart->TrbNormal.TRBPtrLo = XHC_LOW_32BIT((UINT8 *) Urb->DataPhy + TotalLen);
- TrbStart->TrbNormal.TRBPtrHi = XHC_HIGH_32BIT((UINT8 *) Urb->DataPhy + TotalLen);
- TrbStart->TrbNormal.Length = (UINT32) Len;
+
+ TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue;
+ TrbStart->TrbNormal.TRBPtrLo = XHC_LOW_32BIT ((UINT8 *)Urb->DataPhy + TotalLen);
+ TrbStart->TrbNormal.TRBPtrHi = XHC_HIGH_32BIT ((UINT8 *)Urb->DataPhy + TotalLen);
+ TrbStart->TrbNormal.Length = (UINT32)Len;
TrbStart->TrbNormal.TDSize = 0;
TrbStart->TrbNormal.IntTarget = 0;
TrbStart->TrbNormal.ISP = 1;
@@ -443,7 +453,7 @@ XhcCreateTransferTrb (
break;
default:
- DEBUG ((EFI_D_INFO, "Not supported EPType 0x%x!\n",EPType));
+ DEBUG ((DEBUG_INFO, "Not supported EPType 0x%x!\n", EPType));
ASSERT (FALSE);
break;
}
@@ -451,7 +461,6 @@ XhcCreateTransferTrb (
return EFI_SUCCESS;
}
-
/**
Initialize the XHCI host controller for schedule.
@@ -460,13 +469,13 @@ XhcCreateTransferTrb (
**/
VOID
XhcInitSched (
- IN USB_XHCI_INSTANCE *Xhc
+ IN USB_XHCI_INSTANCE *Xhc
)
{
VOID *Dcbaa;
EFI_PHYSICAL_ADDRESS DcbaaPhy;
UINT64 CmdRing;
- EFI_PHYSICAL_ADDRESS CmdRingPhy;
+ EFI_PHYSICAL_ADDRESS CmdRingPhy;
UINTN Entries;
UINT32 MaxScratchpadBufs;
UINT64 *ScratchBuf;
@@ -497,8 +506,8 @@ XhcInitSched (
// The Device Context Base Address Array shall contain MaxSlotsEn + 1 entries.
// Software shall set Device Context Base Address Array entries for unallocated Device Slots to '0'.
//
- Entries = (Xhc->MaxSlotsEn + 1) * sizeof(UINT64);
- Dcbaa = UsbHcAllocateMem (Xhc->MemPool, Entries);
+ Entries = (Xhc->MaxSlotsEn + 1) * sizeof (UINT64);
+ Dcbaa = UsbHcAllocateMem (Xhc->MemPool, Entries, FALSE);
ASSERT (Dcbaa != NULL);
ZeroMem (Dcbaa, Entries);
@@ -517,7 +526,7 @@ XhcInitSched (
ScratchEntryMap = AllocateZeroPool (sizeof (UINTN) * MaxScratchpadBufs);
ASSERT (ScratchEntryMap != NULL);
Xhc->ScratchEntryMap = ScratchEntryMap;
-
+
//
// Allocate the buffer to record the host address for each entry
//
@@ -526,14 +535,14 @@ XhcInitSched (
Xhc->ScratchEntry = ScratchEntry;
ScratchPhy = 0;
- Status = UsbHcAllocateAlignedPages (
- Xhc->PciIo,
- EFI_SIZE_TO_PAGES (MaxScratchpadBufs * sizeof (UINT64)),
- Xhc->PageSize,
- (VOID **) &ScratchBuf,
- &ScratchPhy,
- &Xhc->ScratchMap
- );
+ Status = UsbHcAllocateAlignedPages (
+ Xhc->PciIo,
+ EFI_SIZE_TO_PAGES (MaxScratchpadBufs * sizeof (UINT64)),
+ Xhc->PageSize,
+ (VOID **)&ScratchBuf,
+ &ScratchPhy,
+ &Xhc->ScratchMap
+ );
ASSERT_EFI_ERROR (Status);
ZeroMem (ScratchBuf, MaxScratchpadBufs * sizeof (UINT64));
@@ -544,14 +553,14 @@ XhcInitSched (
//
for (Index = 0; Index < MaxScratchpadBufs; Index++) {
ScratchEntryPhy = 0;
- Status = UsbHcAllocateAlignedPages (
- Xhc->PciIo,
- EFI_SIZE_TO_PAGES (Xhc->PageSize),
- Xhc->PageSize,
- (VOID **) &ScratchEntry[Index],
- &ScratchEntryPhy,
- (VOID **) &ScratchEntryMap[Index]
- );
+ Status = UsbHcAllocateAlignedPages (
+ Xhc->PciIo,
+ EFI_SIZE_TO_PAGES (Xhc->PageSize),
+ Xhc->PageSize,
+ (VOID **)&ScratchEntry[Index],
+ &ScratchEntryPhy,
+ (VOID **)&ScratchEntryMap[Index]
+ );
ASSERT_EFI_ERROR (Status);
ZeroMem ((VOID *)(UINTN)ScratchEntry[Index], Xhc->PageSize);
//
@@ -559,11 +568,12 @@ XhcInitSched (
//
*ScratchBuf++ = ScratchEntryPhy;
}
+
//
// The Scratchpad Buffer Array contains pointers to the Scratchpad Buffers. Entry 0 of the
// Device Context Base Address Array points to the Scratchpad Buffer Array.
//
- *(UINT64 *)Dcbaa = (UINT64)(UINTN) ScratchPhy;
+ *(UINT64 *)Dcbaa = (UINT64)(UINTN)ScratchPhy;
}
//
@@ -576,10 +586,10 @@ XhcInitSched (
// So divide it to two 32-bytes width register access.
//
DcbaaPhy = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Dcbaa, Entries);
- XhcWriteOpReg (Xhc, XHC_DCBAAP_OFFSET, XHC_LOW_32BIT(DcbaaPhy));
+ XhcWriteOpReg (Xhc, XHC_DCBAAP_OFFSET, XHC_LOW_32BIT (DcbaaPhy));
XhcWriteOpReg (Xhc, XHC_DCBAAP_OFFSET + 4, XHC_HIGH_32BIT (DcbaaPhy));
- DEBUG ((EFI_D_INFO, "XhcInitSched:DCBAA=0x%x\n", (UINT64)(UINTN)Xhc->DCBAA));
+ DEBUG ((DEBUG_INFO, "XhcInitSched:DCBAA=0x%x\n", (UINT64)(UINTN)Xhc->DCBAA));
//
// Define the Command Ring Dequeue Pointer by programming the Command Ring Control Register
@@ -593,19 +603,17 @@ XhcInitSched (
// Transfer Ring it checks for a Cycle bit transition. If a transition detected, the ring is empty.
// So we set RCS as inverted PCS init value to let Command Ring empty
//
- CmdRing = (UINT64)(UINTN)Xhc->CmdRing.RingSeg0;
- CmdRingPhy = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, (VOID *)(UINTN) CmdRing, sizeof (TRB_TEMPLATE) * CMD_RING_TRB_NUMBER);
+ CmdRing = (UINT64)(UINTN)Xhc->CmdRing.RingSeg0;
+ CmdRingPhy = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, (VOID *)(UINTN)CmdRing, sizeof (TRB_TEMPLATE) * CMD_RING_TRB_NUMBER);
ASSERT ((CmdRingPhy & 0x3F) == 0);
CmdRingPhy |= XHC_CRCR_RCS;
//
// Some 3rd party XHCI external cards don't support single 64-bytes width register access,
// So divide it to two 32-bytes width register access.
//
- XhcWriteOpReg (Xhc, XHC_CRCR_OFFSET, XHC_LOW_32BIT(CmdRingPhy));
+ XhcWriteOpReg (Xhc, XHC_CRCR_OFFSET, XHC_LOW_32BIT (CmdRingPhy));
XhcWriteOpReg (Xhc, XHC_CRCR_OFFSET + 4, XHC_HIGH_32BIT (CmdRingPhy));
- DEBUG ((EFI_D_INFO, "XhcInitSched:XHC_CRCR=0x%x\n", Xhc->CmdRing.RingSeg0));
-
//
// Disable the 'interrupter enable' bit in USB_CMD
// and clear IE & IP bit in all Interrupter X Management Registers.
@@ -620,7 +628,14 @@ XhcInitSched (
// Allocate EventRing for Cmd, Ctrl, Bulk, Interrupt, AsynInterrupt transfer
//
CreateEventRing (Xhc, &Xhc->EventRing);
- DEBUG ((EFI_D_INFO, "XhcInitSched:XHC_EVENTRING=0x%x\n", Xhc->EventRing.EventRingSeg0));
+ DEBUG ((
+ DEBUG_INFO,
+ "XhcInitSched: Created CMD ring [%p~%p) EVENT ring [%p~%p)\n",
+ Xhc->CmdRing.RingSeg0,
+ (UINTN)Xhc->CmdRing.RingSeg0 + sizeof (TRB_TEMPLATE) * CMD_RING_TRB_NUMBER,
+ Xhc->EventRing.EventRingSeg0,
+ (UINTN)Xhc->EventRing.EventRingSeg0 + sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER
+ ));
}
/**
@@ -640,39 +655,40 @@ XhcInitSched (
EFI_STATUS
EFIAPI
XhcRecoverHaltedEndpoint (
- IN USB_XHCI_INSTANCE *Xhc,
- IN URB *Urb
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN URB *Urb
)
{
- EFI_STATUS Status;
- UINT8 Dci;
- UINT8 SlotId;
+ EFI_STATUS Status;
+ UINT8 Dci;
+ UINT8 SlotId;
Status = EFI_SUCCESS;
SlotId = XhcBusDevAddrToSlotId (Xhc, Urb->Ep.BusAddr);
if (SlotId == 0) {
return EFI_DEVICE_ERROR;
}
+
Dci = XhcEndpointToDci (Urb->Ep.EpAddr, (UINT8)(Urb->Ep.Direction));
ASSERT (Dci < 32);
-
- DEBUG ((EFI_D_INFO, "Recovery Halted Slot = %x,Dci = %x\n", SlotId, Dci));
+
+ DEBUG ((DEBUG_INFO, "Recovery Halted Slot = %x,Dci = %x\n", SlotId, Dci));
//
// 1) Send Reset endpoint command to transit from halt to stop state
//
- Status = XhcResetEndpoint(Xhc, SlotId, Dci);
- if (EFI_ERROR(Status)) {
- DEBUG ((EFI_D_ERROR, "XhcRecoverHaltedEndpoint: Reset Endpoint Failed, Status = %r\n", Status));
+ Status = XhcResetEndpoint (Xhc, SlotId, Dci);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "XhcRecoverHaltedEndpoint: Reset Endpoint Failed, Status = %r\n", Status));
goto Done;
}
//
// 2)Set dequeue pointer
//
- Status = XhcSetTrDequeuePointer(Xhc, SlotId, Dci, Urb);
- if (EFI_ERROR(Status)) {
- DEBUG ((EFI_D_ERROR, "XhcRecoverHaltedEndpoint: Set Transfer Ring Dequeue Pointer Failed, Status = %r\n", Status));
+ Status = XhcSetTrDequeuePointer (Xhc, SlotId, Dci, Urb);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "XhcRecoverHaltedEndpoint: Set Transfer Ring Dequeue Pointer Failed, Status = %r\n", Status));
goto Done;
}
@@ -695,46 +711,58 @@ Done:
@param Urb The urb which doesn't get completed in a specified timeout range.
@retval EFI_SUCCESS The dequeuing of the TDs is successful.
+ @retval EFI_ALREADY_STARTED The Urb is finished so no deque is needed.
@retval Others Failed to stop the endpoint and dequeue the TDs.
**/
EFI_STATUS
EFIAPI
XhcDequeueTrbFromEndpoint (
- IN USB_XHCI_INSTANCE *Xhc,
- IN URB *Urb
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN URB *Urb
)
{
- EFI_STATUS Status;
- UINT8 Dci;
- UINT8 SlotId;
+ EFI_STATUS Status;
+ UINT8 Dci;
+ UINT8 SlotId;
Status = EFI_SUCCESS;
SlotId = XhcBusDevAddrToSlotId (Xhc, Urb->Ep.BusAddr);
if (SlotId == 0) {
return EFI_DEVICE_ERROR;
}
+
Dci = XhcEndpointToDci (Urb->Ep.EpAddr, (UINT8)(Urb->Ep.Direction));
ASSERT (Dci < 32);
-
- DEBUG ((EFI_D_INFO, "Stop Slot = %x,Dci = %x\n", SlotId, Dci));
+
+ DEBUG ((DEBUG_VERBOSE, "Stop Slot = %x,Dci = %x\n", SlotId, Dci));
//
// 1) Send Stop endpoint command to stop xHC from executing of the TDs on the endpoint
//
- Status = XhcStopEndpoint(Xhc, SlotId, Dci);
- if (EFI_ERROR(Status)) {
- DEBUG ((EFI_D_ERROR, "XhcDequeueTrbFromEndpoint: Stop Endpoint Failed, Status = %r\n", Status));
+ Status = XhcStopEndpoint (Xhc, SlotId, Dci, Urb);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "XhcDequeueTrbFromEndpoint: Stop Endpoint Failed, Status = %r\n", Status));
goto Done;
}
//
// 2)Set dequeue pointer
//
- Status = XhcSetTrDequeuePointer(Xhc, SlotId, Dci, Urb);
- if (EFI_ERROR(Status)) {
- DEBUG ((EFI_D_ERROR, "XhcDequeueTrbFromEndpoint: Set Transfer Ring Dequeue Pointer Failed, Status = %r\n", Status));
- goto Done;
+ if (Urb->Finished && (Urb->Result == EFI_USB_NOERROR)) {
+ //
+ // Return Already Started to indicate the pending URB is finished.
+ // This fixes BULK data loss when transfer is detected as timeout
+ // but finished just before stopping endpoint.
+ //
+ Status = EFI_ALREADY_STARTED;
+ DEBUG ((DEBUG_INFO, "XhcDequeueTrbFromEndpoint: Pending URB is finished: Length Actual/Expect = %d/%d!\n", Urb->Completed, Urb->DataLen));
+ } else {
+ Status = XhcSetTrDequeuePointer (Xhc, SlotId, Dci, Urb);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "XhcDequeueTrbFromEndpoint: Set Transfer Ring Dequeue Pointer Failed, Status = %r\n", Status));
+ goto Done;
+ }
}
//
@@ -755,8 +783,8 @@ Done:
**/
VOID
CreateEventRing (
- IN USB_XHCI_INSTANCE *Xhc,
- OUT EVENT_RING *EventRing
+ IN USB_XHCI_INSTANCE *Xhc,
+ OUT EVENT_RING *EventRing
)
{
VOID *Buf;
@@ -768,18 +796,18 @@ CreateEventRing (
ASSERT (EventRing != NULL);
Size = sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER;
- Buf = UsbHcAllocateMem (Xhc->MemPool, Size);
+ Buf = UsbHcAllocateMem (Xhc->MemPool, Size, TRUE);
ASSERT (Buf != NULL);
- ASSERT (((UINTN) Buf & 0x3F) == 0);
+ ASSERT (((UINTN)Buf & 0x3F) == 0);
ZeroMem (Buf, Size);
EventRing->EventRingSeg0 = Buf;
EventRing->TrbNumber = EVENT_RING_TRB_NUMBER;
- EventRing->EventRingDequeue = (TRB_TEMPLATE *) EventRing->EventRingSeg0;
- EventRing->EventRingEnqueue = (TRB_TEMPLATE *) EventRing->EventRingSeg0;
-
+ EventRing->EventRingDequeue = (TRB_TEMPLATE *)EventRing->EventRingSeg0;
+ EventRing->EventRingEnqueue = (TRB_TEMPLATE *)EventRing->EventRingSeg0;
+
DequeuePhy = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Buf, Size);
-
+
//
// Software maintains an Event Ring Consumer Cycle State (CCS) bit, initializing it to '1'
// and toggling it every time the Event Ring Dequeue Pointer wraps back to the beginning of the Event Ring.
@@ -787,12 +815,12 @@ CreateEventRing (
EventRing->EventRingCCS = 1;
Size = sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER;
- Buf = UsbHcAllocateMem (Xhc->MemPool, Size);
+ Buf = UsbHcAllocateMem (Xhc->MemPool, Size, FALSE);
ASSERT (Buf != NULL);
- ASSERT (((UINTN) Buf & 0x3F) == 0);
+ ASSERT (((UINTN)Buf & 0x3F) == 0);
ZeroMem (Buf, Size);
- ERSTBase = (EVENT_RING_SEG_TABLE_ENTRY *) Buf;
+ ERSTBase = (EVENT_RING_SEG_TABLE_ENTRY *)Buf;
EventRing->ERSTBase = ERSTBase;
ERSTBase->PtrLo = XHC_LOW_32BIT (DequeuePhy);
ERSTBase->PtrHi = XHC_HIGH_32BIT (DequeuePhy);
@@ -817,12 +845,12 @@ CreateEventRing (
XhcWriteRuntimeReg (
Xhc,
XHC_ERDP_OFFSET,
- XHC_LOW_32BIT((UINT64)(UINTN)DequeuePhy)
+ XHC_LOW_32BIT ((UINT64)(UINTN)DequeuePhy)
);
XhcWriteRuntimeReg (
Xhc,
XHC_ERDP_OFFSET + 4,
- XHC_HIGH_32BIT((UINT64)(UINTN)DequeuePhy)
+ XHC_HIGH_32BIT ((UINT64)(UINTN)DequeuePhy)
);
//
// Program the Interrupter Event Ring Segment Table Base Address (ERSTBA) register(5.5.2.3.2)
@@ -833,12 +861,12 @@ CreateEventRing (
XhcWriteRuntimeReg (
Xhc,
XHC_ERSTBA_OFFSET,
- XHC_LOW_32BIT((UINT64)(UINTN)ERSTPhy)
+ XHC_LOW_32BIT ((UINT64)(UINTN)ERSTPhy)
);
XhcWriteRuntimeReg (
Xhc,
XHC_ERSTBA_OFFSET + 4,
- XHC_HIGH_32BIT((UINT64)(UINTN)ERSTPhy)
+ XHC_HIGH_32BIT ((UINT64)(UINTN)ERSTPhy)
);
//
// Need set IMAN IE bit to enble the ring interrupt
@@ -856,39 +884,39 @@ CreateEventRing (
**/
VOID
CreateTransferRing (
- IN USB_XHCI_INSTANCE *Xhc,
- IN UINTN TrbNum,
- OUT TRANSFER_RING *TransferRing
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN UINTN TrbNum,
+ OUT TRANSFER_RING *TransferRing
)
{
VOID *Buf;
LINK_TRB *EndTrb;
EFI_PHYSICAL_ADDRESS PhyAddr;
- Buf = UsbHcAllocateMem (Xhc->MemPool, sizeof (TRB_TEMPLATE) * TrbNum);
+ Buf = UsbHcAllocateMem (Xhc->MemPool, sizeof (TRB_TEMPLATE) * TrbNum, TRUE);
ASSERT (Buf != NULL);
- ASSERT (((UINTN) Buf & 0x3F) == 0);
+ ASSERT (((UINTN)Buf & 0x3F) == 0);
ZeroMem (Buf, sizeof (TRB_TEMPLATE) * TrbNum);
- TransferRing->RingSeg0 = Buf;
- TransferRing->TrbNumber = TrbNum;
- TransferRing->RingEnqueue = (TRB_TEMPLATE *) TransferRing->RingSeg0;
- TransferRing->RingDequeue = (TRB_TEMPLATE *) TransferRing->RingSeg0;
- TransferRing->RingPCS = 1;
+ TransferRing->RingSeg0 = Buf;
+ TransferRing->TrbNumber = TrbNum;
+ TransferRing->RingEnqueue = (TRB_TEMPLATE *)TransferRing->RingSeg0;
+ TransferRing->RingDequeue = (TRB_TEMPLATE *)TransferRing->RingSeg0;
+ TransferRing->RingPCS = 1;
//
// 4.9.2 Transfer Ring Management
// To form a ring (or circular queue) a Link TRB may be inserted at the end of a ring to
// point to the first TRB in the ring.
//
- EndTrb = (LINK_TRB *) ((UINTN)Buf + sizeof (TRB_TEMPLATE) * (TrbNum - 1));
+ EndTrb = (LINK_TRB *)((UINTN)Buf + sizeof (TRB_TEMPLATE) * (TrbNum - 1));
EndTrb->Type = TRB_TYPE_LINK;
- PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Buf, sizeof (TRB_TEMPLATE) * TrbNum);
+ PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Buf, sizeof (TRB_TEMPLATE) * TrbNum);
EndTrb->PtrLo = XHC_LOW_32BIT (PhyAddr);
EndTrb->PtrHi = XHC_HIGH_32BIT (PhyAddr);
//
// Toggle Cycle (TC). When set to '1', the xHC shall toggle its interpretation of the Cycle bit.
//
- EndTrb->TC = 1;
+ EndTrb->TC = 1;
//
// Set Cycle bit as other TRB PCS init value
//
@@ -905,11 +933,11 @@ CreateTransferRing (
EFI_STATUS
EFIAPI
XhcFreeEventRing (
- IN USB_XHCI_INSTANCE *Xhc,
- IN EVENT_RING *EventRing
-)
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN EVENT_RING *EventRing
+ )
{
- if(EventRing->EventRingSeg0 == NULL) {
+ if (EventRing->EventRingSeg0 == NULL) {
return EFI_SUCCESS;
}
@@ -933,20 +961,21 @@ XhcFreeEventRing (
**/
VOID
XhcFreeSched (
- IN USB_XHCI_INSTANCE *Xhc
+ IN USB_XHCI_INSTANCE *Xhc
)
{
- UINT32 Index;
- UINT64 *ScratchEntry;
-
+ UINT32 Index;
+ UINT64 *ScratchEntry;
+
if (Xhc->ScratchBuf != NULL) {
ScratchEntry = Xhc->ScratchEntry;
for (Index = 0; Index < Xhc->MaxScratchpadBufs; Index++) {
//
// Free Scratchpad Buffers
//
- UsbHcFreeAlignedPages (Xhc->PciIo, (VOID*)(UINTN)ScratchEntry[Index], EFI_SIZE_TO_PAGES (Xhc->PageSize), (VOID *) Xhc->ScratchEntryMap[Index]);
+ UsbHcFreeAlignedPages (Xhc->PciIo, (VOID *)(UINTN)ScratchEntry[Index], EFI_SIZE_TO_PAGES (Xhc->PageSize), (VOID *)Xhc->ScratchEntryMap[Index]);
}
+
//
// Free Scratchpad Buffer Array
//
@@ -959,14 +988,14 @@ XhcFreeSched (
UsbHcFreeMem (Xhc->MemPool, Xhc->CmdRing.RingSeg0, sizeof (TRB_TEMPLATE) * CMD_RING_TRB_NUMBER);
Xhc->CmdRing.RingSeg0 = NULL;
}
-
- XhcFreeEventRing (Xhc,&Xhc->EventRing);
+
+ XhcFreeEventRing (Xhc, &Xhc->EventRing);
if (Xhc->DCBAA != NULL) {
- UsbHcFreeMem (Xhc->MemPool, Xhc->DCBAA, (Xhc->MaxSlotsEn + 1) * sizeof(UINT64));
+ UsbHcFreeMem (Xhc->MemPool, Xhc->DCBAA, (Xhc->MaxSlotsEn + 1) * sizeof (UINT64));
Xhc->DCBAA = NULL;
}
-
+
//
// Free memory pool at last
//
@@ -977,45 +1006,44 @@ XhcFreeSched (
}
/**
- Check if the Trb is a transaction of the URBs in XHCI's asynchronous transfer list.
+ Check if the Trb is a transaction of the URB.
@param Xhc The XHCI Instance.
- @param Trb The TRB to be checked.
- @param Urb The pointer to the matched Urb.
+ @param Trb The TRB to be checked
+ @param Urb The URB to be checked.
- @retval TRUE The Trb is matched with a transaction of the URBs in the async list.
- @retval FALSE The Trb is not matched with any URBs in the async list.
+ @retval TRUE It is a transaction of the URB.
+ @retval FALSE It is not any transaction of the URB.
**/
BOOLEAN
-IsAsyncIntTrb (
- IN USB_XHCI_INSTANCE *Xhc,
- IN TRB_TEMPLATE *Trb,
- OUT URB **Urb
+IsTransferRingTrb (
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN TRB_TEMPLATE *Trb,
+ IN URB *Urb
)
{
- LIST_ENTRY *Entry;
- LIST_ENTRY *Next;
- TRB_TEMPLATE *CheckedTrb;
- URB *CheckedUrb;
- UINTN Index;
+ LINK_TRB *LinkTrb;
+ TRB_TEMPLATE *CheckedTrb;
+ UINTN Index;
+ EFI_PHYSICAL_ADDRESS PhyAddr;
- EFI_LIST_FOR_EACH_SAFE (Entry, Next, &Xhc->AsyncIntTransfers) {
- CheckedUrb = EFI_LIST_CONTAINER (Entry, URB, UrbList);
- CheckedTrb = CheckedUrb->TrbStart;
- for (Index = 0; Index < CheckedUrb->TrbNum; Index++) {
- if (Trb == CheckedTrb) {
- *Urb = CheckedUrb;
- return TRUE;
- }
- CheckedTrb++;
- //
- // If the checked TRB is the link TRB at the end of the transfer ring,
- // recircle it to the head of the ring.
- //
- if (CheckedTrb->Type == TRB_TYPE_LINK) {
- CheckedTrb = (TRB_TEMPLATE*) CheckedUrb->Ring->RingSeg0;
- }
+ CheckedTrb = Urb->TrbStart;
+ for (Index = 0; Index < Urb->TrbNum; Index++) {
+ if (Trb == CheckedTrb) {
+ return TRUE;
+ }
+
+ CheckedTrb++;
+ //
+ // If the checked TRB is the link TRB at the end of the transfer ring,
+ // recircle it to the head of the ring.
+ //
+ if (CheckedTrb->Type == TRB_TYPE_LINK) {
+ LinkTrb = (LINK_TRB *)CheckedTrb;
+ PhyAddr = (EFI_PHYSICAL_ADDRESS)(LinkTrb->PtrLo | LShiftU64 ((UINT64)LinkTrb->PtrHi, 32));
+ CheckedTrb = (TRB_TEMPLATE *)(UINTN)UsbHcGetHostAddrForPciAddr (Xhc->MemPool, (VOID *)(UINTN)PhyAddr, sizeof (TRB_TEMPLATE));
+ ASSERT (CheckedTrb == Urb->Ring->RingSeg0);
}
}
@@ -1023,33 +1051,33 @@ IsAsyncIntTrb (
}
/**
- Check if the Trb is a transaction of the URB.
+ Check if the Trb is a transaction of the URBs in XHCI's asynchronous transfer list.
- @param Trb The TRB to be checked
- @param Urb The transfer ring to be checked.
+ @param Xhc The XHCI Instance.
+ @param Trb The TRB to be checked.
+ @param Urb The pointer to the matched Urb.
- @retval TRUE It is a transaction of the URB.
- @retval FALSE It is not any transaction of the URB.
+ @retval TRUE The Trb is matched with a transaction of the URBs in the async list.
+ @retval FALSE The Trb is not matched with any URBs in the async list.
**/
BOOLEAN
-IsTransferRingTrb (
- IN TRB_TEMPLATE *Trb,
- IN URB *Urb
+IsAsyncIntTrb (
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN TRB_TEMPLATE *Trb,
+ OUT URB **Urb
)
{
- TRB_TEMPLATE *CheckedTrb;
- UINTN Index;
+ LIST_ENTRY *Entry;
+ LIST_ENTRY *Next;
+ URB *CheckedUrb;
- CheckedTrb = Urb->Ring->RingSeg0;
-
- ASSERT (Urb->Ring->TrbNumber == CMD_RING_TRB_NUMBER || Urb->Ring->TrbNumber == TR_RING_TRB_NUMBER);
-
- for (Index = 0; Index < Urb->Ring->TrbNumber; Index++) {
- if (Trb == CheckedTrb) {
+ BASE_LIST_FOR_EACH_SAFE (Entry, Next, &Xhc->AsyncIntTransfers) {
+ CheckedUrb = EFI_LIST_CONTAINER (Entry, URB, UrbList);
+ if (IsTransferRingTrb (Xhc, Trb, CheckedUrb)) {
+ *Urb = CheckedUrb;
return TRUE;
}
- CheckedTrb++;
}
return FALSE;
@@ -1067,21 +1095,21 @@ IsTransferRingTrb (
**/
BOOLEAN
XhcCheckUrbResult (
- IN USB_XHCI_INSTANCE *Xhc,
- IN URB *Urb
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN URB *Urb
)
{
- EVT_TRB_TRANSFER *EvtTrb;
- TRB_TEMPLATE *TRBPtr;
- UINTN Index;
- UINT8 TRBType;
- EFI_STATUS Status;
- URB *AsyncUrb;
- URB *CheckedUrb;
- UINT64 XhcDequeue;
- UINT32 High;
- UINT32 Low;
- EFI_PHYSICAL_ADDRESS PhyAddr;
+ EVT_TRB_TRANSFER *EvtTrb;
+ TRB_TEMPLATE *TRBPtr;
+ UINTN Index;
+ UINT8 TRBType;
+ EFI_STATUS Status;
+ URB *AsyncUrb;
+ URB *CheckedUrb;
+ UINT64 XhcDequeue;
+ UINT32 High;
+ UINT32 Low;
+ EFI_PHYSICAL_ADDRESS PhyAddr;
ASSERT ((Xhc != NULL) && (Urb != NULL));
@@ -1118,69 +1146,82 @@ XhcCheckUrbResult (
if ((EvtTrb->Type != TRB_TYPE_COMMAND_COMPLT_EVENT) && (EvtTrb->Type != TRB_TYPE_TRANS_EVENT)) {
continue;
}
-
+
//
// Need convert pci device address to host address
//
- PhyAddr = (EFI_PHYSICAL_ADDRESS)(EvtTrb->TRBPtrLo | LShiftU64 ((UINT64) EvtTrb->TRBPtrHi, 32));
- TRBPtr = (TRB_TEMPLATE *)(UINTN) UsbHcGetHostAddrForPciAddr (Xhc->MemPool, (VOID *)(UINTN) PhyAddr, sizeof (TRB_TEMPLATE));
+ PhyAddr = (EFI_PHYSICAL_ADDRESS)(EvtTrb->TRBPtrLo | LShiftU64 ((UINT64)EvtTrb->TRBPtrHi, 32));
+ TRBPtr = (TRB_TEMPLATE *)(UINTN)UsbHcGetHostAddrForPciAddr (Xhc->MemPool, (VOID *)(UINTN)PhyAddr, sizeof (TRB_TEMPLATE));
//
- // Update the status of Urb according to the finished event regardless of whether
- // the urb is current checked one or in the XHCI's async transfer list.
+ // Update the status of URB including the pending URB, the URB that is currently checked,
+ // and URBs in the XHCI's async interrupt transfer list.
// This way is used to avoid that those completed async transfer events don't get
// handled in time and are flushed by newer coming events.
//
- if (IsTransferRingTrb (TRBPtr, Urb)) {
+ if ((Xhc->PendingUrb != NULL) && IsTransferRingTrb (Xhc, TRBPtr, Xhc->PendingUrb)) {
+ CheckedUrb = Xhc->PendingUrb;
+ } else if (IsTransferRingTrb (Xhc, TRBPtr, Urb)) {
CheckedUrb = Urb;
- } else if (IsAsyncIntTrb (Xhc, TRBPtr, &AsyncUrb)) {
+ } else if (IsAsyncIntTrb (Xhc, TRBPtr, &AsyncUrb)) {
CheckedUrb = AsyncUrb;
} else {
continue;
}
-
+
switch (EvtTrb->Completecode) {
case TRB_COMPLETION_STALL_ERROR:
CheckedUrb->Result |= EFI_USB_ERR_STALL;
CheckedUrb->Finished = TRUE;
- DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: STALL_ERROR! Completecode = %x\n",EvtTrb->Completecode));
+ DEBUG ((DEBUG_ERROR, "XhcCheckUrbResult: STALL_ERROR! Completecode = %x\n", EvtTrb->Completecode));
goto EXIT;
case TRB_COMPLETION_BABBLE_ERROR:
CheckedUrb->Result |= EFI_USB_ERR_BABBLE;
CheckedUrb->Finished = TRUE;
- DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: BABBLE_ERROR! Completecode = %x\n",EvtTrb->Completecode));
+ DEBUG ((DEBUG_ERROR, "XhcCheckUrbResult: BABBLE_ERROR! Completecode = %x\n", EvtTrb->Completecode));
goto EXIT;
case TRB_COMPLETION_DATA_BUFFER_ERROR:
CheckedUrb->Result |= EFI_USB_ERR_BUFFER;
CheckedUrb->Finished = TRUE;
- DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: ERR_BUFFER! Completecode = %x\n",EvtTrb->Completecode));
+ DEBUG ((DEBUG_ERROR, "XhcCheckUrbResult: ERR_BUFFER! Completecode = %x\n", EvtTrb->Completecode));
goto EXIT;
case TRB_COMPLETION_USB_TRANSACTION_ERROR:
CheckedUrb->Result |= EFI_USB_ERR_TIMEOUT;
CheckedUrb->Finished = TRUE;
- DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: TRANSACTION_ERROR! Completecode = %x\n",EvtTrb->Completecode));
+ DEBUG ((DEBUG_ERROR, "XhcCheckUrbResult: TRANSACTION_ERROR! Completecode = %x\n", EvtTrb->Completecode));
goto EXIT;
+ case TRB_COMPLETION_STOPPED:
+ case TRB_COMPLETION_STOPPED_LENGTH_INVALID:
+ CheckedUrb->Result |= EFI_USB_ERR_TIMEOUT;
+ CheckedUrb->Finished = TRUE;
+ //
+ // The pending URB is timeout and force stopped when stopping endpoint.
+ // Continue the loop to receive the Command Complete Event for stopping endpoint.
+ //
+ continue;
+
case TRB_COMPLETION_SHORT_PACKET:
case TRB_COMPLETION_SUCCESS:
if (EvtTrb->Completecode == TRB_COMPLETION_SHORT_PACKET) {
- DEBUG ((EFI_D_VERBOSE, "XhcCheckUrbResult: short packet happens!\n"));
+ DEBUG ((DEBUG_VERBOSE, "XhcCheckUrbResult: short packet happens!\n"));
}
- TRBType = (UINT8) (TRBPtr->Type);
+ TRBType = (UINT8)(TRBPtr->Type);
if ((TRBType == TRB_TYPE_DATA_STAGE) ||
(TRBType == TRB_TYPE_NORMAL) ||
- (TRBType == TRB_TYPE_ISOCH)) {
- CheckedUrb->Completed += (((TRANSFER_TRB_NORMAL*)TRBPtr)->Length - EvtTrb->Length);
+ (TRBType == TRB_TYPE_ISOCH))
+ {
+ CheckedUrb->Completed += (((TRANSFER_TRB_NORMAL *)TRBPtr)->Length - EvtTrb->Length);
}
break;
default:
- DEBUG ((EFI_D_ERROR, "Transfer Default Error Occur! Completecode = 0x%x!\n",EvtTrb->Completecode));
+ DEBUG ((DEBUG_ERROR, "Transfer Default Error Occur! Completecode = 0x%x!\n", EvtTrb->Completecode));
CheckedUrb->Result |= EFI_USB_ERR_TIMEOUT;
CheckedUrb->Finished = TRUE;
goto EXIT;
@@ -1211,9 +1252,9 @@ EXIT:
// Some 3rd party XHCI external cards don't support single 64-bytes width register access,
// So divide it to two 32-bytes width register access.
//
- Low = XhcReadRuntimeReg (Xhc, XHC_ERDP_OFFSET);
- High = XhcReadRuntimeReg (Xhc, XHC_ERDP_OFFSET + 4);
- XhcDequeue = (UINT64)(LShiftU64((UINT64)High, 32) | Low);
+ Low = XhcReadRuntimeReg (Xhc, XHC_ERDP_OFFSET);
+ High = XhcReadRuntimeReg (Xhc, XHC_ERDP_OFFSET + 4);
+ XhcDequeue = (UINT64)(LShiftU64 ((UINT64)High, 32) | Low);
PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Xhc->EventRing.EventRingDequeue, sizeof (TRB_TEMPLATE));
@@ -1229,34 +1270,39 @@ EXIT:
return Urb->Finished;
}
-
/**
Execute the transfer by polling the URB. This is a synchronous operation.
- @param Xhc The XHCI Instance.
- @param CmdTransfer The executed URB is for cmd transfer or not.
- @param Urb The URB to execute.
- @param Timeout The time to wait before abort, in millisecond.
+ @param Xhc The XHCI Instance.
+ @param CmdTransfer The executed URB is for cmd transfer or not.
+ @param Urb The URB to execute.
+ @param Timeout The time to wait before abort, in millisecond.
- @return EFI_DEVICE_ERROR The transfer failed due to transfer error.
- @return EFI_TIMEOUT The transfer failed due to time out.
- @return EFI_SUCCESS The transfer finished OK.
+ @return EFI_DEVICE_ERROR The transfer failed due to transfer error.
+ @return EFI_TIMEOUT The transfer failed due to time out.
+ @return EFI_SUCCESS The transfer finished OK.
+ @retval EFI_OUT_OF_RESOURCES Memory for the timer event could not be allocated.
**/
EFI_STATUS
XhcExecTransfer (
- IN USB_XHCI_INSTANCE *Xhc,
- IN BOOLEAN CmdTransfer,
- IN URB *Urb,
- IN UINTN Timeout
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN BOOLEAN CmdTransfer,
+ IN URB *Urb,
+ IN UINTN Timeout
)
{
- EFI_STATUS Status;
- UINTN Index;
- UINT64 Loop;
- UINT8 SlotId;
- UINT8 Dci;
- BOOLEAN Finished;
+ EFI_STATUS Status;
+ UINT8 SlotId;
+ UINT8 Dci;
+ BOOLEAN Finished;
+ EFI_EVENT TimeoutEvent;
+ BOOLEAN IndefiniteTimeout;
+
+ Status = EFI_SUCCESS;
+ Finished = FALSE;
+ TimeoutEvent = NULL;
+ IndefiniteTimeout = FALSE;
if (CmdTransfer) {
SlotId = 0;
@@ -1266,31 +1312,62 @@ XhcExecTransfer (
if (SlotId == 0) {
return EFI_DEVICE_ERROR;
}
- Dci = XhcEndpointToDci (Urb->Ep.EpAddr, (UINT8)(Urb->Ep.Direction));
+
+ Dci = XhcEndpointToDci (Urb->Ep.EpAddr, (UINT8)(Urb->Ep.Direction));
ASSERT (Dci < 32);
}
- Status = EFI_SUCCESS;
- Loop = Timeout * XHC_1_MILLISECOND;
if (Timeout == 0) {
- Loop = 0xFFFFFFFF;
+ IndefiniteTimeout = TRUE;
+ goto RINGDOORBELL;
}
+ Status = gBS->CreateEvent (
+ EVT_TIMER,
+ TPL_CALLBACK,
+ NULL,
+ NULL,
+ &TimeoutEvent
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto DONE;
+ }
+
+ Status = gBS->SetTimer (
+ TimeoutEvent,
+ TimerRelative,
+ EFI_TIMER_PERIOD_MILLISECONDS (Timeout)
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto DONE;
+ }
+
+RINGDOORBELL:
XhcRingDoorBell (Xhc, SlotId, Dci);
- for (Index = 0; Index < Loop; Index++) {
+ do {
Finished = XhcCheckUrbResult (Xhc, Urb);
if (Finished) {
break;
}
+
gBS->Stall (XHC_1_MICROSECOND);
- }
+ } while (IndefiniteTimeout || EFI_ERROR (gBS->CheckEvent (TimeoutEvent)));
- if (Index == Loop) {
+DONE:
+ if (EFI_ERROR (Status)) {
+ Urb->Result = EFI_USB_ERR_NOTEXECUTE;
+ } else if (!Finished) {
Urb->Result = EFI_USB_ERR_TIMEOUT;
Status = EFI_TIMEOUT;
} else if (Urb->Result != EFI_USB_NOERROR) {
- Status = EFI_DEVICE_ERROR;
+ Status = EFI_DEVICE_ERROR;
+ }
+
+ if (TimeoutEvent != NULL) {
+ gBS->CloseEvent (TimeoutEvent);
}
return Status;
@@ -1310,26 +1387,37 @@ XhcExecTransfer (
**/
EFI_STATUS
XhciDelAsyncIntTransfer (
- IN USB_XHCI_INSTANCE *Xhc,
- IN UINT8 BusAddr,
- IN UINT8 EpNum
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN UINT8 BusAddr,
+ IN UINT8 EpNum
)
{
LIST_ENTRY *Entry;
LIST_ENTRY *Next;
URB *Urb;
EFI_USB_DATA_DIRECTION Direction;
+ EFI_STATUS Status;
Direction = ((EpNum & 0x80) != 0) ? EfiUsbDataIn : EfiUsbDataOut;
EpNum &= 0x0F;
Urb = NULL;
- EFI_LIST_FOR_EACH_SAFE (Entry, Next, &Xhc->AsyncIntTransfers) {
+ BASE_LIST_FOR_EACH_SAFE (Entry, Next, &Xhc->AsyncIntTransfers) {
Urb = EFI_LIST_CONTAINER (Entry, URB, UrbList);
if ((Urb->Ep.BusAddr == BusAddr) &&
(Urb->Ep.EpAddr == EpNum) &&
- (Urb->Ep.Direction == Direction)) {
+ (Urb->Ep.Direction == Direction))
+ {
+ //
+ // Device doesn't finish the IntTransfer until real data comes
+ // So the TRB should be removed as well.
+ //
+ Status = XhcDequeueTrbFromEndpoint (Xhc, Urb);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "XhciDelAsyncIntTransfer: XhcDequeueTrbFromEndpoint failed\n"));
+ }
+
RemoveEntryList (&Urb->UrbList);
FreePool (Urb->Data);
XhcFreeUrb (Xhc, Urb);
@@ -1348,21 +1436,97 @@ XhciDelAsyncIntTransfer (
**/
VOID
XhciDelAllAsyncIntTransfers (
- IN USB_XHCI_INSTANCE *Xhc
+ IN USB_XHCI_INSTANCE *Xhc
)
{
- LIST_ENTRY *Entry;
- LIST_ENTRY *Next;
- URB *Urb;
+ LIST_ENTRY *Entry;
+ LIST_ENTRY *Next;
+ URB *Urb;
+ EFI_STATUS Status;
- EFI_LIST_FOR_EACH_SAFE (Entry, Next, &Xhc->AsyncIntTransfers) {
+ BASE_LIST_FOR_EACH_SAFE (Entry, Next, &Xhc->AsyncIntTransfers) {
Urb = EFI_LIST_CONTAINER (Entry, URB, UrbList);
+
+ //
+ // Device doesn't finish the IntTransfer until real data comes
+ // So the TRB should be removed as well.
+ //
+ Status = XhcDequeueTrbFromEndpoint (Xhc, Urb);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "XhciDelAllAsyncIntTransfers: XhcDequeueTrbFromEndpoint failed\n"));
+ }
+
RemoveEntryList (&Urb->UrbList);
FreePool (Urb->Data);
XhcFreeUrb (Xhc, Urb);
}
}
+/**
+ Insert a single asynchronous interrupt transfer for
+ the device and endpoint.
+
+ @param Xhc The XHCI Instance
+ @param BusAddr The logical device address assigned by UsbBus driver
+ @param EpAddr Endpoint addrress
+ @param DevSpeed The device speed
+ @param MaxPacket The max packet length of the endpoint
+ @param DataLen The length of data buffer
+ @param Callback The function to call when data is transferred
+ @param Context The context to the callback
+
+ @return Created URB or NULL
+
+**/
+URB *
+XhciInsertAsyncIntTransfer (
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN UINT8 BusAddr,
+ IN UINT8 EpAddr,
+ IN UINT8 DevSpeed,
+ IN UINTN MaxPacket,
+ IN UINTN DataLen,
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback,
+ IN VOID *Context
+ )
+{
+ VOID *Data;
+ URB *Urb;
+
+ Data = AllocateZeroPool (DataLen);
+ if (Data == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: failed to allocate buffer\n", __FUNCTION__));
+ return NULL;
+ }
+
+ Urb = XhcCreateUrb (
+ Xhc,
+ BusAddr,
+ EpAddr,
+ DevSpeed,
+ MaxPacket,
+ XHC_INT_TRANSFER_ASYNC,
+ NULL,
+ Data,
+ DataLen,
+ Callback,
+ Context
+ );
+ if (Urb == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: failed to create URB\n", __FUNCTION__));
+ FreePool (Data);
+ return NULL;
+ }
+
+ //
+ // New asynchronous transfer must inserted to the head.
+ // Check the comments in XhcMoniteAsyncRequests
+ //
+ InsertHeadList (&Xhc->AsyncIntTransfers, &Urb->UrbList);
+
+ return Urb;
+}
+
/**
Update the queue head for next round of asynchronous transfer
@@ -1372,17 +1536,18 @@ XhciDelAllAsyncIntTransfers (
**/
VOID
XhcUpdateAsyncRequest (
- IN USB_XHCI_INSTANCE *Xhc,
- IN URB *Urb
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN URB *Urb
)
{
- EFI_STATUS Status;
+ EFI_STATUS Status;
if (Urb->Result == EFI_USB_NOERROR) {
Status = XhcCreateTransferTrb (Xhc, Urb);
if (EFI_ERROR (Status)) {
return;
}
+
Status = RingIntTransferDoorBell (Xhc, Urb);
if (EFI_ERROR (Status)) {
return;
@@ -1403,16 +1568,16 @@ XhcUpdateAsyncRequest (
**/
EFI_STATUS
XhcFlushAsyncIntMap (
- IN USB_XHCI_INSTANCE *Xhc,
- IN URB *Urb
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN URB *Urb
)
{
- EFI_STATUS Status;
- EFI_PHYSICAL_ADDRESS PhyAddr;
- EFI_PCI_IO_PROTOCOL_OPERATION MapOp;
- EFI_PCI_IO_PROTOCOL *PciIo;
- UINTN Len;
- VOID *Map;
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS PhyAddr;
+ EFI_PCI_IO_PROTOCOL_OPERATION MapOp;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINTN Len;
+ VOID *Map;
PciIo = Xhc->PciIo;
Len = Urb->DataLen;
@@ -1437,8 +1602,8 @@ XhcFlushAsyncIntMap (
goto ON_ERROR;
}
- Urb->DataPhy = (VOID *) ((UINTN) PhyAddr);
- Urb->DataMap = Map;
+ Urb->DataPhy = (VOID *)((UINTN)PhyAddr);
+ Urb->DataMap = Map;
return EFI_SUCCESS;
ON_ERROR:
@@ -1455,24 +1620,24 @@ ON_ERROR:
VOID
EFIAPI
XhcMonitorAsyncRequests (
- IN EFI_EVENT Event,
- IN VOID *Context
+ IN EFI_EVENT Event,
+ IN VOID *Context
)
{
- USB_XHCI_INSTANCE *Xhc;
- LIST_ENTRY *Entry;
- LIST_ENTRY *Next;
- UINT8 *ProcBuf;
- URB *Urb;
- UINT8 SlotId;
- EFI_STATUS Status;
- EFI_TPL OldTpl;
+ USB_XHCI_INSTANCE *Xhc;
+ LIST_ENTRY *Entry;
+ LIST_ENTRY *Next;
+ UINT8 *ProcBuf;
+ URB *Urb;
+ UINT8 SlotId;
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
OldTpl = gBS->RaiseTPL (XHC_TPL);
- Xhc = (USB_XHCI_INSTANCE*) Context;
+ Xhc = (USB_XHCI_INSTANCE *)Context;
- EFI_LIST_FOR_EACH_SAFE (Entry, Next, &Xhc->AsyncIntTransfers) {
+ BASE_LIST_FOR_EACH_SAFE (Entry, Next, &Xhc->AsyncIntTransfers) {
Urb = EFI_LIST_CONTAINER (Entry, URB, UrbList);
//
@@ -1499,7 +1664,7 @@ XhcMonitorAsyncRequests (
//
Status = XhcFlushAsyncIntMap (Xhc, Urb);
if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "XhcMonitorAsyncRequests: Fail to Flush AsyncInt Mapped Memeory\n"));
+ DEBUG ((DEBUG_ERROR, "XhcMonitorAsyncRequests: Fail to Flush AsyncInt Mapped Memeory\n"));
}
//
@@ -1509,9 +1674,12 @@ XhcMonitorAsyncRequests (
//
ProcBuf = NULL;
if (Urb->Result == EFI_USB_NOERROR) {
- ASSERT (Urb->Completed <= Urb->DataLen);
-
- ProcBuf = AllocateZeroPool (Urb->Completed);
+ //
+ // Make sure the data received from HW is no more than expected.
+ //
+ if (Urb->Completed <= Urb->DataLen) {
+ ProcBuf = AllocateZeroPool (Urb->Completed);
+ }
if (ProcBuf == NULL) {
XhcUpdateAsyncRequest (Xhc, Urb);
@@ -1537,7 +1705,7 @@ XhcMonitorAsyncRequests (
// his callback. Some drivers may has a lower TPL restriction.
//
gBS->RestoreTPL (OldTpl);
- (Urb->Callback) (ProcBuf, Urb->Completed, Urb->Context, Urb->Result);
+ (Urb->Callback)(ProcBuf, Urb->Completed, Urb->Context, Urb->Result);
OldTpl = gBS->RaiseTPL (XHC_TPL);
}
@@ -1565,18 +1733,20 @@ XhcMonitorAsyncRequests (
EFI_STATUS
EFIAPI
XhcPollPortStatusChange (
- IN USB_XHCI_INSTANCE *Xhc,
- IN USB_DEV_ROUTE ParentRouteChart,
- IN UINT8 Port,
- IN EFI_USB_PORT_STATUS *PortState
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN USB_DEV_ROUTE ParentRouteChart,
+ IN UINT8 Port,
+ IN EFI_USB_PORT_STATUS *PortState
)
{
- EFI_STATUS Status;
- UINT8 Speed;
- UINT8 SlotId;
- USB_DEV_ROUTE RouteChart;
+ EFI_STATUS Status;
+ UINT8 Speed;
+ UINT8 SlotId;
+ UINT8 Retries;
+ USB_DEV_ROUTE RouteChart;
- Status = EFI_SUCCESS;
+ Status = EFI_SUCCESS;
+ Retries = XHC_INIT_DEVICE_SLOT_RETRIES;
if ((PortState->PortChangeStatus & (USB_PORT_STAT_C_CONNECTION | USB_PORT_STAT_C_ENABLE | USB_PORT_STAT_C_OVERCURRENT | USB_PORT_STAT_C_RESET)) == 0) {
return EFI_SUCCESS;
@@ -1587,13 +1757,14 @@ XhcPollPortStatusChange (
RouteChart.Route.RootPortNum = Port + 1;
RouteChart.Route.TierNum = 1;
} else {
- if(Port < 14) {
+ if (Port < 14) {
RouteChart.Route.RouteString = ParentRouteChart.Route.RouteString | (Port << (4 * (ParentRouteChart.Route.TierNum - 1)));
} else {
RouteChart.Route.RouteString = ParentRouteChart.Route.RouteString | (15 << (4 * (ParentRouteChart.Route.TierNum - 1)));
}
- RouteChart.Route.RootPortNum = ParentRouteChart.Route.RootPortNum;
- RouteChart.Route.TierNum = ParentRouteChart.Route.TierNum + 1;
+
+ RouteChart.Route.RootPortNum = ParentRouteChart.Route.RootPortNum;
+ RouteChart.Route.TierNum = ParentRouteChart.Route.TierNum + 1;
}
SlotId = XhcRouteStringToSlotId (Xhc, RouteChart);
@@ -1606,7 +1777,8 @@ XhcPollPortStatusChange (
}
if (((PortState->PortStatus & USB_PORT_STAT_ENABLE) != 0) &&
- ((PortState->PortStatus & USB_PORT_STAT_CONNECTION) != 0)) {
+ ((PortState->PortStatus & USB_PORT_STAT_CONNECTION) != 0))
+ {
//
// Has a device attached, Identify device speed after port is enabled.
//
@@ -1618,23 +1790,34 @@ XhcPollPortStatusChange (
} else if ((PortState->PortStatus & USB_PORT_STAT_SUPER_SPEED) != 0) {
Speed = EFI_USB_SPEED_SUPER;
}
- //
- // Execute Enable_Slot cmd for attached device, initialize device context and assign device address.
- //
- SlotId = XhcRouteStringToSlotId (Xhc, RouteChart);
- if ((SlotId == 0) && ((PortState->PortChangeStatus & USB_PORT_STAT_C_RESET) != 0)) {
- if (Xhc->HcCParams.Data.Csz == 0) {
- Status = XhcInitializeDeviceSlot (Xhc, ParentRouteChart, Port, RouteChart, Speed);
- } else {
- Status = XhcInitializeDeviceSlot64 (Xhc, ParentRouteChart, Port, RouteChart, Speed);
+
+ do {
+ //
+ // Execute Enable_Slot cmd for attached device, initialize device context and assign device address.
+ //
+ SlotId = XhcRouteStringToSlotId (Xhc, RouteChart);
+ if ((SlotId == 0) && ((PortState->PortChangeStatus & USB_PORT_STAT_C_RESET) != 0)) {
+ if (Xhc->HcCParams.Data.Csz == 0) {
+ Status = XhcInitializeDeviceSlot (Xhc, ParentRouteChart, Port, RouteChart, Speed);
+ } else {
+ Status = XhcInitializeDeviceSlot64 (Xhc, ParentRouteChart, Port, RouteChart, Speed);
+ }
}
- }
- }
+
+ //
+ // According to the xHCI specification (section 4.6.5), "a USB Transaction
+ // Error Completion Code for an Address Device Command may be due to a Stall
+ // response from a device. Software should issue a Disable Slot Command for
+ // the Device Slot then an Enable Slot Command to recover from this error."
+ // Therefore, retry the device slot initialization if it fails due to a
+ // device error.
+ //
+ } while ((Status == EFI_DEVICE_ERROR) && (Retries-- != 0));
+ }
return Status;
}
-
/**
Calculate the device context index by endpoint address and direction.
@@ -1646,19 +1829,20 @@ XhcPollPortStatusChange (
**/
UINT8
XhcEndpointToDci (
- IN UINT8 EpAddr,
- IN UINT8 Direction
+ IN UINT8 EpAddr,
+ IN UINT8 Direction
)
{
- UINT8 Index;
+ UINT8 Index;
if (EpAddr == 0) {
return 1;
} else {
- Index = (UINT8) (2 * EpAddr);
+ Index = (UINT8)(2 * EpAddr);
if (Direction == EfiUsbDataIn) {
Index += 1;
}
+
return Index;
}
}
@@ -1684,7 +1868,8 @@ XhcBusDevAddrToSlotId (
for (Index = 0; Index < 255; Index++) {
if (Xhc->UsbDevContext[Index + 1].Enabled &&
(Xhc->UsbDevContext[Index + 1].SlotId != 0) &&
- (Xhc->UsbDevContext[Index + 1].BusDevAddr == BusDevAddr)) {
+ (Xhc->UsbDevContext[Index + 1].BusDevAddr == BusDevAddr))
+ {
break;
}
}
@@ -1717,7 +1902,8 @@ XhcRouteStringToSlotId (
for (Index = 0; Index < 255; Index++) {
if (Xhc->UsbDevContext[Index + 1].Enabled &&
(Xhc->UsbDevContext[Index + 1].SlotId != 0) &&
- (Xhc->UsbDevContext[Index + 1].RouteString.Dword == RouteString.Dword)) {
+ (Xhc->UsbDevContext[Index + 1].RouteString.Dword == RouteString.Dword))
+ {
break;
}
}
@@ -1741,12 +1927,12 @@ XhcRouteStringToSlotId (
EFI_STATUS
EFIAPI
XhcSyncEventRing (
- IN USB_XHCI_INSTANCE *Xhc,
- IN EVENT_RING *EvtRing
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN EVENT_RING *EvtRing
)
{
- UINTN Index;
- TRB_TEMPLATE *EvtTrb1;
+ UINTN Index;
+ TRB_TEMPLATE *EvtTrb1;
ASSERT (EvtRing != NULL);
@@ -1763,8 +1949,8 @@ XhcSyncEventRing (
EvtTrb1++;
- if ((UINTN)EvtTrb1 >= ((UINTN) EvtRing->EventRingSeg0 + sizeof (TRB_TEMPLATE) * EvtRing->TrbNumber)) {
- EvtTrb1 = EvtRing->EventRingSeg0;
+ if ((UINTN)EvtTrb1 >= ((UINTN)EvtRing->EventRingSeg0 + sizeof (TRB_TEMPLATE) * EvtRing->TrbNumber)) {
+ EvtTrb1 = EvtRing->EventRingSeg0;
EvtRing->EventRingCCS = (EvtRing->EventRingCCS) ? 0 : 1;
}
}
@@ -1790,12 +1976,12 @@ XhcSyncEventRing (
EFI_STATUS
EFIAPI
XhcSyncTrsRing (
- IN USB_XHCI_INSTANCE *Xhc,
- IN TRANSFER_RING *TrsRing
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN TRANSFER_RING *TrsRing
)
{
- UINTN Index;
- TRB_TEMPLATE *TrsTrb;
+ UINTN Index;
+ TRB_TEMPLATE *TrsTrb;
ASSERT (TrsRing != NULL);
//
@@ -1808,18 +1994,19 @@ XhcSyncTrsRing (
if (TrsTrb->CycleBit != (TrsRing->RingPCS & BIT0)) {
break;
}
+
TrsTrb++;
- if ((UINT8) TrsTrb->Type == TRB_TYPE_LINK) {
- ASSERT (((LINK_TRB*)TrsTrb)->TC != 0);
+ if ((UINT8)TrsTrb->Type == TRB_TYPE_LINK) {
+ ASSERT (((LINK_TRB *)TrsTrb)->TC != 0);
//
// set cycle bit in Link TRB as normal
//
- ((LINK_TRB*)TrsTrb)->CycleBit = TrsRing->RingPCS & BIT0;
+ ((LINK_TRB *)TrsTrb)->CycleBit = TrsRing->RingPCS & BIT0;
//
// Toggle PCS maintained by software
//
TrsRing->RingPCS = (TrsRing->RingPCS & BIT0) ? 0 : 1;
- TrsTrb = (TRB_TEMPLATE *) TrsRing->RingSeg0; // Use host address
+ TrsTrb = (TRB_TEMPLATE *)TrsRing->RingSeg0; // Use host address
}
}
@@ -1856,9 +2043,9 @@ XhcSyncTrsRing (
EFI_STATUS
EFIAPI
XhcCheckNewEvent (
- IN USB_XHCI_INSTANCE *Xhc,
- IN EVENT_RING *EvtRing,
- OUT TRB_TEMPLATE **NewEvtTrb
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN EVENT_RING *EvtRing,
+ OUT TRB_TEMPLATE **NewEvtTrb
)
{
ASSERT (EvtRing != NULL);
@@ -1873,7 +2060,7 @@ XhcCheckNewEvent (
//
// If the dequeue pointer is beyond the ring, then roll-back it to the begining of the ring.
//
- if ((UINTN)EvtRing->EventRingDequeue >= ((UINTN) EvtRing->EventRingSeg0 + sizeof (TRB_TEMPLATE) * EvtRing->TrbNumber)) {
+ if ((UINTN)EvtRing->EventRingDequeue >= ((UINTN)EvtRing->EventRingSeg0 + sizeof (TRB_TEMPLATE) * EvtRing->TrbNumber)) {
EvtRing->EventRingDequeue = EvtRing->EventRingSeg0;
}
@@ -1893,9 +2080,9 @@ XhcCheckNewEvent (
EFI_STATUS
EFIAPI
XhcRingDoorBell (
- IN USB_XHCI_INSTANCE *Xhc,
- IN UINT8 SlotId,
- IN UINT8 Dci
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN UINT8 SlotId,
+ IN UINT8 Dci
)
{
if (SlotId == 0) {
@@ -1918,12 +2105,12 @@ XhcRingDoorBell (
**/
EFI_STATUS
RingIntTransferDoorBell (
- IN USB_XHCI_INSTANCE *Xhc,
- IN URB *Urb
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN URB *Urb
)
{
- UINT8 SlotId;
- UINT8 Dci;
+ UINT8 SlotId;
+ UINT8 Dci;
SlotId = XhcBusDevAddrToSlotId (Xhc, Urb->Ep.BusAddr);
Dci = XhcEndpointToDci (Urb->Ep.EpAddr, (UINT8)(Urb->Ep.Direction));
@@ -1946,11 +2133,11 @@ RingIntTransferDoorBell (
EFI_STATUS
EFIAPI
XhcInitializeDeviceSlot (
- IN USB_XHCI_INSTANCE *Xhc,
- IN USB_DEV_ROUTE ParentRouteChart,
- IN UINT16 ParentPort,
- IN USB_DEV_ROUTE RouteChart,
- IN UINT8 DeviceSpeed
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN USB_DEV_ROUTE ParentRouteChart,
+ IN UINT16 ParentPort,
+ IN USB_DEV_ROUTE RouteChart,
+ IN UINT8 DeviceSpeed
)
{
EFI_STATUS Status;
@@ -1971,17 +2158,18 @@ XhcInitializeDeviceSlot (
CmdTrb.Type = TRB_TYPE_EN_SLOT;
Status = XhcCmdTransfer (
- Xhc,
- (TRB_TEMPLATE *) (UINTN) &CmdTrb,
- XHC_GENERIC_TIMEOUT,
- (TRB_TEMPLATE **) (UINTN) &EvtTrb
- );
+ Xhc,
+ (TRB_TEMPLATE *)(UINTN)&CmdTrb,
+ XHC_GENERIC_TIMEOUT,
+ (TRB_TEMPLATE **)(UINTN)&EvtTrb
+ );
if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "XhcInitializeDeviceSlot: Enable Slot Failed, Status = %r\n", Status));
+ DEBUG ((DEBUG_ERROR, "XhcInitializeDeviceSlot: Enable Slot Failed, Status = %r\n", Status));
return Status;
}
+
ASSERT (EvtTrb->SlotId <= Xhc->MaxSlotsEn);
- DEBUG ((EFI_D_INFO, "Enable Slot Successfully, The Slot ID = 0x%x\n", EvtTrb->SlotId));
+ DEBUG ((DEBUG_INFO, "Enable Slot Successfully, The Slot ID = 0x%x\n", EvtTrb->SlotId));
SlotId = (UINT8)EvtTrb->SlotId;
ASSERT (SlotId != 0);
@@ -1995,12 +2183,12 @@ XhcInitializeDeviceSlot (
// 4.3.3 Device Slot Initialization
// 1) Allocate an Input Context data structure (6.2.5) and initialize all fields to '0'.
//
- InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT));
+ InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT), FALSE);
ASSERT (InputContext != NULL);
- ASSERT (((UINTN) InputContext & 0x3F) == 0);
+ ASSERT (((UINTN)InputContext & 0x3F) == 0);
ZeroMem (InputContext, sizeof (INPUT_CONTEXT));
- Xhc->UsbDevContext[SlotId].InputContext = (VOID *) InputContext;
+ Xhc->UsbDevContext[SlotId].InputContext = (VOID *)InputContext;
//
// 2) Initialize the Input Control Context (6.2.5.1) of the Input Context by setting the A0 and A1
@@ -2021,14 +2209,15 @@ XhcInitializeDeviceSlot (
//
// The device is behind of hub device.
//
- ParentSlotId = XhcRouteStringToSlotId(Xhc, ParentRouteChart);
+ ParentSlotId = XhcRouteStringToSlotId (Xhc, ParentRouteChart);
ASSERT (ParentSlotId != 0);
//
- //if the Full/Low device attached to a High Speed Hub, Init the TTPortNum and TTHubSlotId field of slot context
+ // if the Full/Low device attached to a High Speed Hub, Init the TTPortNum and TTHubSlotId field of slot context
//
ParentDeviceContext = (DEVICE_CONTEXT *)Xhc->UsbDevContext[ParentSlotId].OutputContext;
if ((ParentDeviceContext->Slot.TTPortNum == 0) &&
- (ParentDeviceContext->Slot.TTHubSlotId == 0)) {
+ (ParentDeviceContext->Slot.TTHubSlotId == 0))
+ {
if ((ParentDeviceContext->Slot.Speed == (EFI_USB_SPEED_HIGH + 1)) && (DeviceSpeed < EFI_USB_SPEED_HIGH)) {
//
// Full/Low device attached to High speed hub port that isolates the high speed signaling
@@ -2055,9 +2244,9 @@ XhcInitializeDeviceSlot (
//
// 4) Allocate and initialize the Transfer Ring for the Default Control Endpoint.
//
- EndpointTransferRing = AllocateZeroPool (sizeof (TRANSFER_RING));
+ EndpointTransferRing = AllocateZeroPool (sizeof (TRANSFER_RING));
Xhc->UsbDevContext[SlotId].EndpointTransferRing[0] = EndpointTransferRing;
- CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[0]);
+ CreateTransferRing (Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[0]);
//
// 5) Initialize the Input default control Endpoint 0 Context (6.2.3).
//
@@ -2070,6 +2259,7 @@ XhcInitializeDeviceSlot (
} else {
InputContext->EP[0].MaxPacketSize = 8;
}
+
//
// Initial value of Average TRB Length for Control endpoints would be 8B, Interrupt endpoints
// 1KB, and Bulk and Isoch endpoints 3KB.
@@ -2095,9 +2285,9 @@ XhcInitializeDeviceSlot (
//
// 6) Allocate the Output Device Context data structure (6.2.1) and initialize it to '0'.
//
- OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT));
+ OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT), FALSE);
ASSERT (OutputContext != NULL);
- ASSERT (((UINTN) OutputContext & 0x3F) == 0);
+ ASSERT (((UINTN)OutputContext & 0x3F) == 0);
ZeroMem (OutputContext, sizeof (DEVICE_CONTEXT));
Xhc->UsbDevContext[SlotId].OutputContext = OutputContext;
@@ -2109,7 +2299,7 @@ XhcInitializeDeviceSlot (
//
// Fill DCBAA with PCI device address
//
- Xhc->DCBAA[SlotId] = (UINT64) (UINTN) PhyAddr;
+ Xhc->DCBAA[SlotId] = (UINT64)(UINTN)PhyAddr;
//
// 8) Issue an Address Device Command for the Device Slot, where the command points to the Input
@@ -2120,22 +2310,25 @@ XhcInitializeDeviceSlot (
//
gBS->Stall (XHC_RESET_RECOVERY_DELAY);
ZeroMem (&CmdTrbAddr, sizeof (CmdTrbAddr));
- PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Xhc->UsbDevContext[SlotId].InputContext, sizeof (INPUT_CONTEXT));
+ PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Xhc->UsbDevContext[SlotId].InputContext, sizeof (INPUT_CONTEXT));
CmdTrbAddr.PtrLo = XHC_LOW_32BIT (PhyAddr);
CmdTrbAddr.PtrHi = XHC_HIGH_32BIT (PhyAddr);
CmdTrbAddr.CycleBit = 1;
CmdTrbAddr.Type = TRB_TYPE_ADDRESS_DEV;
CmdTrbAddr.SlotId = Xhc->UsbDevContext[SlotId].SlotId;
- Status = XhcCmdTransfer (
- Xhc,
- (TRB_TEMPLATE *) (UINTN) &CmdTrbAddr,
- XHC_GENERIC_TIMEOUT,
- (TRB_TEMPLATE **) (UINTN) &EvtTrb
- );
+ Status = XhcCmdTransfer (
+ Xhc,
+ (TRB_TEMPLATE *)(UINTN)&CmdTrbAddr,
+ XHC_GENERIC_TIMEOUT,
+ (TRB_TEMPLATE **)(UINTN)&EvtTrb
+ );
if (!EFI_ERROR (Status)) {
- DeviceAddress = (UINT8) ((DEVICE_CONTEXT *) OutputContext)->Slot.DeviceAddress;
- DEBUG ((EFI_D_INFO, " Address %d assigned successfully\n", DeviceAddress));
+ DeviceAddress = (UINT8)((DEVICE_CONTEXT *)OutputContext)->Slot.DeviceAddress;
+ DEBUG ((DEBUG_INFO, " Address %d assigned successfully\n", DeviceAddress));
Xhc->UsbDevContext[SlotId].XhciDevAddr = DeviceAddress;
+ } else {
+ DEBUG ((DEBUG_ERROR, " Slot %d address not assigned successfully. Status = %r\n", SlotId, Status));
+ XhcDisableSlotCmd (Xhc, SlotId);
}
return Status;
@@ -2156,11 +2349,11 @@ XhcInitializeDeviceSlot (
EFI_STATUS
EFIAPI
XhcInitializeDeviceSlot64 (
- IN USB_XHCI_INSTANCE *Xhc,
- IN USB_DEV_ROUTE ParentRouteChart,
- IN UINT16 ParentPort,
- IN USB_DEV_ROUTE RouteChart,
- IN UINT8 DeviceSpeed
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN USB_DEV_ROUTE ParentRouteChart,
+ IN UINT16 ParentPort,
+ IN USB_DEV_ROUTE RouteChart,
+ IN UINT8 DeviceSpeed
)
{
EFI_STATUS Status;
@@ -2181,17 +2374,18 @@ XhcInitializeDeviceSlot64 (
CmdTrb.Type = TRB_TYPE_EN_SLOT;
Status = XhcCmdTransfer (
- Xhc,
- (TRB_TEMPLATE *) (UINTN) &CmdTrb,
- XHC_GENERIC_TIMEOUT,
- (TRB_TEMPLATE **) (UINTN) &EvtTrb
- );
+ Xhc,
+ (TRB_TEMPLATE *)(UINTN)&CmdTrb,
+ XHC_GENERIC_TIMEOUT,
+ (TRB_TEMPLATE **)(UINTN)&EvtTrb
+ );
if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "XhcInitializeDeviceSlot64: Enable Slot Failed, Status = %r\n", Status));
+ DEBUG ((DEBUG_ERROR, "XhcInitializeDeviceSlot64: Enable Slot Failed, Status = %r\n", Status));
return Status;
}
+
ASSERT (EvtTrb->SlotId <= Xhc->MaxSlotsEn);
- DEBUG ((EFI_D_INFO, "Enable Slot Successfully, The Slot ID = 0x%x\n", EvtTrb->SlotId));
+ DEBUG ((DEBUG_INFO, "Enable Slot Successfully, The Slot ID = 0x%x\n", EvtTrb->SlotId));
SlotId = (UINT8)EvtTrb->SlotId;
ASSERT (SlotId != 0);
@@ -2205,12 +2399,12 @@ XhcInitializeDeviceSlot64 (
// 4.3.3 Device Slot Initialization
// 1) Allocate an Input Context data structure (6.2.5) and initialize all fields to '0'.
//
- InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT_64));
+ InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT_64), FALSE);
ASSERT (InputContext != NULL);
- ASSERT (((UINTN) InputContext & 0x3F) == 0);
+ ASSERT (((UINTN)InputContext & 0x3F) == 0);
ZeroMem (InputContext, sizeof (INPUT_CONTEXT_64));
- Xhc->UsbDevContext[SlotId].InputContext = (VOID *) InputContext;
+ Xhc->UsbDevContext[SlotId].InputContext = (VOID *)InputContext;
//
// 2) Initialize the Input Control Context (6.2.5.1) of the Input Context by setting the A0 and A1
@@ -2231,14 +2425,15 @@ XhcInitializeDeviceSlot64 (
//
// The device is behind of hub device.
//
- ParentSlotId = XhcRouteStringToSlotId(Xhc, ParentRouteChart);
+ ParentSlotId = XhcRouteStringToSlotId (Xhc, ParentRouteChart);
ASSERT (ParentSlotId != 0);
//
- //if the Full/Low device attached to a High Speed Hub, Init the TTPortNum and TTHubSlotId field of slot context
+ // if the Full/Low device attached to a High Speed Hub, Init the TTPortNum and TTHubSlotId field of slot context
//
ParentDeviceContext = (DEVICE_CONTEXT_64 *)Xhc->UsbDevContext[ParentSlotId].OutputContext;
if ((ParentDeviceContext->Slot.TTPortNum == 0) &&
- (ParentDeviceContext->Slot.TTHubSlotId == 0)) {
+ (ParentDeviceContext->Slot.TTHubSlotId == 0))
+ {
if ((ParentDeviceContext->Slot.Speed == (EFI_USB_SPEED_HIGH + 1)) && (DeviceSpeed < EFI_USB_SPEED_HIGH)) {
//
// Full/Low device attached to High speed hub port that isolates the high speed signaling
@@ -2265,9 +2460,9 @@ XhcInitializeDeviceSlot64 (
//
// 4) Allocate and initialize the Transfer Ring for the Default Control Endpoint.
//
- EndpointTransferRing = AllocateZeroPool (sizeof (TRANSFER_RING));
+ EndpointTransferRing = AllocateZeroPool (sizeof (TRANSFER_RING));
Xhc->UsbDevContext[SlotId].EndpointTransferRing[0] = EndpointTransferRing;
- CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[0]);
+ CreateTransferRing (Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[0]);
//
// 5) Initialize the Input default control Endpoint 0 Context (6.2.3).
//
@@ -2280,6 +2475,7 @@ XhcInitializeDeviceSlot64 (
} else {
InputContext->EP[0].MaxPacketSize = 8;
}
+
//
// Initial value of Average TRB Length for Control endpoints would be 8B, Interrupt endpoints
// 1KB, and Bulk and Isoch endpoints 3KB.
@@ -2305,9 +2501,9 @@ XhcInitializeDeviceSlot64 (
//
// 6) Allocate the Output Device Context data structure (6.2.1) and initialize it to '0'.
//
- OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT_64));
+ OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT_64), FALSE);
ASSERT (OutputContext != NULL);
- ASSERT (((UINTN) OutputContext & 0x3F) == 0);
+ ASSERT (((UINTN)OutputContext & 0x3F) == 0);
ZeroMem (OutputContext, sizeof (DEVICE_CONTEXT_64));
Xhc->UsbDevContext[SlotId].OutputContext = OutputContext;
@@ -2319,7 +2515,7 @@ XhcInitializeDeviceSlot64 (
//
// Fill DCBAA with PCI device address
//
- Xhc->DCBAA[SlotId] = (UINT64) (UINTN) PhyAddr;
+ Xhc->DCBAA[SlotId] = (UINT64)(UINTN)PhyAddr;
//
// 8) Issue an Address Device Command for the Device Slot, where the command points to the Input
@@ -2330,27 +2526,30 @@ XhcInitializeDeviceSlot64 (
//
gBS->Stall (XHC_RESET_RECOVERY_DELAY);
ZeroMem (&CmdTrbAddr, sizeof (CmdTrbAddr));
- PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Xhc->UsbDevContext[SlotId].InputContext, sizeof (INPUT_CONTEXT_64));
+ PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Xhc->UsbDevContext[SlotId].InputContext, sizeof (INPUT_CONTEXT_64));
CmdTrbAddr.PtrLo = XHC_LOW_32BIT (PhyAddr);
CmdTrbAddr.PtrHi = XHC_HIGH_32BIT (PhyAddr);
CmdTrbAddr.CycleBit = 1;
CmdTrbAddr.Type = TRB_TYPE_ADDRESS_DEV;
CmdTrbAddr.SlotId = Xhc->UsbDevContext[SlotId].SlotId;
- Status = XhcCmdTransfer (
- Xhc,
- (TRB_TEMPLATE *) (UINTN) &CmdTrbAddr,
- XHC_GENERIC_TIMEOUT,
- (TRB_TEMPLATE **) (UINTN) &EvtTrb
- );
+ Status = XhcCmdTransfer (
+ Xhc,
+ (TRB_TEMPLATE *)(UINTN)&CmdTrbAddr,
+ XHC_GENERIC_TIMEOUT,
+ (TRB_TEMPLATE **)(UINTN)&EvtTrb
+ );
if (!EFI_ERROR (Status)) {
- DeviceAddress = (UINT8) ((DEVICE_CONTEXT_64 *) OutputContext)->Slot.DeviceAddress;
- DEBUG ((EFI_D_INFO, " Address %d assigned successfully\n", DeviceAddress));
+ DeviceAddress = (UINT8)((DEVICE_CONTEXT_64 *)OutputContext)->Slot.DeviceAddress;
+ DEBUG ((DEBUG_INFO, " Address %d assigned successfully\n", DeviceAddress));
Xhc->UsbDevContext[SlotId].XhciDevAddr = DeviceAddress;
+ } else {
+ DEBUG ((DEBUG_ERROR, " Slot %d address not assigned successfully. Status = %r\n", SlotId, Status));
+ XhcDisableSlotCmd64 (Xhc, SlotId);
}
+
return Status;
}
-
/**
Disable the specified device slot.
@@ -2363,8 +2562,8 @@ XhcInitializeDeviceSlot64 (
EFI_STATUS
EFIAPI
XhcDisableSlotCmd (
- IN USB_XHCI_INSTANCE *Xhc,
- IN UINT8 SlotId
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN UINT8 SlotId
)
{
EFI_STATUS Status;
@@ -2380,14 +2579,15 @@ XhcDisableSlotCmd (
for (Index = 0; Index < 255; Index++) {
if (!Xhc->UsbDevContext[Index + 1].Enabled ||
(Xhc->UsbDevContext[Index + 1].SlotId == 0) ||
- (Xhc->UsbDevContext[Index + 1].ParentRouteString.Dword != Xhc->UsbDevContext[SlotId].RouteString.Dword)) {
+ (Xhc->UsbDevContext[Index + 1].ParentRouteString.Dword != Xhc->UsbDevContext[SlotId].RouteString.Dword))
+ {
continue;
}
Status = XhcDisableSlotCmd (Xhc, Xhc->UsbDevContext[Index + 1].SlotId);
if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "XhcDisableSlotCmd: failed to disable child, ignore error\n"));
+ DEBUG ((DEBUG_ERROR, "XhcDisableSlotCmd: failed to disable child, ignore error\n"));
Xhc->UsbDevContext[Index + 1].SlotId = 0;
}
}
@@ -2395,22 +2595,23 @@ XhcDisableSlotCmd (
//
// Construct the disable slot command
//
- DEBUG ((EFI_D_INFO, "Disable device slot %d!\n", SlotId));
+ DEBUG ((DEBUG_INFO, "Disable device slot %d!\n", SlotId));
ZeroMem (&CmdTrbDisSlot, sizeof (CmdTrbDisSlot));
CmdTrbDisSlot.CycleBit = 1;
CmdTrbDisSlot.Type = TRB_TYPE_DIS_SLOT;
CmdTrbDisSlot.SlotId = SlotId;
- Status = XhcCmdTransfer (
- Xhc,
- (TRB_TEMPLATE *) (UINTN) &CmdTrbDisSlot,
- XHC_GENERIC_TIMEOUT,
- (TRB_TEMPLATE **) (UINTN) &EvtTrb
- );
+ Status = XhcCmdTransfer (
+ Xhc,
+ (TRB_TEMPLATE *)(UINTN)&CmdTrbDisSlot,
+ XHC_GENERIC_TIMEOUT,
+ (TRB_TEMPLATE **)(UINTN)&EvtTrb
+ );
if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "XhcDisableSlotCmd: Disable Slot Command Failed, Status = %r\n", Status));
+ DEBUG ((DEBUG_ERROR, "XhcDisableSlotCmd: Disable Slot Command Failed, Status = %r\n", Status));
return Status;
}
+
//
// Free the slot's device context entry
//
@@ -2425,6 +2626,7 @@ XhcDisableSlotCmd (
if (RingSeg != NULL) {
UsbHcFreeMem (Xhc->MemPool, RingSeg, sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER);
}
+
FreePool (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index]);
Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index] = NULL;
}
@@ -2447,6 +2649,7 @@ XhcDisableSlotCmd (
if (Xhc->UsbDevContext[SlotId].OutputContext != NULL) {
UsbHcFreeMem (Xhc->MemPool, Xhc->UsbDevContext[SlotId].OutputContext, sizeof (DEVICE_CONTEXT));
}
+
//
// Doesn't zero the entry because XhcAsyncInterruptTransfer() may be invoked to remove the established
// asynchronous interrupt pipe after the device is disabled. It needs the device address mapping info to
@@ -2470,8 +2673,8 @@ XhcDisableSlotCmd (
EFI_STATUS
EFIAPI
XhcDisableSlotCmd64 (
- IN USB_XHCI_INSTANCE *Xhc,
- IN UINT8 SlotId
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN UINT8 SlotId
)
{
EFI_STATUS Status;
@@ -2487,14 +2690,15 @@ XhcDisableSlotCmd64 (
for (Index = 0; Index < 255; Index++) {
if (!Xhc->UsbDevContext[Index + 1].Enabled ||
(Xhc->UsbDevContext[Index + 1].SlotId == 0) ||
- (Xhc->UsbDevContext[Index + 1].ParentRouteString.Dword != Xhc->UsbDevContext[SlotId].RouteString.Dword)) {
+ (Xhc->UsbDevContext[Index + 1].ParentRouteString.Dword != Xhc->UsbDevContext[SlotId].RouteString.Dword))
+ {
continue;
}
Status = XhcDisableSlotCmd64 (Xhc, Xhc->UsbDevContext[Index + 1].SlotId);
if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "XhcDisableSlotCmd: failed to disable child, ignore error\n"));
+ DEBUG ((DEBUG_ERROR, "XhcDisableSlotCmd: failed to disable child, ignore error\n"));
Xhc->UsbDevContext[Index + 1].SlotId = 0;
}
}
@@ -2502,22 +2706,23 @@ XhcDisableSlotCmd64 (
//
// Construct the disable slot command
//
- DEBUG ((EFI_D_INFO, "Disable device slot %d!\n", SlotId));
+ DEBUG ((DEBUG_INFO, "Disable device slot %d!\n", SlotId));
ZeroMem (&CmdTrbDisSlot, sizeof (CmdTrbDisSlot));
CmdTrbDisSlot.CycleBit = 1;
CmdTrbDisSlot.Type = TRB_TYPE_DIS_SLOT;
CmdTrbDisSlot.SlotId = SlotId;
- Status = XhcCmdTransfer (
- Xhc,
- (TRB_TEMPLATE *) (UINTN) &CmdTrbDisSlot,
- XHC_GENERIC_TIMEOUT,
- (TRB_TEMPLATE **) (UINTN) &EvtTrb
- );
+ Status = XhcCmdTransfer (
+ Xhc,
+ (TRB_TEMPLATE *)(UINTN)&CmdTrbDisSlot,
+ XHC_GENERIC_TIMEOUT,
+ (TRB_TEMPLATE **)(UINTN)&EvtTrb
+ );
if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "XhcDisableSlotCmd: Disable Slot Command Failed, Status = %r\n", Status));
+ DEBUG ((DEBUG_ERROR, "XhcDisableSlotCmd: Disable Slot Command Failed, Status = %r\n", Status));
return Status;
}
+
//
// Free the slot's device context entry
//
@@ -2532,6 +2737,7 @@ XhcDisableSlotCmd64 (
if (RingSeg != NULL) {
UsbHcFreeMem (Xhc->MemPool, RingSeg, sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER);
}
+
FreePool (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index]);
Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index] = NULL;
}
@@ -2552,8 +2758,9 @@ XhcDisableSlotCmd64 (
}
if (Xhc->UsbDevContext[SlotId].OutputContext != NULL) {
- UsbHcFreeMem (Xhc->MemPool, Xhc->UsbDevContext[SlotId].OutputContext, sizeof (DEVICE_CONTEXT_64));
+ UsbHcFreeMem (Xhc->MemPool, Xhc->UsbDevContext[SlotId].OutputContext, sizeof (DEVICE_CONTEXT_64));
}
+
//
// Doesn't zero the entry because XhcAsyncInterruptTransfer() may be invoked to remove the established
// asynchronous interrupt pipe after the device is disabled. It needs the device address mapping info to
@@ -2580,27 +2787,30 @@ XhcDisableSlotCmd64 (
UINT8
EFIAPI
XhcInitializeEndpointContext (
- IN USB_XHCI_INSTANCE *Xhc,
- IN UINT8 SlotId,
- IN UINT8 DeviceSpeed,
- IN INPUT_CONTEXT *InputContext,
- IN USB_INTERFACE_DESCRIPTOR *IfDesc
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN UINT8 SlotId,
+ IN UINT8 DeviceSpeed,
+ IN INPUT_CONTEXT *InputContext,
+ IN USB_INTERFACE_DESCRIPTOR *IfDesc
)
{
- USB_ENDPOINT_DESCRIPTOR *EpDesc;
- UINTN NumEp;
- UINTN EpIndex;
- UINT8 EpAddr;
- UINT8 Direction;
- UINT8 Dci;
- UINT8 MaxDci;
- EFI_PHYSICAL_ADDRESS PhyAddr;
- UINT8 Interval;
- TRANSFER_RING *EndpointTransferRing;
+ USB_ENDPOINT_DESCRIPTOR *EpDesc;
+ UINTN NumEp;
+ UINTN EpIndex;
+ UINT8 EpAddr;
+ UINT8 Direction;
+ UINT8 Dci;
+ UINT8 MaxDci;
+ EFI_PHYSICAL_ADDRESS PhyAddr;
+ UINT8 Interval;
+ TRANSFER_RING *EndpointTransferRing;
MaxDci = 0;
NumEp = IfDesc->NumEndpoints;
+ if (NumEp == 0) {
+ MaxDci = 1;
+ }
EpDesc = (USB_ENDPOINT_DESCRIPTOR *)(IfDesc + 1);
for (EpIndex = 0; EpIndex < NumEp; EpIndex++) {
@@ -2646,9 +2856,16 @@ XhcInitializeEndpointContext (
InputContext->EP[Dci-1].AverageTRBLength = 0x1000;
if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] == NULL) {
- EndpointTransferRing = AllocateZeroPool(sizeof (TRANSFER_RING));
- Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing;
- CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]);
+ EndpointTransferRing = AllocateZeroPool (sizeof (TRANSFER_RING));
+ Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *)EndpointTransferRing;
+ CreateTransferRing (Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]);
+ DEBUG ((
+ DEBUG_INFO,
+ "Endpoint[%x]: Created BULK ring [%p~%p)\n",
+ EpDesc->EndpointAddress,
+ EndpointTransferRing->RingSeg0,
+ (UINTN)EndpointTransferRing->RingSeg0 + TR_RING_TRB_NUMBER * sizeof (TRB_TEMPLATE)
+ ));
}
break;
@@ -2660,6 +2877,7 @@ XhcInitializeEndpointContext (
InputContext->EP[Dci-1].CErr = 0;
InputContext->EP[Dci-1].EPType = ED_ISOCH_OUT;
}
+
//
// Get the bInterval from descriptor and init the the interval field of endpoint context.
// Refer to XHCI 1.1 spec section 6.2.3.6.
@@ -2677,7 +2895,7 @@ XhcInitializeEndpointContext (
//
// Do not support isochronous transfer now.
//
- DEBUG ((EFI_D_INFO, "XhcInitializeEndpointContext: Unsupport ISO EP found, Transfer ring is not allocated.\n"));
+ DEBUG ((DEBUG_INFO, "XhcInitializeEndpointContext: Unsupport ISO EP found, Transfer ring is not allocated.\n"));
EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);
continue;
case USB_ENDPOINT_INTERRUPT:
@@ -2688,6 +2906,7 @@ XhcInitializeEndpointContext (
InputContext->EP[Dci-1].CErr = 3;
InputContext->EP[Dci-1].EPType = ED_INTERRUPT_OUT;
}
+
InputContext->EP[Dci-1].AverageTRBLength = 0x1000;
InputContext->EP[Dci-1].MaxESITPayload = EpDesc->MaxPacketSize;
//
@@ -2699,7 +2918,7 @@ XhcInitializeEndpointContext (
// Calculate through the bInterval field of Endpoint descriptor.
//
ASSERT (Interval != 0);
- InputContext->EP[Dci-1].Interval = (UINT32)HighBitSet32((UINT32)Interval) + 3;
+ InputContext->EP[Dci-1].Interval = (UINT32)HighBitSet32 ((UINT32)Interval) + 3;
} else if ((DeviceSpeed == EFI_USB_SPEED_HIGH) || (DeviceSpeed == EFI_USB_SPEED_SUPER)) {
Interval = EpDesc->Interval;
ASSERT (Interval >= 1 && Interval <= 16);
@@ -2714,19 +2933,27 @@ XhcInitializeEndpointContext (
}
if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] == NULL) {
- EndpointTransferRing = AllocateZeroPool(sizeof (TRANSFER_RING));
- Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing;
- CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]);
+ EndpointTransferRing = AllocateZeroPool (sizeof (TRANSFER_RING));
+ Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *)EndpointTransferRing;
+ CreateTransferRing (Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]);
+ DEBUG ((
+ DEBUG_INFO,
+ "Endpoint[%x]: Created INT ring [%p~%p)\n",
+ EpDesc->EndpointAddress,
+ EndpointTransferRing->RingSeg0,
+ (UINTN)EndpointTransferRing->RingSeg0 + TR_RING_TRB_NUMBER * sizeof (TRB_TEMPLATE)
+ ));
}
+
break;
case USB_ENDPOINT_CONTROL:
//
// Do not support control transfer now.
//
- DEBUG ((EFI_D_INFO, "XhcInitializeEndpointContext: Unsupport Control EP found, Transfer ring is not allocated.\n"));
+ DEBUG ((DEBUG_INFO, "XhcInitializeEndpointContext: Unsupport Control EP found, Transfer ring is not allocated.\n"));
default:
- DEBUG ((EFI_D_INFO, "XhcInitializeEndpointContext: Unknown EP found, Transfer ring is not allocated.\n"));
+ DEBUG ((DEBUG_INFO, "XhcInitializeEndpointContext: Unknown EP found, Transfer ring is not allocated.\n"));
EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);
continue;
}
@@ -2736,8 +2963,8 @@ XhcInitializeEndpointContext (
((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0,
sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER
);
- PhyAddr &= ~((EFI_PHYSICAL_ADDRESS)0x0F);
- PhyAddr |= (EFI_PHYSICAL_ADDRESS)((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingPCS;
+ PhyAddr &= ~((EFI_PHYSICAL_ADDRESS)0x0F);
+ PhyAddr |= (EFI_PHYSICAL_ADDRESS)((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingPCS;
InputContext->EP[Dci-1].PtrLo = XHC_LOW_32BIT (PhyAddr);
InputContext->EP[Dci-1].PtrHi = XHC_HIGH_32BIT (PhyAddr);
@@ -2762,27 +2989,30 @@ XhcInitializeEndpointContext (
UINT8
EFIAPI
XhcInitializeEndpointContext64 (
- IN USB_XHCI_INSTANCE *Xhc,
- IN UINT8 SlotId,
- IN UINT8 DeviceSpeed,
- IN INPUT_CONTEXT_64 *InputContext,
- IN USB_INTERFACE_DESCRIPTOR *IfDesc
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN UINT8 SlotId,
+ IN UINT8 DeviceSpeed,
+ IN INPUT_CONTEXT_64 *InputContext,
+ IN USB_INTERFACE_DESCRIPTOR *IfDesc
)
{
- USB_ENDPOINT_DESCRIPTOR *EpDesc;
- UINTN NumEp;
- UINTN EpIndex;
- UINT8 EpAddr;
- UINT8 Direction;
- UINT8 Dci;
- UINT8 MaxDci;
- EFI_PHYSICAL_ADDRESS PhyAddr;
- UINT8 Interval;
- TRANSFER_RING *EndpointTransferRing;
+ USB_ENDPOINT_DESCRIPTOR *EpDesc;
+ UINTN NumEp;
+ UINTN EpIndex;
+ UINT8 EpAddr;
+ UINT8 Direction;
+ UINT8 Dci;
+ UINT8 MaxDci;
+ EFI_PHYSICAL_ADDRESS PhyAddr;
+ UINT8 Interval;
+ TRANSFER_RING *EndpointTransferRing;
MaxDci = 0;
NumEp = IfDesc->NumEndpoints;
+ if (NumEp == 0) {
+ MaxDci = 1;
+ }
EpDesc = (USB_ENDPOINT_DESCRIPTOR *)(IfDesc + 1);
for (EpIndex = 0; EpIndex < NumEp; EpIndex++) {
@@ -2828,9 +3058,16 @@ XhcInitializeEndpointContext64 (
InputContext->EP[Dci-1].AverageTRBLength = 0x1000;
if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] == NULL) {
- EndpointTransferRing = AllocateZeroPool(sizeof (TRANSFER_RING));
- Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing;
- CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]);
+ EndpointTransferRing = AllocateZeroPool (sizeof (TRANSFER_RING));
+ Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *)EndpointTransferRing;
+ CreateTransferRing (Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]);
+ DEBUG ((
+ DEBUG_INFO,
+ "Endpoint64[%x]: Created BULK ring [%p~%p)\n",
+ EpDesc->EndpointAddress,
+ EndpointTransferRing->RingSeg0,
+ (UINTN)EndpointTransferRing->RingSeg0 + TR_RING_TRB_NUMBER * sizeof (TRB_TEMPLATE)
+ ));
}
break;
@@ -2842,6 +3079,7 @@ XhcInitializeEndpointContext64 (
InputContext->EP[Dci-1].CErr = 0;
InputContext->EP[Dci-1].EPType = ED_ISOCH_OUT;
}
+
//
// Get the bInterval from descriptor and init the the interval field of endpoint context.
// Refer to XHCI 1.1 spec section 6.2.3.6.
@@ -2859,7 +3097,7 @@ XhcInitializeEndpointContext64 (
//
// Do not support isochronous transfer now.
//
- DEBUG ((EFI_D_INFO, "XhcInitializeEndpointContext64: Unsupport ISO EP found, Transfer ring is not allocated.\n"));
+ DEBUG ((DEBUG_INFO, "XhcInitializeEndpointContext64: Unsupport ISO EP found, Transfer ring is not allocated.\n"));
EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);
continue;
case USB_ENDPOINT_INTERRUPT:
@@ -2870,6 +3108,7 @@ XhcInitializeEndpointContext64 (
InputContext->EP[Dci-1].CErr = 3;
InputContext->EP[Dci-1].EPType = ED_INTERRUPT_OUT;
}
+
InputContext->EP[Dci-1].AverageTRBLength = 0x1000;
InputContext->EP[Dci-1].MaxESITPayload = EpDesc->MaxPacketSize;
//
@@ -2881,7 +3120,7 @@ XhcInitializeEndpointContext64 (
// Calculate through the bInterval field of Endpoint descriptor.
//
ASSERT (Interval != 0);
- InputContext->EP[Dci-1].Interval = (UINT32)HighBitSet32((UINT32)Interval) + 3;
+ InputContext->EP[Dci-1].Interval = (UINT32)HighBitSet32 ((UINT32)Interval) + 3;
} else if ((DeviceSpeed == EFI_USB_SPEED_HIGH) || (DeviceSpeed == EFI_USB_SPEED_SUPER)) {
Interval = EpDesc->Interval;
ASSERT (Interval >= 1 && Interval <= 16);
@@ -2896,19 +3135,27 @@ XhcInitializeEndpointContext64 (
}
if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] == NULL) {
- EndpointTransferRing = AllocateZeroPool(sizeof (TRANSFER_RING));
- Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing;
- CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]);
+ EndpointTransferRing = AllocateZeroPool (sizeof (TRANSFER_RING));
+ Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *)EndpointTransferRing;
+ CreateTransferRing (Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]);
+ DEBUG ((
+ DEBUG_INFO,
+ "Endpoint64[%x]: Created INT ring [%p~%p)\n",
+ EpDesc->EndpointAddress,
+ EndpointTransferRing->RingSeg0,
+ (UINTN)EndpointTransferRing->RingSeg0 + TR_RING_TRB_NUMBER * sizeof (TRB_TEMPLATE)
+ ));
}
+
break;
case USB_ENDPOINT_CONTROL:
//
// Do not support control transfer now.
//
- DEBUG ((EFI_D_INFO, "XhcInitializeEndpointContext64: Unsupport Control EP found, Transfer ring is not allocated.\n"));
+ DEBUG ((DEBUG_INFO, "XhcInitializeEndpointContext64: Unsupport Control EP found, Transfer ring is not allocated.\n"));
default:
- DEBUG ((EFI_D_INFO, "XhcInitializeEndpointContext64: Unknown EP found, Transfer ring is not allocated.\n"));
+ DEBUG ((DEBUG_INFO, "XhcInitializeEndpointContext64: Unknown EP found, Transfer ring is not allocated.\n"));
EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);
continue;
}
@@ -2918,8 +3165,8 @@ XhcInitializeEndpointContext64 (
((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0,
sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER
);
- PhyAddr &= ~((EFI_PHYSICAL_ADDRESS)0x0F);
- PhyAddr |= (EFI_PHYSICAL_ADDRESS)((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingPCS;
+ PhyAddr &= ~((EFI_PHYSICAL_ADDRESS)0x0F);
+ PhyAddr |= (EFI_PHYSICAL_ADDRESS)((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingPCS;
InputContext->EP[Dci-1].PtrLo = XHC_LOW_32BIT (PhyAddr);
InputContext->EP[Dci-1].PtrHi = XHC_HIGH_32BIT (PhyAddr);
@@ -2943,23 +3190,24 @@ XhcInitializeEndpointContext64 (
EFI_STATUS
EFIAPI
XhcSetConfigCmd (
- IN USB_XHCI_INSTANCE *Xhc,
- IN UINT8 SlotId,
- IN UINT8 DeviceSpeed,
- IN USB_CONFIG_DESCRIPTOR *ConfigDesc
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN UINT8 SlotId,
+ IN UINT8 DeviceSpeed,
+ IN USB_CONFIG_DESCRIPTOR *ConfigDesc
)
{
- EFI_STATUS Status;
- USB_INTERFACE_DESCRIPTOR *IfDesc;
- UINT8 Index;
- UINT8 Dci;
- UINT8 MaxDci;
- EFI_PHYSICAL_ADDRESS PhyAddr;
+ EFI_STATUS Status;
+ USB_INTERFACE_DESCRIPTOR *IfDesc;
+ UINT8 Index;
+ UINT8 Dci;
+ UINT8 MaxDci;
+ EFI_PHYSICAL_ADDRESS PhyAddr;
CMD_TRB_CONFIG_ENDPOINT CmdTrbCfgEP;
INPUT_CONTEXT *InputContext;
DEVICE_CONTEXT *OutputContext;
EVT_TRB_COMMAND_COMPLETION *EvtTrb;
+
//
// 4.6.6 Configure Endpoint
//
@@ -2997,21 +3245,21 @@ XhcSetConfigCmd (
// configure endpoint
//
ZeroMem (&CmdTrbCfgEP, sizeof (CmdTrbCfgEP));
- PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT));
+ PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT));
CmdTrbCfgEP.PtrLo = XHC_LOW_32BIT (PhyAddr);
CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (PhyAddr);
CmdTrbCfgEP.CycleBit = 1;
CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT;
CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId;
- DEBUG ((EFI_D_INFO, "Configure Endpoint\n"));
+ DEBUG ((DEBUG_INFO, "Configure Endpoint\n"));
Status = XhcCmdTransfer (
Xhc,
- (TRB_TEMPLATE *) (UINTN) &CmdTrbCfgEP,
+ (TRB_TEMPLATE *)(UINTN)&CmdTrbCfgEP,
XHC_GENERIC_TIMEOUT,
- (TRB_TEMPLATE **) (UINTN) &EvtTrb
+ (TRB_TEMPLATE **)(UINTN)&EvtTrb
);
if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "XhcSetConfigCmd: Config Endpoint Failed, Status = %r\n", Status));
+ DEBUG ((DEBUG_ERROR, "XhcSetConfigCmd: Config Endpoint Failed, Status = %r\n", Status));
} else {
Xhc->UsbDevContext[SlotId].ActiveConfiguration = ConfigDesc->ConfigurationValue;
}
@@ -3033,23 +3281,24 @@ XhcSetConfigCmd (
EFI_STATUS
EFIAPI
XhcSetConfigCmd64 (
- IN USB_XHCI_INSTANCE *Xhc,
- IN UINT8 SlotId,
- IN UINT8 DeviceSpeed,
- IN USB_CONFIG_DESCRIPTOR *ConfigDesc
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN UINT8 SlotId,
+ IN UINT8 DeviceSpeed,
+ IN USB_CONFIG_DESCRIPTOR *ConfigDesc
)
{
- EFI_STATUS Status;
- USB_INTERFACE_DESCRIPTOR *IfDesc;
- UINT8 Index;
- UINT8 Dci;
- UINT8 MaxDci;
- EFI_PHYSICAL_ADDRESS PhyAddr;
+ EFI_STATUS Status;
+ USB_INTERFACE_DESCRIPTOR *IfDesc;
+ UINT8 Index;
+ UINT8 Dci;
+ UINT8 MaxDci;
+ EFI_PHYSICAL_ADDRESS PhyAddr;
CMD_TRB_CONFIG_ENDPOINT CmdTrbCfgEP;
INPUT_CONTEXT_64 *InputContext;
DEVICE_CONTEXT_64 *OutputContext;
EVT_TRB_COMMAND_COMPLETION *EvtTrb;
+
//
// 4.6.6 Configure Endpoint
//
@@ -3077,7 +3326,7 @@ XhcSetConfigCmd64 (
if (Dci > MaxDci) {
MaxDci = Dci;
}
-
+
IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length);
}
@@ -3087,21 +3336,21 @@ XhcSetConfigCmd64 (
// configure endpoint
//
ZeroMem (&CmdTrbCfgEP, sizeof (CmdTrbCfgEP));
- PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT_64));
+ PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT_64));
CmdTrbCfgEP.PtrLo = XHC_LOW_32BIT (PhyAddr);
CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (PhyAddr);
CmdTrbCfgEP.CycleBit = 1;
CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT;
CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId;
- DEBUG ((EFI_D_INFO, "Configure Endpoint\n"));
+ DEBUG ((DEBUG_INFO, "Configure Endpoint\n"));
Status = XhcCmdTransfer (
Xhc,
- (TRB_TEMPLATE *) (UINTN) &CmdTrbCfgEP,
+ (TRB_TEMPLATE *)(UINTN)&CmdTrbCfgEP,
XHC_GENERIC_TIMEOUT,
- (TRB_TEMPLATE **) (UINTN) &EvtTrb
+ (TRB_TEMPLATE **)(UINTN)&EvtTrb
);
if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "XhcSetConfigCmd64: Config Endpoint Failed, Status = %r\n", Status));
+ DEBUG ((DEBUG_ERROR, "XhcSetConfigCmd64: Config Endpoint Failed, Status = %r\n", Status));
} else {
Xhc->UsbDevContext[SlotId].ActiveConfiguration = ConfigDesc->ConfigurationValue;
}
@@ -3115,6 +3364,7 @@ XhcSetConfigCmd64 (
@param Xhc The XHCI Instance.
@param SlotId The slot id to be configured.
@param Dci The device context index of endpoint.
+ @param PendingUrb The pending URB to check completion status when stopping the end point.
@retval EFI_SUCCESS Stop endpoint successfully.
@retval Others Failed to stop endpoint.
@@ -3123,16 +3373,40 @@ XhcSetConfigCmd64 (
EFI_STATUS
EFIAPI
XhcStopEndpoint (
- IN USB_XHCI_INSTANCE *Xhc,
- IN UINT8 SlotId,
- IN UINT8 Dci
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN UINT8 SlotId,
+ IN UINT8 Dci,
+ IN URB *PendingUrb OPTIONAL
)
{
- EFI_STATUS Status;
- EVT_TRB_COMMAND_COMPLETION *EvtTrb;
- CMD_TRB_STOP_ENDPOINT CmdTrbStopED;
+ EFI_STATUS Status;
+ EVT_TRB_COMMAND_COMPLETION *EvtTrb;
+ CMD_TRB_STOP_ENDPOINT CmdTrbStopED;
- DEBUG ((EFI_D_INFO, "XhcStopEndpoint: Slot = 0x%x, Dci = 0x%x\n", SlotId, Dci));
+ DEBUG ((DEBUG_VERBOSE, "XhcStopEndpoint: Slot = 0x%x, Dci = 0x%x\n", SlotId, Dci));
+
+ //
+ // When XhcCheckUrbResult waits for the Stop_Endpoint completion, it also checks
+ // the PendingUrb completion status, because it's possible that the PendingUrb is
+ // finished just before stopping the end point, but after the looping check.
+ //
+ // The PendingUrb could be passed to XhcCmdTransfer to XhcExecTransfer to XhcCheckUrbResult
+ // through function parameter, but That will cause every consumer of XhcCmdTransfer,
+ // XhcExecTransfer and XhcCheckUrbResult pass a NULL PendingUrb.
+ // But actually only XhcCheckUrbResult is aware of the PendingUrb.
+ // So we choose to save the PendingUrb into the USB_XHCI_INSTANCE and use it in XhcCheckUrbResult.
+ //
+ ASSERT (Xhc->PendingUrb == NULL);
+ Xhc->PendingUrb = PendingUrb;
+ //
+ // Reset the URB result from Timeout to NoError.
+ // The USB result will be:
+ // changed to Timeout when Stop/StopInvalidLength Transfer Event is received, or
+ // remain NoError when Success/ShortPacket Transfer Event is received.
+ //
+ if (PendingUrb != NULL) {
+ PendingUrb->Result = EFI_USB_NOERROR;
+ }
//
// Send stop endpoint command to transit Endpoint from running to stop state
@@ -3142,16 +3416,18 @@ XhcStopEndpoint (
CmdTrbStopED.Type = TRB_TYPE_STOP_ENDPOINT;
CmdTrbStopED.EDID = Dci;
CmdTrbStopED.SlotId = SlotId;
- Status = XhcCmdTransfer (
- Xhc,
- (TRB_TEMPLATE *) (UINTN) &CmdTrbStopED,
- XHC_GENERIC_TIMEOUT,
- (TRB_TEMPLATE **) (UINTN) &EvtTrb
- );
- if (EFI_ERROR(Status)) {
- DEBUG ((EFI_D_ERROR, "XhcStopEndpoint: Stop Endpoint Failed, Status = %r\n", Status));
+ Status = XhcCmdTransfer (
+ Xhc,
+ (TRB_TEMPLATE *)(UINTN)&CmdTrbStopED,
+ XHC_GENERIC_TIMEOUT,
+ (TRB_TEMPLATE **)(UINTN)&EvtTrb
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "XhcStopEndpoint: Stop Endpoint Failed, Status = %r\n", Status));
}
+ Xhc->PendingUrb = NULL;
+
return Status;
}
@@ -3169,16 +3445,16 @@ XhcStopEndpoint (
EFI_STATUS
EFIAPI
XhcResetEndpoint (
- IN USB_XHCI_INSTANCE *Xhc,
- IN UINT8 SlotId,
- IN UINT8 Dci
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN UINT8 SlotId,
+ IN UINT8 Dci
)
{
EFI_STATUS Status;
EVT_TRB_COMMAND_COMPLETION *EvtTrb;
CMD_TRB_RESET_ENDPOINT CmdTrbResetED;
- DEBUG ((EFI_D_INFO, "XhcResetEndpoint: Slot = 0x%x, Dci = 0x%x\n", SlotId, Dci));
+ DEBUG ((DEBUG_INFO, "XhcResetEndpoint: Slot = 0x%x, Dci = 0x%x\n", SlotId, Dci));
//
// Send stop endpoint command to transit Endpoint from running to stop state
@@ -3188,14 +3464,14 @@ XhcResetEndpoint (
CmdTrbResetED.Type = TRB_TYPE_RESET_ENDPOINT;
CmdTrbResetED.EDID = Dci;
CmdTrbResetED.SlotId = SlotId;
- Status = XhcCmdTransfer (
- Xhc,
- (TRB_TEMPLATE *) (UINTN) &CmdTrbResetED,
- XHC_GENERIC_TIMEOUT,
- (TRB_TEMPLATE **) (UINTN) &EvtTrb
- );
- if (EFI_ERROR(Status)) {
- DEBUG ((EFI_D_ERROR, "XhcResetEndpoint: Reset Endpoint Failed, Status = %r\n", Status));
+ Status = XhcCmdTransfer (
+ Xhc,
+ (TRB_TEMPLATE *)(UINTN)&CmdTrbResetED,
+ XHC_GENERIC_TIMEOUT,
+ (TRB_TEMPLATE **)(UINTN)&EvtTrb
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "XhcResetEndpoint: Reset Endpoint Failed, Status = %r\n", Status));
}
return Status;
@@ -3217,10 +3493,10 @@ XhcResetEndpoint (
EFI_STATUS
EFIAPI
XhcSetTrDequeuePointer (
- IN USB_XHCI_INSTANCE *Xhc,
- IN UINT8 SlotId,
- IN UINT8 Dci,
- IN URB *Urb
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN UINT8 SlotId,
+ IN UINT8 Dci,
+ IN URB *Urb
)
{
EFI_STATUS Status;
@@ -3228,27 +3504,27 @@ XhcSetTrDequeuePointer (
CMD_SET_TR_DEQ_POINTER CmdSetTRDeq;
EFI_PHYSICAL_ADDRESS PhyAddr;
- DEBUG ((EFI_D_INFO, "XhcSetTrDequeuePointer: Slot = 0x%x, Dci = 0x%x, Urb = 0x%x\n", SlotId, Dci, Urb));
+ DEBUG ((DEBUG_VERBOSE, "XhcSetTrDequeuePointer: Slot = 0x%x, Dci = 0x%x, Urb = 0x%x\n", SlotId, Dci, Urb));
//
// Send stop endpoint command to transit Endpoint from running to stop state
//
ZeroMem (&CmdSetTRDeq, sizeof (CmdSetTRDeq));
- PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Urb->Ring->RingEnqueue, sizeof (CMD_SET_TR_DEQ_POINTER));
+ PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Urb->Ring->RingEnqueue, sizeof (CMD_SET_TR_DEQ_POINTER));
CmdSetTRDeq.PtrLo = XHC_LOW_32BIT (PhyAddr) | Urb->Ring->RingPCS;
CmdSetTRDeq.PtrHi = XHC_HIGH_32BIT (PhyAddr);
CmdSetTRDeq.CycleBit = 1;
CmdSetTRDeq.Type = TRB_TYPE_SET_TR_DEQUE;
CmdSetTRDeq.Endpoint = Dci;
CmdSetTRDeq.SlotId = SlotId;
- Status = XhcCmdTransfer (
- Xhc,
- (TRB_TEMPLATE *) (UINTN) &CmdSetTRDeq,
- XHC_GENERIC_TIMEOUT,
- (TRB_TEMPLATE **) (UINTN) &EvtTrb
- );
- if (EFI_ERROR(Status)) {
- DEBUG ((EFI_D_ERROR, "XhcSetTrDequeuePointer: Set TR Dequeue Pointer Failed, Status = %r\n", Status));
+ Status = XhcCmdTransfer (
+ Xhc,
+ (TRB_TEMPLATE *)(UINTN)&CmdSetTRDeq,
+ XHC_GENERIC_TIMEOUT,
+ (TRB_TEMPLATE **)(UINTN)&EvtTrb
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "XhcSetTrDequeuePointer: Set TR Dequeue Pointer Failed, Status = %r\n", Status));
}
return Status;
@@ -3269,26 +3545,26 @@ XhcSetTrDequeuePointer (
EFI_STATUS
EFIAPI
XhcSetInterface (
- IN USB_XHCI_INSTANCE *Xhc,
- IN UINT8 SlotId,
- IN UINT8 DeviceSpeed,
- IN USB_CONFIG_DESCRIPTOR *ConfigDesc,
- IN EFI_USB_DEVICE_REQUEST *Request
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN UINT8 SlotId,
+ IN UINT8 DeviceSpeed,
+ IN USB_CONFIG_DESCRIPTOR *ConfigDesc,
+ IN EFI_USB_DEVICE_REQUEST *Request
)
{
- EFI_STATUS Status;
- USB_INTERFACE_DESCRIPTOR *IfDescActive;
- USB_INTERFACE_DESCRIPTOR *IfDescSet;
- USB_INTERFACE_DESCRIPTOR *IfDesc;
- USB_ENDPOINT_DESCRIPTOR *EpDesc;
- UINTN NumEp;
- UINTN EpIndex;
- UINT8 EpAddr;
- UINT8 Direction;
- UINT8 Dci;
- UINT8 MaxDci;
- EFI_PHYSICAL_ADDRESS PhyAddr;
- VOID *RingSeg;
+ EFI_STATUS Status;
+ USB_INTERFACE_DESCRIPTOR *IfDescActive;
+ USB_INTERFACE_DESCRIPTOR *IfDescSet;
+ USB_INTERFACE_DESCRIPTOR *IfDesc;
+ USB_ENDPOINT_DESCRIPTOR *EpDesc;
+ UINTN NumEp;
+ UINTN EpIndex;
+ UINT8 EpAddr;
+ UINT8 Direction;
+ UINT8 Dci;
+ UINT8 MaxDci;
+ EFI_PHYSICAL_ADDRESS PhyAddr;
+ VOID *RingSeg;
CMD_TRB_CONFIG_ENDPOINT CmdTrbCfgEP;
INPUT_CONTEXT *InputContext;
@@ -3317,18 +3593,18 @@ XhcSetInterface (
MaxDci = 0;
IfDescActive = NULL;
- IfDescSet = NULL;
+ IfDescSet = NULL;
IfDesc = (USB_INTERFACE_DESCRIPTOR *)(ConfigDesc + 1);
- while ((UINTN) IfDesc < ((UINTN) ConfigDesc + ConfigDesc->TotalLength)) {
+ while ((UINTN)IfDesc < ((UINTN)ConfigDesc + ConfigDesc->TotalLength)) {
if ((IfDesc->DescriptorType == USB_DESC_TYPE_INTERFACE) && (IfDesc->Length >= sizeof (USB_INTERFACE_DESCRIPTOR))) {
- if (IfDesc->InterfaceNumber == (UINT8) Request->Index) {
+ if (IfDesc->InterfaceNumber == (UINT8)Request->Index) {
if (IfDesc->AlternateSetting == Xhc->UsbDevContext[SlotId].ActiveAlternateSetting[IfDesc->InterfaceNumber]) {
//
// Find out the active interface descriptor.
//
IfDescActive = IfDesc;
- } else if (IfDesc->AlternateSetting == (UINT8) Request->Value) {
+ } else if (IfDesc->AlternateSetting == (UINT8)Request->Value) {
//
// Find out the interface descriptor to set.
//
@@ -3336,6 +3612,7 @@ XhcSetInterface (
}
}
}
+
IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length);
}
@@ -3354,8 +3631,8 @@ XhcSetInterface (
//
if ((IfDescActive != NULL) && (IfDescSet != NULL)) {
- NumEp = IfDescActive->NumEndpoints;
- EpDesc = (USB_ENDPOINT_DESCRIPTOR *) (IfDescActive + 1);
+ NumEp = IfDescActive->NumEndpoints;
+ EpDesc = (USB_ENDPOINT_DESCRIPTOR *)(IfDescActive + 1);
for (EpIndex = 0; EpIndex < NumEp; EpIndex++) {
while (EpDesc->DescriptorType != USB_DESC_TYPE_ENDPOINT) {
EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);
@@ -3366,22 +3643,24 @@ XhcSetInterface (
continue;
}
- EpAddr = (UINT8) (EpDesc->EndpointAddress & 0x0F);
- Direction = (UINT8) ((EpDesc->EndpointAddress & 0x80) ? EfiUsbDataIn : EfiUsbDataOut);
+ EpAddr = (UINT8)(EpDesc->EndpointAddress & 0x0F);
+ Direction = (UINT8)((EpDesc->EndpointAddress & 0x80) ? EfiUsbDataIn : EfiUsbDataOut);
Dci = XhcEndpointToDci (EpAddr, Direction);
ASSERT (Dci < 32);
if (Dci > MaxDci) {
MaxDci = Dci;
}
+
//
// XHCI 4.3.6 - Setting Alternate Interfaces
// 1) Stop any Running Transfer Rings affected by the Alternate Interface setting.
//
- Status = XhcStopEndpoint (Xhc, SlotId, Dci);
+ Status = XhcStopEndpoint (Xhc, SlotId, Dci, NULL);
if (EFI_ERROR (Status)) {
return Status;
}
+
//
// XHCI 4.3.6 - Setting Alternate Interfaces
// 2) Free Transfer Rings of all endpoints that will be affected by the Alternate Interface setting.
@@ -3391,6 +3670,7 @@ XhcSetInterface (
if (RingSeg != NULL) {
UsbHcFreeMem (Xhc->MemPool, RingSeg, sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER);
}
+
FreePool (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1]);
Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1] = NULL;
}
@@ -3430,26 +3710,26 @@ XhcSetInterface (
// 5) Issue and successfully complete a Configure Endpoint Command.
//
ZeroMem (&CmdTrbCfgEP, sizeof (CmdTrbCfgEP));
- PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT));
+ PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT));
CmdTrbCfgEP.PtrLo = XHC_LOW_32BIT (PhyAddr);
CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (PhyAddr);
CmdTrbCfgEP.CycleBit = 1;
CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT;
CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId;
- DEBUG ((EFI_D_INFO, "SetInterface: Configure Endpoint\n"));
+ DEBUG ((DEBUG_INFO, "SetInterface: Configure Endpoint\n"));
Status = XhcCmdTransfer (
Xhc,
- (TRB_TEMPLATE *) (UINTN) &CmdTrbCfgEP,
+ (TRB_TEMPLATE *)(UINTN)&CmdTrbCfgEP,
XHC_GENERIC_TIMEOUT,
- (TRB_TEMPLATE **) (UINTN) &EvtTrb
+ (TRB_TEMPLATE **)(UINTN)&EvtTrb
);
if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "SetInterface: Config Endpoint Failed, Status = %r\n", Status));
+ DEBUG ((DEBUG_ERROR, "SetInterface: Config Endpoint Failed, Status = %r\n", Status));
} else {
//
// Update the active AlternateSetting.
//
- Xhc->UsbDevContext[SlotId].ActiveAlternateSetting[(UINT8) Request->Index] = (UINT8) Request->Value;
+ Xhc->UsbDevContext[SlotId].ActiveAlternateSetting[(UINT8)Request->Index] = (UINT8)Request->Value;
}
}
@@ -3471,26 +3751,26 @@ XhcSetInterface (
EFI_STATUS
EFIAPI
XhcSetInterface64 (
- IN USB_XHCI_INSTANCE *Xhc,
- IN UINT8 SlotId,
- IN UINT8 DeviceSpeed,
- IN USB_CONFIG_DESCRIPTOR *ConfigDesc,
- IN EFI_USB_DEVICE_REQUEST *Request
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN UINT8 SlotId,
+ IN UINT8 DeviceSpeed,
+ IN USB_CONFIG_DESCRIPTOR *ConfigDesc,
+ IN EFI_USB_DEVICE_REQUEST *Request
)
{
- EFI_STATUS Status;
- USB_INTERFACE_DESCRIPTOR *IfDescActive;
- USB_INTERFACE_DESCRIPTOR *IfDescSet;
- USB_INTERFACE_DESCRIPTOR *IfDesc;
- USB_ENDPOINT_DESCRIPTOR *EpDesc;
- UINTN NumEp;
- UINTN EpIndex;
- UINT8 EpAddr;
- UINT8 Direction;
- UINT8 Dci;
- UINT8 MaxDci;
- EFI_PHYSICAL_ADDRESS PhyAddr;
- VOID *RingSeg;
+ EFI_STATUS Status;
+ USB_INTERFACE_DESCRIPTOR *IfDescActive;
+ USB_INTERFACE_DESCRIPTOR *IfDescSet;
+ USB_INTERFACE_DESCRIPTOR *IfDesc;
+ USB_ENDPOINT_DESCRIPTOR *EpDesc;
+ UINTN NumEp;
+ UINTN EpIndex;
+ UINT8 EpAddr;
+ UINT8 Direction;
+ UINT8 Dci;
+ UINT8 MaxDci;
+ EFI_PHYSICAL_ADDRESS PhyAddr;
+ VOID *RingSeg;
CMD_TRB_CONFIG_ENDPOINT CmdTrbCfgEP;
INPUT_CONTEXT_64 *InputContext;
@@ -3519,18 +3799,18 @@ XhcSetInterface64 (
MaxDci = 0;
IfDescActive = NULL;
- IfDescSet = NULL;
+ IfDescSet = NULL;
IfDesc = (USB_INTERFACE_DESCRIPTOR *)(ConfigDesc + 1);
- while ((UINTN) IfDesc < ((UINTN) ConfigDesc + ConfigDesc->TotalLength)) {
+ while ((UINTN)IfDesc < ((UINTN)ConfigDesc + ConfigDesc->TotalLength)) {
if ((IfDesc->DescriptorType == USB_DESC_TYPE_INTERFACE) && (IfDesc->Length >= sizeof (USB_INTERFACE_DESCRIPTOR))) {
- if (IfDesc->InterfaceNumber == (UINT8) Request->Index) {
+ if (IfDesc->InterfaceNumber == (UINT8)Request->Index) {
if (IfDesc->AlternateSetting == Xhc->UsbDevContext[SlotId].ActiveAlternateSetting[IfDesc->InterfaceNumber]) {
//
// Find out the active interface descriptor.
//
IfDescActive = IfDesc;
- } else if (IfDesc->AlternateSetting == (UINT8) Request->Value) {
+ } else if (IfDesc->AlternateSetting == (UINT8)Request->Value) {
//
// Find out the interface descriptor to set.
//
@@ -3538,6 +3818,7 @@ XhcSetInterface64 (
}
}
}
+
IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length);
}
@@ -3556,8 +3837,8 @@ XhcSetInterface64 (
//
if ((IfDescActive != NULL) && (IfDescSet != NULL)) {
- NumEp = IfDescActive->NumEndpoints;
- EpDesc = (USB_ENDPOINT_DESCRIPTOR *) (IfDescActive + 1);
+ NumEp = IfDescActive->NumEndpoints;
+ EpDesc = (USB_ENDPOINT_DESCRIPTOR *)(IfDescActive + 1);
for (EpIndex = 0; EpIndex < NumEp; EpIndex++) {
while (EpDesc->DescriptorType != USB_DESC_TYPE_ENDPOINT) {
EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);
@@ -3568,22 +3849,24 @@ XhcSetInterface64 (
continue;
}
- EpAddr = (UINT8) (EpDesc->EndpointAddress & 0x0F);
- Direction = (UINT8) ((EpDesc->EndpointAddress & 0x80) ? EfiUsbDataIn : EfiUsbDataOut);
+ EpAddr = (UINT8)(EpDesc->EndpointAddress & 0x0F);
+ Direction = (UINT8)((EpDesc->EndpointAddress & 0x80) ? EfiUsbDataIn : EfiUsbDataOut);
Dci = XhcEndpointToDci (EpAddr, Direction);
ASSERT (Dci < 32);
if (Dci > MaxDci) {
MaxDci = Dci;
}
+
//
// XHCI 4.3.6 - Setting Alternate Interfaces
// 1) Stop any Running Transfer Rings affected by the Alternate Interface setting.
//
- Status = XhcStopEndpoint (Xhc, SlotId, Dci);
+ Status = XhcStopEndpoint (Xhc, SlotId, Dci, NULL);
if (EFI_ERROR (Status)) {
return Status;
}
+
//
// XHCI 4.3.6 - Setting Alternate Interfaces
// 2) Free Transfer Rings of all endpoints that will be affected by the Alternate Interface setting.
@@ -3593,6 +3876,7 @@ XhcSetInterface64 (
if (RingSeg != NULL) {
UsbHcFreeMem (Xhc->MemPool, RingSeg, sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER);
}
+
FreePool (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1]);
Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1] = NULL;
}
@@ -3632,26 +3916,26 @@ XhcSetInterface64 (
// 5) Issue and successfully complete a Configure Endpoint Command.
//
ZeroMem (&CmdTrbCfgEP, sizeof (CmdTrbCfgEP));
- PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT_64));
+ PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT_64));
CmdTrbCfgEP.PtrLo = XHC_LOW_32BIT (PhyAddr);
CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (PhyAddr);
CmdTrbCfgEP.CycleBit = 1;
CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT;
CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId;
- DEBUG ((EFI_D_INFO, "SetInterface64: Configure Endpoint\n"));
+ DEBUG ((DEBUG_INFO, "SetInterface64: Configure Endpoint\n"));
Status = XhcCmdTransfer (
Xhc,
- (TRB_TEMPLATE *) (UINTN) &CmdTrbCfgEP,
+ (TRB_TEMPLATE *)(UINTN)&CmdTrbCfgEP,
XHC_GENERIC_TIMEOUT,
- (TRB_TEMPLATE **) (UINTN) &EvtTrb
+ (TRB_TEMPLATE **)(UINTN)&EvtTrb
);
if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "SetInterface64: Config Endpoint Failed, Status = %r\n", Status));
+ DEBUG ((DEBUG_ERROR, "SetInterface64: Config Endpoint Failed, Status = %r\n", Status));
} else {
//
// Update the active AlternateSetting.
//
- Xhc->UsbDevContext[SlotId].ActiveAlternateSetting[(UINT8) Request->Index] = (UINT8) Request->Value;
+ Xhc->UsbDevContext[SlotId].ActiveAlternateSetting[(UINT8)Request->Index] = (UINT8)Request->Value;
}
}
@@ -3671,15 +3955,16 @@ XhcSetInterface64 (
EFI_STATUS
EFIAPI
XhcEvaluateContext (
- IN USB_XHCI_INSTANCE *Xhc,
- IN UINT8 SlotId,
- IN UINT32 MaxPacketSize
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN UINT8 SlotId,
+ IN UINT32 MaxPacketSize
)
{
EFI_STATUS Status;
CMD_TRB_EVALUATE_CONTEXT CmdTrbEvalu;
EVT_TRB_COMMAND_COMPLETION *EvtTrb;
INPUT_CONTEXT *InputContext;
+ DEVICE_CONTEXT *OutputContext;
EFI_PHYSICAL_ADDRESS PhyAddr;
ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0);
@@ -3687,29 +3972,34 @@ XhcEvaluateContext (
//
// 4.6.7 Evaluate Context
//
- InputContext = Xhc->UsbDevContext[SlotId].InputContext;
+ InputContext = Xhc->UsbDevContext[SlotId].InputContext;
+ OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;
ZeroMem (InputContext, sizeof (INPUT_CONTEXT));
+ CopyMem (&InputContext->EP[0], &OutputContext->EP[0], sizeof (ENDPOINT_CONTEXT));
+
InputContext->InputControlContext.Dword2 |= BIT1;
InputContext->EP[0].MaxPacketSize = MaxPacketSize;
+ InputContext->EP[0].EPState = 0;
ZeroMem (&CmdTrbEvalu, sizeof (CmdTrbEvalu));
- PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT));
+ PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT));
CmdTrbEvalu.PtrLo = XHC_LOW_32BIT (PhyAddr);
CmdTrbEvalu.PtrHi = XHC_HIGH_32BIT (PhyAddr);
CmdTrbEvalu.CycleBit = 1;
CmdTrbEvalu.Type = TRB_TYPE_EVALU_CONTXT;
CmdTrbEvalu.SlotId = Xhc->UsbDevContext[SlotId].SlotId;
- DEBUG ((EFI_D_INFO, "Evaluate context\n"));
+ DEBUG ((DEBUG_INFO, "Evaluate context\n"));
Status = XhcCmdTransfer (
Xhc,
- (TRB_TEMPLATE *) (UINTN) &CmdTrbEvalu,
+ (TRB_TEMPLATE *)(UINTN)&CmdTrbEvalu,
XHC_GENERIC_TIMEOUT,
- (TRB_TEMPLATE **) (UINTN) &EvtTrb
+ (TRB_TEMPLATE **)(UINTN)&EvtTrb
);
if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "XhcEvaluateContext: Evaluate Context Failed, Status = %r\n", Status));
+ DEBUG ((DEBUG_ERROR, "XhcEvaluateContext: Evaluate Context Failed, Status = %r\n", Status));
}
+
return Status;
}
@@ -3726,15 +4016,16 @@ XhcEvaluateContext (
EFI_STATUS
EFIAPI
XhcEvaluateContext64 (
- IN USB_XHCI_INSTANCE *Xhc,
- IN UINT8 SlotId,
- IN UINT32 MaxPacketSize
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN UINT8 SlotId,
+ IN UINT32 MaxPacketSize
)
{
EFI_STATUS Status;
CMD_TRB_EVALUATE_CONTEXT CmdTrbEvalu;
EVT_TRB_COMMAND_COMPLETION *EvtTrb;
INPUT_CONTEXT_64 *InputContext;
+ DEVICE_CONTEXT_64 *OutputContext;
EFI_PHYSICAL_ADDRESS PhyAddr;
ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0);
@@ -3742,33 +4033,37 @@ XhcEvaluateContext64 (
//
// 4.6.7 Evaluate Context
//
- InputContext = Xhc->UsbDevContext[SlotId].InputContext;
+ InputContext = Xhc->UsbDevContext[SlotId].InputContext;
+ OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;
ZeroMem (InputContext, sizeof (INPUT_CONTEXT_64));
+ CopyMem (&InputContext->EP[0], &OutputContext->EP[0], sizeof (ENDPOINT_CONTEXT_64));
+
InputContext->InputControlContext.Dword2 |= BIT1;
InputContext->EP[0].MaxPacketSize = MaxPacketSize;
+ InputContext->EP[0].EPState = 0;
ZeroMem (&CmdTrbEvalu, sizeof (CmdTrbEvalu));
- PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT_64));
+ PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT_64));
CmdTrbEvalu.PtrLo = XHC_LOW_32BIT (PhyAddr);
CmdTrbEvalu.PtrHi = XHC_HIGH_32BIT (PhyAddr);
CmdTrbEvalu.CycleBit = 1;
CmdTrbEvalu.Type = TRB_TYPE_EVALU_CONTXT;
CmdTrbEvalu.SlotId = Xhc->UsbDevContext[SlotId].SlotId;
- DEBUG ((EFI_D_INFO, "Evaluate context\n"));
+ DEBUG ((DEBUG_INFO, "Evaluate context\n"));
Status = XhcCmdTransfer (
Xhc,
- (TRB_TEMPLATE *) (UINTN) &CmdTrbEvalu,
+ (TRB_TEMPLATE *)(UINTN)&CmdTrbEvalu,
XHC_GENERIC_TIMEOUT,
- (TRB_TEMPLATE **) (UINTN) &EvtTrb
+ (TRB_TEMPLATE **)(UINTN)&EvtTrb
);
if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "XhcEvaluateContext64: Evaluate Context Failed, Status = %r\n", Status));
+ DEBUG ((DEBUG_ERROR, "XhcEvaluateContext64: Evaluate Context Failed, Status = %r\n", Status));
}
+
return Status;
}
-
/**
Evaluate the slot context for hub device through XHCI's Configure_Endpoint cmd.
@@ -3783,11 +4078,11 @@ XhcEvaluateContext64 (
**/
EFI_STATUS
XhcConfigHubContext (
- IN USB_XHCI_INSTANCE *Xhc,
- IN UINT8 SlotId,
- IN UINT8 PortNum,
- IN UINT8 TTT,
- IN UINT8 MTT
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN UINT8 SlotId,
+ IN UINT8 PortNum,
+ IN UINT8 TTT,
+ IN UINT8 MTT
)
{
EFI_STATUS Status;
@@ -3811,29 +4106,30 @@ XhcConfigHubContext (
//
// Copy the slot context from OutputContext to Input context
//
- CopyMem(&(InputContext->Slot), &(OutputContext->Slot), sizeof (SLOT_CONTEXT));
+ CopyMem (&(InputContext->Slot), &(OutputContext->Slot), sizeof (SLOT_CONTEXT));
InputContext->Slot.Hub = 1;
InputContext->Slot.PortNum = PortNum;
InputContext->Slot.TTT = TTT;
InputContext->Slot.MTT = MTT;
ZeroMem (&CmdTrbCfgEP, sizeof (CmdTrbCfgEP));
- PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT));
+ PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT));
CmdTrbCfgEP.PtrLo = XHC_LOW_32BIT (PhyAddr);
CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (PhyAddr);
CmdTrbCfgEP.CycleBit = 1;
CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT;
CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId;
- DEBUG ((EFI_D_INFO, "Configure Hub Slot Context\n"));
+ DEBUG ((DEBUG_INFO, "Configure Hub Slot Context\n"));
Status = XhcCmdTransfer (
- Xhc,
- (TRB_TEMPLATE *) (UINTN) &CmdTrbCfgEP,
- XHC_GENERIC_TIMEOUT,
- (TRB_TEMPLATE **) (UINTN) &EvtTrb
- );
+ Xhc,
+ (TRB_TEMPLATE *)(UINTN)&CmdTrbCfgEP,
+ XHC_GENERIC_TIMEOUT,
+ (TRB_TEMPLATE **)(UINTN)&EvtTrb
+ );
if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "XhcConfigHubContext: Config Endpoint Failed, Status = %r\n", Status));
+ DEBUG ((DEBUG_ERROR, "XhcConfigHubContext: Config Endpoint Failed, Status = %r\n", Status));
}
+
return Status;
}
@@ -3851,11 +4147,11 @@ XhcConfigHubContext (
**/
EFI_STATUS
XhcConfigHubContext64 (
- IN USB_XHCI_INSTANCE *Xhc,
- IN UINT8 SlotId,
- IN UINT8 PortNum,
- IN UINT8 TTT,
- IN UINT8 MTT
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN UINT8 SlotId,
+ IN UINT8 PortNum,
+ IN UINT8 TTT,
+ IN UINT8 MTT
)
{
EFI_STATUS Status;
@@ -3879,30 +4175,29 @@ XhcConfigHubContext64 (
//
// Copy the slot context from OutputContext to Input context
//
- CopyMem(&(InputContext->Slot), &(OutputContext->Slot), sizeof (SLOT_CONTEXT_64));
+ CopyMem (&(InputContext->Slot), &(OutputContext->Slot), sizeof (SLOT_CONTEXT_64));
InputContext->Slot.Hub = 1;
InputContext->Slot.PortNum = PortNum;
InputContext->Slot.TTT = TTT;
InputContext->Slot.MTT = MTT;
ZeroMem (&CmdTrbCfgEP, sizeof (CmdTrbCfgEP));
- PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT_64));
+ PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT_64));
CmdTrbCfgEP.PtrLo = XHC_LOW_32BIT (PhyAddr);
CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (PhyAddr);
CmdTrbCfgEP.CycleBit = 1;
CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT;
CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId;
- DEBUG ((EFI_D_INFO, "Configure Hub Slot Context\n"));
+ DEBUG ((DEBUG_INFO, "Configure Hub Slot Context\n"));
Status = XhcCmdTransfer (
- Xhc,
- (TRB_TEMPLATE *) (UINTN) &CmdTrbCfgEP,
- XHC_GENERIC_TIMEOUT,
- (TRB_TEMPLATE **) (UINTN) &EvtTrb
- );
+ Xhc,
+ (TRB_TEMPLATE *)(UINTN)&CmdTrbCfgEP,
+ XHC_GENERIC_TIMEOUT,
+ (TRB_TEMPLATE **)(UINTN)&EvtTrb
+ );
if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "XhcConfigHubContext64: Config Endpoint Failed, Status = %r\n", Status));
+ DEBUG ((DEBUG_ERROR, "XhcConfigHubContext64: Config Endpoint Failed, Status = %r\n", Status));
}
+
return Status;
}
-
-