X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FBus%2FPci%2FEhciDxe%2FEhci.c;h=e8fb1120b7736b1f680a27a9f73784b4f7086989;hp=0eaa9cce5dec3e0aa9b843f79a6d37002d72b043;hb=1c61953576f35507eb24032fe2804eaf9a0e976c;hpb=d01c093a582c001ae3817706b3d664e9ea3d00ba diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c index 0eaa9cce5d..e8fb1120b7 100644 --- a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c +++ b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c @@ -81,7 +81,7 @@ EhcGetCapability ( *PortNumber = (UINT8) (Ehc->HcStructParams & HCSP_NPORTS); *Is64BitCapable = (UINT8) (Ehc->HcCapParams & HCCP_64BIT); - EHC_DEBUG (("EhcGetCapability: %d ports, 64 bit %d\n", *PortNumber, *Is64BitCapable)); + DEBUG ((EFI_D_INFO, "EhcGetCapability: %d ports, 64 bit %d\n", *PortNumber, *Is64BitCapable)); gBS->RestoreTPL (OldTpl); return EFI_SUCCESS; @@ -126,7 +126,7 @@ EhcReset ( // Host Controller must be Halt when Reset it // if (!EhcIsHalt (Ehc)) { - Status = EhcHaltHC (Ehc, EHC_GENERIC_TIME); + Status = EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT); if (EFI_ERROR (Status)) { Status = EFI_DEVICE_ERROR; @@ -142,7 +142,7 @@ EhcReset ( EhcAckAllInterrupt (Ehc); EhcFreeSched (Ehc); - Status = EhcResetHC (Ehc, EHC_STALL_1_SECOND); + Status = EhcResetHC (Ehc, EHC_RESET_TIMEOUT); if (EFI_ERROR (Status)) { goto ON_EXIT; @@ -161,7 +161,7 @@ EhcReset ( } ON_EXIT: - EHC_DEBUG (("EhcReset: exit status %r\n", Status)); + DEBUG ((EFI_D_INFO, "EhcReset: exit status %r\n", Status)); gBS->RestoreTPL (OldTpl); return Status; } @@ -206,7 +206,7 @@ EhcGetState ( gBS->RestoreTPL (OldTpl); - EHC_DEBUG (("EhcGetState: current state %d\n", *State)); + DEBUG ((EFI_D_INFO, "EhcGetState: current state %d\n", *State)); return EFI_SUCCESS; } @@ -251,7 +251,7 @@ EhcSetState ( switch (State) { case EfiUsbHcStateHalt: - Status = EhcHaltHC (Ehc, EHC_GENERIC_TIME); + Status = EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT); break; case EfiUsbHcStateOperational: @@ -260,7 +260,17 @@ EhcSetState ( break; } - Status = EhcRunHC (Ehc, EHC_GENERIC_TIME); + // + // Software must not write a one to this field unless the host controller + // is in the Halted state. Doing so will yield undefined results. + // refers to Spec[EHCI1.0-2.3.1] + // + if (!EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT)) { + Status = EFI_DEVICE_ERROR; + break; + } + + Status = EhcRunHC (Ehc, EHC_GENERIC_TIMEOUT); break; case EfiUsbHcStateSuspend: @@ -271,7 +281,7 @@ EhcSetState ( Status = EFI_INVALID_PARAMETER; } - EHC_DEBUG (("EhcSetState: exit status %r\n", Status)); + DEBUG ((EFI_D_INFO, "EhcSetState: exit status %r\n", Status)); gBS->RestoreTPL (OldTpl); return Status; } @@ -437,10 +447,10 @@ EhcSetRootHubPortFeature ( // Make sure Host Controller not halt before reset it // if (EhcIsHalt (Ehc)) { - Status = EhcRunHC (Ehc, EHC_GENERIC_TIME); + Status = EhcRunHC (Ehc, EHC_GENERIC_TIMEOUT); if (EFI_ERROR (Status)) { - EHC_DEBUG (("EhcSetRootHubPortFeature :failed to start HC - %r\n", Status)); + DEBUG ((EFI_D_INFO, "EhcSetRootHubPortFeature :failed to start HC - %r\n", Status)); break; } } @@ -470,7 +480,7 @@ EhcSetRootHubPortFeature ( } ON_EXIT: - EHC_DEBUG (("EhcSetRootHubPortFeature: exit status %r\n", Status)); + DEBUG ((EFI_D_INFO, "EhcSetRootHubPortFeature: exit status %r\n", Status)); gBS->RestoreTPL (OldTpl); return Status; @@ -598,7 +608,7 @@ EhcClearRootHubPortFeature ( } ON_EXIT: - EHC_DEBUG (("EhcClearRootHubPortFeature: exit status %r\n", Status)); + DEBUG ((EFI_D_INFO, "EhcClearRootHubPortFeature: exit status %r\n", Status)); gBS->RestoreTPL (OldTpl); return Status; } @@ -690,7 +700,7 @@ EhcControlTransfer ( *TransferResult = EFI_USB_ERR_SYSTEM; if (EhcIsHalt (Ehc) || EhcIsSysError (Ehc)) { - EHC_ERROR (("EhcControlTransfer: HC halted at entrance\n")); + DEBUG ((EFI_D_ERROR, "EhcControlTransfer: HC halted at entrance\n")); EhcAckAllInterrupt (Ehc); goto ON_EXIT; @@ -726,7 +736,7 @@ EhcControlTransfer ( ); if (Urb == NULL) { - EHC_ERROR (("EhcControlTransfer: failed to create URB")); + DEBUG ((EFI_D_ERROR, "EhcControlTransfer: failed to create URB")); Status = EFI_OUT_OF_RESOURCES; goto ON_EXIT; @@ -755,7 +765,7 @@ ON_EXIT: gBS->RestoreTPL (OldTpl); if (EFI_ERROR (Status)) { - EHC_ERROR (("EhcControlTransfer: error - %r, transfer - %x\n", Status, *TransferResult)); + DEBUG ((EFI_D_ERROR, "EhcControlTransfer: error - %r, transfer - %x\n", Status, *TransferResult)); } return Status; @@ -841,7 +851,7 @@ EhcBulkTransfer ( Status = EFI_DEVICE_ERROR; if (EhcIsHalt (Ehc) || EhcIsSysError (Ehc)) { - EHC_ERROR (("EhcBulkTransfer: HC is halted\n")); + DEBUG ((EFI_D_ERROR, "EhcBulkTransfer: HC is halted\n")); EhcAckAllInterrupt (Ehc); goto ON_EXIT; @@ -871,7 +881,7 @@ EhcBulkTransfer ( ); if (Urb == NULL) { - EHC_ERROR (("EhcBulkTransfer: failed to create URB\n")); + DEBUG ((EFI_D_ERROR, "EhcBulkTransfer: failed to create URB\n")); Status = EFI_OUT_OF_RESOURCES; goto ON_EXIT; @@ -897,7 +907,7 @@ ON_EXIT: gBS->RestoreTPL (OldTpl); if (EFI_ERROR (Status)) { - EHC_ERROR (("EhcBulkTransfer: error - %r, transfer - %x\n", Status, *TransferResult)); + DEBUG ((EFI_D_ERROR, "EhcBulkTransfer: error - %r, transfer - %x\n", Status, *TransferResult)); } return Status; @@ -988,14 +998,14 @@ EhcAsyncInterruptTransfer ( if (!IsNewTransfer) { Status = EhciDelAsyncIntTransfer (Ehc, DeviceAddress, EndPointAddress, DataToggle); - EHC_DEBUG (("EhcAsyncInterruptTransfer: remove old transfer - %r\n", Status)); + DEBUG ((EFI_D_INFO, "EhcAsyncInterruptTransfer: remove old transfer - %r\n", Status)); goto ON_EXIT; } Status = EFI_SUCCESS; if (EhcIsHalt (Ehc) || EhcIsSysError (Ehc)) { - EHC_ERROR (("EhcAsyncInterruptTransfer: HC is halt\n")); + DEBUG ((EFI_D_ERROR, "EhcAsyncInterruptTransfer: HC is halt\n")); EhcAckAllInterrupt (Ehc); Status = EFI_DEVICE_ERROR; @@ -1007,7 +1017,7 @@ EhcAsyncInterruptTransfer ( Data = AllocatePool (DataLength); if (Data == NULL) { - EHC_ERROR (("EhcAsyncInterruptTransfer: failed to allocate buffer\n")); + DEBUG ((EFI_D_ERROR, "EhcAsyncInterruptTransfer: failed to allocate buffer\n")); Status = EFI_OUT_OF_RESOURCES; goto ON_EXIT; @@ -1031,7 +1041,7 @@ EhcAsyncInterruptTransfer ( ); if (Urb == NULL) { - EHC_ERROR (("EhcAsyncInterruptTransfer: failed to create URB\n")); + DEBUG ((EFI_D_ERROR, "EhcAsyncInterruptTransfer: failed to create URB\n")); gBS->FreePool (Data); Status = EFI_OUT_OF_RESOURCES; @@ -1131,7 +1141,7 @@ EhcSyncInterruptTransfer ( Status = EFI_DEVICE_ERROR; if (EhcIsHalt (Ehc) || EhcIsSysError (Ehc)) { - EHC_ERROR (("EhcSyncInterruptTransfer: HC is halt\n")); + DEBUG ((EFI_D_ERROR, "EhcSyncInterruptTransfer: HC is halt\n")); EhcAckAllInterrupt (Ehc); goto ON_EXIT; @@ -1157,7 +1167,7 @@ EhcSyncInterruptTransfer ( ); if (Urb == NULL) { - EHC_ERROR (("EhcSyncInterruptTransfer: failed to create URB\n")); + DEBUG ((EFI_D_ERROR, "EhcSyncInterruptTransfer: failed to create URB\n")); Status = EFI_OUT_OF_RESOURCES; goto ON_EXIT; @@ -1180,7 +1190,7 @@ ON_EXIT: gBS->RestoreTPL (OldTpl); if (EFI_ERROR (Status)) { - EHC_ERROR (("EhcSyncInterruptTransfer: error - %r, transfer - %x\n", Status, *TransferResult)); + DEBUG ((EFI_D_ERROR, "EhcSyncInterruptTransfer: error - %r, transfer - %x\n", Status, *TransferResult)); } return Status; @@ -1295,14 +1305,13 @@ Returns: --*/ { - return EfiLibInstallAllDriverProtocols ( + return EfiLibInstallDriverBindingComponentName2 ( ImageHandle, SystemTable, &gEhciDriverBinding, ImageHandle, &gEhciComponentName, - NULL, - NULL + &gEhciComponentName2 ); } @@ -1386,7 +1395,8 @@ ON_EXIT: /** Create and initialize a USB2_HC_DEV - @param PciIo The PciIo on this device + @param PciIo The PciIo on this device + @param OriginalPciAttributes Original PCI attributes @return The allocated and initialized USB2_HC_DEV structure @return if created, otherwise NULL. @@ -1395,7 +1405,8 @@ ON_EXIT: STATIC USB2_HC_DEV * EhcCreateUsb2Hc ( - IN EFI_PCI_IO_PROTOCOL *PciIo + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN UINT64 OriginalPciAttributes ) { USB2_HC_DEV *Ehc; @@ -1428,7 +1439,8 @@ EhcCreateUsb2Hc ( Ehc->Usb2Hc.MajorRevision = 0x1; Ehc->Usb2Hc.MinorRevision = 0x1; - Ehc->PciIo = PciIo; + Ehc->PciIo = PciIo; + Ehc->OriginalPciAttributes = OriginalPciAttributes; InitializeListHead (&Ehc->AsyncIntTransfers); @@ -1436,7 +1448,7 @@ EhcCreateUsb2Hc ( Ehc->HcCapParams = EhcReadCapRegister (Ehc, EHC_HCCPARAMS_OFFSET); Ehc->CapLen = EhcReadCapRegister (Ehc, EHC_CAPLENGTH_OFFSET) & 0x0FF; - EHC_DEBUG (("EhcCreateUsb2Hc: capability length %d\n", Ehc->CapLen)); + DEBUG ((EFI_D_INFO, "EhcCreateUsb2Hc: capability length %d\n", Ehc->CapLen)); // // Create AsyncRequest Polling Timer @@ -1482,6 +1494,9 @@ EhcDriverBindingStart ( EFI_STATUS Status; USB2_HC_DEV *Ehc; EFI_PCI_IO_PROTOCOL *PciIo; + UINT64 Supports; + UINT64 OriginalPciAttributes; + BOOLEAN PciAttributesSaved; // // Open the PciIo Protocol, then enable the USB host controller @@ -1496,29 +1511,54 @@ EhcDriverBindingStart ( ); if (EFI_ERROR (Status)) { - EHC_ERROR (("EhcDriverBindingStart: failed to open PCI_IO\n")); + DEBUG ((EFI_D_ERROR, "EhcDriverBindingStart: failed to open PCI_IO\n")); return EFI_DEVICE_ERROR; } + PciAttributesSaved = FALSE; + // + // Save original PCI attributes + // Status = PciIo->Attributes ( PciIo, - EfiPciIoAttributeOperationEnable, - EFI_PCI_DEVICE_ENABLE, - NULL + EfiPciIoAttributeOperationGet, + 0, + &OriginalPciAttributes + ); + + if (EFI_ERROR (Status)) { + goto CLOSE_PCIIO; + } + PciAttributesSaved = TRUE; + + Status = PciIo->Attributes ( + PciIo, + EfiPciIoAttributeOperationSupported, + 0, + &Supports ); + if (!EFI_ERROR (Status)) { + Supports &= EFI_PCI_DEVICE_ENABLE; + Status = PciIo->Attributes ( + PciIo, + EfiPciIoAttributeOperationEnable, + Supports, + NULL + ); + } if (EFI_ERROR (Status)) { - EHC_ERROR (("EhcDriverBindingStart: failed to enable controller\n")); + DEBUG ((EFI_D_ERROR, "EhcDriverBindingStart: failed to enable controller\n")); goto CLOSE_PCIIO; } // // Create then install USB2_HC_PROTOCOL // - Ehc = EhcCreateUsb2Hc (PciIo); + Ehc = EhcCreateUsb2Hc (PciIo, OriginalPciAttributes); if (Ehc == NULL) { - EHC_ERROR (("EhcDriverBindingStart: failed to create USB2_HC\n")); + DEBUG ((EFI_D_ERROR, "EhcDriverBindingStart: failed to create USB2_HC\n")); Status = EFI_OUT_OF_RESOURCES; goto CLOSE_PCIIO; @@ -1532,7 +1572,7 @@ EhcDriverBindingStart ( ); if (EFI_ERROR (Status)) { - EHC_ERROR (("EhcDriverBindingStart: failed to install USB2_HC Protocol\n")); + DEBUG ((EFI_D_ERROR, "EhcDriverBindingStart: failed to install USB2_HC Protocol\n")); goto FREE_POOL; } @@ -1540,24 +1580,24 @@ EhcDriverBindingStart ( // Robustnesss improvement such as for UoL // EhcClearLegacySupport (Ehc); - EhcResetHC (Ehc, EHC_STALL_1_SECOND); + EhcResetHC (Ehc, EHC_RESET_TIMEOUT); Status = EhcInitHC (Ehc); if (EFI_ERROR (Status)) { - EHC_ERROR (("EhcDriverBindingStart: failed to init host controller\n")); + DEBUG ((EFI_D_ERROR, "EhcDriverBindingStart: failed to init host controller\n")); goto UNINSTALL_USBHC; } // // Start the asynchronous interrupt monitor // - Status = gBS->SetTimer (Ehc->PollTimer, TimerPeriodic, EHC_ASYNC_POLL_TIME); + Status = gBS->SetTimer (Ehc->PollTimer, TimerPeriodic, EHC_ASYNC_POLL_INTERVAL); if (EFI_ERROR (Status)) { - EHC_ERROR (("EhcDriverBindingStart: failed to start async interrupt monitor\n")); + DEBUG ((EFI_D_ERROR, "EhcDriverBindingStart: failed to start async interrupt monitor\n")); - EhcHaltHC (Ehc, EHC_GENERIC_TIME); + EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT); goto UNINSTALL_USBHC; } @@ -1565,14 +1605,23 @@ EhcDriverBindingStart ( // Install the component name protocol, don't fail the start // because of something for display. // - AddUnicodeString ( + AddUnicodeString2 ( "eng", gEhciComponentName.SupportedLanguages, &Ehc->ControllerNameTable, - L"Enhanced Host Controller (USB 2.0)" + L"Enhanced Host Controller (USB 2.0)", + TRUE + ); + AddUnicodeString2 ( + "en", + gEhciComponentName2.SupportedLanguages, + &Ehc->ControllerNameTable, + L"Enhanced Host Controller (USB 2.0)", + FALSE ); - EHC_DEBUG (("EhcDriverBindingStart: EHCI started for controller @ %x\n", Controller)); + + DEBUG ((EFI_D_INFO, "EhcDriverBindingStart: EHCI started for controller @ %x\n", Controller)); return EFI_SUCCESS; UNINSTALL_USBHC: @@ -1588,6 +1637,18 @@ FREE_POOL: gBS->FreePool (Ehc); CLOSE_PCIIO: + if (PciAttributesSaved == TRUE) { + // + // Restore original PCI attributes + // + PciIo->Attributes ( + PciIo, + EfiPciIoAttributeOperationSet, + OriginalPciAttributes, + NULL + ); + } + gBS->CloseProtocol ( Controller, &gEfiPciIoProtocolGuid, @@ -1651,8 +1712,8 @@ EhcDriverBindingStop ( // Stop AsyncRequest Polling timer then stop the EHCI driver // and uninstall the EHCI protocl. // - gBS->SetTimer (Ehc->PollTimer, TimerCancel, EHC_ASYNC_POLL_TIME); - EhcHaltHC (Ehc, EHC_GENERIC_TIME); + gBS->SetTimer (Ehc->PollTimer, TimerCancel, EHC_ASYNC_POLL_INTERVAL); + EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT); Status = gBS->UninstallProtocolInterface ( Controller, @@ -1675,14 +1736,14 @@ EhcDriverBindingStop ( } // - // Disable the USB Host Controller + // Restore original PCI attributes // PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationDisable, - EFI_PCI_DEVICE_ENABLE, - NULL - ); + PciIo, + EfiPciIoAttributeOperationSet, + Ehc->OriginalPciAttributes, + NULL + ); gBS->CloseProtocol ( Controller, @@ -1691,8 +1752,9 @@ EhcDriverBindingStop ( Controller ); - gBS->FreePool (Ehc); - return Status; + FreePool (Ehc); + + return EFI_SUCCESS; } EFI_DRIVER_BINDING_PROTOCOL