From a9292c1363437b081ea72fd8f3b2ed075e2a7ef3 Mon Sep 17 00:00:00 2001 From: erictian Date: Wed, 14 Sep 2011 12:13:03 +0000 Subject: [PATCH] 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 --- MdeModulePkg/Bus/Pci/XhciDxe/ComponentName.c | 2 +- MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c | 257 +++--- MdeModulePkg/Bus/Pci/XhciDxe/Xhci.h | 528 +++++++++-- MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf | 2 - MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c | 115 +-- MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h | 174 ++-- MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c | 894 ++++++++----------- MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.h | 340 ++++--- MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c | 24 +- MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.h | 7 +- MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c | 19 +- 11 files changed, 1315 insertions(+), 1047 deletions(-) diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/ComponentName.c b/MdeModulePkg/Bus/Pci/XhciDxe/ComponentName.c index 2975e5612f..706aa292c8 100644 --- a/MdeModulePkg/Bus/Pci/XhciDxe/ComponentName.c +++ b/MdeModulePkg/Bus/Pci/XhciDxe/ComponentName.c @@ -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. diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c b/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c index 30eb3ea916..bbde0ca0b7 100644 --- a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c +++ b/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c @@ -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); diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.h b/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.h index 953ba4c5c2..3793d9c1c2 100644 --- a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.h +++ b/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.h @@ -29,42 +29,41 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include -#include #include #include -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) +// +// XHC delay experience value for polling operation. +// The unit is microsecond, set it as 1ms. // -// Sync and Async transfer polling interval, set by experience, -// and the unit of Async is 100us, means 50ms as interval. +#define XHC_POLL_DELAY (1000) // -#define XHC_SYNC_POLL_INTERVAL (20 * XHC_1_MILLISECOND) -#define XHC_ASYNC_POLL_INTERVAL (50 * 10000U) +// 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; -}; - -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. + // Store device contexts managed by XHCI instance + // The array supports up to 255 devices, entry 0 is reserved and should not be used. // - EFI_USB_CONFIG_DESCRIPTOR **ConfDesc; + USB_DEV_CONTEXT UsbDevContext[256]; }; + 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 diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf b/MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf index da701a62b6..286f3ac321 100644 --- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf +++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf @@ -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 diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c b/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c index d4c22d094e..874967974c 100644 --- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c +++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c @@ -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 ) { diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h b/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h index d004bf989a..c1c086cf28 100644 --- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h +++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h @@ -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 diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c index 370b8ea441..6745d2f81a 100644 --- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c +++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c @@ -15,167 +15,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "Xhci.h" -/** - Allocates a buffer of a certain pool type at a specified alignment. - - Allocates the number bytes specified by AllocationSize of a certain pool type with an alignment - specified by Alignment. The allocated buffer is returned. If AllocationSize is 0, then a valid - buffer of 0 size is returned. If there is not enough memory at the specified alignment remaining - to satisfy the request, then NULL is returned. - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - - @param PoolType The type of pool to allocate. - @param AllocationSize The number of bytes to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateAlignedPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize, - IN UINTN Alignment - ) -{ - VOID *RawAddress; - UINTN AlignedAddress; - UINTN AlignmentMask; - UINTN OverAllocationSize; - UINTN RealAllocationSize; - VOID **FreePointer; - - // - // Alignment must be a power of two or zero. - // - ASSERT ((Alignment & (Alignment - 1)) == 0); - - if (Alignment == 0) { - AlignmentMask = Alignment; - } else { - AlignmentMask = Alignment - 1; - } - // - // Calculate the extra memory size, over-allocate memory pool and get the aligned memory address. - // - OverAllocationSize = sizeof (RawAddress) + AlignmentMask; - RealAllocationSize = AllocationSize + OverAllocationSize; - // - // Make sure that AllocationSize plus OverAllocationSize does not overflow. - // - ASSERT (RealAllocationSize > AllocationSize); - - RawAddress = NULL; - gBS->AllocatePool (PoolType, RealAllocationSize, &RawAddress); - if (RawAddress == NULL) { - return NULL; - } - AlignedAddress = ((UINTN) RawAddress + OverAllocationSize) & ~AlignmentMask; - // - // Save the original memory address just before the aligned address. - // - FreePointer = (VOID **)(AlignedAddress - sizeof (RawAddress)); - *FreePointer = RawAddress; - - return (VOID *) AlignedAddress; -} - -/** - Allocates and zeros a buffer of a certain pool type at a specified alignment. - - Allocates the number bytes specified by AllocationSize of a certain pool type with an alignment - specified by Alignment, clears the buffer with zeros, and returns a pointer to the allocated - buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory at the specified alignment remaining to satisfy the request, then NULL is returned. - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - - @param PoolType The type of pool to allocate. - @param AllocationSize The number of bytes to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateAlignedZeroPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize, - IN UINTN Alignment - ) -{ - VOID *Memory; - Memory = InternalAllocateAlignedPool (PoolType, AllocationSize, Alignment); - if (Memory != NULL) { - ZeroMem (Memory, AllocationSize); - } - return Memory; -} - -/** - Allocates and zeros a buffer of type EfiBootServicesData at a specified alignment. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData with an - alignment specified by Alignment, clears the buffer with zeros, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory at the specified alignment remaining to satisfy the request, then NULL is - returned. - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - - @param AllocationSize The number of bytes to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedZeroPool ( - IN UINTN AllocationSize, - IN UINTN Alignment - ) -{ - return InternalAllocateAlignedZeroPool (EfiBootServicesData, AllocationSize, Alignment); -} - -/** - Frees a buffer that was previously allocated with one of the aligned pool allocation functions - in the Memory Allocation Library. - - Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the - aligned pool allocation services of the Memory Allocation Library. - If Buffer was not allocated with an aligned pool allocation function in the Memory Allocation - Library, then ASSERT(). - - @param Buffer Pointer to the buffer to free. - -**/ -VOID -EFIAPI -FreeAlignedPool ( - IN VOID *Buffer - ) -{ - VOID *RawAddress; - VOID **FreePointer; - EFI_STATUS Status; - - // - // Get the pre-saved original address in the over-allocate pool. - // - FreePointer = (VOID **)((UINTN) Buffer - sizeof (RawAddress)); - RawAddress = *FreePointer; - - Status = gBS->FreePool (RawAddress); - ASSERT_EFI_ERROR (Status); -} - /** Create a command transfer TRB to support XHCI command interfaces. - @param Xhc The XHCI device. + @param Xhc The XHCI Instance. @param CmdTrb The cmd TRB to be executed. @return Created URB or NULL. @@ -183,8 +26,8 @@ FreeAlignedPool ( **/ URB* XhcCreateCmdTrb ( - IN USB_XHCI_DEV *Xhc, - IN TRB *CmdTrb + IN USB_XHCI_INSTANCE *Xhc, + IN TRB_TEMPLATE *CmdTrb ) { URB *Urb; @@ -200,7 +43,7 @@ XhcCreateCmdTrb ( XhcSyncTrsRing (Xhc, Urb->Ring); Urb->TrbNum = 1; Urb->TrbStart = Urb->Ring->RingEnqueue; - CopyMem (Urb->TrbStart, CmdTrb, sizeof (TRB)); + CopyMem (Urb->TrbStart, CmdTrb, sizeof (TRB_TEMPLATE)); Urb->TrbStart->CycleBit = Urb->Ring->RingPCS & BIT0; Urb->TrbEnd = Urb->TrbStart; @@ -214,9 +57,9 @@ XhcCreateCmdTrb ( /** Execute a XHCI cmd TRB pointed by CmdTrb. - @param Xhc The XHCI device. + @param Xhc The XHCI Instance. @param CmdTrb The cmd TRB to be executed. - @param TimeOut Indicates the maximum time, in millisecond, which the + @param Timeout Indicates the maximum time, in millisecond, which the transfer is allowed to complete. @param EvtTrb The event TRB corresponding to the cmd TRB. @@ -229,10 +72,10 @@ XhcCreateCmdTrb ( EFI_STATUS EFIAPI XhcCmdTransfer ( - IN USB_XHCI_DEV *Xhc, - IN TRB *CmdTrb, - IN UINTN TimeOut, - OUT TRB **EvtTrb + IN USB_XHCI_INSTANCE *Xhc, + IN TRB_TEMPLATE *CmdTrb, + IN UINTN Timeout, + OUT TRB_TEMPLATE **EvtTrb ) { EFI_STATUS Status; @@ -265,7 +108,7 @@ XhcCmdTransfer ( ASSERT (Urb->EvtRing == &Xhc->CmdEventRing); - Status = XhcExecTransfer (Xhc, TRUE, Urb, TimeOut); + Status = XhcExecTransfer (Xhc, TRUE, Urb, Timeout); *EvtTrb = Urb->EvtTrbStart; if (Urb->Result == EFI_USB_NOERROR) { @@ -281,7 +124,7 @@ ON_EXIT: /** 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 @@ -298,7 +141,7 @@ ON_EXIT: **/ URB* XhcCreateUrb ( - IN USB_XHCI_DEV *Xhc, + IN USB_XHCI_INSTANCE *Xhc, IN UINT8 DevAddr, IN UINT8 EpAddr, IN UINT8 DevSpeed, @@ -345,7 +188,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 @@ -353,11 +196,11 @@ XhcCreateUrb ( **/ EFI_STATUS XhcCreateTransferTrb ( - IN USB_XHCI_DEV *Xhc, + IN USB_XHCI_INSTANCE *Xhc, IN URB *Urb ) { - DEVICE_CONTEXT *OutputDevContxt; + DEVICE_CONTEXT *OutputContext; TRANSFER_RING *EPRing; UINT8 EPType; UINT8 SlotId; @@ -367,12 +210,13 @@ XhcCreateTransferTrb ( UINTN Len; UINTN TrbNum; - SlotId = XhcDevAddrToSlotId(Urb->Ep.DevAddr); + SlotId = XhcDevAddrToSlotId(Xhc, Urb->Ep.DevAddr); Dci = XhcEndpointToDci (Urb->Ep.EpAddr, (UINT8)(Urb->Ep.Direction)); - EPRing = (TRANSFER_RING *)(UINTN) UsbDevContext[SlotId].EndpointTransferRing[Dci-1]; + ASSERT (Dci < 32); + EPRing = (TRANSFER_RING *)(UINTN) Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]; Urb->Ring = EPRing; - OutputDevContxt = (DEVICE_CONTEXT *)(UINTN) Xhc->DCBAA[SlotId]; - EPType = (UINT8) OutputDevContxt->EP[Dci-1].EPType; + OutputContext = (DEVICE_CONTEXT *)(UINTN) Xhc->DCBAA[SlotId]; + EPType = (UINT8) OutputContext->EP[Dci-1].EPType; // // Construct the TRB @@ -387,28 +231,28 @@ XhcCreateTransferTrb ( // // For control transfer, create SETUP_STAGE_TRB first. // - TrbStart = EPRing->RingEnqueue; - ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->bmRequestType = Urb->Request->RequestType; - ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->bRequest = Urb->Request->Request; - ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->wValue = Urb->Request->Value; - ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->wIndex = Urb->Request->Index; - ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->wLength = Urb->Request->Length; - ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->Lenth = 8; - ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->IntTarget = Urb->EvtRing->EventInterrupter; - ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->IOC = 1; - ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->IDT = 1; - ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->Type = TRB_TYPE_SETUP_STAGE; + TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue; + TrbStart->TrbCtrSetup.bmRequestType = Urb->Request->RequestType; + TrbStart->TrbCtrSetup.bRequest = Urb->Request->Request; + TrbStart->TrbCtrSetup.wValue = Urb->Request->Value; + TrbStart->TrbCtrSetup.wIndex = Urb->Request->Index; + TrbStart->TrbCtrSetup.wLength = Urb->Request->Length; + TrbStart->TrbCtrSetup.Lenth = 8; + TrbStart->TrbCtrSetup.IntTarget = Urb->EvtRing->EventInterrupter; + TrbStart->TrbCtrSetup.IOC = 1; + TrbStart->TrbCtrSetup.IDT = 1; + TrbStart->TrbCtrSetup.Type = TRB_TYPE_SETUP_STAGE; if (Urb->Ep.Direction == EfiUsbDataIn) { - ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->TRT = 3; + TrbStart->TrbCtrSetup.TRT = 3; } else if (Urb->Ep.Direction == EfiUsbDataOut) { - ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->TRT = 2; + TrbStart->TrbCtrSetup.TRT = 2; } else { - ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->TRT = 0; + TrbStart->TrbCtrSetup.TRT = 0; } // // Update the cycle bit // - ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->CycleBit = EPRing->RingPCS & BIT0; + TrbStart->TrbCtrSetup.CycleBit = EPRing->RingPCS & BIT0; Urb->TrbNum++; // @@ -416,28 +260,28 @@ XhcCreateTransferTrb ( // if (Urb->DataLen > 0) { XhcSyncTrsRing (Xhc, EPRing); - TrbStart = EPRing->RingEnqueue; - ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->TRBPtrLo = XHC_LOW_32BIT(Urb->Data); - ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->TRBPtrHi = XHC_HIGH_32BIT(Urb->Data); - ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->Lenth = (UINT32) Urb->DataLen; - ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->TDSize = 0; - ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->IntTarget = Urb->EvtRing->EventInterrupter; - ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->ISP = 1; - ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->IOC = 1; - ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->IDT = 0; - ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->CH = 0; - ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->Type = TRB_TYPE_DATA_STAGE; + TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue; + TrbStart->TrbCtrData.TRBPtrLo = XHC_LOW_32BIT(Urb->Data); + TrbStart->TrbCtrData.TRBPtrHi = XHC_HIGH_32BIT(Urb->Data); + TrbStart->TrbCtrData.Lenth = (UINT32) Urb->DataLen; + TrbStart->TrbCtrData.TDSize = 0; + TrbStart->TrbCtrData.IntTarget = Urb->EvtRing->EventInterrupter; + TrbStart->TrbCtrData.ISP = 1; + TrbStart->TrbCtrData.IOC = 1; + TrbStart->TrbCtrData.IDT = 0; + TrbStart->TrbCtrData.CH = 0; + TrbStart->TrbCtrData.Type = TRB_TYPE_DATA_STAGE; if (Urb->Ep.Direction == EfiUsbDataIn) { - ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->DIR = 1; + TrbStart->TrbCtrData.DIR = 1; } else if (Urb->Ep.Direction == EfiUsbDataOut) { - ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->DIR = 0; + TrbStart->TrbCtrData.DIR = 0; } else { - ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->DIR = 0; + TrbStart->TrbCtrData.DIR = 0; } // // Update the cycle bit // - ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->CycleBit = EPRing->RingPCS & BIT0; + TrbStart->TrbCtrData.CycleBit = EPRing->RingPCS & BIT0; Urb->TrbNum++; } // @@ -445,28 +289,28 @@ XhcCreateTransferTrb ( // Get the pointer to next TRB for status stage use // XhcSyncTrsRing (Xhc, EPRing); - TrbStart = EPRing->RingEnqueue; - ((TRANSFER_TRB_CONTROL_STATUS *) TrbStart)->IntTarget = Urb->EvtRing->EventInterrupter; - ((TRANSFER_TRB_CONTROL_STATUS *) TrbStart)->IOC = 1; - ((TRANSFER_TRB_CONTROL_STATUS *) TrbStart)->CH = 0; - ((TRANSFER_TRB_CONTROL_STATUS *) TrbStart)->Type = TRB_TYPE_STATUS_STAGE; + TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue; + TrbStart->TrbCtrStatus.IntTarget = Urb->EvtRing->EventInterrupter; + TrbStart->TrbCtrStatus.IOC = 1; + TrbStart->TrbCtrStatus.CH = 0; + TrbStart->TrbCtrStatus.Type = TRB_TYPE_STATUS_STAGE; if (Urb->Ep.Direction == EfiUsbDataIn) { - ((TRANSFER_TRB_CONTROL_STATUS *) TrbStart)->DIR = 0; + TrbStart->TrbCtrStatus.DIR = 0; } else if (Urb->Ep.Direction == EfiUsbDataOut) { - ((TRANSFER_TRB_CONTROL_STATUS *) TrbStart)->DIR = 1; + TrbStart->TrbCtrStatus.DIR = 1; } else { - ((TRANSFER_TRB_CONTROL_STATUS *) TrbStart)->DIR = 0; + TrbStart->TrbCtrStatus.DIR = 0; } // // Update the cycle bit // - ((TRANSFER_TRB_CONTROL_STATUS *) TrbStart)->CycleBit = EPRing->RingPCS & BIT0; + TrbStart->TrbCtrStatus.CycleBit = EPRing->RingPCS & BIT0; // // Update the enqueue pointer // XhcSyncTrsRing (Xhc, EPRing); Urb->TrbNum++; - Urb->TrbEnd = TrbStart; + Urb->TrbEnd = (TRB_TEMPLATE *)(UINTN)TrbStart; break; @@ -479,26 +323,26 @@ XhcCreateTransferTrb ( TotalLen = 0; Len = 0; TrbNum = 0; - TrbStart = EPRing->RingEnqueue; + TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue; while (TotalLen < Urb->DataLen) { if ((TotalLen + 0x10000) >= Urb->DataLen) { Len = Urb->DataLen - TotalLen; } else { Len = 0x10000; } - TrbStart = EPRing->RingEnqueue; - ((TRANSFER_TRB_NORMAL *) TrbStart)->TRBPtrLo = XHC_LOW_32BIT((UINT8 *) Urb->Data + TotalLen); - ((TRANSFER_TRB_NORMAL *) TrbStart)->TRBPtrHi = XHC_HIGH_32BIT((UINT8 *) Urb->Data + TotalLen); - ((TRANSFER_TRB_NORMAL *) TrbStart)->Lenth = (UINT32) Len; - ((TRANSFER_TRB_NORMAL *) TrbStart)->TDSize = 0; - ((TRANSFER_TRB_NORMAL *) TrbStart)->IntTarget = Urb->EvtRing->EventInterrupter; - ((TRANSFER_TRB_NORMAL *) TrbStart)->ISP = 1; - ((TRANSFER_TRB_NORMAL *) TrbStart)->IOC = 1; - ((TRANSFER_TRB_NORMAL *) TrbStart)->Type = TRB_TYPE_NORMAL; + TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue; + TrbStart->TrbNormal.TRBPtrLo = XHC_LOW_32BIT((UINT8 *) Urb->Data + TotalLen); + TrbStart->TrbNormal.TRBPtrHi = XHC_HIGH_32BIT((UINT8 *) Urb->Data + TotalLen); + TrbStart->TrbNormal.Lenth = (UINT32) Len; + TrbStart->TrbNormal.TDSize = 0; + TrbStart->TrbNormal.IntTarget = Urb->EvtRing->EventInterrupter; + TrbStart->TrbNormal.ISP = 1; + TrbStart->TrbNormal.IOC = 1; + TrbStart->TrbNormal.Type = TRB_TYPE_NORMAL; // // Update the cycle bit // - ((TRANSFER_TRB_NORMAL *) TrbStart)->CycleBit = EPRing->RingPCS & BIT0; + TrbStart->TrbNormal.CycleBit = EPRing->RingPCS & BIT0; XhcSyncTrsRing (Xhc, EPRing); TrbNum++; @@ -506,7 +350,7 @@ XhcCreateTransferTrb ( } Urb->TrbNum = TrbNum; - Urb->TrbEnd = TrbStart; + Urb->TrbEnd = (TRB_TEMPLATE *)(UINTN)TrbStart; break; case ED_INTERRUPT_OUT: @@ -525,26 +369,26 @@ XhcCreateTransferTrb ( TotalLen = 0; Len = 0; TrbNum = 0; - TrbStart = EPRing->RingEnqueue; + TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue; while (TotalLen < Urb->DataLen) { if ((TotalLen + 0x10000) >= Urb->DataLen) { Len = Urb->DataLen - TotalLen; } else { Len = 0x10000; } - TrbStart = EPRing->RingEnqueue; - ((TRANSFER_TRB_NORMAL *) TrbStart)->TRBPtrLo = XHC_LOW_32BIT((UINT8 *) Urb->Data + TotalLen); - ((TRANSFER_TRB_NORMAL *) TrbStart)->TRBPtrHi = XHC_HIGH_32BIT((UINT8 *) Urb->Data + TotalLen); - ((TRANSFER_TRB_NORMAL *) TrbStart)->Lenth = (UINT32) Len; - ((TRANSFER_TRB_NORMAL *) TrbStart)->TDSize = 0; - ((TRANSFER_TRB_NORMAL *) TrbStart)->IntTarget = Urb->EvtRing->EventInterrupter; - ((TRANSFER_TRB_NORMAL *) TrbStart)->ISP = 1; - ((TRANSFER_TRB_NORMAL *) TrbStart)->IOC = 1; - ((TRANSFER_TRB_NORMAL *) TrbStart)->Type = TRB_TYPE_NORMAL; + TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue; + TrbStart->TrbNormal.TRBPtrLo = XHC_LOW_32BIT((UINT8 *) Urb->Data + TotalLen); + TrbStart->TrbNormal.TRBPtrHi = XHC_HIGH_32BIT((UINT8 *) Urb->Data + TotalLen); + TrbStart->TrbNormal.Lenth = (UINT32) Len; + TrbStart->TrbNormal.TDSize = 0; + TrbStart->TrbNormal.IntTarget = Urb->EvtRing->EventInterrupter; + TrbStart->TrbNormal.ISP = 1; + TrbStart->TrbNormal.IOC = 1; + TrbStart->TrbNormal.Type = TRB_TYPE_NORMAL; // // Update the cycle bit // - ((TRANSFER_TRB_NORMAL *) TrbStart)->CycleBit = EPRing->RingPCS & BIT0; + TrbStart->TrbNormal.CycleBit = EPRing->RingPCS & BIT0; XhcSyncTrsRing (Xhc, EPRing); TrbNum++; @@ -552,7 +396,7 @@ XhcCreateTransferTrb ( } Urb->TrbNum = TrbNum; - Urb->TrbEnd = TrbStart; + Urb->TrbEnd = (TRB_TEMPLATE *)(UINTN)TrbStart; break; default: @@ -568,12 +412,12 @@ XhcCreateTransferTrb ( /** 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 ) { VOID *Dcbaa; @@ -599,8 +443,9 @@ XhcInitSched ( // Software shall set Device Context Base Address Array entries for unallocated Device Slots to '0'. // Entries = (Xhc->MaxSlotsEn + 1) * sizeof(UINT64); - Dcbaa = AllocateAlignedZeroPool(Entries, 64); + Dcbaa = AllocatePages (EFI_SIZE_TO_PAGES (Entries)); ASSERT (Dcbaa != NULL); + ZeroMem (Dcbaa, Entries); // // A Scratchpad Buffer is a PAGESIZE block of system memory located on a PAGESIZE boundary. @@ -611,12 +456,15 @@ XhcInitSched ( Xhc->MaxScratchpadBufs = MaxScratchpadBufs; ASSERT (MaxScratchpadBufs <= 1023); if (MaxScratchpadBufs != 0) { - ScratchBuf = AllocateAlignedZeroPool(MaxScratchpadBufs * sizeof (UINT64), Xhc->PageSize); + ScratchBuf = AllocateAlignedPages (EFI_SIZE_TO_PAGES (MaxScratchpadBufs * sizeof (UINT64)), Xhc->PageSize); ASSERT (ScratchBuf != NULL); + ZeroMem (ScratchBuf, MaxScratchpadBufs * sizeof (UINT64)); Xhc->ScratchBuf = ScratchBuf; for (Index = 0; Index < MaxScratchpadBufs; Index++) { - ScratchEntryBuf = AllocateAlignedZeroPool(Xhc->PageSize, Xhc->PageSize); + ScratchEntryBuf = AllocateAlignedPages (EFI_SIZE_TO_PAGES (Xhc->PageSize), Xhc->PageSize); + ASSERT (ScratchEntryBuf != NULL); + ZeroMem (ScratchEntryBuf, Xhc->PageSize); *ScratchBuf++ = (UINT64)(UINTN)ScratchEntryBuf; } @@ -631,7 +479,7 @@ XhcInitSched ( // Program the Device Context Base Address Array Pointer (DCBAAP) register (5.4.6) with // a 64-bit address pointing to where the Device Context Base Address Array is located. // - Xhc->DCBAA = (UINT64 *)(UINTN)Dcbaa; + Xhc->DCBAA = (UINT64 *)(UINTN)Dcbaa; XhcWriteOpReg64 (Xhc, XHC_DCBAAP_OFFSET, (UINT64)(UINTN)Xhc->DCBAA); DEBUG ((EFI_D_INFO, "XhcInitSched:DCBAA=0x%x\n", (UINT64)(UINTN)Xhc->DCBAA)); @@ -670,8 +518,8 @@ XhcInitSched ( CreateEventRing (Xhc, CMD_INTER, &Xhc->CmdEventRing); CreateEventRing (Xhc, CTRL_INTER, &Xhc->CtrlTrEventRing); CreateEventRing (Xhc, BULK_INTER, &Xhc->BulkTrEventRing); - CreateEventRing (Xhc, INT_INTER, &Xhc->IntTrEventRing); - CreateEventRing (Xhc, INT_INTER_ASYNC, &Xhc->AsynIntTrEventRing); + CreateEventRing (Xhc, INT_INTER, &Xhc->IntTrEventRing); + CreateEventRing (Xhc, INT_INTER_ASYNC, &Xhc->AsynIntTrEventRing); } /** @@ -681,7 +529,7 @@ XhcInitSched ( 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. @@ -691,19 +539,19 @@ XhcInitSched ( EFI_STATUS EFIAPI XhcRecoverHaltedEndpoint ( - IN USB_XHCI_DEV *Xhc, + IN USB_XHCI_INSTANCE *Xhc, IN URB *Urb ) { - EFI_STATUS Status; - EVT_TRB_COMMAND *EvtTrb; - CMD_TRB_RESET_ED CmdTrbResetED; - CMD_SET_TR_DEQ CmdSetTRDeq; - UINT8 Dci; - UINT8 SlotId; + EFI_STATUS Status; + EVT_TRB_COMMAND_COMPLETION *EvtTrb; + CMD_TRB_RESET_ENDPOINT CmdTrbResetED; + CMD_SET_TR_DEQ_POINTER CmdSetTRDeq; + UINT8 Dci; + UINT8 SlotId; Status = EFI_SUCCESS; - SlotId = XhcDevAddrToSlotId(Urb->Ep.DevAddr); + SlotId = XhcDevAddrToSlotId(Xhc, Urb->Ep.DevAddr); Dci = XhcEndpointToDci(Urb->Ep.EpAddr, (UINT8)(Urb->Ep.Direction)); DEBUG ((EFI_D_INFO, "Recovery Halted Slot = %x,Dci = %x\n", SlotId, Dci)); @@ -718,9 +566,9 @@ XhcRecoverHaltedEndpoint ( CmdTrbResetED.SlotId = SlotId; Status = XhcCmdTransfer ( Xhc, - (TRB *) (UINTN) &CmdTrbResetED, + (TRB_TEMPLATE *) (UINTN) &CmdTrbResetED, XHC_GENERIC_TIMEOUT, - (TRB **) (UINTN) &EvtTrb + (TRB_TEMPLATE **) (UINTN) &EvtTrb ); ASSERT (!EFI_ERROR(Status)); @@ -736,9 +584,9 @@ XhcRecoverHaltedEndpoint ( CmdSetTRDeq.SlotId = SlotId; Status = XhcCmdTransfer ( Xhc, - (TRB *) (UINTN) &CmdSetTRDeq, + (TRB_TEMPLATE *) (UINTN) &CmdSetTRDeq, XHC_GENERIC_TIMEOUT, - (TRB **) (UINTN) &EvtTrb + (TRB_TEMPLATE **) (UINTN) &EvtTrb ); ASSERT (!EFI_ERROR(Status)); @@ -753,14 +601,14 @@ XhcRecoverHaltedEndpoint ( /** 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 ) @@ -770,24 +618,26 @@ CreateEventRing ( ASSERT (EventRing != NULL); - Buf = AllocateAlignedZeroPool(sizeof (TRB) * EVENT_RING_TRB_NUMBER, 64); + Buf = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER)); ASSERT (Buf != NULL); ASSERT (((UINTN) Buf & 0x3F) == 0); + ZeroMem (Buf, sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER); EventRing->EventRingSeg0 = Buf; EventRing->EventInterrupter = EventInterrupter; EventRing->TrbNumber = EVENT_RING_TRB_NUMBER; - EventRing->EventRingDequeue = (TRB *) EventRing->EventRingSeg0; - EventRing->EventRingEnqueue = (TRB *) EventRing->EventRingSeg0; + EventRing->EventRingDequeue = (TRB_TEMPLATE *) EventRing->EventRingSeg0; + EventRing->EventRingEnqueue = (TRB_TEMPLATE *) EventRing->EventRingSeg0; // // Software maintains an Event Ring Consumer Cycle State (CCS) bit, initializing it to '1' // and toggling it every time the Event Ring Dequeue Pointer wraps back to the beginning of the Event Ring. // EventRing->EventRingCCS = 1; - Buf = AllocateAlignedZeroPool(sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER, 64); + Buf = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER)); ASSERT (Buf != NULL); ASSERT (((UINTN) Buf & 0x3F) == 0); + ZeroMem (Buf, sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER); ERSTBase = (EVENT_RING_SEG_TABLE_ENTRY *) Buf; EventRing->ERSTBase = ERSTBase; @@ -828,36 +678,37 @@ CreateEventRing ( /** 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 ) { VOID *Buf; - LNK_TRB *EndTrb; + LINK_TRB *EndTrb; - Buf = AllocateAlignedZeroPool(sizeof (TRB) * TrbNum, 64); + Buf = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (TRB_TEMPLATE) * TrbNum)); ASSERT (Buf != NULL); ASSERT (((UINTN) Buf & 0x3F) == 0); + ZeroMem (Buf, sizeof (TRB_TEMPLATE) * TrbNum); TransferRing->RingSeg0 = Buf; TransferRing->TrbNumber = TrbNum; - TransferRing->RingEnqueue = (TRB *) TransferRing->RingSeg0; - TransferRing->RingDequeue = (TRB *) TransferRing->RingSeg0; + TransferRing->RingEnqueue = (TRB_TEMPLATE *) TransferRing->RingSeg0; + TransferRing->RingDequeue = (TRB_TEMPLATE *) TransferRing->RingSeg0; TransferRing->RingPCS = 1; // // 4.9.2 Transfer Ring Management // To form a ring (or circular queue) a Link TRB may be inserted at the end of a ring to // point to the first TRB in the ring. // - EndTrb = (LNK_TRB*) ((UINTN)Buf + sizeof (TRB) * (TrbNum - 1)); + EndTrb = (LINK_TRB *) ((UINTN)Buf + sizeof (TRB_TEMPLATE) * (TrbNum - 1)); EndTrb->Type = TRB_TYPE_LINK; EndTrb->PtrLo = XHC_LOW_32BIT (Buf); EndTrb->PtrHi = XHC_HIGH_32BIT (Buf); @@ -874,14 +725,14 @@ CreateTransferRing ( /** Free XHCI event ring. - @param Xhc The XHCI device. + @param Xhc The XHCI Instance. @param EventRing The event ring to be freed. **/ EFI_STATUS EFIAPI XhcFreeEventRing ( - IN USB_XHCI_DEV *Xhc, + IN USB_XHCI_INSTANCE *Xhc, IN EVENT_RING *EventRing ) { @@ -909,43 +760,47 @@ XhcFreeEventRing ( RingBuf = (VOID *)(UINTN)(EventRingPtr->PtrLo | ((UINT64)EventRingPtr->PtrHi << 32)); if(RingBuf != NULL) { - FreeAlignedPool (RingBuf); + FreePages (RingBuf, EFI_SIZE_TO_PAGES (sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER)); ZeroMem (EventRingPtr, sizeof (EVENT_RING_SEG_TABLE_ENTRY)); } } - FreeAlignedPool (TablePtr); + FreePages (TablePtr, EFI_SIZE_TO_PAGES (sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER)); return EFI_SUCCESS; } /** 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 ) { UINT32 Index; + UINT64 *ScratchBuf; if (Xhc->ScratchBuf != NULL) { + ScratchBuf = Xhc->ScratchBuf; for (Index = 0; Index < Xhc->MaxScratchpadBufs; Index++) { - FreeAlignedPool ((VOID*)(UINTN)*Xhc->ScratchBuf++); + FreeAlignedPages ((VOID*)(UINTN)*ScratchBuf++, EFI_SIZE_TO_PAGES (Xhc->PageSize)); } + FreeAlignedPages (Xhc->ScratchBuf, EFI_SIZE_TO_PAGES (Xhc->MaxScratchpadBufs * sizeof (UINT64))); } if (Xhc->DCBAA != NULL) { - FreeAlignedPool (Xhc->DCBAA); + FreePages (Xhc->DCBAA, EFI_SIZE_TO_PAGES((Xhc->MaxSlotsEn + 1) * sizeof(UINT64))); Xhc->DCBAA = NULL; } if (Xhc->CmdRing.RingSeg0 != NULL){ - FreeAlignedPool (Xhc->CmdRing.RingSeg0); + FreePages (Xhc->CmdRing.RingSeg0, EFI_SIZE_TO_PAGES (sizeof (TRB_TEMPLATE) * CMD_RING_TRB_NUMBER)); Xhc->CmdRing.RingSeg0 = NULL; } + XhcFreeEventRing (Xhc,&Xhc->CmdEventRing); XhcFreeEventRing (Xhc,&Xhc->CtrlTrEventRing); XhcFreeEventRing (Xhc,&Xhc->BulkTrEventRing); @@ -966,11 +821,11 @@ XhcFreeSched ( BOOLEAN IsTransferRingTrb ( IN TRANSFER_RING *Ring, - IN TRB *Trb + IN TRB_TEMPLATE *Trb ) { BOOLEAN Flag; - TRB *Trb1; + TRB_TEMPLATE *Trb1; UINTN Index; Trb1 = Ring->RingSeg0; @@ -993,7 +848,7 @@ IsTransferRingTrb ( Check the URB's execution result and update the URB's result accordingly. - @param Xhc The XHCI device. + @param Xhc The XHCI Instance. @param Urb The URB to check result. @return Whether the result of URB transfer is finialized. @@ -1001,14 +856,14 @@ IsTransferRingTrb ( **/ EFI_STATUS XhcCheckUrbResult ( - IN USB_XHCI_DEV *Xhc, + IN USB_XHCI_INSTANCE *Xhc, IN URB *Urb ) { BOOLEAN StartDone; BOOLEAN EndDone; EVT_TRB_TRANSFER *EvtTrb; - TRB *TRBPtr; + TRB_TEMPLATE *TRBPtr; UINTN Index; UINT8 TRBType; EFI_STATUS Status; @@ -1034,47 +889,47 @@ XhcCheckUrbResult ( Urb->EvtRing->EventRingDequeue = Urb->EvtTrbStart; for (Index = 0; Index < Urb->EvtRing->TrbNumber; Index++) { XhcSyncEventRing (Xhc, Urb->EvtRing); - Status = XhcCheckNewEvent (Xhc, Urb->EvtRing, ((TRB **)&EvtTrb)); + Status = XhcCheckNewEvent (Xhc, Urb->EvtRing, ((TRB_TEMPLATE **)&EvtTrb)); if (Status == EFI_NOT_READY) { Urb->Result |= EFI_USB_ERR_TIMEOUT; goto EXIT; } - TRBPtr = (TRB *)(UINTN)(EvtTrb->TRBPtrLo | (UINT64) EvtTrb->TRBPtrHi << 32); + TRBPtr = (TRB_TEMPLATE *)(UINTN)(EvtTrb->TRBPtrLo | (UINT64) EvtTrb->TRBPtrHi << 32); - switch (EvtTrb->Completcode) { + switch (EvtTrb->Completecode) { case TRB_COMPLETION_STALL_ERROR: Urb->Result |= EFI_USB_ERR_STALL; Status = EFI_DEVICE_ERROR; - DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: STALL_ERROR! Completcode = %x\n",EvtTrb->Completcode)); + DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: STALL_ERROR! Completecode = %x\n",EvtTrb->Completecode)); goto EXIT; break; case TRB_COMPLETION_BABBLE_ERROR: Urb->Result |= EFI_USB_ERR_BABBLE; Status = EFI_DEVICE_ERROR; - DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: BABBLE_ERROR! Completcode = %x\n",EvtTrb->Completcode)); + DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: BABBLE_ERROR! Completecode = %x\n",EvtTrb->Completecode)); goto EXIT; break; case TRB_COMPLETION_DATA_BUFFER_ERROR: Urb->Result |= EFI_USB_ERR_BUFFER; Status = EFI_DEVICE_ERROR; - DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: ERR_BUFFER! Completcode = %x\n",EvtTrb->Completcode)); + DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: ERR_BUFFER! Completecode = %x\n",EvtTrb->Completecode)); goto EXIT; break; case TRB_COMPLETION_USB_TRANSACTION_ERROR: Urb->Result |= EFI_USB_ERR_TIMEOUT; Status = EFI_DEVICE_ERROR; - DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: TRANSACTION_ERROR! Completcode = %x\n",EvtTrb->Completcode)); + DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: TRANSACTION_ERROR! Completecode = %x\n",EvtTrb->Completecode)); goto EXIT; break; case TRB_COMPLETION_SHORT_PACKET: case TRB_COMPLETION_SUCCESS: if (IsTransferRingTrb (Urb->Ring, TRBPtr)) { - if (EvtTrb->Completcode == TRB_COMPLETION_SHORT_PACKET) { + if (EvtTrb->Completecode == TRB_COMPLETION_SHORT_PACKET) { DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: short packet happens!\n")); } TRBType = (UINT8) (TRBPtr->Type); @@ -1088,7 +943,7 @@ XhcCheckUrbResult ( break; default: - DEBUG ((EFI_D_ERROR, "Transfer Default Error Occur! Completcode = 0x%x!\n",EvtTrb->Completcode)); + DEBUG ((EFI_D_ERROR, "Transfer Default Error Occur! Completecode = 0x%x!\n",EvtTrb->Completecode)); Urb->Result |= EFI_USB_ERR_TIMEOUT; Status = EFI_DEVICE_ERROR; goto EXIT; @@ -1119,10 +974,10 @@ EXIT: /** 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. @@ -1131,10 +986,10 @@ EXIT: **/ 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 ) { EFI_STATUS Status; @@ -1147,13 +1002,13 @@ XhcExecTransfer ( SlotId = 0; Dci = 0; } else { - SlotId = XhcDevAddrToSlotId(Urb->Ep.DevAddr); + SlotId = XhcDevAddrToSlotId(Xhc, Urb->Ep.DevAddr); Dci = XhcEndpointToDci(Urb->Ep.EpAddr, (UINT8)(Urb->Ep.Direction)); } Status = EFI_SUCCESS; - Loop = (TimeOut * XHC_1_MILLISECOND / XHC_SYNC_POLL_INTERVAL) + 1; - if (TimeOut == 0) { + Loop = (Timeout * XHC_1_MILLISECOND / XHC_POLL_DELAY) + 1; + if (Timeout == 0) { Loop = 0xFFFFFFFF; } @@ -1164,7 +1019,7 @@ XhcExecTransfer ( if ((Status != EFI_NOT_READY)) { break; } - gBS->Stall (XHC_SYNC_POLL_INTERVAL); + gBS->Stall (XHC_POLL_DELAY); } return Status; @@ -1174,7 +1029,7 @@ XhcExecTransfer ( 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. @@ -1184,7 +1039,7 @@ XhcExecTransfer ( **/ EFI_STATUS XhciDelAsyncIntTransfer ( - IN USB_XHCI_DEV *Xhc, + IN USB_XHCI_INSTANCE *Xhc, IN UINT8 DevAddr, IN UINT8 EpNum ) @@ -1219,12 +1074,12 @@ XhciDelAsyncIntTransfer ( /** Remove all the asynchronous interrutp transfers. - @param Xhc The XHCI device. + @param Xhc The XHCI Instance. **/ VOID XhciDelAllAsyncIntTransfers ( - IN USB_XHCI_DEV *Xhc + IN USB_XHCI_INSTANCE *Xhc ) { LIST_ENTRY *Entry; @@ -1242,13 +1097,13 @@ XhciDelAllAsyncIntTransfers ( /** Update the queue head for next round of asynchronous transfer - @param Xhc The XHCI device. + @param Xhc The XHCI Instance. @param Urb The URB to update **/ VOID XhcUpdateAsyncRequest ( - IN USB_XHCI_DEV* Xhc, + IN USB_XHCI_INSTANCE *Xhc, IN URB *Urb ) { @@ -1267,7 +1122,7 @@ XhcUpdateAsyncRequest ( Interrupt transfer periodic check handler. @param Event Interrupt event. - @param Context Pointer to USB_XHCI_DEV. + @param Context Pointer to USB_XHCI_INSTANCE. **/ VOID @@ -1277,7 +1132,7 @@ XhcMonitorAsyncRequests ( IN VOID *Context ) { - USB_XHCI_DEV *Xhc; + USB_XHCI_INSTANCE *Xhc; LIST_ENTRY *Entry; LIST_ENTRY *Next; UINT8 *ProcBuf; @@ -1288,7 +1143,7 @@ XhcMonitorAsyncRequests ( OldTpl = gBS->RaiseTPL (XHC_TPL); - Xhc = (USB_XHCI_DEV*) Context; + Xhc = (USB_XHCI_INSTANCE*) Context; EFI_LIST_FOR_EACH_SAFE (Entry, Next, &Xhc->AsyncIntTransfers) { Urb = EFI_LIST_CONTAINER (Entry, URB, UrbList); @@ -1296,7 +1151,7 @@ XhcMonitorAsyncRequests ( // // Make sure that the device is available before every check. // - SlotId = XhcDevAddrToSlotId(Urb->Ep.DevAddr); + SlotId = XhcDevAddrToSlotId(Xhc, Urb->Ep.DevAddr); if (SlotId == 0) { continue; } @@ -1320,7 +1175,7 @@ XhcMonitorAsyncRequests ( if (Urb->Result == EFI_USB_NOERROR) { ASSERT (Urb->Completed <= Urb->DataLen); - ProcBuf = AllocatePool (Urb->Completed); + ProcBuf = AllocateZeroPool (Urb->Completed); if (ProcBuf == NULL) { XhcUpdateAsyncRequest (Xhc, Urb); @@ -1362,7 +1217,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. @@ -1374,7 +1229,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 @@ -1388,17 +1243,17 @@ XhcPollPortStatusChange ( Status = EFI_SUCCESS; if (ParentRouteChart.Dword == 0) { - RouteChart.Field.RouteString = 0; - RouteChart.Field.RootPortNum = Port + 1; - RouteChart.Field.TierNum = 1; + RouteChart.Route.RouteString = 0; + RouteChart.Route.RootPortNum = Port + 1; + RouteChart.Route.TierNum = 1; } else { if(Port < 14) { - RouteChart.Field.RouteString = ParentRouteChart.Field.RouteString | (Port << (4 * (ParentRouteChart.Field.TierNum - 1))); + RouteChart.Route.RouteString = ParentRouteChart.Route.RouteString | (Port << (4 * (ParentRouteChart.Route.TierNum - 1))); } else { - RouteChart.Field.RouteString = ParentRouteChart.Field.RouteString | (15 << (4 * (ParentRouteChart.Field.TierNum - 1))); + RouteChart.Route.RouteString = ParentRouteChart.Route.RouteString | (15 << (4 * (ParentRouteChart.Route.TierNum - 1))); } - RouteChart.Field.RootPortNum = ParentRouteChart.Field.RootPortNum; - RouteChart.Field.TierNum = ParentRouteChart.Field.TierNum + 1; + RouteChart.Route.RootPortNum = ParentRouteChart.Route.RootPortNum; + RouteChart.Route.TierNum = ParentRouteChart.Route.TierNum + 1; } if (((PortState->PortStatus & USB_PORT_STAT_ENABLE) != 0) && @@ -1417,7 +1272,7 @@ XhcPollPortStatusChange ( // // Execute Enable_Slot cmd for attached device, initialize device context and assign device address. // - SlotId = XhcRouteStringToSlotId (RouteChart); + SlotId = XhcRouteStringToSlotId (Xhc, RouteChart); if (SlotId == 0) { Status = XhcInitializeDeviceSlot (Xhc, ParentRouteChart, Port, RouteChart, Speed); ASSERT_EFI_ERROR (Status); @@ -1426,7 +1281,7 @@ XhcPollPortStatusChange ( // // Device is detached. Disable the allocated device slot and release resource. // - SlotId = XhcRouteStringToSlotId (RouteChart); + SlotId = XhcRouteStringToSlotId (Xhc, RouteChart); if (SlotId != 0) { Status = XhcDisableSlotCmd (Xhc, SlotId); ASSERT_EFI_ERROR (Status); @@ -1467,6 +1322,7 @@ XhcEndpointToDci ( /** 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. @@ -1474,15 +1330,16 @@ XhcEndpointToDci ( **/ UINT8 XhcDevAddrToSlotId ( - IN UINT8 DevAddr + IN USB_XHCI_INSTANCE *Xhc, + IN UINT8 DevAddr ) { UINT8 Index; for (Index = 0; Index < 255; Index++) { - if (UsbDevContext[Index + 1].Enabled && - (UsbDevContext[Index + 1].SlotId != 0) && - (UsbDevContext[Index + 1].XhciDevAddr == DevAddr)) { + if (Xhc->UsbDevContext[Index + 1].Enabled && + (Xhc->UsbDevContext[Index + 1].SlotId != 0) && + (Xhc->UsbDevContext[Index + 1].XhciDevAddr == DevAddr)) { break; } } @@ -1491,13 +1348,14 @@ XhcDevAddrToSlotId ( return 0; } - return UsbDevContext[Index + 1].SlotId; + return Xhc->UsbDevContext[Index + 1].SlotId; } /** 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. @@ -1505,15 +1363,16 @@ XhcDevAddrToSlotId ( UINT8 EFIAPI XhcBusDevAddrToSlotId ( - IN UINT8 BusDevAddr + IN USB_XHCI_INSTANCE *Xhc, + IN UINT8 BusDevAddr ) { UINT8 Index; for (Index = 0; Index < 255; Index++) { - if (UsbDevContext[Index + 1].Enabled && - (UsbDevContext[Index + 1].SlotId != 0) && - (UsbDevContext[Index + 1].BusDevAddr == BusDevAddr)) { + if (Xhc->UsbDevContext[Index + 1].Enabled && + (Xhc->UsbDevContext[Index + 1].SlotId != 0) && + (Xhc->UsbDevContext[Index + 1].BusDevAddr == BusDevAddr)) { break; } } @@ -1522,13 +1381,14 @@ XhcBusDevAddrToSlotId ( return 0; } - return UsbDevContext[Index + 1].SlotId; + return Xhc->UsbDevContext[Index + 1].SlotId; } /** 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. @@ -1536,15 +1396,16 @@ XhcBusDevAddrToSlotId ( UINT8 EFIAPI XhcRouteStringToSlotId ( - IN USB_DEV_ROUTE RouteString + IN USB_XHCI_INSTANCE *Xhc, + IN USB_DEV_ROUTE RouteString ) { UINT8 Index; for (Index = 0; Index < 255; Index++) { - if (UsbDevContext[Index + 1].Enabled && - (UsbDevContext[Index + 1].SlotId != 0) && - (UsbDevContext[Index + 1].RouteString.Dword == RouteString.Dword)) { + if (Xhc->UsbDevContext[Index + 1].Enabled && + (Xhc->UsbDevContext[Index + 1].SlotId != 0) && + (Xhc->UsbDevContext[Index + 1].RouteString.Dword == RouteString.Dword)) { break; } } @@ -1553,13 +1414,13 @@ XhcRouteStringToSlotId ( return 0; } - return UsbDevContext[Index + 1].SlotId; + return Xhc->UsbDevContext[Index + 1].SlotId; } /** 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. @@ -1568,14 +1429,14 @@ XhcRouteStringToSlotId ( EFI_STATUS EFIAPI XhcSyncEventRing ( - IN USB_XHCI_DEV *Xhc, + IN USB_XHCI_INSTANCE *Xhc, IN EVENT_RING *EvtRing ) { UINTN Index; - TRB *EvtTrb1; - TRB *EvtTrb2; - TRB *XhcDequeue; + TRB_TEMPLATE *EvtTrb1; + TRB_TEMPLATE *EvtTrb2; + TRB_TEMPLATE *XhcDequeue; ASSERT (EvtRing != NULL); @@ -1604,10 +1465,10 @@ XhcSyncEventRing ( // // Apply the EventRingDequeue to Xhc // - XhcDequeue = (TRB *)(UINTN) XhcReadRuntimeReg64 ( - Xhc, - XHC_ERDP_OFFSET + (32 * EvtRing->EventInterrupter) - ); + XhcDequeue = (TRB_TEMPLATE *)(UINTN) XhcReadRuntimeReg64 ( + Xhc, + XHC_ERDP_OFFSET + (32 * EvtRing->EventInterrupter) + ); if (((UINT64)(UINTN)XhcDequeue & (~0x0F)) != ((UINT64)(UINTN)EvtRing->EventRingDequeue & (~0x0F))) { XhcWriteRuntimeReg64 ( @@ -1623,7 +1484,7 @@ XhcSyncEventRing ( /** 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. @@ -1632,12 +1493,12 @@ XhcSyncEventRing ( EFI_STATUS EFIAPI XhcSyncTrsRing ( - IN USB_XHCI_DEV *Xhc, + IN USB_XHCI_INSTANCE *Xhc, IN TRANSFER_RING *TrsRing ) { UINTN Index; - TRB *TrsTrb; + TRB_TEMPLATE *TrsTrb; ASSERT (TrsRing != NULL); // @@ -1652,16 +1513,16 @@ XhcSyncTrsRing ( } TrsTrb++; if ((UINT8) TrsTrb->Type == TRB_TYPE_LINK) { - ASSERT (((LNK_TRB*)TrsTrb)->TC != 0); + ASSERT (((LINK_TRB*)TrsTrb)->TC != 0); // // set cycle bit in Link TRB as normal // - ((LNK_TRB*)TrsTrb)->CycleBit = TrsRing->RingPCS & BIT0; + ((LINK_TRB*)TrsTrb)->CycleBit = TrsRing->RingPCS & BIT0; // // Toggle PCS maintained by software // TrsRing->RingPCS = (TrsRing->RingPCS & BIT0) ? 0 : 1; - TrsTrb = (TRB*)(UINTN)((TrsTrb->Dword1 | ((UINT64)TrsTrb->Dword2 << 32)) & ~0x0F); + TrsTrb = (TRB_TEMPLATE *)(UINTN)((TrsTrb->Parameter1 | ((UINT64)TrsTrb->Parameter2 << 32)) & ~0x0F); } } @@ -1674,12 +1535,12 @@ XhcSyncTrsRing ( // // Clear the Trb context for enqueue, but reserve the PCS bit // - TrsTrb->Dword1 = 0; - TrsTrb->Dword2 = 0; - TrsTrb->Dword3 = 0; - TrsTrb->RsvdZ1 = 0; - TrsTrb->Type = 0; - TrsTrb->RsvdZ2 = 0; + TrsTrb->Parameter1 = 0; + TrsTrb->Parameter2 = 0; + TrsTrb->Status = 0; + TrsTrb->RsvdZ1 = 0; + TrsTrb->Type = 0; + TrsTrb->Control = 0; return EFI_SUCCESS; } @@ -1687,7 +1548,7 @@ XhcSyncTrsRing ( /** 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. @@ -1698,13 +1559,13 @@ XhcSyncTrsRing ( 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 ) { EFI_STATUS Status; - TRB *EvtTrb; + TRB_TEMPLATE*EvtTrb; ASSERT (EvtRing != NULL); @@ -1717,7 +1578,7 @@ XhcCheckNewEvent ( Status = EFI_SUCCESS; - if (((EvtTrb->Dword3 >> 24) & 0xFF) != TRB_COMPLETION_SUCCESS) { + if (((EvtTrb->Status >> 24) & 0xFF) != TRB_COMPLETION_SUCCESS) { Status = EFI_DEVICE_ERROR; } @@ -1725,7 +1586,7 @@ XhcCheckNewEvent ( // // If the dequeue pointer is beyond the ring, then roll-back it to the begining of the ring. // - if ((UINTN)EvtRing->EventRingDequeue >= ((UINTN) EvtRing->EventRingSeg0 + sizeof (TRB) * EvtRing->TrbNumber)) { + if ((UINTN)EvtRing->EventRingDequeue >= ((UINTN) EvtRing->EventRingSeg0 + sizeof (TRB_TEMPLATE) * EvtRing->TrbNumber)) { EvtRing->EventRingDequeue = EvtRing->EventRingSeg0; } @@ -1735,7 +1596,7 @@ XhcCheckNewEvent ( /** 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. @@ -1745,7 +1606,7 @@ XhcCheckNewEvent ( EFI_STATUS EFIAPI XhcRingDoorBell ( - IN USB_XHCI_DEV *Xhc, + IN USB_XHCI_INSTANCE *Xhc, IN UINT8 SlotId, IN UINT8 Dci ) @@ -1762,7 +1623,7 @@ XhcRingDoorBell ( /** 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. @@ -1770,14 +1631,14 @@ XhcRingDoorBell ( **/ EFI_STATUS RingIntTransferDoorBell ( - IN USB_XHCI_DEV *Xhc, + IN USB_XHCI_INSTANCE *Xhc, IN URB *Urb ) { UINT8 SlotId; UINT8 Dci; - SlotId = XhcDevAddrToSlotId(Urb->Ep.DevAddr); + SlotId = XhcDevAddrToSlotId(Xhc, Urb->Ep.DevAddr); Dci = XhcEndpointToDci(Urb->Ep.EpAddr, (UINT8)(Urb->Ep.Direction)); XhcRingDoorBell (Xhc, SlotId, Dci); return EFI_SUCCESS; @@ -1786,7 +1647,7 @@ RingIntTransferDoorBell ( /** 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. @@ -1798,34 +1659,34 @@ RingIntTransferDoorBell ( 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, IN UINT8 DeviceSpeed ) { - EFI_STATUS Status; - EVT_TRB_COMMAND *EvtTrb; - INPUT_CONTEXT *InputContext; - DEVICE_CONTEXT *OutputDevContxt; - TRANSFER_RING *EndpointTransferRing; - CMD_TRB_ADDR_DEV CmdTrbAddr; - UINT8 DeviceAddress; - CMD_TRB_EN_SLOT CmdTrb; - UINT8 SlotId; - UINT8 ParentSlotId; - DEVICE_CONTEXT *ParentDeviceContext; - - ZeroMem (&CmdTrb, sizeof (CMD_TRB_EN_SLOT)); + EFI_STATUS Status; + EVT_TRB_COMMAND_COMPLETION *EvtTrb; + INPUT_CONTEXT *InputContext; + DEVICE_CONTEXT *OutputContext; + TRANSFER_RING *EndpointTransferRing; + CMD_TRB_ADDRESS_DEVICE CmdTrbAddr; + UINT8 DeviceAddress; + CMD_TRB_ENABLE_SLOT CmdTrb; + UINT8 SlotId; + UINT8 ParentSlotId; + DEVICE_CONTEXT *ParentDeviceContext; + + ZeroMem (&CmdTrb, sizeof (CMD_TRB_ENABLE_SLOT)); CmdTrb.CycleBit = 1; CmdTrb.Type = TRB_TYPE_EN_SLOT; Status = XhcCmdTransfer ( Xhc, - (TRB *) (UINTN) &CmdTrb, + (TRB_TEMPLATE *) (UINTN) &CmdTrb, XHC_GENERIC_TIMEOUT, - (TRB **) (UINTN) &EvtTrb + (TRB_TEMPLATE **) (UINTN) &EvtTrb ); ASSERT_EFI_ERROR (Status); ASSERT (EvtTrb->SlotId <= Xhc->MaxSlotsEn); @@ -1833,21 +1694,22 @@ XhcInitializeDeviceSlot ( SlotId = (UINT8)EvtTrb->SlotId; ASSERT (SlotId != 0); - ZeroMem (&UsbDevContext[SlotId], sizeof (USB_DEV_CONTEXT)); - UsbDevContext[SlotId].Enabled = TRUE; - UsbDevContext[SlotId].SlotId = SlotId; - UsbDevContext[SlotId].RouteString.Dword = RouteChart.Dword; - UsbDevContext[SlotId].ParentRouteString.Dword = ParentRouteChart.Dword; + ZeroMem (&Xhc->UsbDevContext[SlotId], sizeof (USB_DEV_CONTEXT)); + Xhc->UsbDevContext[SlotId].Enabled = TRUE; + Xhc->UsbDevContext[SlotId].SlotId = SlotId; + Xhc->UsbDevContext[SlotId].RouteString.Dword = RouteChart.Dword; + Xhc->UsbDevContext[SlotId].ParentRouteString.Dword = ParentRouteChart.Dword; // // 4.3.3 Device Slot Initialization // 1) Allocate an Input Context data structure (6.2.5) and initialize all fields to '0'. // - InputContext = AllocateAlignedZeroPool(sizeof (INPUT_CONTEXT), 64); + InputContext = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (INPUT_CONTEXT))); ASSERT (InputContext != NULL); ASSERT (((UINTN) InputContext & 0x3F) == 0); + ZeroMem (InputContext, sizeof (INPUT_CONTEXT)); - UsbDevContext[SlotId].InputContext = (VOID *) InputContext; + Xhc->UsbDevContext[SlotId].InputContext = (VOID *) InputContext; // // 2) Initialize the Input Control Context (6.2.5.1) of the Input Context by setting the A0 and A1 @@ -1859,21 +1721,21 @@ XhcInitializeDeviceSlot ( // // 3) Initialize the Input Slot Context data structure // - InputContext->Slot.RouteStr = RouteChart.Field.RouteString; + InputContext->Slot.RouteString = RouteChart.Route.RouteString; InputContext->Slot.Speed = DeviceSpeed + 1; InputContext->Slot.ContextEntries = 1; - InputContext->Slot.RootHubPortNum = RouteChart.Field.RootPortNum; + InputContext->Slot.RootHubPortNum = RouteChart.Route.RootPortNum; - if (RouteChart.Field.RouteString) { + if (RouteChart.Route.RouteString) { // // The device is behind of hub device. // - ParentSlotId = XhcRouteStringToSlotId(ParentRouteChart); + ParentSlotId = XhcRouteStringToSlotId(Xhc, ParentRouteChart); ASSERT (ParentSlotId != 0); // //if the Full/Low device attached to a High Speed Hub, Init the TTPortNum and TTHubSlotId field of slot context // - ParentDeviceContext = (DEVICE_CONTEXT *)UsbDevContext[ParentSlotId].OutputDevContxt; + ParentDeviceContext = (DEVICE_CONTEXT *)Xhc->UsbDevContext[ParentSlotId].OutputContext; if ((ParentDeviceContext->Slot.TTPortNum == 0) && (ParentDeviceContext->Slot.TTHubSlotId == 0)) { if ((ParentDeviceContext->Slot.Speed == (EFI_USB_SPEED_HIGH + 1)) && (DeviceSpeed < EFI_USB_SPEED_HIGH)) { @@ -1902,9 +1764,9 @@ XhcInitializeDeviceSlot ( // // 4) Allocate and initialize the Transfer Ring for the Default Control Endpoint. // - EndpointTransferRing = AllocateAlignedZeroPool(sizeof (TRANSFER_RING), 64); - UsbDevContext[SlotId].EndpointTransferRing[0] = EndpointTransferRing; - CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)UsbDevContext[SlotId].EndpointTransferRing[0]); + EndpointTransferRing = AllocateZeroPool (sizeof (TRANSFER_RING)); + Xhc->UsbDevContext[SlotId].EndpointTransferRing[0] = EndpointTransferRing; + CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[0]); // // 5) Initialize the Input default control Endpoint 0 Context (6.2.3). // @@ -1931,45 +1793,46 @@ XhcInitializeDeviceSlot ( // // Init the DCS(dequeue cycle state) as the transfer ring's CCS // - InputContext->EP[0].PtrLo = XHC_LOW_32BIT (((TRANSFER_RING *)(UINTN)UsbDevContext[SlotId].EndpointTransferRing[0])->RingSeg0) | BIT0; - InputContext->EP[0].PtrHi = XHC_HIGH_32BIT (((TRANSFER_RING *)(UINTN)UsbDevContext[SlotId].EndpointTransferRing[0])->RingSeg0); + InputContext->EP[0].PtrLo = XHC_LOW_32BIT (((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[0])->RingSeg0) | BIT0; + InputContext->EP[0].PtrHi = XHC_HIGH_32BIT (((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[0])->RingSeg0); // // 6) Allocate the Output Device Context data structure (6.2.1) and initialize it to '0'. // - OutputDevContxt = AllocateAlignedZeroPool(sizeof (DEVICE_CONTEXT), 64); - ASSERT (OutputDevContxt != NULL); - ASSERT (((UINTN) OutputDevContxt & 0x3F) == 0); + OutputContext = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (DEVICE_CONTEXT))); + ASSERT (OutputContext != NULL); + ASSERT (((UINTN) OutputContext & 0x3F) == 0); + ZeroMem (OutputContext, sizeof (DEVICE_CONTEXT)); - UsbDevContext[SlotId].OutputDevContxt = OutputDevContxt; + Xhc->UsbDevContext[SlotId].OutputContext = OutputContext; // // 7) Load the appropriate (Device Slot ID) entry in the Device Context Base Address Array (5.4.6) with // a pointer to the Output Device Context data structure (6.2.1). // - Xhc->DCBAA[SlotId] = (UINT64) (UINTN) OutputDevContxt; + Xhc->DCBAA[SlotId] = (UINT64) (UINTN) OutputContext; // // 8) Issue an Address Device Command for the Device Slot, where the command points to the Input // Context data structure described above. // ZeroMem (&CmdTrbAddr, sizeof (CmdTrbAddr)); - CmdTrbAddr.PtrLo = XHC_LOW_32BIT (UsbDevContext[SlotId].InputContext); - CmdTrbAddr.PtrHi = XHC_HIGH_32BIT (UsbDevContext[SlotId].InputContext); + CmdTrbAddr.PtrLo = XHC_LOW_32BIT (Xhc->UsbDevContext[SlotId].InputContext); + CmdTrbAddr.PtrHi = XHC_HIGH_32BIT (Xhc->UsbDevContext[SlotId].InputContext); CmdTrbAddr.CycleBit = 1; CmdTrbAddr.Type = TRB_TYPE_ADDRESS_DEV; - CmdTrbAddr.SlotId = UsbDevContext[SlotId].SlotId; + CmdTrbAddr.SlotId = Xhc->UsbDevContext[SlotId].SlotId; Status = XhcCmdTransfer ( Xhc, - (TRB *) (UINTN) &CmdTrbAddr, + (TRB_TEMPLATE *) (UINTN) &CmdTrbAddr, XHC_GENERIC_TIMEOUT, - (TRB **) (UINTN) &EvtTrb + (TRB_TEMPLATE **) (UINTN) &EvtTrb ); ASSERT (!EFI_ERROR(Status)); - DeviceAddress = (UINT8) ((DEVICE_CONTEXT *) OutputDevContxt)->Slot.DeviceAddress; + DeviceAddress = (UINT8) ((DEVICE_CONTEXT *) OutputContext)->Slot.DeviceAddress; DEBUG ((EFI_D_INFO, " Address %d assigned succeefully\n", DeviceAddress)); - UsbDevContext[SlotId].XhciDevAddr = DeviceAddress; + Xhc->UsbDevContext[SlotId].XhciDevAddr = DeviceAddress; return Status; } @@ -1977,7 +1840,7 @@ XhcInitializeDeviceSlot ( /** 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. @@ -1986,13 +1849,13 @@ XhcInitializeDeviceSlot ( EFI_STATUS EFIAPI XhcDisableSlotCmd ( - IN USB_XHCI_DEV *Xhc, + IN USB_XHCI_INSTANCE *Xhc, IN UINT8 SlotId ) { EFI_STATUS Status; - TRB *EvtTrb; - CMD_TRB_DIS_SLOT CmdTrbDisSlot; + TRB_TEMPLATE *EvtTrb; + CMD_TRB_DISABLE_SLOT CmdTrbDisSlot; UINT8 Index; VOID *RingSeg; @@ -2001,17 +1864,17 @@ XhcDisableSlotCmd ( // Entry 0 is reserved. // for (Index = 0; Index < 255; Index++) { - if (!UsbDevContext[Index + 1].Enabled || - (UsbDevContext[Index + 1].SlotId == 0) || - (UsbDevContext[Index + 1].ParentRouteString.Dword != UsbDevContext[SlotId].RouteString.Dword)) { + if (!Xhc->UsbDevContext[Index + 1].Enabled || + (Xhc->UsbDevContext[Index + 1].SlotId == 0) || + (Xhc->UsbDevContext[Index + 1].ParentRouteString.Dword != Xhc->UsbDevContext[SlotId].RouteString.Dword)) { continue; } - Status = XhcDisableSlotCmd (Xhc, UsbDevContext[Index + 1].SlotId); + Status = XhcDisableSlotCmd (Xhc, Xhc->UsbDevContext[Index + 1].SlotId); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "XhcDisableSlotCmd: failed to disable child, ignore error\n")); - UsbDevContext[Index + 1].SlotId = 0; + Xhc->UsbDevContext[Index + 1].SlotId = 0; } } @@ -2026,9 +1889,9 @@ XhcDisableSlotCmd ( CmdTrbDisSlot.SlotId = SlotId; Status = XhcCmdTransfer ( Xhc, - (TRB *) (UINTN) &CmdTrbDisSlot, + (TRB_TEMPLATE *) (UINTN) &CmdTrbDisSlot, XHC_GENERIC_TIMEOUT, - (TRB **) (UINTN) &EvtTrb + (TRB_TEMPLATE **) (UINTN) &EvtTrb ); ASSERT_EFI_ERROR(Status); // @@ -2040,34 +1903,34 @@ XhcDisableSlotCmd ( // Free the slot related data structure // for (Index = 0; Index < 31; Index++) { - if (UsbDevContext[SlotId].EndpointTransferRing[Index] != NULL) { - RingSeg = ((TRANSFER_RING *)(UINTN)UsbDevContext[SlotId].EndpointTransferRing[Index])->RingSeg0; + if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index] != NULL) { + RingSeg = ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index])->RingSeg0; if (RingSeg != NULL) { - FreeAlignedPool(RingSeg); + FreePages (RingSeg, EFI_SIZE_TO_PAGES (sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER)); } - FreeAlignedPool(UsbDevContext[SlotId].EndpointTransferRing[Index]); + FreePool (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index]); } } - for (Index = 0; Index < UsbDevContext[SlotId].DevDesc.NumConfigurations; Index++) { - if (UsbDevContext[SlotId].ConfDesc[Index] != NULL) { - FreePool (UsbDevContext[SlotId].ConfDesc[Index]); + for (Index = 0; Index < Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations; Index++) { + if (Xhc->UsbDevContext[SlotId].ConfDesc[Index] != NULL) { + FreePool (Xhc->UsbDevContext[SlotId].ConfDesc[Index]); } } - if (UsbDevContext[SlotId].InputContext != NULL) { - FreeAlignedPool (UsbDevContext[SlotId].InputContext); + if (Xhc->UsbDevContext[SlotId].InputContext != NULL) { + FreePages (Xhc->UsbDevContext[SlotId].InputContext, EFI_SIZE_TO_PAGES (sizeof (INPUT_CONTEXT))); } - if (UsbDevContext[SlotId].OutputDevContxt != NULL) { - FreeAlignedPool (UsbDevContext[SlotId].OutputDevContxt); + if (Xhc->UsbDevContext[SlotId].OutputContext != NULL) { + FreePages (Xhc->UsbDevContext[SlotId].OutputContext, EFI_SIZE_TO_PAGES (sizeof (DEVICE_CONTEXT))); } // // Doesn't zero the entry because XhcAsyncInterruptTransfer() may be invoked to remove the established // asynchronous interrupt pipe after the device is disabled. It needs the device address mapping info to // remove urb from XHCI's asynchronous transfer list. // - UsbDevContext[SlotId].Enabled = FALSE; + Xhc->UsbDevContext[SlotId].Enabled = FALSE; return Status; } @@ -2075,7 +1938,7 @@ XhcDisableSlotCmd ( /** 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. @@ -2086,38 +1949,38 @@ XhcDisableSlotCmd ( EFI_STATUS EFIAPI XhcSetConfigCmd ( - IN USB_XHCI_DEV *Xhc, + IN USB_XHCI_INSTANCE *Xhc, IN UINT8 SlotId, - IN UINT8 DeviceSpeed, + IN UINT8 DeviceSpeed, IN USB_CONFIG_DESCRIPTOR *ConfigDesc ) { - EFI_STATUS Status; - - USB_INTERFACE_DESCRIPTOR *IfDesc; - USB_ENDPOINT_DESCRIPTOR *EpDesc; - UINT8 Index; - UINTN NumEp; - UINTN EpIndex; - UINT8 EpAddr; - UINT8 Direction; - UINT8 Dci; - UINT8 MaxDci; - UINT32 PhyAddr; - UINT8 Interval; - - TRANSFER_RING *EndpointTransferRing; - CMD_CFG_ED CmdTrbCfgEP; - INPUT_CONTEXT *InputContext; - DEVICE_CONTEXT *OutputDevContxt; - EVT_TRB_COMMAND *EvtTrb; + EFI_STATUS Status; + + USB_INTERFACE_DESCRIPTOR *IfDesc; + USB_ENDPOINT_DESCRIPTOR *EpDesc; + UINT8 Index; + UINTN NumEp; + UINTN EpIndex; + UINT8 EpAddr; + UINT8 Direction; + UINT8 Dci; + UINT8 MaxDci; + UINT32 PhyAddr; + UINT8 Interval; + + 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 = UsbDevContext[SlotId].InputContext; - OutputDevContxt = UsbDevContext[SlotId].OutputDevContxt; + InputContext = Xhc->UsbDevContext[SlotId].InputContext; + OutputContext = Xhc->UsbDevContext[SlotId].OutputContext; ZeroMem (InputContext, sizeof (INPUT_CONTEXT)); - CopyMem (&InputContext->Slot, &OutputDevContxt->Slot, sizeof (SLOT_CONTEXT)); + CopyMem (&InputContext->Slot, &OutputContext->Slot, sizeof (SLOT_CONTEXT)); ASSERT (ConfigDesc != NULL); @@ -2141,6 +2004,7 @@ XhcSetConfigCmd ( Direction = (UINT8)((EpDesc->EndpointAddress & 0x80) ? EfiUsbDataIn : EfiUsbDataOut); Dci = XhcEndpointToDci (EpAddr, Direction); + ASSERT (Dci < 32); if (Dci > MaxDci) { MaxDci = Dci; } @@ -2168,10 +2032,10 @@ XhcSetConfigCmd ( } InputContext->EP[Dci-1].AverageTRBLength = 0x1000; - if (UsbDevContext[SlotId].EndpointTransferRing[Dci-1] == NULL) { - EndpointTransferRing = AllocateAlignedZeroPool(sizeof (TRANSFER_RING), 64); - UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing; - CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)UsbDevContext[SlotId].EndpointTransferRing[Dci-1]); + 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; @@ -2200,22 +2064,26 @@ XhcSetConfigCmd ( if ((DeviceSpeed == EFI_USB_SPEED_FULL) || (DeviceSpeed == EFI_USB_SPEED_LOW)) { Interval = EpDesc->Interval; // - // BUGBUG: Hard code the interval to MAX + // Hard code the interval to MAX first, need calculate through the bInterval field of Endpoint descriptor. // InputContext->EP[Dci-1].Interval = 6; - } else if (DeviceSpeed == EFI_USB_SPEED_SUPER) { + } else if ((DeviceSpeed == EFI_USB_SPEED_HIGH) || (DeviceSpeed == EFI_USB_SPEED_SUPER)) { Interval = EpDesc->Interval; - InputContext->EP[Dci-1].Interval = 0x0F; + 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 (UsbDevContext[SlotId].EndpointTransferRing[Dci-1] == NULL) { - EndpointTransferRing = AllocateAlignedZeroPool(sizeof (TRANSFER_RING), 64); - UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing; - CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)UsbDevContext[SlotId].EndpointTransferRing[Dci-1]); + 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; @@ -2225,11 +2093,11 @@ XhcSetConfigCmd ( break; } - PhyAddr = XHC_LOW_32BIT (((TRANSFER_RING *)(UINTN)UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0); + PhyAddr = XHC_LOW_32BIT (((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0); PhyAddr &= ~(0x0F); - PhyAddr |= ((TRANSFER_RING *)(UINTN)UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingPCS; + PhyAddr |= ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingPCS; InputContext->EP[Dci-1].PtrLo = PhyAddr; - InputContext->EP[Dci-1].PtrHi = XHC_HIGH_32BIT (((TRANSFER_RING *)(UINTN)UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0); + InputContext->EP[Dci-1].PtrHi = XHC_HIGH_32BIT (((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0); EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length); } @@ -2246,13 +2114,13 @@ XhcSetConfigCmd ( CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (InputContext); CmdTrbCfgEP.CycleBit = 1; CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT; - CmdTrbCfgEP.SlotId = UsbDevContext[SlotId].SlotId; + CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId; DEBUG ((EFI_D_INFO, "Configure Endpoint\n")); Status = XhcCmdTransfer ( Xhc, - (TRB *) (UINTN) &CmdTrbCfgEP, + (TRB_TEMPLATE *) (UINTN) &CmdTrbCfgEP, XHC_GENERIC_TIMEOUT, - (TRB **) (UINTN) &EvtTrb + (TRB_TEMPLATE **) (UINTN) &EvtTrb ); ASSERT_EFI_ERROR(Status); @@ -2262,7 +2130,7 @@ XhcSetConfigCmd ( /** 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. @@ -2272,22 +2140,22 @@ XhcSetConfigCmd ( EFI_STATUS EFIAPI XhcEvaluateContext ( - IN USB_XHCI_DEV *Xhc, + IN USB_XHCI_INSTANCE *Xhc, IN UINT8 SlotId, IN UINT32 MaxPacketSize ) { - EFI_STATUS Status; - CMD_TRB_EVALU_CONTX CmdTrbEvalu; - EVT_TRB_COMMAND *EvtTrb; - INPUT_CONTEXT *InputContext; + EFI_STATUS Status; + CMD_TRB_EVALUATE_CONTEXT CmdTrbEvalu; + EVT_TRB_COMMAND_COMPLETION *EvtTrb; + INPUT_CONTEXT *InputContext; - ASSERT (UsbDevContext[SlotId].SlotId != 0); + ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0); // // 4.6.7 Evaluate Context // - InputContext = UsbDevContext[SlotId].InputContext; + InputContext = Xhc->UsbDevContext[SlotId].InputContext; ZeroMem (InputContext, sizeof (INPUT_CONTEXT)); InputContext->InputControlContext.Dword2 |= BIT1; @@ -2298,13 +2166,13 @@ XhcEvaluateContext ( CmdTrbEvalu.PtrHi = XHC_HIGH_32BIT (InputContext); CmdTrbEvalu.CycleBit = 1; CmdTrbEvalu.Type = TRB_TYPE_EVALU_CONTXT; - CmdTrbEvalu.SlotId = UsbDevContext[SlotId].SlotId; + CmdTrbEvalu.SlotId = Xhc->UsbDevContext[SlotId].SlotId; DEBUG ((EFI_D_INFO, "Evaluate context\n")); Status = XhcCmdTransfer ( Xhc, - (TRB *) (UINTN) &CmdTrbEvalu, + (TRB_TEMPLATE *) (UINTN) &CmdTrbEvalu, XHC_GENERIC_TIMEOUT, - (TRB **) (UINTN) &EvtTrb + (TRB_TEMPLATE **) (UINTN) &EvtTrb ); ASSERT (!EFI_ERROR(Status)); @@ -2314,7 +2182,7 @@ XhcEvaluateContext ( /** 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. @@ -2325,23 +2193,23 @@ XhcEvaluateContext ( **/ EFI_STATUS XhcConfigHubContext ( - IN USB_XHCI_DEV *Xhc, + IN USB_XHCI_INSTANCE *Xhc, IN UINT8 SlotId, IN UINT8 PortNum, IN UINT8 TTT, IN UINT8 MTT ) { - EFI_STATUS Status; + EFI_STATUS Status; - EVT_TRB_COMMAND *EvtTrb; - INPUT_CONTEXT *InputContext; - DEVICE_CONTEXT *OutputDevContxt; - CMD_CFG_ED CmdTrbCfgEP; + EVT_TRB_COMMAND_COMPLETION *EvtTrb; + INPUT_CONTEXT *InputContext; + DEVICE_CONTEXT *OutputContext; + CMD_TRB_CONFIG_ENDPOINT CmdTrbCfgEP; - ASSERT (UsbDevContext[SlotId].SlotId != 0); - InputContext = UsbDevContext[SlotId].InputContext; - OutputDevContxt = UsbDevContext[SlotId].OutputDevContxt; + ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0); + InputContext = Xhc->UsbDevContext[SlotId].InputContext; + OutputContext = Xhc->UsbDevContext[SlotId].OutputContext; // // 4.6.7 Evaluate Context @@ -2353,7 +2221,7 @@ XhcConfigHubContext ( // // Copy the slot context from OutputContext to Input context // - CopyMem(&(InputContext->Slot), &(OutputDevContxt->Slot), sizeof (SLOT_CONTEXT)); + CopyMem(&(InputContext->Slot), &(OutputContext->Slot), sizeof (SLOT_CONTEXT)); InputContext->Slot.Hub = 1; InputContext->Slot.PortNum = PortNum; InputContext->Slot.TTT = TTT; @@ -2364,13 +2232,13 @@ XhcConfigHubContext ( CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (InputContext); CmdTrbCfgEP.CycleBit = 1; CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT; - CmdTrbCfgEP.SlotId = UsbDevContext[SlotId].SlotId; + CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId; DEBUG ((EFI_D_INFO, "Configure Hub Slot Context\n")); Status = XhcCmdTransfer ( Xhc, - (TRB *) (UINTN) &CmdTrbCfgEP, + (TRB_TEMPLATE *) (UINTN) &CmdTrbCfgEP, XHC_GENERIC_TIMEOUT, - (TRB **) (UINTN) &EvtTrb + (TRB_TEMPLATE **) (UINTN) &EvtTrb ); ASSERT (!EFI_ERROR(Status)); diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.h b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.h index 64f6f79cd8..2090644e04 100644 --- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.h +++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.h @@ -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; - -// -// 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; +} EVT_TRB_COMMAND_COMPLETION; + +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 ); diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c index c3a9c734b8..63480f62a9 100644 --- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c +++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c @@ -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]); } diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.h b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.h index ce041b9f79..14454da28a 100644 --- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.h +++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.h @@ -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; diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c index aacc67fef1..b7141a0ab3 100644 --- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c +++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c @@ -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; } -- 2.39.2