MdeModulePkg XhciDxe: XHCI multiple interface alternate setting support.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Star Zeng <star.zeng@intel.com>
Reviewed-by: Feng Tian <feng.tian@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15617 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Star Zeng 2014-07-04 03:30:46 +00:00 committed by lzeng14
parent 8acb3f7b54
commit e1f2dfec34
4 changed files with 841 additions and 249 deletions

View File

@ -1,7 +1,7 @@
/** @file /** @file
The XHCI controller driver. The XHCI controller driver.
Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR> Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License 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 which accompanies this distribution. The full text of the license may be found at
@ -968,6 +968,10 @@ XhcControlTransfer (
ASSERT (Index < Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations); ASSERT (Index < Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations);
Xhc->UsbDevContext[SlotId].ConfDesc[Index] = AllocateZeroPool(*DataLength); Xhc->UsbDevContext[SlotId].ConfDesc[Index] = AllocateZeroPool(*DataLength);
CopyMem (Xhc->UsbDevContext[SlotId].ConfDesc[Index], Data, *DataLength); CopyMem (Xhc->UsbDevContext[SlotId].ConfDesc[Index], Data, *DataLength);
//
// Default to use AlternateSetting 0 for all interfaces.
//
Xhc->UsbDevContext[SlotId].ActiveAlternateSetting = AllocateZeroPool (Xhc->UsbDevContext[SlotId].ConfDesc[Index]->NumInterfaces * sizeof (UINT8));
} }
} else if (((DescriptorType == USB_DESC_TYPE_HUB) || } else if (((DescriptorType == USB_DESC_TYPE_HUB) ||
(DescriptorType == USB_DESC_TYPE_HUB_SUPER_SPEED)) && (*DataLength > 2)) { (DescriptorType == USB_DESC_TYPE_HUB_SUPER_SPEED)) && (*DataLength > 2)) {
@ -1009,6 +1013,20 @@ XhcControlTransfer (
break; break;
} }
} }
} else if ((Request->Request == USB_REQ_SET_INTERFACE) &&
(Request->RequestType == USB_REQUEST_TYPE (EfiUsbNoData, USB_REQ_TYPE_STANDARD, USB_TARGET_INTERFACE))) {
//
// Hook Set_Interface request from UsbBus as we need configure interface setting.
// Request->Value indicates AlterlateSetting to set
// Request->Index indicates Interface to set
//
if (Xhc->UsbDevContext[SlotId].ActiveAlternateSetting[(UINT8) Request->Index] != (UINT8) Request->Value) {
if (Xhc->HcCParams.Data.Csz == 0) {
Status = XhcSetInterface (Xhc, SlotId, DeviceSpeed, Xhc->UsbDevContext[SlotId].ConfDesc[Xhc->UsbDevContext[SlotId].ActiveConfiguration - 1], Request);
} else {
Status = XhcSetInterface64 (Xhc, SlotId, DeviceSpeed, Xhc->UsbDevContext[SlotId].ConfDesc[Xhc->UsbDevContext[SlotId].ActiveConfiguration - 1], Request);
}
}
} else if ((Request->Request == USB_REQ_GET_STATUS) && } else if ((Request->Request == USB_REQ_GET_STATUS) &&
(Request->RequestType == USB_REQUEST_TYPE (EfiUsbDataIn, USB_REQ_TYPE_CLASS, USB_TARGET_OTHER))) { (Request->RequestType == USB_REQUEST_TYPE (EfiUsbDataIn, USB_REQ_TYPE_CLASS, USB_TARGET_OTHER))) {
ASSERT (Data != NULL); ASSERT (Data != NULL);

View File

@ -2,7 +2,7 @@
Provides some data structure definitions used by the XHCI host controller driver. Provides some data structure definitions used by the XHCI host controller driver.
Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR> Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License 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 which accompanies this distribution. The full text of the license may be found at
@ -196,6 +196,14 @@ struct _USB_DEV_CONTEXT {
// These information is used to support XHCI's Config_Endpoint cmd. // These information is used to support XHCI's Config_Endpoint cmd.
// //
EFI_USB_CONFIG_DESCRIPTOR **ConfDesc; EFI_USB_CONFIG_DESCRIPTOR **ConfDesc;
//
// A device has an active Configuration.
//
UINT8 ActiveConfiguration;
//
// Every interface has an active AlternateSetting.
//
UINT8 *ActiveAlternateSetting;
}; };
struct _USB_XHCI_INSTANCE { struct _USB_XHCI_INSTANCE {

View File

@ -2,7 +2,7 @@
XHCI transfer scheduling routines. XHCI transfer scheduling routines.
Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR> Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License 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 which accompanies this distribution. The full text of the license may be found at
@ -750,7 +750,7 @@ CreateEventRing (
// //
EventRing->EventRingCCS = 1; EventRing->EventRingCCS = 1;
Size = EFI_SIZE_TO_PAGES (sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER); Size = sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER;
Buf = UsbHcAllocateMem (Xhc->MemPool, Size); Buf = UsbHcAllocateMem (Xhc->MemPool, Size);
ASSERT (Buf != NULL); ASSERT (Buf != NULL);
ASSERT (((UINTN) Buf & 0x3F) == 0); ASSERT (((UINTN) Buf & 0x3F) == 0);
@ -2385,6 +2385,10 @@ XhcDisableSlotCmd (
} }
} }
if (Xhc->UsbDevContext[SlotId].ActiveAlternateSetting != NULL) {
FreePool (Xhc->UsbDevContext[SlotId].ActiveAlternateSetting);
}
if (Xhc->UsbDevContext[SlotId].InputContext != NULL) { if (Xhc->UsbDevContext[SlotId].InputContext != NULL) {
UsbHcFreeMem (Xhc->MemPool, Xhc->UsbDevContext[SlotId].InputContext, sizeof (INPUT_CONTEXT)); UsbHcFreeMem (Xhc->MemPool, Xhc->UsbDevContext[SlotId].InputContext, sizeof (INPUT_CONTEXT));
} }
@ -2488,6 +2492,10 @@ XhcDisableSlotCmd64 (
} }
} }
if (Xhc->UsbDevContext[SlotId].ActiveAlternateSetting != NULL) {
FreePool (Xhc->UsbDevContext[SlotId].ActiveAlternateSetting);
}
if (Xhc->UsbDevContext[SlotId].InputContext != NULL) { if (Xhc->UsbDevContext[SlotId].InputContext != NULL) {
UsbHcFreeMem (Xhc->MemPool, Xhc->UsbDevContext[SlotId].InputContext, sizeof (INPUT_CONTEXT_64)); UsbHcFreeMem (Xhc->MemPool, Xhc->UsbDevContext[SlotId].InputContext, sizeof (INPUT_CONTEXT_64));
} }
@ -2506,31 +2514,29 @@ XhcDisableSlotCmd64 (
return Status; return Status;
} }
/** /**
Configure all the device endpoints through XHCI's Configure_Endpoint cmd. Initialize endpoint context in input context.
@param Xhc The XHCI Instance. @param Xhc The XHCI Instance.
@param SlotId The slot id to be configured. @param SlotId The slot id to be configured.
@param DeviceSpeed The device's speed. @param DeviceSpeed The device's speed.
@param ConfigDesc The pointer to the usb device configuration descriptor. @param InputContext The pointer to the input context.
@param IfDesc The pointer to the usb device interface descriptor.
@retval EFI_SUCCESS Successfully configure all the device endpoints. @return The maximum device context index of endpoint.
**/ **/
EFI_STATUS UINT8
EFIAPI EFIAPI
XhcSetConfigCmd ( XhcInitializeEndpointContext (
IN USB_XHCI_INSTANCE *Xhc, IN USB_XHCI_INSTANCE *Xhc,
IN UINT8 SlotId, IN UINT8 SlotId,
IN UINT8 DeviceSpeed, IN UINT8 DeviceSpeed,
IN USB_CONFIG_DESCRIPTOR *ConfigDesc IN INPUT_CONTEXT *InputContext,
IN USB_INTERFACE_DESCRIPTOR *IfDesc
) )
{ {
EFI_STATUS Status;
USB_INTERFACE_DESCRIPTOR *IfDesc;
USB_ENDPOINT_DESCRIPTOR *EpDesc; USB_ENDPOINT_DESCRIPTOR *EpDesc;
UINT8 Index;
UINTN NumEp; UINTN NumEp;
UINTN EpIndex; UINTN EpIndex;
UINT8 EpAddr; UINT8 EpAddr;
@ -2539,30 +2545,10 @@ XhcSetConfigCmd (
UINT8 MaxDci; UINT8 MaxDci;
EFI_PHYSICAL_ADDRESS PhyAddr; EFI_PHYSICAL_ADDRESS PhyAddr;
UINT8 Interval; UINT8 Interval;
TRANSFER_RING *EndpointTransferRing; TRANSFER_RING *EndpointTransferRing;
CMD_TRB_CONFIG_ENDPOINT CmdTrbCfgEP;
INPUT_CONTEXT *InputContext;
DEVICE_CONTEXT *OutputContext;
EVT_TRB_COMMAND_COMPLETION *EvtTrb;
//
// 4.6.6 Configure Endpoint
//
InputContext = Xhc->UsbDevContext[SlotId].InputContext;
OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;
ZeroMem (InputContext, sizeof (INPUT_CONTEXT));
CopyMem (&InputContext->Slot, &OutputContext->Slot, sizeof (SLOT_CONTEXT));
ASSERT (ConfigDesc != NULL);
MaxDci = 0; MaxDci = 0;
IfDesc = (USB_INTERFACE_DESCRIPTOR *)(ConfigDesc + 1);
for (Index = 0; Index < ConfigDesc->NumInterfaces; Index++) {
while (IfDesc->DescriptorType != USB_DESC_TYPE_INTERFACE) {
IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length);
}
NumEp = IfDesc->NumEndpoints; NumEp = IfDesc->NumEndpoints;
EpDesc = (USB_ENDPOINT_DESCRIPTOR *)(IfDesc + 1); EpDesc = (USB_ENDPOINT_DESCRIPTOR *)(IfDesc + 1);
@ -2677,6 +2663,217 @@ XhcSetConfigCmd (
EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length); EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);
} }
return MaxDci;
}
/**
Initialize endpoint context in input context.
@param Xhc The XHCI Instance.
@param SlotId The slot id to be configured.
@param DeviceSpeed The device's speed.
@param InputContext The pointer to the input context.
@param IfDesc The pointer to the usb device interface descriptor.
@return The maximum device context index of endpoint.
**/
UINT8
EFIAPI
XhcInitializeEndpointContext64 (
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;
MaxDci = 0;
NumEp = IfDesc->NumEndpoints;
EpDesc = (USB_ENDPOINT_DESCRIPTOR *)(IfDesc + 1);
for (EpIndex = 0; EpIndex < NumEp; EpIndex++) {
while (EpDesc->DescriptorType != USB_DESC_TYPE_ENDPOINT) {
EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);
}
EpAddr = (UINT8)(EpDesc->EndpointAddress & 0x0F);
Direction = (UINT8)((EpDesc->EndpointAddress & 0x80) ? EfiUsbDataIn : EfiUsbDataOut);
Dci = XhcEndpointToDci (EpAddr, Direction);
ASSERT (Dci < 32);
if (Dci > MaxDci) {
MaxDci = Dci;
}
InputContext->InputControlContext.Dword2 |= (BIT0 << Dci);
InputContext->EP[Dci-1].MaxPacketSize = EpDesc->MaxPacketSize;
if (DeviceSpeed == EFI_USB_SPEED_SUPER) {
//
// 6.2.3.4, shall be set to the value defined in the bMaxBurst field of the SuperSpeed Endpoint Companion Descriptor.
//
InputContext->EP[Dci-1].MaxBurstSize = 0x0;
} else {
InputContext->EP[Dci-1].MaxBurstSize = 0x0;
}
switch (EpDesc->Attributes & USB_ENDPOINT_TYPE_MASK) {
case USB_ENDPOINT_BULK:
if (Direction == EfiUsbDataIn) {
InputContext->EP[Dci-1].CErr = 3;
InputContext->EP[Dci-1].EPType = ED_BULK_IN;
} else {
InputContext->EP[Dci-1].CErr = 3;
InputContext->EP[Dci-1].EPType = ED_BULK_OUT;
}
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]);
}
break;
case USB_ENDPOINT_ISO:
if (Direction == EfiUsbDataIn) {
InputContext->EP[Dci-1].CErr = 0;
InputContext->EP[Dci-1].EPType = ED_ISOCH_IN;
} else {
InputContext->EP[Dci-1].CErr = 0;
InputContext->EP[Dci-1].EPType = ED_ISOCH_OUT;
}
break;
case USB_ENDPOINT_INTERRUPT:
if (Direction == EfiUsbDataIn) {
InputContext->EP[Dci-1].CErr = 3;
InputContext->EP[Dci-1].EPType = ED_INTERRUPT_IN;
} else {
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;
//
// Get the bInterval from descriptor and init the the interval field of endpoint context
//
if ((DeviceSpeed == EFI_USB_SPEED_FULL) || (DeviceSpeed == EFI_USB_SPEED_LOW)) {
Interval = EpDesc->Interval;
//
// Calculate through the bInterval field of Endpoint descriptor.
//
ASSERT (Interval != 0);
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);
//
// Refer to XHCI 1.0 spec section 6.2.3.6, table 61
//
InputContext->EP[Dci-1].Interval = Interval - 1;
InputContext->EP[Dci-1].AverageTRBLength = 0x1000;
InputContext->EP[Dci-1].MaxESITPayload = 0x0002;
InputContext->EP[Dci-1].MaxBurstSize = 0x0;
InputContext->EP[Dci-1].CErr = 3;
}
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]);
}
break;
case USB_ENDPOINT_CONTROL:
default:
ASSERT (0);
break;
}
PhyAddr = UsbHcGetPciAddrForHostAddr (
Xhc->MemPool,
((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0,
sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER
);
PhyAddr &= ~(0x0F);
PhyAddr |= ((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);
EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);
}
return MaxDci;
}
/**
Configure all the device endpoints through XHCI's Configure_Endpoint cmd.
@param Xhc The XHCI Instance.
@param SlotId The slot id to be configured.
@param DeviceSpeed The device's speed.
@param ConfigDesc The pointer to the usb device configuration descriptor.
@retval EFI_SUCCESS Successfully configure all the device endpoints.
**/
EFI_STATUS
EFIAPI
XhcSetConfigCmd (
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;
CMD_TRB_CONFIG_ENDPOINT CmdTrbCfgEP;
INPUT_CONTEXT *InputContext;
DEVICE_CONTEXT *OutputContext;
EVT_TRB_COMMAND_COMPLETION *EvtTrb;
//
// 4.6.6 Configure Endpoint
//
InputContext = Xhc->UsbDevContext[SlotId].InputContext;
OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;
ZeroMem (InputContext, sizeof (INPUT_CONTEXT));
CopyMem (&InputContext->Slot, &OutputContext->Slot, sizeof (SLOT_CONTEXT));
ASSERT (ConfigDesc != NULL);
MaxDci = 0;
IfDesc = (USB_INTERFACE_DESCRIPTOR *)(ConfigDesc + 1);
for (Index = 0; Index < ConfigDesc->NumInterfaces; Index++) {
while ((IfDesc->DescriptorType != USB_DESC_TYPE_INTERFACE) || (IfDesc->AlternateSetting != 0)) {
IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length);
}
Dci = XhcInitializeEndpointContext (Xhc, SlotId, DeviceSpeed, InputContext, IfDesc);
if (Dci > MaxDci) {
MaxDci = Dci;
}
IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length); IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length);
} }
@ -2701,7 +2898,10 @@ XhcSetConfigCmd (
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "XhcSetConfigCmd: Config Endpoint Failed, Status = %r\n", Status)); DEBUG ((EFI_D_ERROR, "XhcSetConfigCmd: Config Endpoint Failed, Status = %r\n", Status));
} else {
Xhc->UsbDevContext[SlotId].ActiveConfiguration = ConfigDesc->ConfigurationValue;
} }
return Status; return Status;
} }
@ -2727,18 +2927,11 @@ XhcSetConfigCmd64 (
{ {
EFI_STATUS Status; EFI_STATUS Status;
USB_INTERFACE_DESCRIPTOR *IfDesc; USB_INTERFACE_DESCRIPTOR *IfDesc;
USB_ENDPOINT_DESCRIPTOR *EpDesc;
UINT8 Index; UINT8 Index;
UINTN NumEp;
UINTN EpIndex;
UINT8 EpAddr;
UINT8 Direction;
UINT8 Dci; UINT8 Dci;
UINT8 MaxDci; UINT8 MaxDci;
EFI_PHYSICAL_ADDRESS PhyAddr; EFI_PHYSICAL_ADDRESS PhyAddr;
UINT8 Interval;
TRANSFER_RING *EndpointTransferRing;
CMD_TRB_CONFIG_ENDPOINT CmdTrbCfgEP; CMD_TRB_CONFIG_ENDPOINT CmdTrbCfgEP;
INPUT_CONTEXT_64 *InputContext; INPUT_CONTEXT_64 *InputContext;
DEVICE_CONTEXT_64 *OutputContext; DEVICE_CONTEXT_64 *OutputContext;
@ -2757,126 +2950,15 @@ XhcSetConfigCmd64 (
IfDesc = (USB_INTERFACE_DESCRIPTOR *)(ConfigDesc + 1); IfDesc = (USB_INTERFACE_DESCRIPTOR *)(ConfigDesc + 1);
for (Index = 0; Index < ConfigDesc->NumInterfaces; Index++) { for (Index = 0; Index < ConfigDesc->NumInterfaces; Index++) {
while (IfDesc->DescriptorType != USB_DESC_TYPE_INTERFACE) { while ((IfDesc->DescriptorType != USB_DESC_TYPE_INTERFACE) || (IfDesc->AlternateSetting != 0)) {
IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length); IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length);
} }
NumEp = IfDesc->NumEndpoints; Dci = XhcInitializeEndpointContext64 (Xhc, SlotId, DeviceSpeed, InputContext, IfDesc);
EpDesc = (USB_ENDPOINT_DESCRIPTOR *)(IfDesc + 1);
for (EpIndex = 0; EpIndex < NumEp; EpIndex++) {
while (EpDesc->DescriptorType != USB_DESC_TYPE_ENDPOINT) {
EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);
}
EpAddr = (UINT8)(EpDesc->EndpointAddress & 0x0F);
Direction = (UINT8)((EpDesc->EndpointAddress & 0x80) ? EfiUsbDataIn : EfiUsbDataOut);
Dci = XhcEndpointToDci (EpAddr, Direction);
ASSERT (Dci < 32);
if (Dci > MaxDci) { if (Dci > MaxDci) {
MaxDci = Dci; MaxDci = Dci;
} }
InputContext->InputControlContext.Dword2 |= (BIT0 << Dci);
InputContext->EP[Dci-1].MaxPacketSize = EpDesc->MaxPacketSize;
if (DeviceSpeed == EFI_USB_SPEED_SUPER) {
//
// 6.2.3.4, shall be set to the value defined in the bMaxBurst field of the SuperSpeed Endpoint Companion Descriptor.
//
InputContext->EP[Dci-1].MaxBurstSize = 0x0;
} else {
InputContext->EP[Dci-1].MaxBurstSize = 0x0;
}
switch (EpDesc->Attributes & USB_ENDPOINT_TYPE_MASK) {
case USB_ENDPOINT_BULK:
if (Direction == EfiUsbDataIn) {
InputContext->EP[Dci-1].CErr = 3;
InputContext->EP[Dci-1].EPType = ED_BULK_IN;
} else {
InputContext->EP[Dci-1].CErr = 3;
InputContext->EP[Dci-1].EPType = ED_BULK_OUT;
}
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]);
}
break;
case USB_ENDPOINT_ISO:
if (Direction == EfiUsbDataIn) {
InputContext->EP[Dci-1].CErr = 0;
InputContext->EP[Dci-1].EPType = ED_ISOCH_IN;
} else {
InputContext->EP[Dci-1].CErr = 0;
InputContext->EP[Dci-1].EPType = ED_ISOCH_OUT;
}
break;
case USB_ENDPOINT_INTERRUPT:
if (Direction == EfiUsbDataIn) {
InputContext->EP[Dci-1].CErr = 3;
InputContext->EP[Dci-1].EPType = ED_INTERRUPT_IN;
} else {
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;
//
// Get the bInterval from descriptor and init the the interval field of endpoint context
//
if ((DeviceSpeed == EFI_USB_SPEED_FULL) || (DeviceSpeed == EFI_USB_SPEED_LOW)) {
Interval = EpDesc->Interval;
//
// Calculate through the bInterval field of Endpoint descriptor.
//
ASSERT (Interval != 0);
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);
//
// Refer to XHCI 1.0 spec section 6.2.3.6, table 61
//
InputContext->EP[Dci-1].Interval = Interval - 1;
InputContext->EP[Dci-1].AverageTRBLength = 0x1000;
InputContext->EP[Dci-1].MaxESITPayload = 0x0002;
InputContext->EP[Dci-1].MaxBurstSize = 0x0;
InputContext->EP[Dci-1].CErr = 3;
}
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]);
}
break;
case USB_ENDPOINT_CONTROL:
default:
ASSERT (0);
break;
}
PhyAddr = UsbHcGetPciAddrForHostAddr (
Xhc->MemPool,
((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0,
sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER
);
PhyAddr &= ~(0x0F);
PhyAddr |= ((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);
EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);
}
IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length); IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length);
} }
@ -2901,11 +2983,452 @@ XhcSetConfigCmd64 (
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "XhcSetConfigCmd64: Config Endpoint Failed, Status = %r\n", Status)); DEBUG ((EFI_D_ERROR, "XhcSetConfigCmd64: Config Endpoint Failed, Status = %r\n", Status));
} else {
Xhc->UsbDevContext[SlotId].ActiveConfiguration = ConfigDesc->ConfigurationValue;
} }
return Status; return Status;
} }
/**
Stop endpoint through XHCI's Stop_Endpoint cmd.
@param Xhc The XHCI Instance.
@param SlotId The slot id to be configured.
@param Dci The device context index of endpoint.
@retval EFI_SUCCESS Stop endpoint successfully.
@retval Others Failed to stop endpoint.
**/
EFI_STATUS
EFIAPI
XhcStopEndpoint (
IN USB_XHCI_INSTANCE *Xhc,
IN UINT8 SlotId,
IN UINT8 Dci
)
{
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));
//
// Send stop endpoint command to transit Endpoint from running to stop state
//
ZeroMem (&CmdTrbStopED, sizeof (CmdTrbStopED));
CmdTrbStopED.CycleBit = 1;
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));
}
return Status;
}
/**
Set interface through XHCI's Configure_Endpoint cmd.
@param Xhc The XHCI Instance.
@param SlotId The slot id to be configured.
@param DeviceSpeed The device's speed.
@param ConfigDesc The pointer to the usb device configuration descriptor.
@param Request USB device request to send.
@retval EFI_SUCCESS Successfully set interface.
**/
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
)
{
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;
DEVICE_CONTEXT *OutputContext;
EVT_TRB_COMMAND_COMPLETION *EvtTrb;
Status = EFI_SUCCESS;
InputContext = Xhc->UsbDevContext[SlotId].InputContext;
OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;
//
// XHCI 4.6.6 Configure Endpoint
// When this command is used to "Set an Alternate Interface on a device", software shall set the Drop
// Context and Add Context flags as follows:
// 1) If an endpoint is not modified by the Alternate Interface setting, then software shall set the Drop
// Context and Add Context flags to '0'.
//
// Except the interface indicated by Reqeust->Index, no impact to other interfaces.
// So the default Drop Context and Add Context flags can be '0' to cover 1).
//
ZeroMem (InputContext, sizeof (INPUT_CONTEXT));
CopyMem (&InputContext->Slot, &OutputContext->Slot, sizeof (SLOT_CONTEXT));
ASSERT (ConfigDesc != NULL);
MaxDci = 0;
IfDescActive = NULL;
IfDescSet = NULL;
IfDesc = (USB_INTERFACE_DESCRIPTOR *)(ConfigDesc + 1);
while ((UINTN) IfDesc < ((UINTN) ConfigDesc + ConfigDesc->TotalLength)) {
if (IfDesc->DescriptorType == USB_DESC_TYPE_INTERFACE) {
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) {
//
// Find out the interface descriptor to set.
//
IfDescSet = IfDesc;
}
}
}
IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length);
}
//
// XHCI 4.6.6 Configure Endpoint
// When this command is used to "Set an Alternate Interface on a device", software shall set the Drop
// Context and Add Context flags as follows:
// 2) If an endpoint previously disabled, is enabled by the Alternate Interface setting, then software shall set
// the Drop Context flag to '0' and Add Context flag to '1', and initialize the Input Endpoint Context.
// 3) If an endpoint previously enabled, is disabled by the Alternate Interface setting, then software shall set
// the Drop Context flag to '1' and Add Context flag to '0'.
// 4) If a parameter of an enabled endpoint is modified by an Alternate Interface setting, the Drop Context
// and Add Context flags shall be set to '1'.
//
// Below codes are to cover 2), 3) and 4).
//
if ((IfDescActive != NULL) && (IfDescSet != NULL)) {
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);
}
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);
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.
//
if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1] != NULL) {
RingSeg = ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1])->RingSeg0;
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;
}
//
// Set the Drop Context flag to '1'.
//
InputContext->InputControlContext.Dword1 |= (BIT0 << Dci);
EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);
}
//
// XHCI 4.3.6 - Setting Alternate Interfaces
// 3) Clear all the Endpoint Context fields of each endpoint that will be disabled by the Alternate
// Interface setting, to '0'.
//
// The step 3) has been covered by the ZeroMem () to InputContext at the start of the function.
//
//
// XHCI 4.3.6 - Setting Alternate Interfaces
// 4) For each endpoint enabled by the Configure Endpoint Command:
// a. Allocate a Transfer Ring.
// b. Initialize the Transfer Ring Segment(s) by clearing all fields of all TRBs to '0'.
// c. Initialize the Endpoint Context data structure.
//
Dci = XhcInitializeEndpointContext (Xhc, SlotId, DeviceSpeed, InputContext, IfDescSet);
if (Dci > MaxDci) {
MaxDci = Dci;
}
InputContext->InputControlContext.Dword2 |= BIT0;
InputContext->Slot.ContextEntries = MaxDci;
//
// XHCI 4.3.6 - Setting Alternate Interfaces
// 5) Issue and successfully complete a Configure Endpoint Command.
//
ZeroMem (&CmdTrbCfgEP, sizeof (CmdTrbCfgEP));
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"));
Status = XhcCmdTransfer (
Xhc,
(TRB_TEMPLATE *) (UINTN) &CmdTrbCfgEP,
XHC_GENERIC_TIMEOUT,
(TRB_TEMPLATE **) (UINTN) &EvtTrb
);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "SetInterface: Config Endpoint Failed, Status = %r\n", Status));
} else {
//
// Update the active AlternateSetting.
//
Xhc->UsbDevContext[SlotId].ActiveAlternateSetting[(UINT8) Request->Index] = (UINT8) Request->Value;
}
}
return Status;
}
/**
Set interface through XHCI's Configure_Endpoint cmd.
@param Xhc The XHCI Instance.
@param SlotId The slot id to be configured.
@param DeviceSpeed The device's speed.
@param ConfigDesc The pointer to the usb device configuration descriptor.
@param Request USB device request to send.
@retval EFI_SUCCESS Successfully set interface.
**/
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
)
{
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;
DEVICE_CONTEXT_64 *OutputContext;
EVT_TRB_COMMAND_COMPLETION *EvtTrb;
Status = EFI_SUCCESS;
InputContext = Xhc->UsbDevContext[SlotId].InputContext;
OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;
//
// XHCI 4.6.6 Configure Endpoint
// When this command is used to "Set an Alternate Interface on a device", software shall set the Drop
// Context and Add Context flags as follows:
// 1) If an endpoint is not modified by the Alternate Interface setting, then software shall set the Drop
// Context and Add Context flags to '0'.
//
// Except the interface indicated by Reqeust->Index, no impact to other interfaces.
// So the default Drop Context and Add Context flags can be '0' to cover 1).
//
ZeroMem (InputContext, sizeof (INPUT_CONTEXT_64));
CopyMem (&InputContext->Slot, &OutputContext->Slot, sizeof (SLOT_CONTEXT_64));
ASSERT (ConfigDesc != NULL);
MaxDci = 0;
IfDescActive = NULL;
IfDescSet = NULL;
IfDesc = (USB_INTERFACE_DESCRIPTOR *)(ConfigDesc + 1);
while ((UINTN) IfDesc < ((UINTN) ConfigDesc + ConfigDesc->TotalLength)) {
if (IfDesc->DescriptorType == USB_DESC_TYPE_INTERFACE) {
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) {
//
// Find out the interface descriptor to set.
//
IfDescSet = IfDesc;
}
}
}
IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length);
}
//
// XHCI 4.6.6 Configure Endpoint
// When this command is used to "Set an Alternate Interface on a device", software shall set the Drop
// Context and Add Context flags as follows:
// 2) If an endpoint previously disabled, is enabled by the Alternate Interface setting, then software shall set
// the Drop Context flag to '0' and Add Context flag to '1', and initialize the Input Endpoint Context.
// 3) If an endpoint previously enabled, is disabled by the Alternate Interface setting, then software shall set
// the Drop Context flag to '1' and Add Context flag to '0'.
// 4) If a parameter of an enabled endpoint is modified by an Alternate Interface setting, the Drop Context
// and Add Context flags shall be set to '1'.
//
// Below codes are to cover 2), 3) and 4).
//
if ((IfDescActive != NULL) && (IfDescSet != NULL)) {
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);
}
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);
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.
//
if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1] != NULL) {
RingSeg = ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1])->RingSeg0;
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;
}
//
// Set the Drop Context flag to '1'.
//
InputContext->InputControlContext.Dword1 |= (BIT0 << Dci);
EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);
}
//
// XHCI 4.3.6 - Setting Alternate Interfaces
// 3) Clear all the Endpoint Context fields of each endpoint that will be disabled by the Alternate
// Interface setting, to '0'.
//
// The step 3) has been covered by the ZeroMem () to InputContext at the start of the function.
//
//
// XHCI 4.3.6 - Setting Alternate Interfaces
// 4) For each endpoint enabled by the Configure Endpoint Command:
// a. Allocate a Transfer Ring.
// b. Initialize the Transfer Ring Segment(s) by clearing all fields of all TRBs to '0'.
// c. Initialize the Endpoint Context data structure.
//
Dci = XhcInitializeEndpointContext64 (Xhc, SlotId, DeviceSpeed, InputContext, IfDescSet);
if (Dci > MaxDci) {
MaxDci = Dci;
}
InputContext->InputControlContext.Dword2 |= BIT0;
InputContext->Slot.ContextEntries = MaxDci;
//
// XHCI 4.3.6 - Setting Alternate Interfaces
// 5) Issue and successfully complete a Configure Endpoint Command.
//
ZeroMem (&CmdTrbCfgEP, sizeof (CmdTrbCfgEP));
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"));
Status = XhcCmdTransfer (
Xhc,
(TRB_TEMPLATE *) (UINTN) &CmdTrbCfgEP,
XHC_GENERIC_TIMEOUT,
(TRB_TEMPLATE **) (UINTN) &EvtTrb
);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "SetInterface64: Config Endpoint Failed, Status = %r\n", Status));
} else {
//
// Update the active AlternateSetting.
//
Xhc->UsbDevContext[SlotId].ActiveAlternateSetting[(UINT8) Request->Index] = (UINT8) Request->Value;
}
}
return Status;
}
/** /**
Evaluate the endpoint 0 context through XHCI's Evaluate_Context cmd. Evaluate the endpoint 0 context through XHCI's Evaluate_Context cmd.

View File

@ -2,7 +2,7 @@
This file contains the definition for XHCI host controller schedule routines. This file contains the definition for XHCI host controller schedule routines.
Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR> Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License 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 which accompanies this distribution. The full text of the license may be found at
@ -1041,6 +1041,49 @@ XhcSetConfigCmd64 (
IN USB_CONFIG_DESCRIPTOR *ConfigDesc IN USB_CONFIG_DESCRIPTOR *ConfigDesc
); );
/**
Set interface through XHCI's Configure_Endpoint cmd.
@param Xhc The XHCI Instance.
@param SlotId The slot id to be configured.
@param DeviceSpeed The device's speed.
@param ConfigDesc The pointer to the usb device configuration descriptor.
@param Request USB device request to send.
@retval EFI_SUCCESS Successfully set interface.
**/
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
);
/**
Set interface through XHCI's Configure_Endpoint cmd.
@param Xhc The XHCI Instance.
@param SlotId The slot id to be configured.
@param DeviceSpeed The device's speed.
@param ConfigDesc The pointer to the usb device configuration descriptor.
@param Request USB device request to send.
@retval EFI_SUCCESS Successfully set interface.
**/
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
);
/** /**
Find out the actual device address according to the requested device address from UsbBus. Find out the actual device address according to the requested device address from UsbBus.