Remove the special logic on EFI_PCI_DEVICE_ENABLE in PciBus driver. And update drivers that use this macro. The reason is that
PciIoAttributes() in PciIo.c treats EFI_PCI_DEVICE_ENABLE specially so that when EFI_PCI_DEVICE_ENABLE is passed in, only the supported bits of driver will be enabled. Now many drivers use EFI_PCI_DEVICE_ENABLE to enable PCI device even if some of them don't support some of the attributes like EFI_PCI_IO_ATTRIBUTE_MEMORY. This doesn't conform to UEFI 2.0 spec.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4115 6f19259b-4bc3-4df7-8a09-765794883524
diff --git a/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/idebus.c b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/idebus.c
index 8f555c7..48c2184 100644
--- a/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/idebus.c
+++ b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/idebus.c
@@ -182,6 +182,7 @@
   UINT16                            ControlBlockBaseAddr;

   UINTN                             DataSize;

   IDE_BUS_DRIVER_PRIVATE_DATA       *IdeBusDriverPrivateData;

+  UINT64                            Supports;

 

   //

   // Local variables declaration for IdeControllerInit support

@@ -297,10 +298,20 @@
 

   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)) {

     goto ErrorExit;

   }

@@ -835,6 +846,7 @@
   BOOLEAN                     AllChildrenStopped;

   UINTN                       Index;

   IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData;

+  UINT64                      Supports;

 

   IdeBusDriverPrivateData = NULL;

 

@@ -849,12 +861,21 @@
                     EFI_OPEN_PROTOCOL_GET_PROTOCOL

                     );

     if (!EFI_ERROR (Status)) {

-      PciIo->Attributes (

-              PciIo,

-              EfiPciIoAttributeOperationDisable,

-              EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_DEVICE_ENABLE,

-              NULL

-              );

+      Status = PciIo->Attributes (

+                        PciIo,

+                        EfiPciIoAttributeOperationSupported,

+                        0,

+                        &Supports

+                        );

+      if (!EFI_ERROR (Status)) {

+        Supports &= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_DEVICE_ENABLE;

+        PciIo->Attributes (

+                PciIo,

+                EfiPciIoAttributeOperationDisable,

+                Supports,

+                NULL

+                );

+      }

     }

 

     gBS->OpenProtocol (

diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciIo.c b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciIo.c
index 5a40789..63ab8e5 100644
--- a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciIo.c
+++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciIo.c
@@ -1462,19 +1462,21 @@
   }

   //

   // Just a trick for ENABLE attribute

+  // EFI_PCI_DEVICE_ENABLE is not defined in UEFI spec, which is the internal usage.

+  // So, this logic doesn't confrom to UEFI spec, which should be removed.

   //

-  if ((Attributes & EFI_PCI_DEVICE_ENABLE) == EFI_PCI_DEVICE_ENABLE) {

-    Attributes &= (PciIoDevice->Supports);

-

-    //

-    // Raise the EFI_P_PC_ENABLE Status code

-    //

-    REPORT_STATUS_CODE_WITH_DEVICE_PATH (

-      EFI_PROGRESS_CODE,

-      EFI_IO_BUS_PCI | EFI_P_PC_ENABLE,

-      PciIoDevice->DevicePath

-      );

-  }

+  //  if ((Attributes & EFI_PCI_DEVICE_ENABLE) == EFI_PCI_DEVICE_ENABLE) {

+  //    Attributes &= (PciIoDevice->Supports);

+  //

+  //    //

+  //    // Raise the EFI_P_PC_ENABLE Status code

+  //    //

+  //    REPORT_STATUS_CODE_WITH_DEVICE_PATH (

+  //      EFI_PROGRESS_CODE,

+  //      EFI_IO_BUS_PCI | EFI_P_PC_ENABLE,

+  //      PciIoDevice->DevicePath

+  //      );

+  //  }

 

   //

   // If no attributes can be supported, then return.

diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c
index 07a690e..488c963 100644
--- a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c
+++ b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c
@@ -1491,6 +1491,7 @@
   EFI_STATUS              Status;

   USB2_HC_DEV             *Ehc;

   EFI_PCI_IO_PROTOCOL     *PciIo;

+  UINT64                  Supports;

 

   //

   // Open the PciIo Protocol, then enable the USB host controller

@@ -1511,10 +1512,19 @@
 

   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"));

@@ -1643,6 +1653,7 @@
   EFI_USB2_HC_PROTOCOL  *Usb2Hc;

   EFI_PCI_IO_PROTOCOL   *PciIo;

   USB2_HC_DEV           *Ehc;

+  UINT64                Supports;

 

   //

   // Test whether the Controller handler passed in is a valid

@@ -1695,12 +1706,21 @@
   //

   // Disable the USB Host Controller

   //

