X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FBus%2FPci%2FEhciDxe%2FEhci.c;h=32ae6b6cdcfd040f2ef004ab95c55beaf0577535;hp=07a690edce0788237587137a6e9853cdbd29c3b6;hb=68246fa809e4a8ab61ce7bbfdd1a0b31d03e83fb;hpb=41e8ff2781f3ca14f73ef5f39e781ccba8cb373d diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c index 07a690edce..32ae6b6cdc 100644 --- a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c +++ b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c @@ -133,7 +133,7 @@ EhcReset ( goto ON_EXIT; } } - + // // Clean up the asynchronous transfers, currently only // interrupt supports asynchronous operation. @@ -262,9 +262,9 @@ EhcSetState ( // // Software must not write a one to this field unless the host controller - // is in the Halted state. Doing so will yield undefined results. + // 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; @@ -454,7 +454,7 @@ EhcSetRootHubPortFeature ( break; } } - + // // Set one to PortReset bit must also set zero to PortEnable bit // @@ -1395,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. @@ -1404,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; @@ -1437,7 +1439,8 @@ EhcCreateUsb2Hc ( Ehc->Usb2Hc.MajorRevision = 0x1; Ehc->Usb2Hc.MinorRevision = 0x1; - Ehc->PciIo = PciIo; + Ehc->PciIo = PciIo; + Ehc->OriginalPciAttributes = OriginalPciAttributes; InitializeListHead (&Ehc->AsyncIntTransfers); @@ -1491,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 @@ -1509,13 +1514,36 @@ EhcDriverBindingStart ( return EFI_DEVICE_ERROR; } + // + // Save original PCI attributes + // Status = PciIo->Attributes ( PciIo, - EfiPciIoAttributeOperationEnable, - EFI_PCI_DEVICE_ENABLE, - NULL + EfiPciIoAttributeOperationGet, + 0, + &OriginalPciAttributes ); + if (EFI_ERROR (Status)) { + return Status; + } + + 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")); goto CLOSE_PCIIO; @@ -1524,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")); @@ -1606,6 +1634,16 @@ FREE_POOL: gBS->FreePool (Ehc); CLOSE_PCIIO: + // + // Restore original PCI attributes + // + PciIo->Attributes ( + PciIo, + EfiPciIoAttributeOperationSet, + OriginalPciAttributes, + NULL + ); + gBS->CloseProtocol ( Controller, &gEfiPciIoProtocolGuid, @@ -1693,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, @@ -1709,8 +1747,9 @@ EhcDriverBindingStop ( Controller ); - gBS->FreePool (Ehc); - return Status; + FreePool (Ehc); + + return EFI_SUCCESS; } EFI_DRIVER_BINDING_PROTOCOL