X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FBus%2FPci%2FEhciDxe%2FEhci.c;h=32ae6b6cdcfd040f2ef004ab95c55beaf0577535;hp=093388d45f69e593bae3d5f0e1537909db41e809;hb=68246fa809e4a8ab61ce7bbfdd1a0b31d03e83fb;hpb=913cb9dc645d6db47d8c2a0be0369083b8bed25d diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c index 093388d45f..32ae6b6cdc 100644 --- a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c +++ b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c @@ -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; @@ -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: @@ -351,7 +361,7 @@ EhcGetRootHubPortStatus ( for (Index = 0; Index < MapSize; Index++) { if (EHC_BIT_IS_SET (State, mUsbPortStateMap[Index].HwState)) { - PortStatus->PortStatus |= mUsbPortStateMap[Index].UefiState; + PortStatus->PortStatus = (UINT16) (PortStatus->PortStatus | mUsbPortStateMap[Index].UefiState); } } @@ -359,7 +369,7 @@ EhcGetRootHubPortStatus ( for (Index = 0; Index < MapSize; Index++) { if (EHC_BIT_IS_SET (State, mUsbPortChangeMap[Index].HwState)) { - PortStatus->PortChangeStatus |= mUsbPortChangeMap[Index].UefiState; + PortStatus->PortChangeStatus = (UINT16) (PortStatus->PortChangeStatus | mUsbPortChangeMap[Index].UefiState); } } @@ -437,7 +447,7 @@ 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)); @@ -707,7 +717,7 @@ EhcControlTransfer ( // endpoint is bidirectional. EhcCreateUrb expects this // combination of Ep addr and its direction. // - Endpoint = 0 | ((TransferDirection == EfiUsbDataIn) ? 0x80 : 0); + Endpoint = (UINT8) (0 | ((TransferDirection == EfiUsbDataIn) ? 0x80 : 0)); Urb = EhcCreateUrb ( Ehc, DeviceAddress, @@ -1271,8 +1281,6 @@ EhcAsyncIsochronousTransfer ( return EFI_UNSUPPORTED; } -//@MT: EFI_DRIVER_ENTRY_POINT (EhcDriverEntryPoint) - EFI_STATUS EFIAPI EhcDriverEntryPoint ( @@ -1297,14 +1305,13 @@ Returns: --*/ { - return EfiLibInstallAllDriverProtocols ( + return EfiLibInstallDriverBindingComponentName2 ( ImageHandle, SystemTable, &gEhciDriverBinding, ImageHandle, &gEhciComponentName, - NULL, - NULL + &gEhciComponentName2 ); } @@ -1340,7 +1347,7 @@ EhcDriverBindingSupported ( Status = gBS->OpenProtocol ( Controller, &gEfiPciIoProtocolGuid, - &PciIo, + (VOID **) &PciIo, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER @@ -1388,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. @@ -1397,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; @@ -1430,7 +1439,8 @@ EhcCreateUsb2Hc ( Ehc->Usb2Hc.MajorRevision = 0x1; Ehc->Usb2Hc.MinorRevision = 0x1; - Ehc->PciIo = PciIo; + Ehc->PciIo = PciIo; + Ehc->OriginalPciAttributes = OriginalPciAttributes; InitializeListHead (&Ehc->AsyncIntTransfers); @@ -1484,6 +1494,8 @@ EhcDriverBindingStart ( EFI_STATUS Status; USB2_HC_DEV *Ehc; EFI_PCI_IO_PROTOCOL *PciIo; + UINT64 Supports; + UINT64 OriginalPciAttributes; // // Open the PciIo Protocol, then enable the USB host controller @@ -1491,7 +1503,7 @@ EhcDriverBindingStart ( Status = gBS->OpenProtocol ( Controller, &gEfiPciIoProtocolGuid, - &PciIo, + (VOID **) &PciIo, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER @@ -1502,12 +1514,35 @@ EhcDriverBindingStart ( return EFI_DEVICE_ERROR; } + // + // Save original PCI attributes + // + Status = PciIo->Attributes ( + PciIo, + EfiPciIoAttributeOperationGet, + 0, + &OriginalPciAttributes + ); + + if (EFI_ERROR (Status)) { + return Status; + } + Status = PciIo->Attributes ( PciIo, - EfiPciIoAttributeOperationEnable, - EFI_PCI_DEVICE_ENABLE, - NULL + 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")); @@ -1517,7 +1552,7 @@ EhcDriverBindingStart ( // // 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")); @@ -1542,7 +1577,7 @@ EhcDriverBindingStart ( // Robustnesss improvement such as for UoL // EhcClearLegacySupport (Ehc); - EhcResetHC (Ehc, EHC_STALL_1_SECOND); + EhcResetHC (Ehc, EHC_RESET_TIMEOUT); Status = EhcInitHC (Ehc); @@ -1554,12 +1589,12 @@ EhcDriverBindingStart ( // // 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")); - EhcHaltHC (Ehc, EHC_GENERIC_TIME); + EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT); goto UNINSTALL_USBHC; } @@ -1567,13 +1602,22 @@ 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)); return EFI_SUCCESS; @@ -1590,6 +1634,16 @@ FREE_POOL: gBS->FreePool (Ehc); CLOSE_PCIIO: + // + // Restore original PCI attributes + // + PciIo->Attributes ( + PciIo, + EfiPciIoAttributeOperationSet, + OriginalPciAttributes, + NULL + ); + gBS->CloseProtocol ( Controller, &gEfiPciIoProtocolGuid, @@ -1636,7 +1690,7 @@ EhcDriverBindingStop ( Status = gBS->OpenProtocol ( Controller, &gEfiUsb2HcProtocolGuid, - &Usb2Hc, + (VOID **) &Usb2Hc, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_GET_PROTOCOL @@ -1653,8 +1707,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, @@ -1677,14 +1731,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, @@ -1693,8 +1747,9 @@ EhcDriverBindingStop ( Controller ); - gBS->FreePool (Ehc); - return Status; + FreePool (Ehc); + + return EFI_SUCCESS; } EFI_DRIVER_BINDING_PROTOCOL