-  PciIo->Attributes (

-           PciIo,

-           EfiPciIoAttributeOperationDisable,

-           EFI_PCI_DEVICE_ENABLE,

-           NULL

-           );

+  Status = PciIo->Attributes (

+                    PciIo,

+                    EfiPciIoAttributeOperationSupported,

+                    0,

+                    &Supports

+                    );

+  if (!EFI_ERROR (Status)) {

+    Supports &= EFI_PCI_DEVICE_ENABLE;

+    Status = PciIo->Attributes (

+                      PciIo,

+                      EfiPciIoAttributeOperationDisable,

+                      Supports,

+                      NULL

+                      );

+  }

 

   gBS->CloseProtocol (

          Controller,

@@ -1710,7 +1730,7 @@
          );

 

   gBS->FreePool (Ehc);

-  return Status;

+  return EFI_SUCCESS;

 }

 

 EFI_DRIVER_BINDING_PROTOCOL

diff --git a/MdeModulePkg/Bus/Pci/UhciDxe/Uhci.c b/MdeModulePkg/Bus/Pci/UhciDxe/Uhci.c
index 00108b87..36ce1bd 100644
--- a/MdeModulePkg/Bus/Pci/UhciDxe/Uhci.c
+++ b/MdeModulePkg/Bus/Pci/UhciDxe/Uhci.c
@@ -2068,6 +2068,7 @@
   )

 {

   USB_HC_DEV          *Uhc;

+  UINT64              Supports;

 

   //

   // Uninstall the USB_HC and USB_HC2 protocol, then disable the controller

@@ -2089,11 +2090,18 @@
 

   UhciFreeAllAsyncReq (Uhc);

   UhciDestoryFrameList (Uhc);

-

+  

+  Uhc->PciIo->Attributes (

+                Uhc->PciIo,

+                EfiPciIoAttributeOperationSupported,

+                0,

+                &Supports

+                );

+  Supports &= EFI_PCI_DEVICE_ENABLE;

   Uhc->PciIo->Attributes (

                 Uhc->PciIo,

                 EfiPciIoAttributeOperationDisable,

-                EFI_PCI_DEVICE_ENABLE,

+                Supports,

                 NULL

                 );

 

@@ -2126,6 +2134,7 @@
   EFI_STATUS          Status;

   EFI_PCI_IO_PROTOCOL *PciIo;

   USB_HC_DEV          *Uhc;

+  UINT64              Supports;

 

   //

   // Open PCIIO, then enable the EHC device and turn off emulation

@@ -2148,10 +2157,19 @@
 

   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)) {

     goto CLOSE_PCIIO;

diff --git a/MdeModulePkg/Bus/Pci/UndiRuntimeDxe/Init.c b/MdeModulePkg/Bus/Pci/UndiRuntimeDxe/Init.c
index 8315bc4..784bf55 100644
--- a/MdeModulePkg/Bus/Pci/UndiRuntimeDxe/Init.c
+++ b/MdeModulePkg/Bus/Pci/UndiRuntimeDxe/Init.c
@@ -287,6 +287,7 @@
   UINT8                     *TmpPxePointer;

   EFI_PCI_IO_PROTOCOL       *PciIoFncs;

   UINTN                     Len;   

+  UINT64                    Supports;

 

   Status = gBS->OpenProtocol (

                   Controller,

@@ -380,10 +381,19 @@
 

   Status = PciIoFncs->Attributes (

                         PciIoFncs,

-                        EfiPciIoAttributeOperationEnable,

-                        EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER,

-                        NULL

+                        EfiPciIoAttributeOperationSupported,

+                        0,

+                        &Supports

                         );

+  if (!EFI_ERROR (Status)) {

+    Supports &= EFI_PCI_DEVICE_ENABLE;

+    Status = PciIoFncs->Attributes (

+                          PciIoFncs,

+                          EfiPciIoAttributeOperationEnable,

+                          Supports,

+                          NULL

+                          );

+  }

   //

   // Read all the registers from device's PCI Configuration space

   //

diff --git a/Nt32Pkg/Library/EdkGenericBdsLib/BdsBoot.c b/Nt32Pkg/Library/EdkGenericBdsLib/BdsBoot.c
index cc6adcd..2c97bb0 100644
--- a/Nt32Pkg/Library/EdkGenericBdsLib/BdsBoot.c
+++ b/Nt32Pkg/Library/EdkGenericBdsLib/BdsBoot.c
@@ -1232,7 +1232,7 @@
   Status = gBS->HandleProtocol (

              mBdsImageHandle,

              &gEfiLoadedImageProtocolGuid,

-             &LoadedImage

+             (VOID **) &LoadedImage

              );

   if (!EFI_ERROR (Status)) {

     Status = gBS->HandleProtocol (