1) remove wrong global variable usage because it will bring data corrupt if there are multiple XHCI host controllers.

2) coding style clean up.

Signed-off-by: erictian
Reviewed-by: ydong10
Reviewed-by: jshi19

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12351 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
erictian 2011-09-14 12:13:03 +00:00
parent a2d111ed25
commit a9292c1363
11 changed files with 1312 additions and 1044 deletions

View File

@ -175,7 +175,7 @@ XhciComponentNameGetControllerName (
{
EFI_STATUS Status;
EFI_USB2_HC_PROTOCOL *Usb2Hc;
USB_XHCI_DEV *XhciDev;
USB_XHCI_INSTANCE *XhciDev;
//
// This is a device driver, so ChildHandle must be NULL.

View File

@ -14,11 +14,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "Xhci.h"
//
// The device context array which supports up to 255 devices, entry 0 is reserved and should not be used.
//
USB_DEV_CONTEXT UsbDevContext[256];
//
// Two arrays used to translate the XHCI port state (change)
// to the UEFI protocol's port state (change).
@ -46,6 +41,27 @@ EFI_DRIVER_BINDING_PROTOCOL gXhciDriverBinding = {
NULL
};
//
// Template for Xhci's Usb2 Host Controller Protocol Instance.
//
EFI_USB2_HC_PROTOCOL gXhciUsb2HcTemplate = {
XhcGetCapability,
XhcReset,
XhcGetState,
XhcSetState,
XhcControlTransfer,
XhcBulkTransfer,
XhcAsyncInterruptTransfer,
XhcSyncInterruptTransfer,
XhcIsochronousTransfer,
XhcAsyncIsochronousTransfer,
XhcGetRootHubPortStatus,
XhcSetRootHubPortFeature,
XhcClearRootHubPortFeature,
0x3,
0x0
};
/**
Retrieves the capability of root hub ports.
@ -68,8 +84,8 @@ XhcGetCapability (
OUT UINT8 *Is64BitCapable
)
{
USB_XHCI_DEV *Xhc;
EFI_TPL OldTpl;
USB_XHCI_INSTANCE *Xhc;
EFI_TPL OldTpl;
if ((MaxSpeed == NULL) || (PortNumber == NULL) || (Is64BitCapable == NULL)) {
return EFI_INVALID_PARAMETER;
@ -109,9 +125,9 @@ XhcReset (
IN UINT16 Attributes
)
{
USB_XHCI_DEV *Xhc;
EFI_STATUS Status;
EFI_TPL OldTpl;
USB_XHCI_INSTANCE *Xhc;
EFI_STATUS Status;
EFI_TPL OldTpl;
OldTpl = gBS->RaiseTPL (XHC_TPL);
@ -188,8 +204,8 @@ XhcGetState (
OUT EFI_USB_HC_STATE *State
)
{
USB_XHCI_DEV *Xhc;
EFI_TPL OldTpl;
USB_XHCI_INSTANCE *Xhc;
EFI_TPL OldTpl;
if (State == NULL) {
return EFI_INVALID_PARAMETER;
@ -230,7 +246,7 @@ XhcSetState (
IN EFI_USB_HC_STATE State
)
{
USB_XHCI_DEV *Xhc;
USB_XHCI_INSTANCE *Xhc;
EFI_STATUS Status;
EFI_USB_HC_STATE CurState;
EFI_TPL OldTpl;
@ -309,7 +325,7 @@ XhcGetRootHubPortStatus (
OUT EFI_USB_PORT_STATUS *PortStatus
)
{
USB_XHCI_DEV *Xhc;
USB_XHCI_INSTANCE *Xhc;
UINT32 Offset;
UINT32 State;
UINT32 TotalPort;
@ -419,7 +435,7 @@ XhcSetRootHubPortFeature (
IN EFI_USB_PORT_FEATURE PortFeature
)
{
USB_XHCI_DEV *Xhc;
USB_XHCI_INSTANCE *Xhc;
UINT32 Offset;
UINT32 State;
UINT32 TotalPort;
@ -480,15 +496,15 @@ XhcSetRootHubPortFeature (
}
}
RouteChart.Field.RouteString = 0;
RouteChart.Field.RootPortNum = PortNumber + 1;
RouteChart.Field.TierNum = 1;
RouteChart.Route.RouteString = 0;
RouteChart.Route.RootPortNum = PortNumber + 1;
RouteChart.Route.TierNum = 1;
//
// BUGBUG: If the port reset operation happens after the usb super speed device is enabled,
// If the port reset operation happens after the usb super speed device is enabled,
// The subsequent configuration, such as getting device descriptor, will fail.
// So here a workaround is introduced to skip the reset operation if the device is enabled.
//
SlotId = XhcRouteStringToSlotId (RouteChart);
SlotId = XhcRouteStringToSlotId (Xhc, RouteChart);
if (SlotId == 0) {
//
// 4.3.1 Resetting a Root Hub Port
@ -549,7 +565,7 @@ XhcClearRootHubPortFeature (
IN EFI_USB_PORT_FEATURE PortFeature
)
{
USB_XHCI_DEV *Xhc;
USB_XHCI_INSTANCE *Xhc;
UINT32 Offset;
UINT32 State;
UINT32 TotalPort;
@ -674,7 +690,7 @@ ON_EXIT:
@param Data Data buffer to be transmitted or received from USB
device.
@param DataLength The size (in bytes) of the data buffer.
@param TimeOut Indicates the maximum timeout, in millisecond.
@param Timeout Indicates the maximum timeout, in millisecond.
@param Translator Transaction translator to be used by this device.
@param TransferResult Return the result of this control transfer.
@ -696,12 +712,12 @@ XhcControlTransfer (
IN EFI_USB_DATA_DIRECTION TransferDirection,
IN OUT VOID *Data,
IN OUT UINTN *DataLength,
IN UINTN TimeOut,
IN UINTN Timeout,
IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
OUT UINT32 *TransferResult
)
{
USB_XHCI_DEV *Xhc;
USB_XHCI_INSTANCE *Xhc;
URB *Urb;
UINT8 Endpoint;
UINT8 Index;
@ -772,7 +788,7 @@ XhcControlTransfer (
//
// Check if the device is still enabled before every transaction.
//
SlotId = XhcBusDevAddrToSlotId (DeviceAddress);
SlotId = XhcBusDevAddrToSlotId (Xhc, DeviceAddress);
if (SlotId == 0) {
goto ON_EXIT;
}
@ -780,22 +796,23 @@ XhcControlTransfer (
//
// Acquire the actual device address assigned by XHCI's Address_Device cmd.
//
XhciDevAddr = UsbDevContext[SlotId].XhciDevAddr;
XhciDevAddr = Xhc->UsbDevContext[SlotId].XhciDevAddr;
//
// Hook the Set_Address request from UsbBus.
// According to XHCI 1.0 spec, the Set_Address request is replaced by XHCI's Address_Device cmd.
//
if (Request->Request == USB_REQ_SET_ADDRESS) {
if ((Request->Request == USB_REQ_SET_ADDRESS) &&
(Request->RequestType == USB_REQUEST_TYPE (EfiUsbNoData, USB_REQ_TYPE_STANDARD, USB_TARGET_DEVICE))) {
//
// Reset the BusDevAddr field of all disabled entries in UsbDevContext array firstly.
// This way is used to clean the history to avoid using wrong device address by XhcAsyncInterruptTransfer().
//
for (Index = 0; Index < 255; Index++) {
if (!UsbDevContext[Index + 1].Enabled &&
(UsbDevContext[Index + 1].SlotId != 0) &&
(UsbDevContext[Index + 1].BusDevAddr == (UINT8)Request->Value)) {
UsbDevContext[Index + 1].BusDevAddr = 0;
if (!Xhc->UsbDevContext[Index + 1].Enabled &&
(Xhc->UsbDevContext[Index + 1].SlotId != 0) &&
(Xhc->UsbDevContext[Index + 1].BusDevAddr == (UINT8)Request->Value)) {
Xhc->UsbDevContext[Index + 1].BusDevAddr = 0;
}
}
//
@ -804,18 +821,19 @@ XhcControlTransfer (
// and the actual device address assigned by XHCI. The the following invocations through EFI_USB2_HC_PROTOCOL interface
// can find out the actual device address by it.
//
UsbDevContext[SlotId].BusDevAddr = (UINT8)Request->Value;
Xhc->UsbDevContext[SlotId].BusDevAddr = (UINT8)Request->Value;
Status = EFI_SUCCESS;
goto ON_EXIT;
}
//
// BUGBUG: If the port reset operation happens after the usb super speed device is enabled,
// If the port reset operation happens after the usb super speed device is enabled,
// The subsequent configuration, such as getting device descriptor, will fail.
// So here a workaround is introduced to skip the reset operation if the device is enabled.
//
if ((Request->Request == USB_REQ_SET_FEATURE) &&
(Request->Value == EfiUsbPortReset)) {
if ((Request->Request == USB_REQ_SET_FEATURE) &&
(Request->RequestType == USB_REQUEST_TYPE (EfiUsbNoData, USB_REQ_TYPE_CLASS, USB_TARGET_OTHER)) &&
(Request->Value == EfiUsbPortReset)) {
if (DeviceSpeed == EFI_USB_SPEED_SUPER) {
Status = EFI_SUCCESS;
goto ON_EXIT;
@ -850,7 +868,7 @@ XhcControlTransfer (
goto ON_EXIT;
}
ASSERT (Urb->EvtRing == &Xhc->CtrlTrEventRing);
Status = XhcExecTransfer (Xhc, FALSE, Urb, TimeOut);
Status = XhcExecTransfer (Xhc, FALSE, Urb, Timeout);
//
// Get the status from URB. The result is updated in XhcCheckUrbResult
@ -873,42 +891,48 @@ XhcControlTransfer (
// Hook Get_Status request form UsbBus as we need trace device attach/detach event happened at hub.
// Hook Set_Config request from UsbBus as we need configure device endpoint.
//
if (Request->Request == USB_REQ_GET_DESCRIPTOR) {
if ((Request->Request == USB_REQ_GET_DESCRIPTOR) &&
(Request->RequestType == USB_REQUEST_TYPE (EfiUsbDataIn, USB_REQ_TYPE_STANDARD, USB_TARGET_DEVICE))) {
DescriptorType = (UINT8)(Request->Value >> 8);
if ((DescriptorType == USB_DESC_TYPE_DEVICE) && (*DataLength == sizeof (EFI_USB_DEVICE_DESCRIPTOR))) {
ASSERT (Data != NULL);
//
// Store a copy of device scriptor as hub device need this info to configure endpoint.
//
CopyMem (&UsbDevContext[SlotId].DevDesc, Data, *DataLength);
if (UsbDevContext[SlotId].DevDesc.BcdUSB == 0x0300) {
CopyMem (&Xhc->UsbDevContext[SlotId].DevDesc, Data, *DataLength);
if (Xhc->UsbDevContext[SlotId].DevDesc.BcdUSB == 0x0300) {
//
// If it's a usb3.0 device, then its max packet size is a 2^n.
//
MaxPacket0 = 1 << UsbDevContext[SlotId].DevDesc.MaxPacketSize0;
MaxPacket0 = 1 << Xhc->UsbDevContext[SlotId].DevDesc.MaxPacketSize0;
} else {
MaxPacket0 = UsbDevContext[SlotId].DevDesc.MaxPacketSize0;
MaxPacket0 = Xhc->UsbDevContext[SlotId].DevDesc.MaxPacketSize0;
}
UsbDevContext[SlotId].ConfDesc = AllocateZeroPool (UsbDevContext[SlotId].DevDesc.NumConfigurations * sizeof (EFI_USB_CONFIG_DESCRIPTOR *));
Xhc->UsbDevContext[SlotId].ConfDesc = AllocateZeroPool (Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations * sizeof (EFI_USB_CONFIG_DESCRIPTOR *));
Status = XhcEvaluateContext (Xhc, SlotId, MaxPacket0);
ASSERT_EFI_ERROR (Status);
} else if ((DescriptorType == USB_DESC_TYPE_CONFIG) && (*DataLength == ((UINT16 *)Data)[1])) {
//
// Get configuration value from request, Store the configuration descriptor for Configure_Endpoint cmd.
//
Index = (UINT8)Request->Value;
ASSERT (Index < UsbDevContext[SlotId].DevDesc.NumConfigurations);
UsbDevContext[SlotId].ConfDesc[Index] = AllocateZeroPool(*DataLength);
CopyMem (UsbDevContext[SlotId].ConfDesc[Index], Data, *DataLength);
} else if (((DescriptorType == USB_DESC_TYPE_HUB) ||
(DescriptorType == USB_DESC_TYPE_HUB_SUPER_SPEED))) {
} else if (DescriptorType == USB_DESC_TYPE_CONFIG) {
ASSERT (Data != NULL);
if (*DataLength == ((UINT16 *)Data)[1]) {
//
// Get configuration value from request, Store the configuration descriptor for Configure_Endpoint cmd.
//
Index = (UINT8)Request->Value;
ASSERT (Index < Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations);
Xhc->UsbDevContext[SlotId].ConfDesc[Index] = AllocateZeroPool(*DataLength);
CopyMem (Xhc->UsbDevContext[SlotId].ConfDesc[Index], Data, *DataLength);
}
} else if ((DescriptorType == USB_DESC_TYPE_HUB) ||
(DescriptorType == USB_DESC_TYPE_HUB_SUPER_SPEED)) {
ASSERT (Data != NULL);
HubDesc = (EFI_USB_HUB_DESCRIPTOR *)Data;
//
// The bit 5,6 of HubCharacter field of Hub Descriptor is TTT.
//
TTT = (UINT8)((HubDesc->HubCharacter & (BIT5 | BIT6)) >> 5);
if (UsbDevContext[SlotId].DevDesc.DeviceProtocol == 2) {
if (Xhc->UsbDevContext[SlotId].DevDesc.DeviceProtocol == 2) {
//
// BUGBUG: Don't support multi-TT feature for super speed hub.
// Don't support multi-TT feature for super speed hub now.
//
MTT = 1;
ASSERT (FALSE);
@ -924,17 +948,20 @@ XhcControlTransfer (
MTT
);
}
} else if (Request->Request == USB_REQ_SET_CONFIG) {
} else if ((Request->Request == USB_REQ_SET_CONFIG) &&
(Request->RequestType == USB_REQUEST_TYPE (EfiUsbNoData, USB_REQ_TYPE_STANDARD, USB_TARGET_DEVICE))) {
//
// Hook Set_Config request from UsbBus as we need configure device endpoint.
//
for (Index = 0; Index < UsbDevContext[SlotId].DevDesc.NumConfigurations; Index++) {
if (UsbDevContext[SlotId].ConfDesc[Index]->ConfigurationValue == (UINT8)Request->Value) {
XhcSetConfigCmd (Xhc, SlotId, DeviceSpeed, UsbDevContext[SlotId].ConfDesc[Index]);
for (Index = 0; Index < Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations; Index++) {
if (Xhc->UsbDevContext[SlotId].ConfDesc[Index]->ConfigurationValue == (UINT8)Request->Value) {
XhcSetConfigCmd (Xhc, SlotId, DeviceSpeed, Xhc->UsbDevContext[SlotId].ConfDesc[Index]);
break;
}
}
} 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))) {
ASSERT (Data != NULL);
//
// Hook Get_Status request from UsbBus to keep track of the port status change.
//
@ -979,7 +1006,7 @@ XhcControlTransfer (
}
}
XhcPollPortStatusChange (Xhc, UsbDevContext[SlotId].RouteString, (UINT8)Request->Index, &PortStatus);
XhcPollPortStatusChange (Xhc, Xhc->UsbDevContext[SlotId].RouteString, (UINT8)Request->Index, &PortStatus);
}
FREE_URB:
@ -1014,7 +1041,7 @@ ON_EXIT:
@param DataToggle On input, the initial data toggle for the transfer;
On output, it is updated to to next data toggle to
use of the subsequent bulk transfer.
@param TimeOut Indicates the maximum time, in millisecond, which
@param Timeout Indicates the maximum time, in millisecond, which
the transfer is allowed to complete.
@param Translator A pointr to the transaction translator data.
@param TransferResult A pointer to the detailed result information of the
@ -1039,12 +1066,12 @@ XhcBulkTransfer (
IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM],
IN OUT UINTN *DataLength,
IN OUT UINT8 *DataToggle,
IN UINTN TimeOut,
IN UINTN Timeout,
IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
OUT UINT32 *TransferResult
)
{
USB_XHCI_DEV *Xhc;
USB_XHCI_INSTANCE *Xhc;
URB *Urb;
UINT8 XhciDevAddr;
UINT8 SlotId;
@ -1086,7 +1113,7 @@ XhcBulkTransfer (
//
// Check if the device is still enabled before every transaction.
//
SlotId = XhcBusDevAddrToSlotId (DeviceAddress);
SlotId = XhcBusDevAddrToSlotId (Xhc, DeviceAddress);
if (SlotId == 0) {
goto ON_EXIT;
}
@ -1094,7 +1121,7 @@ XhcBulkTransfer (
//
// Acquire the actual device address assigned by XHCI's Address_Device cmd.
//
XhciDevAddr = UsbDevContext[SlotId].XhciDevAddr;
XhciDevAddr = Xhc->UsbDevContext[SlotId].XhciDevAddr;
//
// Create a new URB, insert it into the asynchronous
@ -1122,7 +1149,7 @@ XhcBulkTransfer (
ASSERT (Urb->EvtRing == &Xhc->BulkTrEventRing);
Status = XhcExecTransfer (Xhc, FALSE, Urb, TimeOut);
Status = XhcExecTransfer (Xhc, FALSE, Urb, Timeout);
*TransferResult = Urb->Result;
*DataLength = Urb->Completed;
@ -1193,7 +1220,7 @@ XhcAsyncInterruptTransfer (
IN VOID *Context OPTIONAL
)
{
USB_XHCI_DEV *Xhc;
USB_XHCI_INSTANCE *Xhc;
URB *Urb;
EFI_STATUS Status;
UINT8 XhciDevAddr;
@ -1235,8 +1262,8 @@ XhcAsyncInterruptTransfer (
// The delete request may happen after device is detached.
//
for (Index = 0; Index < 255; Index++) {
if ((UsbDevContext[Index + 1].SlotId != 0) &&
(UsbDevContext[Index + 1].BusDevAddr == DeviceAddress)) {
if ((Xhc->UsbDevContext[Index + 1].SlotId != 0) &&
(Xhc->UsbDevContext[Index + 1].BusDevAddr == DeviceAddress)) {
break;
}
}
@ -1249,7 +1276,7 @@ XhcAsyncInterruptTransfer (
//
// Acquire the actual device address assigned by XHCI's Address_Device cmd.
//
XhciDevAddr = UsbDevContext[Index + 1].XhciDevAddr;
XhciDevAddr = Xhc->UsbDevContext[Index + 1].XhciDevAddr;
Status = XhciDelAsyncIntTransfer (Xhc, XhciDevAddr, EndPointAddress);
DEBUG ((EFI_D_INFO, "XhcAsyncInterruptTransfer: remove old transfer, Status = %r\n", Status));
@ -1267,7 +1294,7 @@ XhcAsyncInterruptTransfer (
//
// Check if the device is still enabled before every transaction.
//
SlotId = XhcBusDevAddrToSlotId (DeviceAddress);
SlotId = XhcBusDevAddrToSlotId (Xhc, DeviceAddress);
if (SlotId == 0) {
goto ON_EXIT;
}
@ -1275,9 +1302,9 @@ XhcAsyncInterruptTransfer (
//
// Acquire the actual device address assigned by XHCI's Address_Device cmd.
//
XhciDevAddr = UsbDevContext[SlotId].XhciDevAddr;
XhciDevAddr = Xhc->UsbDevContext[SlotId].XhciDevAddr;
Data = AllocatePool (DataLength);
Data = AllocateZeroPool (DataLength);
if (Data == NULL) {
DEBUG ((EFI_D_ERROR, "XhcAsyncInterruptTransfer: failed to allocate buffer\n"));
@ -1337,7 +1364,7 @@ ON_EXIT:
output, the number of bytes transferred.
@param DataToggle On input, the initial data toggle to use; on output,
it is updated to indicate the next data toggle.
@param TimeOut Maximum time, in second, to complete.
@param Timeout Maximum time, in second, to complete.
@param Translator Transaction translator to use.
@param TransferResult Variable to receive the transfer result.
@ -1359,12 +1386,12 @@ XhcSyncInterruptTransfer (
IN OUT VOID *Data,
IN OUT UINTN *DataLength,
IN OUT UINT8 *DataToggle,
IN UINTN TimeOut,
IN UINTN Timeout,
IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
OUT UINT32 *TransferResult
)
{
USB_XHCI_DEV *Xhc;
USB_XHCI_INSTANCE *Xhc;
URB *Urb;
UINT8 XhciDevAddr;
UINT8 SlotId;
@ -1409,7 +1436,7 @@ XhcSyncInterruptTransfer (
//
// Check if the device is still enabled before every transaction.
//
SlotId = XhcBusDevAddrToSlotId (DeviceAddress);
SlotId = XhcBusDevAddrToSlotId (Xhc, DeviceAddress);
if (SlotId == 0) {
goto ON_EXIT;
}
@ -1417,7 +1444,7 @@ XhcSyncInterruptTransfer (
//
// Acquire the actual device address assigned by XHCI's Address_Device cmd.
//
XhciDevAddr = UsbDevContext[SlotId].XhciDevAddr;
XhciDevAddr = Xhc->UsbDevContext[SlotId].XhciDevAddr;
Urb = XhcCreateUrb (
Xhc,
@ -1439,7 +1466,7 @@ XhcSyncInterruptTransfer (
goto ON_EXIT;
}
Status = XhcExecTransfer (Xhc, FALSE, Urb, TimeOut);
Status = XhcExecTransfer (Xhc, FALSE, Urb, Timeout);
*TransferResult = Urb->Result;
*DataLength = Urb->Completed;
@ -1649,57 +1676,39 @@ ON_EXIT:
}
/**
Create and initialize a USB_XHCI_DEV.
Create and initialize a USB_XHCI_INSTANCE structure.
@param PciIo The PciIo on this device.
@param OriginalPciAttributes Original PCI attributes.
@return The allocated and initialized USB_XHCI_DEV structure if created,
@return The allocated and initialized USB_XHCI_INSTANCE structure if created,
otherwise NULL.
**/
USB_XHCI_DEV*
USB_XHCI_INSTANCE*
XhcCreateUsbHc (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT64 OriginalPciAttributes
)
{
USB_XHCI_DEV *Xhc;
USB_XHCI_INSTANCE *Xhc;
EFI_STATUS Status;
UINT32 PageSize;
UINT16 ExtCapReg;
ZeroMem (UsbDevContext, sizeof (UsbDevContext));
Xhc = AllocateZeroPool (sizeof (USB_XHCI_DEV));
Xhc = AllocateZeroPool (sizeof (USB_XHCI_INSTANCE));
if (Xhc == NULL) {
return NULL;
}
//
// Init EFI_USB2_HC_PROTOCOL interface and private data structure
// Initialize private data structure
//
Xhc->Signature = USB_XHCI_DEV_SIGNATURE;
Xhc->Usb2Hc.GetCapability = XhcGetCapability;
Xhc->Usb2Hc.Reset = XhcReset;
Xhc->Usb2Hc.GetState = XhcGetState;
Xhc->Usb2Hc.SetState = XhcSetState;
Xhc->Usb2Hc.ControlTransfer = XhcControlTransfer;
Xhc->Usb2Hc.BulkTransfer = XhcBulkTransfer;
Xhc->Usb2Hc.AsyncInterruptTransfer = XhcAsyncInterruptTransfer;
Xhc->Usb2Hc.SyncInterruptTransfer = XhcSyncInterruptTransfer;
Xhc->Usb2Hc.IsochronousTransfer = XhcIsochronousTransfer;
Xhc->Usb2Hc.AsyncIsochronousTransfer = XhcAsyncIsochronousTransfer;
Xhc->Usb2Hc.GetRootHubPortStatus = XhcGetRootHubPortStatus;
Xhc->Usb2Hc.SetRootHubPortFeature = XhcSetRootHubPortFeature;
Xhc->Usb2Hc.ClearRootHubPortFeature = XhcClearRootHubPortFeature;
Xhc->Usb2Hc.MajorRevision = 0x3;
Xhc->Usb2Hc.MinorRevision = 0x0;
Xhc->Signature = XHCI_INSTANCE_SIG;
Xhc->PciIo = PciIo;
Xhc->OriginalPciAttributes = OriginalPciAttributes;
CopyMem (&Xhc->Usb2Hc, &gXhciUsb2HcTemplate, sizeof (EFI_USB2_HC_PROTOCOL));
InitializeListHead (&Xhc->AsyncIntTransfers);
@ -1720,19 +1729,18 @@ XhcCreateUsbHc (
//
PageSize = XhcReadOpReg(Xhc, XHC_PAGESIZE_OFFSET) & XHC_PAGESIZE_MASK;
Xhc->PageSize = 1 << (HighBitSet32(PageSize) + 12);
ASSERT (Xhc->PageSize == 0x1000);
ExtCapReg = (UINT16) (Xhc->HcCParams.Data.ExtCapReg);
Xhc->ExtCapRegBase = ExtCapReg << 2;
ExtCapReg = (UINT16) (Xhc->HcCParams.Data.ExtCapReg);
Xhc->ExtCapRegBase = ExtCapReg << 2;
Xhc->UsbLegSupOffset = XhcGetLegSupCapAddr (Xhc);
DEBUG ((EFI_D_INFO, "XhcCreateUsb3Hc: capability length 0x%x\n", Xhc->CapLength));
DEBUG ((EFI_D_INFO, "XhcCreateUsb3Hc: Capability length 0x%x\n", Xhc->CapLength));
DEBUG ((EFI_D_INFO, "XhcCreateUsb3Hc: HcSParams1 0x%x\n", Xhc->HcSParams1));
DEBUG ((EFI_D_INFO, "XhcCreateUsb3Hc: HcSParams2 0x%x\n", Xhc->HcSParams2));
DEBUG ((EFI_D_INFO, "XhcCreateUsb3Hc: HcCParams 0x%x\n", Xhc->HcCParams));
DEBUG ((EFI_D_INFO, "XhcCreateUsb3Hc: DBOff 0x%x\n", Xhc->DBOff));
DEBUG ((EFI_D_INFO, "XhcCreateUsb3Hc: RTSOff 0x%x\n", Xhc->RTSOff));
DEBUG ((EFI_D_INFO, "XhcCreateUsb3Hc: Xhc->UsbLegSupOffset 0x%x\n", Xhc->UsbLegSupOffset));
DEBUG ((EFI_D_INFO, "XhcCreateUsb3Hc: UsbLegSupOffset 0x%x\n", Xhc->UsbLegSupOffset));
//
// Create AsyncRequest Polling Timer
@ -1771,17 +1779,17 @@ XhcExitBootService (
)
{
USB_XHCI_DEV *Xhc;
USB_XHCI_INSTANCE *Xhc;
EFI_PCI_IO_PROTOCOL *PciIo;
Xhc = (USB_XHCI_DEV*) Context;
Xhc = (USB_XHCI_INSTANCE*) Context;
PciIo = Xhc->PciIo;
//
// Stop AsyncRequest Polling timer then stop the XHCI driver
// and uninstall the XHCI protocl.
//
gBS->SetTimer (Xhc->PollTimer, TimerCancel, XHC_ASYNC_POLL_INTERVAL);
gBS->SetTimer (Xhc->PollTimer, TimerCancel, 0);
XhcHaltHC (Xhc, XHC_GENERIC_TIMEOUT);
if (Xhc->PollTimer != NULL) {
@ -1827,7 +1835,7 @@ XhcDriverBindingStart (
UINT64 Supports;
UINT64 OriginalPciAttributes;
BOOLEAN PciAttributesSaved;
USB_XHCI_DEV *Xhc;
USB_XHCI_INSTANCE *Xhc;
//
// Open the PciIo Protocol, then enable the USB host controller
@ -1916,7 +1924,7 @@ XhcDriverBindingStart (
//
// Start the asynchronous interrupt monitor
//
Status = gBS->SetTimer (Xhc->PollTimer, TimerPeriodic, XHC_ASYNC_POLL_INTERVAL);
Status = gBS->SetTimer (Xhc->PollTimer, TimerPeriodic, XHC_ASYNC_TIMER_INTERVAL);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "XhcDriverBindingStart: failed to start async interrupt monitor\n"));
XhcHaltHC (Xhc, XHC_GENERIC_TIMEOUT);
@ -2025,7 +2033,8 @@ XhcDriverBindingStop (
EFI_STATUS Status;
EFI_USB2_HC_PROTOCOL *Usb2Hc;
EFI_PCI_IO_PROTOCOL *PciIo;
USB_XHCI_DEV *Xhc;
USB_XHCI_INSTANCE *Xhc;
UINT8 Index;
//
// Test whether the Controller handler passed in is a valid
@ -2052,7 +2061,21 @@ XhcDriverBindingStop (
// Stop AsyncRequest Polling timer then stop the XHCI driver
// and uninstall the XHCI protocl.
//
gBS->SetTimer (Xhc->PollTimer, TimerCancel, XHC_ASYNC_POLL_INTERVAL);
gBS->SetTimer (Xhc->PollTimer, TimerCancel, 0);
//
// Disable the device slots occupied by these devices on its downstream ports.
// Entry 0 is reserved.
//
for (Index = 0; Index < 255; Index++) {
if (!Xhc->UsbDevContext[Index + 1].Enabled ||
(Xhc->UsbDevContext[Index + 1].SlotId == 0)) {
continue;
}
XhcDisableSlotCmd (Xhc, Xhc->UsbDevContext[Index + 1].SlotId);
}
XhcHaltHC (Xhc, XHC_GENERIC_TIMEOUT);
XhcClearBiosOwnership (Xhc);

View File

@ -29,42 +29,41 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/UefiBootServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiLib.h>
#include <Library/PcdLib.h>
#include <Library/DebugLib.h>
#include <IndustryStandard/Pci.h>
typedef struct _USB_XHCI_DEV USB_XHCI_DEV;
typedef struct _USB_DEV_CONTEXT USB_DEV_CONTEXT;
typedef struct _USB_XHCI_INSTANCE USB_XHCI_INSTANCE;
typedef struct _USB_DEV_CONTEXT USB_DEV_CONTEXT;
#include "XhciReg.h"
#include "XhciSched.h"
#include "ComponentName.h"
//
// XHC timeout experience values
// Convert millisecond to microsecond.
//
#define XHC_1_MICROSECOND 1
#define XHC_1_MILLISECOND (1000 * XHC_1_MICROSECOND)
#define XHC_1_SECOND (1000 * XHC_1_MILLISECOND)
#define XHC_1_MILLISECOND (1000)
//
// XHCI register operation timeout, set by experience
// XHC generic timeout experience values.
// The unit is microsecond, setting it as 10ms.
//
#define XHC_RESET_TIMEOUT (1 * XHC_1_SECOND)
#define XHC_GENERIC_TIMEOUT (10 * XHC_1_MILLISECOND)
#define XHC_GENERIC_TIMEOUT (10 * 1000)
//
// Wait for roothub port power stable, refers to Spec[XHCI1.0-2.3.9]
// XHC reset timeout experience values.
// The unit is microsecond, setting it as 1s.
//
#define XHC_ROOT_PORT_RECOVERY_STALL (20 * XHC_1_MILLISECOND)
#define XHC_RESET_TIMEOUT (1000 * 1000)
//
// Sync and Async transfer polling interval, set by experience,
// and the unit of Async is 100us, means 50ms as interval.
// XHC delay experience value for polling operation.
// The unit is microsecond, set it as 1ms.
//
#define XHC_SYNC_POLL_INTERVAL (20 * XHC_1_MILLISECOND)
#define XHC_ASYNC_POLL_INTERVAL (50 * 10000U)
#define XHC_POLL_DELAY (1000)
//
// XHC async transfer timer interval, set by experience.
// The unit is 100us, takes 50ms as interval.
//
#define XHC_ASYNC_TIMER_INTERVAL EFI_TIMER_PERIOD_MILLISECONDS(50)
//
// XHC raises TPL to TPL_NOTIFY to serialize all its operations
@ -93,21 +92,29 @@ typedef struct _USB_DEV_CONTEXT USB_DEV_CONTEXT;
#define EFI_LIST_CONTAINER(Entry, Type, Field) BASE_CR(Entry, Type, Field)
#define XHC_LOW_32BIT(Addr64) ((UINT32)(((UINTN)(Addr64)) & 0xFFFFFFFF))
#define XHC_HIGH_32BIT(Addr64) ((UINT32)(RShiftU64((UINTN)(Addr64), 32) & 0xFFFFFFFF))
#define XHC_BIT_IS_SET(Data, Bit) ((BOOLEAN)(((Data) & (Bit)) == (Bit)))
#define XHC_LOW_32BIT(Addr64) ((UINT32)(((UINTN)(Addr64)) & 0xFFFFFFFF))
#define XHC_HIGH_32BIT(Addr64) ((UINT32)(RShiftU64((UINTN)(Addr64), 32) & 0xFFFFFFFF))
#define XHC_BIT_IS_SET(Data, Bit) ((BOOLEAN)(((Data) & (Bit)) == (Bit)))
#define XHC_REG_BIT_IS_SET(Xhc, Offset, Bit) \
(XHC_BIT_IS_SET(XhcReadOpReg ((Xhc), (Offset)), (Bit)))
#define XHCI_IS_DATAIN(EndpointAddr) XHC_BIT_IS_SET((EndpointAddr), 0x80)
#define XHCI_IS_DATAIN(EndpointAddr) XHC_BIT_IS_SET((EndpointAddr), 0x80)
#define USB_XHCI_DEV_SIGNATURE SIGNATURE_32 ('x', 'h', 'c', 'i')
#define XHC_FROM_THIS(a) CR(a, USB_XHCI_DEV, Usb2Hc, USB_XHCI_DEV_SIGNATURE)
#define XHCI_INSTANCE_SIG SIGNATURE_32 ('x', 'h', 'c', 'i')
#define XHC_FROM_THIS(a) CR(a, USB_XHCI_INSTANCE, Usb2Hc, XHCI_INSTANCE_SIG)
#define USB_DESC_TYPE_HUB 0x29
#define USB_DESC_TYPE_HUB_SUPER_SPEED 0x2a
//
// The RequestType in EFI_USB_DEVICE_REQUEST is composed of
// three fields: One bit direction, 2 bit type, and 5 bit
// target.
//
#define USB_REQUEST_TYPE(Dir, Type, Target) \
((UINT8)((((Dir) == EfiUsbDataIn ? 0x01 : 0) << 7) | (Type) | (Target)))
//
// Xhci Data and Ctrl Structures
//
@ -129,7 +136,63 @@ typedef struct {
} EFI_USB_HUB_DESCRIPTOR;
#pragma pack()
struct _USB_XHCI_DEV {
struct _USB_DEV_CONTEXT {
//
// Whether this entry in UsbDevContext array is used or not.
//
BOOLEAN Enabled;
//
// The slot id assigned to the new device through XHCI's Enable_Slot cmd.
//
UINT8 SlotId;
//
// The route string presented an attached usb device.
//
USB_DEV_ROUTE RouteString;
//
// The route string of parent device if it exists. Otherwise it's zero.
//
USB_DEV_ROUTE ParentRouteString;
//
// The actual device address assigned by XHCI through Address_Device command.
//
UINT8 XhciDevAddr;
//
// The requested device address from UsbBus driver through Set_Address standard usb request.
// As XHCI spec replaces this request with Address_Device command, we have to record the
// requested device address and establish a mapping relationship with the actual device address.
// Then UsbBus driver just need to be aware of the requested device address to access usb device
// through EFI_USB2_HC_PROTOCOL. Xhci driver would be responsible for translating it to actual
// device address and access the actual device.
//
UINT8 BusDevAddr;
//
// The pointer to the input device context.
//
VOID *InputContext;
//
// The pointer to the output device context.
//
VOID *OutputContext;
//
// The transfer queue for every endpoint.
//
VOID *EndpointTransferRing[31];
//
// The device descriptor which is stored to support XHCI's Evaluate_Context cmd.
//
EFI_USB_DEVICE_DESCRIPTOR DevDesc;
//
// As a usb device may include multiple configuration descriptors, we dynamically allocate an array
// to store them.
// Note that every configuration descriptor stored here includes those lower level descriptors,
// such as Interface descriptor, Endpoint descriptor, and so on.
// These information is used to support XHCI's Config_Endpoint cmd.
//
EFI_USB_CONFIG_DESCRIPTOR **ConfDesc;
};
struct _USB_XHCI_INSTANCE {
UINT32 Signature;
EFI_PCI_IO_PROTOCOL *PciIo;
UINT64 OriginalPciAttributes;
@ -189,68 +252,17 @@ struct _USB_XHCI_DEV {
//
EFI_UNICODE_STRING_TABLE *ControllerNameTable;
//
// Store device contexts managed by XHCI instance
// The array supports up to 255 devices, entry 0 is reserved and should not be used.
//
USB_DEV_CONTEXT UsbDevContext[256];
};
struct _USB_DEV_CONTEXT {
//
// Whether this entry in UsbDevContext array is used or not.
//
BOOLEAN Enabled;
//
// The slot id assigned to the new device through XHCI's Enable_Slot cmd.
//
UINT8 SlotId;
//
// The route string presented an attached usb device.
//
USB_DEV_ROUTE RouteString;
//
// The route string of parent device if it exists. Otherwise it's zero.
//
USB_DEV_ROUTE ParentRouteString;
//
// The actual device address assigned by XHCI through Address_Device command.
//
UINT8 XhciDevAddr;
//
// The requested device address from UsbBus driver through Set_Address standard usb request.
// As XHCI spec replaces this request with Address_Device command, we have to record the
// requested device address and establish a mapping relationship with the actual device address.
// Then UsbBus driver just need to be aware of the requested device address to access usb device
// through EFI_USB2_HC_PROTOCOL. Xhci driver would be responsible for translating it to actual
// device address and access the actual device.
//
UINT8 BusDevAddr;
//
// The pointer to the input device context.
//
VOID *InputContext;
//
// The pointer to the output device context.
//
VOID *OutputDevContxt;
//
// The transfer queue for every endpoint.
//
VOID *EndpointTransferRing[31];
//
// The device descriptor which is stored to support XHCI's Evaluate_Context cmd.
//
EFI_USB_DEVICE_DESCRIPTOR DevDesc;
//
// As a usb device may include multiple configuration descriptors, we dynamically allocate an array
// to store them.
// Note that every configuration descriptor stored here includes those lower level descriptors,
// such as Interface descriptor, Endpoint descriptor, and so on.
// These information is used to support XHCI's Config_Endpoint cmd.
//
EFI_USB_CONFIG_DESCRIPTOR **ConfDesc;
};
extern EFI_DRIVER_BINDING_PROTOCOL gXhciDriverBinding;
extern EFI_COMPONENT_NAME_PROTOCOL gXhciComponentName;
extern EFI_COMPONENT_NAME2_PROTOCOL gXhciComponentName2;
extern USB_DEV_CONTEXT UsbDevContext[];
/**
Test to see if this driver supports ControllerHandle. Any
@ -316,6 +328,109 @@ XhcDriverBindingStop (
IN EFI_HANDLE *ChildHandleBuffer
);
/**
Retrieves the capability of root hub ports.
@param This The EFI_USB2_HC_PROTOCOL instance.
@param MaxSpeed Max speed supported by the controller.
@param PortNumber Number of the root hub ports.
@param Is64BitCapable Whether the controller supports 64-bit memory
addressing.
@retval EFI_SUCCESS Host controller capability were retrieved successfully.
@retval EFI_INVALID_PARAMETER Either of the three capability pointer is NULL.
**/
EFI_STATUS
EFIAPI
XhcGetCapability (
IN EFI_USB2_HC_PROTOCOL *This,
OUT UINT8 *MaxSpeed,
OUT UINT8 *PortNumber,
OUT UINT8 *Is64BitCapable
);
/**
Provides software reset for the USB host controller.
@param This This EFI_USB2_HC_PROTOCOL instance.
@param Attributes A bit mask of the reset operation to perform.
@retval EFI_SUCCESS The reset operation succeeded.
@retval EFI_INVALID_PARAMETER Attributes is not valid.
@retval EFI_UNSUPPOURTED The type of reset specified by Attributes is
not currently supported by the host controller.
@retval EFI_DEVICE_ERROR Host controller isn't halted to reset.
**/
EFI_STATUS
EFIAPI
XhcReset (
IN EFI_USB2_HC_PROTOCOL *This,
IN UINT16 Attributes
);
/**
Retrieve the current state of the USB host controller.
@param This This EFI_USB2_HC_PROTOCOL instance.
@param State Variable to return the current host controller
state.
@retval EFI_SUCCESS Host controller state was returned in State.
@retval EFI_INVALID_PARAMETER State is NULL.
@retval EFI_DEVICE_ERROR An error was encountered while attempting to
retrieve the host controller's current state.
**/
EFI_STATUS
EFIAPI
XhcGetState (
IN EFI_USB2_HC_PROTOCOL *This,
OUT EFI_USB_HC_STATE *State
);
/**
Sets the USB host controller to a specific state.
@param This This EFI_USB2_HC_PROTOCOL instance.
@param State The state of the host controller that will be set.
@retval EFI_SUCCESS The USB host controller was successfully placed
in the state specified by State.
@retval EFI_INVALID_PARAMETER State is invalid.
@retval EFI_DEVICE_ERROR Failed to set the state due to device error.
**/
EFI_STATUS
EFIAPI
XhcSetState (
IN EFI_USB2_HC_PROTOCOL *This,
IN EFI_USB_HC_STATE State
);
/**
Retrieves the current status of a USB root hub port.
@param This This EFI_USB2_HC_PROTOCOL instance.
@param PortNumber The root hub port to retrieve the state from.
This value is zero-based.
@param PortStatus Variable to receive the port state.
@retval EFI_SUCCESS The status of the USB root hub port specified.
by PortNumber was returned in PortStatus.
@retval EFI_INVALID_PARAMETER PortNumber is invalid.
@retval EFI_DEVICE_ERROR Can't read register.
**/
EFI_STATUS
EFIAPI
XhcGetRootHubPortStatus (
IN EFI_USB2_HC_PROTOCOL *This,
IN UINT8 PortNumber,
OUT EFI_USB_PORT_STATUS *PortStatus
);
/**
Sets a feature for the specified root hub port.
@ -359,4 +474,255 @@ XhcClearRootHubPortFeature (
IN EFI_USB_PORT_FEATURE PortFeature
);
/**
Submits control transfer to a target USB device.
@param This This EFI_USB2_HC_PROTOCOL instance.
@param DeviceAddress The target device address.
@param DeviceSpeed Target device speed.
@param MaximumPacketLength Maximum packet size the default control transfer
endpoint is capable of sending or receiving.
@param Request USB device request to send.
@param TransferDirection Specifies the data direction for the data stage
@param Data Data buffer to be transmitted or received from USB
device.
@param DataLength The size (in bytes) of the data buffer.
@param Timeout Indicates the maximum timeout, in millisecond.
@param Translator Transaction translator to be used by this device.
@param TransferResult Return the result of this control transfer.
@retval EFI_SUCCESS Transfer was completed successfully.
@retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resources.
@retval EFI_INVALID_PARAMETER Some parameters are invalid.
@retval EFI_TIMEOUT Transfer failed due to timeout.
@retval EFI_DEVICE_ERROR Transfer failed due to host controller or device error.
**/
EFI_STATUS
EFIAPI
XhcControlTransfer (
IN EFI_USB2_HC_PROTOCOL *This,
IN UINT8 DeviceAddress,
IN UINT8 DeviceSpeed,
IN UINTN MaximumPacketLength,
IN EFI_USB_DEVICE_REQUEST *Request,
IN EFI_USB_DATA_DIRECTION TransferDirection,
IN OUT VOID *Data,
IN OUT UINTN *DataLength,
IN UINTN Timeout,
IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
OUT UINT32 *TransferResult
);
/**
Submits bulk transfer to a bulk endpoint of a USB device.
@param This This EFI_USB2_HC_PROTOCOL instance.
@param DeviceAddress Target device address.
@param EndPointAddress Endpoint number and its direction in bit 7.
@param DeviceSpeed Device speed, Low speed device doesn't support bulk
transfer.
@param MaximumPacketLength Maximum packet size the endpoint is capable of
sending or receiving.
@param DataBuffersNumber Number of data buffers prepared for the transfer.
@param Data Array of pointers to the buffers of data to transmit
from or receive into.
@param DataLength The lenght of the data buffer.
@param DataToggle On input, the initial data toggle for the transfer;
On output, it is updated to to next data toggle to
use of the subsequent bulk transfer.
@param Timeout Indicates the maximum time, in millisecond, which
the transfer is allowed to complete.
@param Translator A pointr to the transaction translator data.
@param TransferResult A pointer to the detailed result information of the
bulk transfer.
@retval EFI_SUCCESS The transfer was completed successfully.
@retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resource.
@retval EFI_INVALID_PARAMETER Some parameters are invalid.
@retval EFI_TIMEOUT The transfer failed due to timeout.
@retval EFI_DEVICE_ERROR The transfer failed due to host controller error.
**/
EFI_STATUS
EFIAPI
XhcBulkTransfer (
IN EFI_USB2_HC_PROTOCOL *This,
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
IN UINT8 DeviceSpeed,
IN UINTN MaximumPacketLength,
IN UINT8 DataBuffersNumber,
IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM],
IN OUT UINTN *DataLength,
IN OUT UINT8 *DataToggle,
IN UINTN Timeout,
IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
OUT UINT32 *TransferResult
);
/**
Submits an asynchronous interrupt transfer to an
interrupt endpoint of a USB device.
@param This This EFI_USB2_HC_PROTOCOL instance.
@param DeviceAddress Target device address.
@param EndPointAddress Endpoint number and its direction encoded in bit 7
@param DeviceSpeed Indicates device speed.
@param MaximumPacketLength Maximum packet size the target endpoint is capable
@param IsNewTransfer If TRUE, to submit an new asynchronous interrupt
transfer If FALSE, to remove the specified
asynchronous interrupt.
@param DataToggle On input, the initial data toggle to use; on output,
it is updated to indicate the next data toggle.
@param PollingInterval The he interval, in milliseconds, that the transfer
is polled.
@param DataLength The length of data to receive at the rate specified
by PollingInterval.
@param Translator Transaction translator to use.
@param CallBackFunction Function to call at the rate specified by
PollingInterval.
@param Context Context to CallBackFunction.
@retval EFI_SUCCESS The request has been successfully submitted or canceled.
@retval EFI_INVALID_PARAMETER Some parameters are invalid.
@retval EFI_OUT_OF_RESOURCES The request failed due to a lack of resources.
@retval EFI_DEVICE_ERROR The transfer failed due to host controller error.
**/
EFI_STATUS
EFIAPI
XhcAsyncInterruptTransfer (
IN EFI_USB2_HC_PROTOCOL *This,
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
IN UINT8 DeviceSpeed,
IN UINTN MaximumPacketLength,
IN BOOLEAN IsNewTransfer,
IN OUT UINT8 *DataToggle,
IN UINTN PollingInterval,
IN UINTN DataLength,
IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction,
IN VOID *Context OPTIONAL
);
/**
Submits synchronous interrupt transfer to an interrupt endpoint
of a USB device.
@param This This EFI_USB2_HC_PROTOCOL instance.
@param DeviceAddress Target device address.
@param EndPointAddress Endpoint number and its direction encoded in bit 7
@param DeviceSpeed Indicates device speed.
@param MaximumPacketLength Maximum packet size the target endpoint is capable
of sending or receiving.
@param Data Buffer of data that will be transmitted to USB
device or received from USB device.
@param DataLength On input, the size, in bytes, of the data buffer; On
output, the number of bytes transferred.
@param DataToggle On input, the initial data toggle to use; on output,
it is updated to indicate the next data toggle.
@param Timeout Maximum time, in second, to complete.
@param Translator Transaction translator to use.
@param TransferResult Variable to receive the transfer result.
@return EFI_SUCCESS The transfer was completed successfully.
@return EFI_OUT_OF_RESOURCES The transfer failed due to lack of resource.
@return EFI_INVALID_PARAMETER Some parameters are invalid.
@return EFI_TIMEOUT The transfer failed due to timeout.
@return EFI_DEVICE_ERROR The failed due to host controller or device error
**/
EFI_STATUS
EFIAPI
XhcSyncInterruptTransfer (
IN EFI_USB2_HC_PROTOCOL *This,
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
IN UINT8 DeviceSpeed,
IN UINTN MaximumPacketLength,
IN OUT VOID *Data,
IN OUT UINTN *DataLength,
IN OUT UINT8 *DataToggle,
IN UINTN Timeout,
IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
OUT UINT32 *TransferResult
);
/**
Submits isochronous transfer to a target USB device.
@param This This EFI_USB2_HC_PROTOCOL instance.
@param DeviceAddress Target device address.
@param EndPointAddress End point address with its direction.
@param DeviceSpeed Device speed, Low speed device doesn't support this
type.
@param MaximumPacketLength Maximum packet size that the endpoint is capable of
sending or receiving.
@param DataBuffersNumber Number of data buffers prepared for the transfer.
@param Data Array of pointers to the buffers of data that will
be transmitted to USB device or received from USB
device.
@param DataLength The size, in bytes, of the data buffer.
@param Translator Transaction translator to use.
@param TransferResult Variable to receive the transfer result.
@return EFI_UNSUPPORTED Isochronous transfer is unsupported.
**/
EFI_STATUS
EFIAPI
XhcIsochronousTransfer (
IN EFI_USB2_HC_PROTOCOL *This,
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
IN UINT8 DeviceSpeed,
IN UINTN MaximumPacketLength,
IN UINT8 DataBuffersNumber,
IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
IN UINTN DataLength,
IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
OUT UINT32 *TransferResult
);
/**
Submits Async isochronous transfer to a target USB device.
@param This This EFI_USB2_HC_PROTOCOL instance.
@param DeviceAddress Target device address.
@param EndPointAddress End point address with its direction.
@param DeviceSpeed Device speed, Low speed device doesn't support this
type.
@param MaximumPacketLength Maximum packet size that the endpoint is capable of
sending or receiving.
@param DataBuffersNumber Number of data buffers prepared for the transfer.
@param Data Array of pointers to the buffers of data that will
be transmitted to USB device or received from USB
device.
@param DataLength The size, in bytes, of the data buffer.
@param Translator Transaction translator to use.
@param IsochronousCallBack Function to be called when the transfer complete.
@param Context Context passed to the call back function as
parameter.
@return EFI_UNSUPPORTED Isochronous transfer isn't supported.
**/
EFI_STATUS
EFIAPI
XhcAsyncIsochronousTransfer (
IN EFI_USB2_HC_PROTOCOL *This,
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
IN UINT8 DeviceSpeed,
IN UINTN MaximumPacketLength,
IN UINT8 DataBuffersNumber,
IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
IN UINTN DataLength,
IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack,
IN VOID *Context
);
#endif

View File

@ -50,7 +50,6 @@
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
MemoryAllocationLib
@ -60,7 +59,6 @@
UefiDriverEntryPoint
BaseMemoryLib
DebugLib
PcdLib
[Guids]
gEfiEventExitBootServicesGuid ## PRODUCES ## Event

View File

@ -18,7 +18,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
/**
Read 1-byte width XHCI capability register.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the 1-byte width capability register.
@return The register content read.
@ -27,7 +27,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
UINT8
XhcReadCapReg8 (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset
)
{
@ -54,7 +54,7 @@ XhcReadCapReg8 (
/**
Read 4-bytes width XHCI capability register.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the 4-bytes width capability register.
@return The register content read.
@ -63,7 +63,7 @@ XhcReadCapReg8 (
**/
UINT32
XhcReadCapReg (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset
)
{
@ -90,7 +90,7 @@ XhcReadCapReg (
/**
Read 4-bytes width XHCI Operational register.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the 4-bytes width operational register.
@return The register content read.
@ -99,7 +99,7 @@ XhcReadCapReg (
**/
UINT32
XhcReadOpReg (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset
)
{
@ -128,14 +128,14 @@ XhcReadOpReg (
/**
Write the data to the 4-bytes width XHCI operational register.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the 4-bytes width operational register.
@param Data The data to write.
**/
VOID
XhcWriteOpReg (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset,
IN UINT32 Data
)
@ -161,14 +161,14 @@ XhcWriteOpReg (
/**
Write the data to the 2-bytes width XHCI operational register.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the 2-bytes width operational register.
@param Data The data to write.
**/
VOID
XhcWriteOpReg16 (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset,
IN UINT16 Data
)
@ -194,14 +194,14 @@ XhcWriteOpReg16 (
/**
Write the data to the 8-bytes width XHCI operational register.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the 8-bytes width operational register.
@param Data The data to write.
**/
VOID
XhcWriteOpReg64 (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset,
IN UINT64 Data
)
@ -227,7 +227,7 @@ XhcWriteOpReg64 (
/**
Read XHCI door bell register.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the door bell register.
@return The register content read
@ -235,7 +235,7 @@ XhcWriteOpReg64 (
**/
UINT32
XhcReadDoorBellReg (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset
)
{
@ -264,14 +264,14 @@ XhcReadDoorBellReg (
/**
Write the data to the XHCI door bell register.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the door bell register.
@param Data The data to write.
**/
VOID
XhcWriteDoorBellReg (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset,
IN UINT32 Data
)
@ -297,7 +297,7 @@ XhcWriteDoorBellReg (
/**
Read XHCI runtime register.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the runtime register.
@return The register content read
@ -305,7 +305,7 @@ XhcWriteDoorBellReg (
**/
UINT32
XhcReadRuntimeReg (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset
)
{
@ -334,7 +334,7 @@ XhcReadRuntimeReg (
/**
Read 8-bytes width XHCI runtime register.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the 8-bytes width runtime register.
@return The register content read
@ -342,7 +342,7 @@ XhcReadRuntimeReg (
**/
UINT64
XhcReadRuntimeReg64 (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset
)
{
@ -371,14 +371,14 @@ XhcReadRuntimeReg64 (
/**
Write the data to the XHCI runtime register.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the runtime register.
@param Data The data to write.
**/
VOID
XhcWriteRuntimeReg (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset,
IN UINT32 Data
)
@ -404,14 +404,14 @@ XhcWriteRuntimeReg (
/**
Write the data to the 8-bytes width XHCI runtime register.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the 8-bytes width runtime register.
@param Data The data to write.
**/
VOID
XhcWriteRuntimeReg64 (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset,
IN UINT64 Data
)
@ -437,7 +437,7 @@ XhcWriteRuntimeReg64 (
/**
Read XHCI extended capability register.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the extended capability register.
@return The register content read
@ -445,7 +445,7 @@ XhcWriteRuntimeReg64 (
**/
UINT32
XhcReadExtCapReg (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset
)
{
@ -474,14 +474,14 @@ XhcReadExtCapReg (
/**
Write the data to the XHCI extended capability register.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the extended capability register.
@param Data The data to write.
**/
VOID
XhcWriteExtCapReg (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset,
IN UINT32 Data
)
@ -508,14 +508,14 @@ XhcWriteExtCapReg (
/**
Set one bit of the runtime register while keeping other bits.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the runtime register.
@param Bit The bit mask of the register to set.
**/
VOID
XhcSetRuntimeRegBit (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset,
IN UINT32 Bit
)
@ -530,14 +530,14 @@ XhcSetRuntimeRegBit (
/**
Clear one bit of the runtime register while keeping other bits.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the runtime register.
@param Bit The bit mask of the register to set.
**/
VOID
XhcClearRuntimeRegBit (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset,
IN UINT32 Bit
)
@ -552,14 +552,14 @@ XhcClearRuntimeRegBit (
/**
Set one bit of the operational register while keeping other bits.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the operational register.
@param Bit The bit mask of the register to set.
**/
VOID
XhcSetOpRegBit (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset,
IN UINT32 Bit
)
@ -575,14 +575,14 @@ XhcSetOpRegBit (
/**
Clear one bit of the operational register while keeping other bits.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the operational register.
@param Bit The bit mask of the register to clear.
**/
VOID
XhcClearOpRegBit (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset,
IN UINT32 Bit
)
@ -598,7 +598,7 @@ XhcClearOpRegBit (
Wait the operation register's bit as specified by Bit
to become set (or clear).
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the operation register.
@param Bit The bit of the register to wait for.
@param WaitToSet Wait the bit to set or clear.
@ -610,7 +610,7 @@ XhcClearOpRegBit (
**/
EFI_STATUS
XhcWaitOpRegBit (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset,
IN UINT32 Bit,
IN BOOLEAN WaitToSet,
@ -618,13 +618,16 @@ XhcWaitOpRegBit (
)
{
UINT32 Index;
UINTN Loop;
for (Index = 0; Index < Timeout / XHC_SYNC_POLL_INTERVAL + 1; Index++) {
Loop = (Timeout * XHC_1_MILLISECOND / XHC_POLL_DELAY) + 1;
for (Index = 0; Index < Loop; Index++) {
if (XHC_REG_BIT_IS_SET (Xhc, Offset, Bit) == WaitToSet) {
return EFI_SUCCESS;
}
gBS->Stall (XHC_SYNC_POLL_INTERVAL);
gBS->Stall (XHC_POLL_DELAY);
}
return EFI_TIMEOUT;
@ -633,12 +636,12 @@ XhcWaitOpRegBit (
/**
Set Bios Ownership
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
**/
VOID
XhcSetBiosOwnership (
IN USB_XHCI_DEV *Xhc
IN USB_XHCI_INSTANCE *Xhc
)
{
UINT32 Buffer;
@ -653,12 +656,12 @@ XhcSetBiosOwnership (
/**
Clear Bios Ownership
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
**/
VOID
XhcClearBiosOwnership (
IN USB_XHCI_DEV *Xhc
IN USB_XHCI_INSTANCE *Xhc
)
{
UINT32 Buffer;
@ -673,14 +676,14 @@ XhcClearBiosOwnership (
/**
Calculate the XHCI legacy support capability register offset.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@return The offset of XHCI legacy support capability register.
**/
UINT32
XhcGetLegSupCapAddr (
IN USB_XHCI_DEV *Xhc
IN USB_XHCI_INSTANCE *Xhc
)
{
UINT32 ExtCapOffset;
@ -710,7 +713,7 @@ XhcGetLegSupCapAddr (
/**
Whether the XHCI host controller is halted.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@retval TRUE The controller is halted.
@retval FALSE It isn't halted.
@ -718,7 +721,7 @@ XhcGetLegSupCapAddr (
**/
BOOLEAN
XhcIsHalt (
IN USB_XHCI_DEV *Xhc
IN USB_XHCI_INSTANCE *Xhc
)
{
return XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT);
@ -728,7 +731,7 @@ XhcIsHalt (
/**
Whether system error occurred.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@retval TRUE System error happened.
@retval FALSE No system error.
@ -736,7 +739,7 @@ XhcIsHalt (
**/
BOOLEAN
XhcIsSysError (
IN USB_XHCI_DEV *Xhc
IN USB_XHCI_INSTANCE *Xhc
)
{
return XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HSE);
@ -745,7 +748,7 @@ XhcIsSysError (
/**
Reset the XHCI host controller.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Timeout Time to wait before abort (in millisecond, ms).
@retval EFI_SUCCESS The XHCI host controller is reset.
@ -754,7 +757,7 @@ XhcIsSysError (
**/
EFI_STATUS
XhcResetHC (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Timeout
)
{
@ -781,7 +784,7 @@ XhcResetHC (
/**
Halt the XHCI host controller.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Timeout Time to wait before abort (in millisecond, ms).
@return EFI_SUCCESS The XHCI host controller is halt.
@ -790,7 +793,7 @@ XhcResetHC (
**/
EFI_STATUS
XhcHaltHC (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Timeout
)
{
@ -805,7 +808,7 @@ XhcHaltHC (
/**
Set the XHCI host controller to run.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Timeout Time to wait before abort (in millisecond, ms).
@return EFI_SUCCESS The XHCI host controller is running.
@ -814,7 +817,7 @@ XhcHaltHC (
**/
EFI_STATUS
XhcRunHC (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Timeout
)
{

View File

@ -71,53 +71,59 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define USBLEGSP_OS_SEMAPHORE BIT24 // HC OS Owned Semaphore
#pragma pack (1)
typedef struct {
UINT8 MaxSlots; // Number of Device Slots
UINT16 MaxIntrs:11; // Number of Interrupters
UINT16 Rsvd:5;
UINT8 MaxPorts; // Number of Ports
} HCSPARAMS1;
//
// Structural Parameters 1 Register Bitmap Definition
//
typedef union _XHC_HCSPARAMS1 {
UINT32 Dword;
struct {
UINT8 MaxSlots; // Number of Device Slots
UINT16 MaxIntrs:11; // Number of Interrupters
UINT16 Rsvd:5;
UINT8 MaxPorts; // Number of Ports
} Data;
typedef union {
UINT32 Dword;
HCSPARAMS1 Data;
} XHC_HCSPARAMS1;
typedef struct {
UINT32 Ist:4; // Isochronous Scheduling Threshold
UINT32 Erst:4; // Event Ring Segment Table Max
UINT32 Rsvd:13;
UINT32 ScratchBufHi:5; // Max Scratchpad Buffers Hi
UINT32 Spr:1; // Scratchpad Restore
UINT32 ScratchBufLo:5; // Max Scratchpad Buffers Lo
} HCSPARAMS2;
//
// Structural Parameters 2 Register Bitmap Definition
//
typedef union _XHC_HCSPARAMS2 {
UINT32 Dword;
struct {
UINT32 Ist:4; // Isochronous Scheduling Threshold
UINT32 Erst:4; // Event Ring Segment Table Max
UINT32 Rsvd:13;
UINT32 ScratchBufHi:5; // Max Scratchpad Buffers Hi
UINT32 Spr:1; // Scratchpad Restore
UINT32 ScratchBufLo:5; // Max Scratchpad Buffers Lo
} Data;
typedef union {
UINT32 Dword;
HCSPARAMS2 Data;
} XHC_HCSPARAMS2;
typedef struct {
UINT16 Ac64:1; // 64-bit Addressing Capability
UINT16 Bnc:1; // BW Negotiation Capability
UINT16 Csz:1; // Context Size
UINT16 Ppc:1; // Port Power Control
UINT16 Pind:1; // Port Indicators
UINT16 Lhrc:1; // Light HC Reset Capability
UINT16 Ltc:1; // Latency Tolerance Messaging Capability
UINT16 Nss:1; // No Secondary SID Support
UINT16 Pae:1; // Parse All Event Data
UINT16 Rsvd:3;
UINT16 MaxPsaSize:4; // Maximum Primary Stream Array Size
UINT16 ExtCapReg; // xHCI Extended Capabilities Pointer
} HCCPARAMS;
//
// Capability Parameters Register Bitmap Definition
//
typedef union _XHC_HCCPARAMS {
UINT32 Dword;
struct {
UINT16 Ac64:1; // 64-bit Addressing Capability
UINT16 Bnc:1; // BW Negotiation Capability
UINT16 Csz:1; // Context Size
UINT16 Ppc:1; // Port Power Control
UINT16 Pind:1; // Port Indicators
UINT16 Lhrc:1; // Light HC Reset Capability
UINT16 Ltc:1; // Latency Tolerance Messaging Capability
UINT16 Nss:1; // No Secondary SID Support
UINT16 Pae:1; // Parse All Event Data
UINT16 Rsvd:3;
UINT16 MaxPsaSize:4; // Maximum Primary Stream Array Size
UINT16 ExtCapReg; // xHCI Extended Capabilities Pointer
} Data;
typedef union {
UINT32 Dword;
HCCPARAMS Data;
} XHC_HCCPARAMS;
#pragma pack ()
@ -184,7 +190,7 @@ typedef struct {
/**
Read 1-byte width XHCI capability register.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the 1-byte width capability register.
@return The register content read.
@ -193,14 +199,14 @@ typedef struct {
**/
UINT8
XhcReadCapReg8 (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset
);
/**
Read 4-bytes width XHCI capability register.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the 4-bytes width capability register.
@return The register content read.
@ -209,14 +215,14 @@ XhcReadCapReg8 (
**/
UINT32
XhcReadCapReg (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset
);
/**
Read 4-bytes width XHCI Operational register.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the 4-bytes width operational register.
@return The register content read.
@ -225,21 +231,21 @@ XhcReadCapReg (
**/
UINT32
XhcReadOpReg (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset
);
/**
Write the data to the 4-bytes width XHCI operational register.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the 4-bytes width operational register.
@param Data The data to write.
**/
VOID
XhcWriteOpReg (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset,
IN UINT32 Data
);
@ -247,14 +253,14 @@ XhcWriteOpReg (
/**
Write the data to the 2-bytes width XHCI operational register.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the 2-bytes width operational register.
@param Data The data to write.
**/
VOID
XhcWriteOpReg16 (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset,
IN UINT16 Data
);
@ -262,14 +268,14 @@ XhcWriteOpReg16 (
/**
Write the data to the 8-bytes width XHCI operational register.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the 8-bytes width operational register.
@param Data The data to write.
**/
VOID
XhcWriteOpReg64 (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset,
IN UINT64 Data
);
@ -277,7 +283,7 @@ XhcWriteOpReg64 (
/**
Read XHCI runtime register.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the runtime register.
@return The register content read
@ -285,14 +291,14 @@ XhcWriteOpReg64 (
**/
UINT32
XhcReadRuntimeReg (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset
);
/**
Read 8-bytes width XHCI runtime register.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the 8-bytes width runtime register.
@return The register content read
@ -300,21 +306,21 @@ XhcReadRuntimeReg (
**/
UINT64
XhcReadRuntimeReg64 (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset
);
/**
Write the data to the XHCI runtime register.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the runtime register.
@param Data The data to write.
**/
VOID
XhcWriteRuntimeReg (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset,
IN UINT32 Data
);
@ -322,14 +328,14 @@ XhcWriteRuntimeReg (
/**
Write the data to the 8-bytes width XHCI runtime register.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the 8-bytes width runtime register.
@param Data The data to write.
**/
VOID
XhcWriteRuntimeReg64 (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset,
IN UINT64 Data
);
@ -337,7 +343,7 @@ XhcWriteRuntimeReg64 (
/**
Read XHCI door bell register.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the door bell register.
@return The register content read
@ -345,21 +351,21 @@ XhcWriteRuntimeReg64 (
**/
UINT32
XhcReadDoorBellReg (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset
);
/**
Write the data to the XHCI door bell register.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the door bell register.
@param Data The data to write.
**/
VOID
XhcWriteDoorBellReg (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset,
IN UINT32 Data
);
@ -367,14 +373,14 @@ XhcWriteDoorBellReg (
/**
Set one bit of the operational register while keeping other bits.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the operational register.
@param Bit The bit mask of the register to set.
**/
VOID
XhcSetOpRegBit (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset,
IN UINT32 Bit
);
@ -382,14 +388,14 @@ XhcSetOpRegBit (
/**
Clear one bit of the operational register while keeping other bits.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the operational register.
@param Bit The bit mask of the register to clear.
**/
VOID
XhcClearOpRegBit (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset,
IN UINT32 Bit
);
@ -398,7 +404,7 @@ XhcClearOpRegBit (
Wait the operation register's bit as specified by Bit
to be set (or clear).
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the operational register.
@param Bit The bit of the register to wait for.
@param WaitToSet Wait the bit to set or clear.
@ -410,7 +416,7 @@ XhcClearOpRegBit (
**/
EFI_STATUS
XhcWaitOpRegBit (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset,
IN UINT32 Bit,
IN BOOLEAN WaitToSet,
@ -420,7 +426,7 @@ XhcWaitOpRegBit (
/**
Read XHCI runtime register.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the runtime register.
@return The register content read
@ -428,21 +434,21 @@ XhcWaitOpRegBit (
**/
UINT32
XhcReadRuntimeReg (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset
);
/**
Write the data to the XHCI runtime register.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the runtime register.
@param Data The data to write.
**/
VOID
XhcWriteRuntimeReg (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset,
IN UINT32 Data
);
@ -450,14 +456,14 @@ XhcWriteRuntimeReg (
/**
Set one bit of the runtime register while keeping other bits.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the runtime register.
@param Bit The bit mask of the register to set.
**/
VOID
XhcSetRuntimeRegBit (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset,
IN UINT32 Bit
);
@ -465,14 +471,14 @@ XhcSetRuntimeRegBit (
/**
Clear one bit of the runtime register while keeping other bits.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Offset The offset of the runtime register.
@param Bit The bit mask of the register to set.
**/
VOID
XhcClearRuntimeRegBit (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Offset,
IN UINT32 Bit
);
@ -480,7 +486,7 @@ XhcClearRuntimeRegBit (
/**
Whether the XHCI host controller is halted.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@retval TRUE The controller is halted.
@retval FALSE It isn't halted.
@ -488,13 +494,13 @@ XhcClearRuntimeRegBit (
**/
BOOLEAN
XhcIsHalt (
IN USB_XHCI_DEV *Xhc
IN USB_XHCI_INSTANCE *Xhc
);
/**
Whether system error occurred.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@retval TRUE System error happened.
@retval FALSE No system error.
@ -502,13 +508,13 @@ XhcIsHalt (
**/
BOOLEAN
XhcIsSysError (
IN USB_XHCI_DEV *Xhc
IN USB_XHCI_INSTANCE *Xhc
);
/**
Reset the XHCI host controller.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Timeout Time to wait before abort (in millisecond, ms).
@retval EFI_SUCCESS The XHCI host controller is reset.
@ -517,14 +523,14 @@ XhcIsSysError (
**/
EFI_STATUS
XhcResetHC (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Timeout
);
/**
Halt the XHCI host controller.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Timeout Time to wait before abort (in millisecond, ms).
@return EFI_SUCCESS The XHCI host controller is halt.
@ -533,14 +539,14 @@ XhcResetHC (
**/
EFI_STATUS
XhcHaltHC (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Timeout
);
/**
Set the XHCI host controller to run.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Timeout Time to wait before abort (in millisecond, ms).
@return EFI_SUCCESS The XHCI host controller is running.
@ -549,21 +555,21 @@ XhcHaltHC (
**/
EFI_STATUS
XhcRunHC (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 Timeout
);
/**
Calculate the XHCI legacy support capability register offset.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@return The offset of XHCI legacy support capability register.
**/
UINT32
XhcGetLegSupCapAddr (
IN USB_XHCI_DEV *Xhc
IN USB_XHCI_INSTANCE *Xhc
);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -82,15 +82,29 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define TRB_COMPLETION_SHORT_PACKET 13
//
// USB device RouteChart record
// The topology string used to present usb device location
//
typedef union _USB_DEV_TOPOLOGY {
UINT32 Dword;
struct {
UINT32 RouteString:20; ///< The tier concatenation of down stream port
UINT32 RootPortNum:8; ///< The root port number of the chain
UINT32 TierNum:4; ///< The Tier the device reside
} Field;
typedef struct _USB_DEV_TOPOLOGY {
//
// The tier concatenation of down stream port.
//
UINT32 RouteString:20;
//
// The root port number of the chain.
//
UINT32 RootPortNum:8;
//
// The Tier the device reside.
//
UINT32 TierNum:4;
} USB_DEV_TOPOLOGY;
//
// USB Device's RouteChart
//
typedef union _USB_DEV_ROUTE {
UINT32 Dword;
USB_DEV_TOPOLOGY Route;
} USB_DEV_ROUTE;
//
@ -106,23 +120,26 @@ typedef struct _USB_ENDPOINT {
} USB_ENDPOINT;
//
// Command TRB
// TRB Template
//
typedef struct _TRB {
UINT32 Dword1;
UINT32 Dword2;
UINT32 Dword3;
typedef struct _TRB_TEMPLATE {
UINT32 Parameter1;
UINT32 Parameter2;
UINT32 Status;
UINT32 CycleBit:1;
UINT32 RsvdZ1:9;
UINT32 Type:6;
UINT32 RsvdZ2:16;
} TRB;
UINT32 Control:16;
} TRB_TEMPLATE;
typedef struct _TRANSFER_RING {
VOID *RingSeg0;
UINTN TrbNumber;
TRB *RingEnqueue;
TRB *RingDequeue;
TRB_TEMPLATE *RingEnqueue;
TRB_TEMPLATE *RingDequeue;
UINT32 RingPCS;
} TRANSFER_RING;
@ -131,8 +148,8 @@ typedef struct _EVENT_RING {
VOID *ERSTBase;
VOID *EventRingSeg0;
UINTN TrbNumber;
TRB *EventRingEnqueue;
TRB *EventRingDequeue;
TRB_TEMPLATE *EventRingEnqueue;
TRB_TEMPLATE *EventRingDequeue;
UINT32 EventRingCCS;
} EVENT_RING;
@ -164,40 +181,13 @@ typedef struct _URB {
// Command/Tranfer Ring info
//
TRANSFER_RING *Ring;
TRB *TrbStart;
TRB *TrbEnd;
TRB_TEMPLATE *TrbStart;
TRB_TEMPLATE *TrbEnd;
UINTN TrbNum;
EVENT_RING *EvtRing;
TRB *EvtTrbStart;
TRB_TEMPLATE *EvtTrbStart;
} URB;
//
// 5.5.2 Interrupter Register Set
//
typedef struct _INTERRUPTER_REGISTER_SET {
UINT32 InterrupterManagement;
UINT32 InterrupterModeration;
UINT32 RingSegTableSize:16;
UINT32 RsvdZ1:16;
UINT32 RsvdZ2;
UINT32 BasePtrLo;
UINT32 BasePtrHi;
UINT32 DequeLo;
UINT32 DequeHi;
} INTERRUPTER_REGISTER_SET;
//
// Host Controller Runtime Registers
//
typedef struct _HC_RUNTIME_REGS {
UINT32 MicroframeIndex;
UINT32 RsvdZ1;
UINT64 RsvdZ2;
UINT64 RsvdZ3;
UINT64 RsvdZ4;
INTERRUPTER_REGISTER_SET IR[1];
} HC_RUNTIME_REGS;
//
// 6.5 Event Ring Segment Table
// The Event Ring Segment Table is used to define multi-segment Event Rings and to enable runtime
@ -221,10 +211,13 @@ typedef struct _EVENT_RING_SEG_TABLE_ENTRY {
//
typedef struct _TRANSFER_TRB_NORMAL {
UINT32 TRBPtrLo;
UINT32 TRBPtrHi;
UINT32 Lenth:17;
UINT32 TDSize:5;
UINT32 IntTarget:10;
UINT32 CycleBit:1;
UINT32 ENT:1;
UINT32 ISP:1;
@ -242,7 +235,7 @@ typedef struct _TRANSFER_TRB_NORMAL {
// 6.4.1.2.1 Setup Stage TRB
// A Setup Stage TRB is created by system software to initiate a USB Setup packet on a control endpoint.
//
typedef struct _TRANSFER_TRB_CONTROL_SETUP{
typedef struct _TRANSFER_TRB_CONTROL_SETUP {
UINT32 bmRequestType:8;
UINT32 bRequest:8;
UINT32 wValue:16;
@ -270,10 +263,13 @@ typedef struct _TRANSFER_TRB_CONTROL_SETUP{
//
typedef struct _TRANSFER_TRB_CONTROL_DATA {
UINT32 TRBPtrLo;
UINT32 TRBPtrHi;
UINT32 Lenth:17;
UINT32 TDSize:5;
UINT32 IntTarget:10;
UINT32 CycleBit:1;
UINT32 ENT:1;
UINT32 ISP:1;
@ -294,8 +290,10 @@ typedef struct _TRANSFER_TRB_CONTROL_DATA {
typedef struct _TRANSFER_TRB_CONTROL_STATUS {
UINT32 RsvdZ1;
UINT32 RsvdZ2;
UINT32 RsvdZ3:22;
UINT32 IntTarget:10;
UINT32 CycleBit:1;
UINT32 ENT:1;
UINT32 RsvdZ4:2;
@ -314,15 +312,18 @@ typedef struct _TRANSFER_TRB_CONTROL_STATUS {
//
typedef struct _EVT_TRB_TRANSFER {
UINT32 TRBPtrLo;
UINT32 TRBPtrHi;
UINT32 Lenth:24;
UINT32 Completcode:8;
UINT32 Completecode:8;
UINT32 CycleBit:1;
UINT32 RsvdZ1:1;
UINT32 ED:1;
UINT32 RsvdZ2:7;
UINT32 Type:6;
UINT32 EndpointID:5;
UINT32 EndpointId:5;
UINT32 RsvdZ3:3;
UINT32 SlotId:8;
} EVT_TRB_TRANSFER;
@ -332,42 +333,39 @@ typedef struct _EVT_TRB_TRANSFER {
// A Command Completion Event TRB shall be generated by the xHC when a command completes on the
// Command Ring. Refer to section 4.11.4 for more information on the use of Command Completion Events.
//
typedef struct _EVT_TRB_COMMAND {
typedef struct _EVT_TRB_COMMAND_COMPLETION {
UINT32 TRBPtrLo;
UINT32 TRBPtrHi;
UINT32 RsvdZ2:24;
UINT32 Completcode:8;
UINT32 Completecode:8;
UINT32 CycleBit:1;
UINT32 RsvdZ3:9;
UINT32 Type:6;
UINT32 VFID:8;
UINT32 SlotId:8;
} EVT_TRB_COMMAND;
} EVT_TRB_COMMAND_COMPLETION;
//
// 6.4.2.3 Port Status Change Event TRB
//
typedef struct _EVT_TRB_PORT {
UINT32 RsvdZ1:24;
UINT32 PortID:8;
UINT32 RsvdZ2;
UINT32 RsvdZ3:24;
UINT32 Completcode:8;
UINT32 CycleBit:1;
UINT32 RsvdZ4:9;
UINT32 Type:6;
UINT32 RsvdZ5:16;
} EVT_TRB_PORT;
typedef union _TRB {
TRB_TEMPLATE TrbTemplate;
TRANSFER_TRB_NORMAL TrbNormal;
TRANSFER_TRB_CONTROL_SETUP TrbCtrSetup;
TRANSFER_TRB_CONTROL_DATA TrbCtrData;
TRANSFER_TRB_CONTROL_STATUS TrbCtrStatus;
} TRB;
//
// 6.4.3.1 No Op Command TRB
// The No Op Command TRB provides a simple means for verifying the operation of the Command Ring
// mechanisms offered by the xHCI.
// mechanisms offered by the xHCI.
//
typedef struct _CMD_TRB_NO_OP {
UINT32 RsvdZ0;
UINT32 RsvdZ1;
UINT32 RsvdZ2;
UINT32 CycleBit:1;
UINT32 RsvdZ3:9;
UINT32 Type:6;
@ -379,44 +377,33 @@ typedef struct _CMD_TRB_NO_OP {
// The Enable Slot Command TRB causes the xHC to select an available Device Slot and return the ID of the
// selected slot to the host in a Command Completion Event.
//
typedef struct _CMD_TRB_EN_SLOT {
typedef struct _CMD_TRB_ENABLE_SLOT {
UINT32 RsvdZ0;
UINT32 RsvdZ1;
UINT32 RsvdZ2;
UINT32 CycleBit:1;
UINT32 RsvdZ3:9;
UINT32 Type:6;
UINT32 RsvdZ4:16;
} CMD_TRB_EN_SLOT;
} CMD_TRB_ENABLE_SLOT;
//
// 6.4.3.3 Disable Slot Command TRB
// The Disable Slot Command TRB releases any bandwidth assigned to the disabled slot and frees any
// internal xHC resources assigned to the slot.
//
typedef struct _CMD_TRB_DIS_SLOT {
typedef struct _CMD_TRB_DISABLE_SLOT {
UINT32 RsvdZ0;
UINT32 RsvdZ1;
UINT32 RsvdZ2;
UINT32 CycleBit:1;
UINT32 RsvdZ3:9;
UINT32 Type:6;
UINT32 RsvdZ4:8;
UINT32 SlotId:8;
} CMD_TRB_DIS_SLOT;
typedef struct _CMD_TRB_RESET_PORT {
UINT32 RsvdZ0;
UINT32 RsvdZ1;
UINT32 RsvdZ2;
UINT32 CycleBit:1;
UINT32 RsvdZ3:8;
UINT32 Tsp:1;
UINT32 Type:6;
UINT32 Endpoint:5;
UINT32 RsvdZ4:3;
UINT32 SlotId:8;
} CMD_TRB_RESET_PORT;
} CMD_TRB_DISABLE_SLOT;
//
// 6.4.3.4 Address Device Command TRB
@ -424,34 +411,40 @@ typedef struct _CMD_TRB_RESET_PORT {
// Addressed state and causes the xHC to select an address for the USB device in the Default State and
// issue a SET_ADDRESS request to the USB device.
//
typedef struct _CMD_TRB_ADDR_DEV {
typedef struct _CMD_TRB_ADDRESS_DEVICE {
UINT32 PtrLo;
UINT32 PtrHi;
UINT32 RsvdZ1;
UINT32 CycleBit:1;
UINT32 RsvdZ2:8;
UINT32 BSR:1;
UINT32 Type:6;
UINT32 RsvdZ3:8;
UINT32 SlotId:8;
} CMD_TRB_ADDR_DEV;
} CMD_TRB_ADDRESS_DEVICE;
//
// 6.4.3.5 Configure Endpoint Command TRB
// The Configure Endpoint Command TRB evaluates the bandwidth and resource requirements of the
// endpoints selected by the command.
//
typedef struct _CMD_CFG_ED {
typedef struct _CMD_TRB_CONFIG_ENDPOINT {
UINT32 PtrLo;
UINT32 PtrHi;
UINT32 RsvdZ1;
UINT32 CycleBit:1;
UINT32 RsvdZ2:8;
UINT32 DC:1;
UINT32 Type:6;
UINT32 RsvdZ3:8;
UINT32 SlotId:8;
} CMD_CFG_ED;
} CMD_TRB_CONFIG_ENDPOINT;
//
// 6.4.3.6 Evaluate Context Command TRB
@ -459,25 +452,29 @@ typedef struct _CMD_CFG_ED {
// Context data structures in the Device Context have been modified by system software and that the xHC
// shall evaluate any changes
//
typedef struct _CMD_TRB_EVALU_CONTX {
typedef struct _CMD_TRB_EVALUATE_CONTEXT {
UINT32 PtrLo;
UINT32 PtrHi;
UINT32 RsvdZ1;
UINT32 CycleBit:1;
UINT32 RsvdZ2:9;
UINT32 Type:6;
UINT32 RsvdZ3:8;
UINT32 SlotId:8;
} CMD_TRB_EVALU_CONTX;
} CMD_TRB_EVALUATE_CONTEXT;
//
// 6.4.3.7 Reset Endpoint Command TRB
// The Reset Endpoint Command TRB is used by system software to reset a specified Transfer Ring
//
typedef struct _CMD_TRB_RESET_ED {
typedef struct _CMD_TRB_RESET_ENDPOINT {
UINT32 RsvdZ0;
UINT32 RsvdZ1;
UINT32 RsvdZ2;
UINT32 CycleBit:1;
UINT32 RsvdZ3:8;
UINT32 TSP:1;
@ -485,17 +482,18 @@ typedef struct _CMD_TRB_RESET_ED {
UINT32 EDID:5;
UINT32 RsvdZ4:3;
UINT32 SlotId:8;
} CMD_TRB_RESET_ED;
} CMD_TRB_RESET_ENDPOINT;
//
// 6.4.3.8 Stop Endpoint Command TRB
// The Stop Endpoint Command TRB command allows software to stop the xHC execution of the TDs on a
// Transfer Ring and temporarily take ownership of TDs that had previously been passed to the xHC.
//
typedef struct _CMD_TRB_STOP_ED {
typedef struct _CMD_TRB_STOP_ENDPOINT {
UINT32 RsvdZ0;
UINT32 RsvdZ1;
UINT32 RsvdZ2;
UINT32 CycleBit:1;
UINT32 RsvdZ3:9;
UINT32 Type:6;
@ -503,34 +501,41 @@ typedef struct _CMD_TRB_STOP_ED {
UINT32 RsvdZ4:2;
UINT32 SP:1;
UINT32 SlotId:8;
} CMD_TRB_STOP_ED;
} CMD_TRB_STOP_ENDPOINT;
//
// 6.4.3.9 Set TR Dequeue Pointer Command TRB
// The Set TR Dequeue Pointer Command TRB is used by system software to modify the TR Dequeue
// Pointer and DCS fields of an Endpoint or Stream Context.
//
typedef struct _CMD_SET_TR_DEQ {
typedef struct _CMD_SET_TR_DEQ_POINTER {
UINT32 PtrLo;
UINT32 PtrHi;
UINT32 RsvdZ1:16;
UINT32 StreamID:16;
UINT32 CycleBit:1;
UINT32 RsvdZ2:9;
UINT32 Type:6;
UINT32 Endpoint:5;
UINT32 RsvdZ3:3;
UINT32 SlotId:8;
} CMD_SET_TR_DEQ;
} CMD_SET_TR_DEQ_POINTER;
//
// 6.4.4.1 Link TRB
// A Link TRB provides support for non-contiguous TRB Rings.
//
typedef struct _LNK_TRB {
typedef struct _LINK_TRB {
UINT32 PtrLo;
UINT32 PtrHi;
UINT32 RsvdZ1:22;
UINT32 InterTarget:10;
UINT32 CycleBit:1;
UINT32 TC:1;
UINT32 RsvdZ2:2;
@ -539,26 +544,13 @@ typedef struct _LNK_TRB {
UINT32 RsvdZ3:4;
UINT32 Type:6;
UINT32 RsvdZ4:16;
} LNK_TRB;
//
// A Link TRB provides support for non-contiguous TRB Rings.
//
typedef struct _NO_OP_TRB {
UINT32 RsvdZ0;
UINT32 RsvdZ1;
UINT32 RsvdZ2;
UINT32 CycleBit:1;
UINT32 RsvdZ3:9;
UINT32 Type:6;
UINT32 RsvdZ4:16;
} CMD_NO_OP_TRB;
} LINK_TRB;
//
// 6.2.2 Slot Context
//
typedef struct _SLOT_CONTEXT {
UINT32 RouteStr:20;
UINT32 RouteString:20;
UINT32 Speed:4;
UINT32 RsvdZ1:1;
UINT32 MTT:1;
@ -651,29 +643,29 @@ typedef struct _INPUT_CONTEXT {
/**
Initialize the XHCI host controller for schedule.
@param Xhc The XHCI device to be initialized.
@param Xhc The XHCI Instance to be initialized.
**/
VOID
XhcInitSched (
IN USB_XHCI_DEV *Xhc
IN USB_XHCI_INSTANCE *Xhc
);
/**
Free the resouce allocated at initializing schedule.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
**/
VOID
XhcFreeSched (
IN USB_XHCI_DEV *Xhc
IN USB_XHCI_INSTANCE *Xhc
);
/**
Ring the door bell to notify XHCI there is a transaction to be executed through URB.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Urb The URB to be rung.
@retval EFI_SUCCESS Successfully ring the door bell.
@ -681,17 +673,17 @@ XhcFreeSched (
**/
EFI_STATUS
RingIntTransferDoorBell (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN URB *Urb
);
/**
Execute the transfer by polling the URB. This is a synchronous operation.
@param Xhc The XHCI device.
@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 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.
@ -700,17 +692,17 @@ RingIntTransferDoorBell (
**/
EFI_STATUS
XhcExecTransfer (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN BOOLEAN CmdTransfer,
IN URB *Urb,
IN UINTN TimeOut
IN UINTN Timeout
);
/**
Delete a single asynchronous interrupt transfer for
the device and endpoint.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param DevAddr The address of the target device.
@param EpNum The endpoint of the target.
@ -720,7 +712,7 @@ XhcExecTransfer (
**/
EFI_STATUS
XhciDelAsyncIntTransfer (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT8 DevAddr,
IN UINT8 EpNum
);
@ -728,39 +720,40 @@ XhciDelAsyncIntTransfer (
/**
Remove all the asynchronous interrupt transfers.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
**/
VOID
XhciDelAllAsyncIntTransfers (
IN USB_XHCI_DEV *Xhc
IN USB_XHCI_INSTANCE *Xhc
);
/**
Set Bios Ownership
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
**/
VOID
XhcSetBiosOwnership (
IN USB_XHCI_DEV *Xhc
IN USB_XHCI_INSTANCE *Xhc
);
/**
Clear Bios Ownership
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
**/
VOID
XhcClearBiosOwnership (
IN USB_XHCI_DEV *Xhc
IN USB_XHCI_INSTANCE *Xhc
);
/**
Find out the slot id according to device address assigned by XHCI's Address_Device cmd.
@param Xhc The XHCI Instance.
@param DevAddr The device address of the target device.
@return The slot id used by the device.
@ -768,13 +761,15 @@ XhcClearBiosOwnership (
**/
UINT8
XhcDevAddrToSlotId (
IN UINT8 DevAddr
IN USB_XHCI_INSTANCE *Xhc,
IN UINT8 DevAddr
);
/**
Find out the slot id according to the device's route string.
@param RouteString The route string described the device location.
@param Xhc The XHCI Instance.
@param RouteString The route string described the device location.
@return The slot id used by the device.
@ -782,7 +777,8 @@ XhcDevAddrToSlotId (
UINT8
EFIAPI
XhcRouteStringToSlotId (
IN USB_DEV_ROUTE RouteString
IN USB_XHCI_INSTANCE *Xhc,
IN USB_DEV_ROUTE RouteString
);
/**
@ -803,7 +799,7 @@ XhcEndpointToDci (
/**
Ring the door bell to notify XHCI there is a transaction to be executed.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param SlotId The slot id of the target device.
@param Dci The device context index of the target slot or endpoint.
@ -813,7 +809,7 @@ XhcEndpointToDci (
EFI_STATUS
EFIAPI
XhcRingDoorBell (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT8 SlotId,
IN UINT8 Dci
);
@ -822,7 +818,7 @@ XhcRingDoorBell (
Interrupt transfer periodic check handler.
@param Event Interrupt event.
@param Context Pointer to USB_XHCI_DEV.
@param Context Pointer to USB_XHCI_INSTANCE.
**/
VOID
@ -835,7 +831,7 @@ XhcMonitorAsyncRequests (
/**
Monitor the port status change. Enable/Disable device slot if there is a device attached/detached.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param ParentRouteChart The route string pointed to the parent device if it exists.
@param Port The port to be polled.
@param PortState The port state.
@ -847,7 +843,7 @@ XhcMonitorAsyncRequests (
EFI_STATUS
EFIAPI
XhcPollPortStatusChange (
IN USB_XHCI_DEV* Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN USB_DEV_ROUTE ParentRouteChart,
IN UINT8 Port,
IN EFI_USB_PORT_STATUS *PortState
@ -856,7 +852,7 @@ XhcPollPortStatusChange (
/**
Evaluate the slot context for hub device through XHCI's Configure_Endpoint cmd.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param SlotId The slot id to be configured.
@param PortNum The total number of downstream port supported by the hub.
@param TTT The TT think time of the hub device.
@ -867,7 +863,7 @@ XhcPollPortStatusChange (
**/
EFI_STATUS
XhcConfigHubContext (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT8 SlotId,
IN UINT8 PortNum,
IN UINT8 TTT,
@ -877,7 +873,7 @@ XhcConfigHubContext (
/**
Configure all the device endpoints through XHCI's Configure_Endpoint cmd.
@param Xhc The XHCI device.
@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.
@ -888,7 +884,7 @@ XhcConfigHubContext (
EFI_STATUS
EFIAPI
XhcSetConfigCmd (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT8 SlotId,
IN UINT8 DeviceSpeed,
IN USB_CONFIG_DESCRIPTOR *ConfigDesc
@ -897,7 +893,8 @@ XhcSetConfigCmd (
/**
Find out the actual device address according to the requested device address from UsbBus.
@param BusDevAddr The requested device address by UsbBus upper driver.
@param Xhc The XHCI Instance.
@param BusDevAddr The requested device address by UsbBus upper driver.
@return The actual device address assigned to the device.
@ -905,13 +902,14 @@ XhcSetConfigCmd (
UINT8
EFIAPI
XhcBusDevAddrToSlotId (
IN UINT8 BusDevAddr
IN USB_XHCI_INSTANCE *Xhc,
IN UINT8 BusDevAddr
);
/**
Assign and initialize the device slot for a new device.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param ParentRouteChart The route string pointed to the parent device.
@param ParentPort The port at which the device is located.
@param RouteChart The route string pointed to the device.
@ -923,7 +921,7 @@ XhcBusDevAddrToSlotId (
EFI_STATUS
EFIAPI
XhcInitializeDeviceSlot (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN USB_DEV_ROUTE ParentRouteChart,
IN UINT16 ParentPort,
IN USB_DEV_ROUTE RouteChart,
@ -933,7 +931,7 @@ XhcInitializeDeviceSlot (
/**
Evaluate the endpoint 0 context through XHCI's Evaluate_Context cmd.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param SlotId The slot id to be evaluated.
@param MaxPacketSize The max packet size supported by the device control transfer.
@ -943,7 +941,7 @@ XhcInitializeDeviceSlot (
EFI_STATUS
EFIAPI
XhcEvaluateContext (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT8 SlotId,
IN UINT32 MaxPacketSize
);
@ -951,7 +949,7 @@ XhcEvaluateContext (
/**
Disable the specified device slot.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param SlotId The slot id to be disabled.
@retval EFI_SUCCESS Successfully disable the device slot.
@ -960,14 +958,14 @@ XhcEvaluateContext (
EFI_STATUS
EFIAPI
XhcDisableSlotCmd (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT8 SlotId
);
/**
Synchronize the specified transfer ring to update the enqueue and dequeue pointer.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param TrsRing The transfer ring to sync.
@retval EFI_SUCCESS The transfer ring is synchronized successfully.
@ -976,14 +974,14 @@ XhcDisableSlotCmd (
EFI_STATUS
EFIAPI
XhcSyncTrsRing (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
TRANSFER_RING *TrsRing
);
/**
Synchronize the specified event ring to update the enqueue and dequeue pointer.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param EvtRing The event ring to sync.
@retval EFI_SUCCESS The event ring is synchronized successfully.
@ -992,14 +990,14 @@ XhcSyncTrsRing (
EFI_STATUS
EFIAPI
XhcSyncEventRing (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
EVENT_RING *EvtRing
);
/**
Check if there is a new generated event.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param EvtRing The event ring to check.
@param NewEvtTrb The new event TRB found.
@ -1010,22 +1008,22 @@ XhcSyncEventRing (
EFI_STATUS
EFIAPI
XhcCheckNewEvent (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN EVENT_RING *EvtRing,
OUT TRB **NewEvtTrb
OUT TRB_TEMPLATE **NewEvtTrb
);
/**
Create XHCI transfer ring.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param TrbNum The number of TRB in the ring.
@param TransferRing The created transfer ring.
**/
VOID
CreateTransferRing (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINTN TrbNum,
OUT TRANSFER_RING *TransferRing
);
@ -1033,14 +1031,14 @@ CreateTransferRing (
/**
Create XHCI event ring.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param EventInterrupter The interrupter of event.
@param EventRing The created event ring.
**/
VOID
CreateEventRing (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT8 EventInterrupter,
OUT EVENT_RING *EventRing
);
@ -1052,7 +1050,7 @@ CreateEventRing (
reenabled. The next write to the Doorbell of the Endpoint will transition the Endpoint Context from the
Stopped to the Running state.
@param Xhc The XHCI device.
@param Xhc The XHCI Instance.
@param Urb The urb which makes the endpoint halted.
@retval EFI_SUCCESS The recovery is successful.
@ -1062,14 +1060,14 @@ CreateEventRing (
EFI_STATUS
EFIAPI
XhcRecoverHaltedEndpoint (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN URB *Urb
);
/**
Create a new URB for a new transaction.
@param Xhc The XHCI device
@param Xhc The XHCI Instance
@param DevAddr The device address
@param EpAddr Endpoint addrress
@param DevSpeed The device speed
@ -1086,7 +1084,7 @@ XhcRecoverHaltedEndpoint (
**/
URB*
XhcCreateUrb (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN UINT8 DevAddr,
IN UINT8 EpAddr,
IN UINT8 DevSpeed,
@ -1102,7 +1100,7 @@ XhcCreateUrb (
/**
Create a transfer TRB.
@param Xhc The XHCI device
@param Xhc The XHCI Instance
@param Urb The urb used to construct the transfer TRB.
@return Created TRB or NULL
@ -1110,7 +1108,7 @@ XhcCreateUrb (
**/
EFI_STATUS
XhcCreateTransferTrb (
IN USB_XHCI_DEV *Xhc,
IN USB_XHCI_INSTANCE *Xhc,
IN URB *Urb
);

View File

@ -45,8 +45,6 @@ EFI_DRIVER_BINDING_PROTOCOL mUsbBusDriverBinding = {
NULL
};
UINT16 mMaxUsbDeviceNum = USB_MAX_DEVICES;
/**
USB_IO function to execute a control transfer. This
function will execute the USB transfer. If transfer
@ -112,7 +110,7 @@ UsbIoControlTransfer (
// Clear TT buffer when CTRL/BULK split transaction failes
// Clear the TRANSLATOR TT buffer, not parent's buffer
//
ASSERT (Dev->Translator.TranslatorHubAddress < mMaxUsbDeviceNum);
ASSERT (Dev->Translator.TranslatorHubAddress < Dev->Bus->MaxDevices);
if (Dev->Translator.TranslatorHubAddress != 0) {
UsbHubCtrlClearTTBuffer (
Dev->Bus->Devices[Dev->Translator.TranslatorHubAddress],
@ -285,7 +283,7 @@ UsbIoBulkTransfer (
// Clear TT buffer when CTRL/BULK split transaction failes.
// Clear the TRANSLATOR TT buffer, not parent's buffer
//
ASSERT (Dev->Translator.TranslatorHubAddress < mMaxUsbDeviceNum);
ASSERT (Dev->Translator.TranslatorHubAddress < Dev->Bus->MaxDevices);
if (Dev->Translator.TranslatorHubAddress != 0) {
UsbHubCtrlClearTTBuffer (
Dev->Bus->Devices[Dev->Translator.TranslatorHubAddress],
@ -913,8 +911,9 @@ UsbBusBuildProtocol (
return EFI_OUT_OF_RESOURCES;
}
UsbBus->Signature = USB_BUS_SIGNATURE;
UsbBus->HostHandle = Controller;
UsbBus->Signature = USB_BUS_SIGNATURE;
UsbBus->HostHandle = Controller;
UsbBus->MaxDevices = USB_MAX_DEVICES;
Status = gBS->OpenProtocol (
Controller,
@ -966,12 +965,12 @@ UsbBusBuildProtocol (
}
if (!EFI_ERROR (Status)) {
//
// The EFI_USB2_HC_PROTOCOL is produced for XHCI support.
// Then its max supported devices are 256. Otherwise it's 128.
//
if (UsbBus->Usb2Hc->MajorRevision == 0x3) {
//
// The EFI_USB2_HC_PROTOCOL is produced for XHCI support.
// Then its max supported devices are 256.
//
mMaxUsbDeviceNum = 256;
UsbBus->MaxDevices = 256;
}
}
@ -1444,7 +1443,8 @@ UsbBusControllerDriverStop (
mUsbRootHubApi.Release (RootIf);
for (Index = 1; Index < mMaxUsbDeviceNum; Index++) {
ASSERT (Bus->MaxDevices <= 256);
for (Index = 1; Index < Bus->MaxDevices; Index++) {
if (Bus->Devices[Index] != NULL) {
UsbRemoveDevice (Bus->Devices[Index]);
}

View File

@ -246,6 +246,12 @@ struct _USB_BUS {
EFI_USB2_HC_PROTOCOL *Usb2Hc;
EFI_USB_HC_PROTOCOL *UsbHc;
//
// Recorded the max supported usb devices.
// XHCI can support up to 255 devices.
// EHCI/UHCI/OHCI supports up to 127 devices.
//
UINT32 MaxDevices;
//
// An array of device that is on the bus. Devices[0] is
// for root hub. Device with address i is at Devices[i].
@ -747,7 +753,6 @@ UsbBusControllerDriverStop (
IN EFI_HANDLE *ChildHandleBuffer
);
extern UINT16 mMaxUsbDeviceNum;
extern EFI_USB_IO_PROTOCOL mUsbIoProtocol;
extern EFI_DRIVER_BINDING_PROTOCOL mUsbBusDriverBinding;
extern EFI_COMPONENT_NAME_PROTOCOL mUsbBusComponentName;

View File

@ -548,7 +548,7 @@ UsbRemoveDevice (
// Remove all the devices on its downstream ports. Search from devices[1].
// Devices[0] is the root hub.
//
for (Index = 1; Index < mMaxUsbDeviceNum; Index++) {
for (Index = 1; Index < Bus->MaxDevices; Index++) {
Child = Bus->Devices[Index];
if ((Child == NULL) || (Child->ParentAddr != Device->Address)) {
@ -567,7 +567,7 @@ UsbRemoveDevice (
DEBUG (( EFI_D_INFO, "UsbRemoveDevice: device %d removed\n", Device->Address));
ASSERT (Device->Address < mMaxUsbDeviceNum);
ASSERT (Device->Address < Bus->MaxDevices);
Bus->Devices[Device->Address] = NULL;
UsbFreeDevice (Device);
@ -599,7 +599,7 @@ UsbFindChild (
//
// Start checking from device 1, device 0 is the root hub
//
for (Index = 1; Index < mMaxUsbDeviceNum; Index++) {
for (Index = 1; Index < Bus->MaxDevices; Index++) {
Device = Bus->Devices[Index];
if ((Device != NULL) && (Device->ParentAddr == HubIf->Device->Address) &&
@ -639,11 +639,11 @@ UsbEnumerateNewDev (
UINT8 Config;
EFI_STATUS Status;
Address = mMaxUsbDeviceNum;
Parent = HubIf->Device;
Bus = Parent->Bus;
HubApi = HubIf->HubApi;
HubApi = HubIf->HubApi;
Address = Bus->MaxDevices;
gBS->Stall (USB_WAIT_PORT_STABLE_STALL);
//
@ -731,13 +731,14 @@ UsbEnumerateNewDev (
// status stage with default address, then switches to new address.
// ADDRESS state. Address zero is reserved for root hub.
//
for (Address = 1; Address < mMaxUsbDeviceNum; Address++) {
ASSERT (Bus->MaxDevices <= 256);
for (Address = 1; Address < Bus->MaxDevices; Address++) {
if (Bus->Devices[Address] == NULL) {
break;
}
}
if (Address == mMaxUsbDeviceNum) {
if (Address >= Bus->MaxDevices) {
DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: address pool is full for port %d\n", Port));
Status = EFI_ACCESS_DENIED;
@ -808,7 +809,7 @@ UsbEnumerateNewDev (
return EFI_SUCCESS;
ON_ERROR:
if (Address != mMaxUsbDeviceNum) {
if (Address != Bus->MaxDevices) {
Bus->Devices[Address] = NULL;
}