]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c
Retire PciHotplugDeviceGuid.
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Pci / PciBusDxe / PciDeviceSupport.c
index 0e95dc18653d6f631d0cdc8698c7d75b96126089..e205fe9dc88cb696d32f9b4dcbb350f18aee7f73 100644 (file)
@@ -1,27 +1,18 @@
-/*++\r
+/** @file\r
 \r
-Copyright (c) 2006 - 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
+Copyright (c) 2006 - 2009, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
 \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+**/\r
 \r
-Module Name:\r
 \r
-  PciDeviceSupport.c\r
-\r
-Abstract:\r
-\r
-  This file provides routine to support Pci device node manipulation\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#include "pcibus.h"\r
+#include "PciBus.h"\r
 #include "PciDeviceSupport.h"\r
 \r
 //\r
@@ -30,50 +21,29 @@ Revision History
 //\r
 LIST_ENTRY  gPciDevicePool;\r
 \r
+/**\r
+  Initialize the gPciDevicePool.\r
+**/\r
 EFI_STATUS\r
 InitializePciDevicePool (\r
   VOID\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Initialize the gPciDevicePool\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
-  None\r
-\r
---*/\r
-// TODO:    EFI_SUCCESS - add return value to function comment\r
 {\r
   InitializeListHead (&gPciDevicePool);\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Insert a root bridge into PCI device pool\r
+\r
+  @param RootBridge    - A pointer to the PCI_IO_DEVICE.\r
+\r
+**/\r
 EFI_STATUS\r
 InsertRootBridge (\r
   PCI_IO_DEVICE *RootBridge\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Insert a root bridge into PCI device pool\r
-\r
-Arguments:\r
-\r
-  RootBridge    - A pointer to the PCI_IO_DEVICE.\r
-\r
-Returns:\r
-\r
-  None\r
-\r
---*/\r
-// TODO:    EFI_SUCCESS - add return value to function comment\r
 {\r
 \r
   InsertTailList (&gPciDevicePool, &(RootBridge->Link));\r
@@ -81,28 +51,19 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  This function is used to insert a PCI device node under\r
+  a bridge\r
+\r
+  @param Bridge         A pointer to the PCI_IO_DEVICE.\r
+  @param PciDeviceNode  A pointer to the PCI_IO_DEVICE.\r
+\r
+**/\r
 EFI_STATUS\r
 InsertPciDevice (\r
   PCI_IO_DEVICE *Bridge,\r
   PCI_IO_DEVICE *PciDeviceNode\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  This function is used to insert a PCI device node under\r
-  a bridge\r
-\r
-Arguments:\r
-  Bridge        - A pointer to the PCI_IO_DEVICE.\r
-  PciDeviceNode - A pointer to the PCI_IO_DEVICE.\r
-\r
-Returns:\r
-\r
-  None\r
-\r
---*/\r
-// TODO:    EFI_SUCCESS - add return value to function comment\r
 {\r
 \r
   InsertTailList (&Bridge->ChildList, &(PciDeviceNode->Link));\r
@@ -111,25 +72,16 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Destroy root bridge and remove it from deivce tree.\r
+  \r
+  @param RootBridge   The bridge want to be removed.\r
+  \r
+**/\r
 EFI_STATUS\r
 DestroyRootBridge (\r
   IN PCI_IO_DEVICE *RootBridge\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-\r
-Arguments:\r
-\r
-  RootBridge   - A pointer to the PCI_IO_DEVICE.\r
-\r
-Returns:\r
-\r
-  None\r
-\r
---*/\r
-// TODO:    EFI_SUCCESS - add return value to function comment\r
 {\r
   DestroyPciDeviceTree (RootBridge);\r
 \r
@@ -138,27 +90,17 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
-EFI_STATUS\r
-FreePciDevice (\r
-  IN PCI_IO_DEVICE *PciIoDevice\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
+/**\r
   Destroy a pci device node.\r
   Also all direct or indirect allocated resource for this node will be freed.\r
 \r
-Arguments:\r
+  @param PciIoDevice  A pointer to the PCI_IO_DEVICE.\r
 \r
-  PciIoDevice   - A pointer to the PCI_IO_DEVICE.\r
-\r
-Returns:\r
-\r
-  None\r
-\r
---*/\r
-// TODO:    EFI_SUCCESS - add return value to function comment\r
+**/\r
+EFI_STATUS\r
+FreePciDevice (\r
+  IN PCI_IO_DEVICE *PciIoDevice\r
+  )\r
 {\r
 \r
   //\r
@@ -177,27 +119,17 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
-EFI_STATUS\r
-DestroyPciDeviceTree (\r
-  IN PCI_IO_DEVICE *Bridge\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
+/**\r
   Destroy all the pci device node under the bridge.\r
   Bridge itself is not included.\r
 \r
-Arguments:\r
-\r
-  Bridge   - A pointer to the PCI_IO_DEVICE.\r
+  @param Bridge   A pointer to the PCI_IO_DEVICE.\r
 \r
-Returns:\r
-\r
-  None\r
-\r
---*/\r
-// TODO:    EFI_SUCCESS - add return value to function comment\r
+**/\r
+EFI_STATUS\r
+DestroyPciDeviceTree (\r
+  IN PCI_IO_DEVICE *Bridge\r
+  )\r
 {\r
   LIST_ENTRY      *CurrentLink;\r
   PCI_IO_DEVICE   *Temp;\r
@@ -223,29 +155,18 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
-EFI_STATUS\r
-DestroyRootBridgeByHandle (\r
-  EFI_HANDLE Controller\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
+/**\r
   Destroy all device nodes under the root bridge\r
   specified by Controller.\r
   The root bridge itself is also included.\r
 \r
-Arguments:\r
-\r
-  Controller   - An efi handle.\r
-\r
-Returns:\r
+  @param Controller   An efi handle.\r
 \r
-  None\r
-\r
---*/\r
-// TODO:    EFI_SUCCESS - add return value to function comment\r
-// TODO:    EFI_NOT_FOUND - add return value to function comment\r
+**/\r
+EFI_STATUS\r
+DestroyRootBridgeByHandle (\r
+  EFI_HANDLE Controller\r
+  )\r
 {\r
 \r
   LIST_ENTRY      *CurrentLink;\r
@@ -253,7 +174,7 @@ Returns:
 \r
   CurrentLink = gPciDevicePool.ForwardLink;\r
 \r
-  while (CurrentLink && CurrentLink != &gPciDevicePool) {\r
+  while (CurrentLink != NULL && CurrentLink != &gPciDevicePool) {\r
     Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
 \r
     if (Temp->Handle == Controller) {\r
@@ -273,32 +194,25 @@ Returns:
   return EFI_NOT_FOUND;\r
 }\r
 \r
-EFI_STATUS\r
-RegisterPciDevice (\r
-  IN  EFI_HANDLE                     Controller,\r
-  IN  PCI_IO_DEVICE                  *PciIoDevice,\r
-  OUT EFI_HANDLE                     *Handle OPTIONAL\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
+/**\r
   This function registers the PCI IO device. It creates a handle for this PCI IO device\r
   (if the handle does not exist), attaches appropriate protocols onto the handle, does\r
   necessary initialization, and sets up parent/child relationship with its bus controller.\r
 \r
-Arguments:\r
-\r
-  Controller    - An EFI handle for the PCI bus controller.\r
-  PciIoDevice   - A PCI_IO_DEVICE pointer to the PCI IO device to be registered.\r
-  Handle        - A pointer to hold the EFI handle for the PCI IO device.\r
-\r
-Returns:\r
+  @param Controller    - An EFI handle for the PCI bus controller.\r
+  @param PciIoDevice   - A PCI_IO_DEVICE pointer to the PCI IO device to be registered.\r
+  @param Handle        - A pointer to hold the EFI handle for the PCI IO device.\r
 \r
-  EFI_SUCCESS   - The PCI device is successfully registered.\r
-  Others        - An error occurred when registering the PCI device.\r
+  @retval EFI_SUCCESS   - The PCI device is successfully registered.\r
+  @retval Others        - An error occurred when registering the PCI device.\r
 \r
---*/\r
+**/\r
+EFI_STATUS\r
+RegisterPciDevice (\r
+  IN  EFI_HANDLE                     Controller,\r
+  IN  PCI_IO_DEVICE                  *PciIoDevice,\r
+  OUT EFI_HANDLE                     *Handle OPTIONAL\r
+  )\r
 {\r
   EFI_STATUS          Status;\r
   VOID                *PlatformOpRomBuffer;\r
@@ -306,6 +220,7 @@ Returns:
   UINT8               PciExpressCapRegOffset;\r
   EFI_PCI_IO_PROTOCOL *PciIo;\r
   UINT8               Data8;\r
+  BOOLEAN             HasEfiImage;\r
 \r
   //\r
   // Install the pciio protocol, device path protocol\r
@@ -344,30 +259,77 @@ Returns:
   PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &Data8);\r
 \r
   //\r
-  // Process Platform OpRom\r
+  // Process OpRom\r
   //\r
-  if (gPciPlatformProtocol != NULL && !PciIoDevice->AllOpRomProcessed) {\r
-    PciIoDevice->AllOpRomProcessed = TRUE;\r
+  if (!PciIoDevice->AllOpRomProcessed) {\r
 \r
-    Status = gPciPlatformProtocol->GetPciRom (\r
-                                     gPciPlatformProtocol,\r
-                                     PciIoDevice->Handle,\r
-                                     &PlatformOpRomBuffer,\r
-                                     &PlatformOpRomSize\r
-                                     );\r
+    //\r
+    // Get the OpRom provided by platform\r
+    //\r
+    if (gPciPlatformProtocol != NULL) {\r
+      Status = gPciPlatformProtocol->GetPciRom (\r
+                                       gPciPlatformProtocol,\r
+                                       PciIoDevice->Handle,\r
+                                       &PlatformOpRomBuffer,\r
+                                       &PlatformOpRomSize\r
+                                       );\r
+      if (!EFI_ERROR (Status)) {\r
+        PciIoDevice->RomSize        = PlatformOpRomSize;\r
+        PciIoDevice->PciIo.RomSize  = PlatformOpRomSize;\r
+        PciIoDevice->PciIo.RomImage = PlatformOpRomBuffer;\r
+        //\r
+        // For OpROM read from gPciPlatformProtocol:\r
+        // Add the Rom Image to internal database for later PCI light enumeration\r
+        //\r
+        PciRomAddImageMapping (\r
+          NULL,\r
+          PciIoDevice->PciRootBridgeIo->SegmentNumber,\r
+          PciIoDevice->BusNumber,\r
+          PciIoDevice->DeviceNumber,\r
+          PciIoDevice->FunctionNumber,\r
+          (UINT64) (UINTN) PciIoDevice->PciIo.RomImage,\r
+          PciIoDevice->PciIo.RomSize\r
+          );\r
+      }\r
+    }\r
+  }\r
 \r
-    if (!EFI_ERROR (Status)) {\r
+  //\r
+  // Determine if there are EFI images in the option rom\r
+  //\r
+  HasEfiImage = ContainEfiImage (PciIoDevice->PciIo.RomImage, PciIoDevice->PciIo.RomSize);\r
 \r
-      //\r
-      // Have Platform OpRom\r
-      //\r
-      PciIoDevice->RomSize        = PlatformOpRomSize;\r
-      PciIoDevice->PciIo.RomSize  = PlatformOpRomSize;\r
-      PciIoDevice->PciIo.RomImage = PlatformOpRomBuffer;\r
+  if (HasEfiImage) {\r
+    Status = gBS->InstallMultipleProtocolInterfaces (\r
+                    &PciIoDevice->Handle,\r
+                    &gEfiLoadFile2ProtocolGuid,\r
+                    &PciIoDevice->LoadFile2,\r
+                    NULL\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      gBS->UninstallMultipleProtocolInterfaces (\r
+             &PciIoDevice->Handle,\r
+             &gEfiDevicePathProtocolGuid,\r
+             PciIoDevice->DevicePath,\r
+             &gEfiPciIoProtocolGuid,\r
+             &PciIoDevice->PciIo,\r
+             NULL\r
+             );\r
+      return Status;\r
+    }\r
+  }\r
 \r
-      //\r
-      // Process Image\r
-      //\r
+\r
+  if (!PciIoDevice->AllOpRomProcessed) {\r
+\r
+    PciIoDevice->AllOpRomProcessed = TRUE;\r
+\r
+    //\r
+    // Dispatch the EFI OpRom for the PCI device.\r
+    // The OpRom is got from platform in the above code\r
+    // or loaded from device in the previous round of bus enumeration\r
+    //\r
+    if (HasEfiImage) {\r
       ProcessOpRomImage (PciIoDevice);\r
     }\r
   }\r
@@ -391,6 +353,14 @@ Returns:
              &PciIoDevice->PciIo,\r
              NULL\r
              );\r
+      if (HasEfiImage) {\r
+        gBS->UninstallMultipleProtocolInterfaces (\r
+               &PciIoDevice->Handle,\r
+               &gEfiLoadFile2ProtocolGuid,\r
+               &PciIoDevice->LoadFile2,\r
+               NULL\r
+               );\r
+      }\r
 \r
       return Status;\r
     }\r
@@ -408,12 +378,6 @@ Returns:
     return Status;\r
   }\r
 \r
-  //\r
-  // Install Pccard Hotplug GUID for Pccard device so that\r
-  // to notify CardBus driver to stop the device when de-register happens\r
-  //\r
-  InstallPciHotplugGuid (PciIoDevice);\r
-\r
   if (Handle != NULL) {\r
     *Handle = PciIoDevice->Handle;\r
   }\r
@@ -426,28 +390,20 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  This function is used to remove the whole PCI devices from the bridge.\r
+\r
+  @param RootBridgeHandle   An efi handle.\r
+  @param Bridge             A pointer to the PCI_IO_DEVICE.\r
+\r
+  @retval EFI_SUCCESS\r
+**/\r
 EFI_STATUS\r
 RemoveAllPciDeviceOnBridge (\r
   EFI_HANDLE               RootBridgeHandle,\r
   PCI_IO_DEVICE            *Bridge\r
   )\r
-/*++\r
 \r
-Routine Description:\r
-\r
-  This function is used to remove the whole PCI devices from the bridge.\r
-\r
-Arguments:\r
-\r
-  RootBridgeHandle   - An efi handle.\r
-  Bridge             - A pointer to the PCI_IO_DEVICE.\r
-\r
-Returns:\r
-\r
-  None\r
-\r
---*/\r
-// TODO:    EFI_SUCCESS - add return value to function comment\r
 {\r
 \r
   LIST_ENTRY      *CurrentLink;\r
@@ -481,32 +437,23 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
-EFI_STATUS\r
-DeRegisterPciDevice (\r
-  IN  EFI_HANDLE                     Controller,\r
-  IN  EFI_HANDLE                     Handle\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
+/**\r
 \r
   This function is used to de-register the PCI device from the EFI,\r
   That includes un-installing PciIo protocol from the specified PCI\r
   device handle.\r
 \r
-Arguments:\r
-\r
-  Controller   - An efi handle.\r
-  Handle       - An efi handle.\r
+  @param Controller   - controller handle\r
+  @param Handle       - device handle\r
 \r
-Returns:\r
-\r
-  None\r
+  @return Status of de-register pci device\r
+**/\r
+EFI_STATUS\r
+DeRegisterPciDevice (\r
+  IN  EFI_HANDLE                     Controller,\r
+  IN  EFI_HANDLE                     Handle\r
+  )\r
 \r
---*/\r
-// TODO:    EFI_SUCCESS - add return value to function comment\r
-// TODO:    EFI_SUCCESS - add return value to function comment\r
-// TODO:    EFI_SUCCESS - add return value to function comment\r
 {\r
   EFI_PCI_IO_PROTOCOL             *PciIo;\r
   EFI_STATUS                      Status;\r
@@ -541,7 +488,7 @@ Returns:
 \r
       CurrentLink = PciIoDevice->ChildList.ForwardLink;\r
 \r
-      while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) {\r
+      while (CurrentLink != NULL && CurrentLink != &PciIoDevice->ChildList) {\r
         Node    = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
         Status  = DeRegisterPciDevice (Controller, Node->Handle);\r
 \r
@@ -552,10 +499,6 @@ Returns:
         CurrentLink = CurrentLink->ForwardLink;\r
       }\r
     }\r
-    //\r
-    // Uninstall Pccard Hotplug GUID for Pccard device\r
-    //\r
-    UninstallPciHotplugGuid (PciIoDevice);\r
 \r
     //\r
     // Close the child handle\r
@@ -592,6 +535,33 @@ Returns:
                       );\r
     }\r
 \r
+    if (!EFI_ERROR (Status)) {\r
+      //\r
+      // Try to uninstall LoadFile2 protocol if exists\r
+      //\r
+      Status = gBS->OpenProtocol (\r
+                      Handle,\r
+                      &gEfiLoadFile2ProtocolGuid,\r
+                      NULL,\r
+                      gPciBusDriverBinding.DriverBindingHandle,\r
+                      Controller,\r
+                      EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+                      );\r
+      if (!EFI_ERROR (Status)) {\r
+        Status = gBS->UninstallMultipleProtocolInterfaces (\r
+                        Handle,\r
+                        &gEfiLoadFile2ProtocolGuid,\r
+                        &PciIoDevice->LoadFile2,\r
+                        NULL\r
+                        );\r
+      }\r
+      //\r
+      // Restore Status\r
+      //\r
+      Status = EFI_SUCCESS;\r
+    }\r
+\r
+\r
     if (EFI_ERROR (Status)) {\r
       gBS->OpenProtocol (\r
             Controller,\r
@@ -622,6 +592,21 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Start to manage the PCI device on specified the root bridge or PCI-PCI Bridge\r
+\r
+  @param Controller          An efi handle.\r
+  @param RootBridge          A pointer to the PCI_IO_DEVICE.\r
+  @param RemainingDevicePath A pointer to the EFI_DEVICE_PATH_PROTOCOL.\r
+  @param NumberOfChildren    Children number.\r
+  @param ChildHandleBuffer   A pointer to the child handle buffer.\r
+\r
+  @retval EFI_NOT_READY   Device is not allocated\r
+  @retval EFI_UNSUPPORTED Device only support PCI-PCI bridge.\r
+  @retval EFI_NOT_FOUND   Can not find the specific device\r
+  @retval EFI_SUCCESS     Success to start Pci device on bridge\r
+\r
+**/\r
 EFI_STATUS\r
 StartPciDevicesOnBridge (\r
   IN EFI_HANDLE                          Controller,\r
@@ -630,31 +615,8 @@ StartPciDevicesOnBridge (
   IN OUT UINT8                           *NumberOfChildren,\r
   IN OUT EFI_HANDLE                      *ChildHandleBuffer\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Start to manage the PCI device on specified the root bridge or PCI-PCI Bridge\r
 \r
-Arguments:\r
-\r
-  Controller          - An efi handle.\r
-  RootBridge          - A pointer to the PCI_IO_DEVICE.\r
-  RemainingDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.\r
-  NumberOfChildren    - Children number.\r
-  ChildHandleBuffer   - A pointer to the child handle buffer.\r
-\r
-Returns:\r
-\r
-  None\r
-\r
---*/\r
-// TODO:    EFI_NOT_READY - add return value to function comment\r
-// TODO:    EFI_SUCCESS - add return value to function comment\r
-// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
-// TODO:    EFI_NOT_FOUND - add return value to function comment\r
 {\r
-  PCI_IO_DEVICE             *Temp;\r
   PCI_IO_DEVICE             *PciIoDevice;\r
   EFI_DEV_PATH_PTR          Node;\r
   EFI_DEVICE_PATH_PROTOCOL  *CurrentDevicePath;\r
@@ -664,15 +626,15 @@ Returns:
 \r
   CurrentLink = RootBridge->ChildList.ForwardLink;\r
 \r
-  while (CurrentLink && CurrentLink != &RootBridge->ChildList) {\r
+  while (CurrentLink != NULL && CurrentLink != &RootBridge->ChildList) {\r
 \r
-    Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+    PciIoDevice = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
     if (RemainingDevicePath != NULL) {\r
 \r
       Node.DevPath = RemainingDevicePath;\r
 \r
-      if (Node.Pci->Device != Temp->DeviceNumber ||\r
-          Node.Pci->Function != Temp->FunctionNumber) {\r
+      if (Node.Pci->Device != PciIoDevice->DeviceNumber || \r
+          Node.Pci->Function != PciIoDevice->FunctionNumber) {\r
         CurrentLink = CurrentLink->ForwardLink;\r
         continue;\r
       }\r
@@ -680,63 +642,61 @@ Returns:
       //\r
       // Check if the device has been assigned with required resource\r
       //\r
-      if (!Temp->Allocated) {\r
+      if (!PciIoDevice->Allocated) {\r
         return EFI_NOT_READY;\r
       }\r
-\r
+      \r
       //\r
       // Check if the current node has been registered before\r
       // If it is not, register it\r
       //\r
-      if (!Temp->Registered) {\r
-        PciIoDevice = Temp;\r
-\r
+      if (!PciIoDevice->Registered) {\r
         Status = RegisterPciDevice (\r
-                  Controller,\r
-                  PciIoDevice,\r
-                  NULL\r
-                  );\r
+                   Controller,\r
+                   PciIoDevice,\r
+                   NULL\r
+                   );\r
 \r
       }\r
 \r
-      if (NumberOfChildren != NULL && ChildHandleBuffer != NULL && Temp->Registered) {\r
-        ChildHandleBuffer[*NumberOfChildren] = Temp->Handle;\r
+      if (NumberOfChildren != NULL && ChildHandleBuffer != NULL && PciIoDevice->Registered) {\r
+        ChildHandleBuffer[*NumberOfChildren] = PciIoDevice->Handle;\r
         (*NumberOfChildren)++;\r
       }\r
-\r
+      \r
       //\r
       // Get the next device path\r
       //\r
-      CurrentDevicePath = EfiNextDevicePathNode (RemainingDevicePath);\r
-      if (EfiIsDevicePathEnd (CurrentDevicePath)) {\r
+      CurrentDevicePath = NextDevicePathNode (RemainingDevicePath);\r
+      if (IsDevicePathEnd (CurrentDevicePath)) {\r
         return EFI_SUCCESS;\r
       }\r
 \r
       //\r
       // If it is a PPB\r
       //\r
-      if (!IsListEmpty (&Temp->ChildList)) {\r
+      if (!IsListEmpty (&PciIoDevice->ChildList)) {\r
         Status = StartPciDevicesOnBridge (\r
-                  Controller,\r
-                  Temp,\r
-                  CurrentDevicePath,\r
-                  NumberOfChildren,\r
-                  ChildHandleBuffer\r
-                  );\r
-\r
-        Temp->PciIo.Attributes (\r
-                      &(Temp->PciIo),\r
-                      EfiPciIoAttributeOperationSupported,\r
-                      0,\r
-                      &Supports\r
-                      );\r
+                   Controller,\r
+                   PciIoDevice,\r
+                   CurrentDevicePath,\r
+                   NumberOfChildren,\r
+                   ChildHandleBuffer\r
+                   );\r
+\r
+        PciIoDevice->PciIo.Attributes (\r
+                             &(PciIoDevice->PciIo),\r
+                             EfiPciIoAttributeOperationSupported,\r
+                             0,\r
+                             &Supports\r
+                             );\r
         Supports &= EFI_PCI_DEVICE_ENABLE;\r
-        Temp->PciIo.Attributes (\r
-                      &(Temp->PciIo),\r
-                      EfiPciIoAttributeOperationEnable,\r
-                      Supports,\r
-                      NULL\r
-                      );\r
+        PciIoDevice->PciIo.Attributes (\r
+                             &(PciIoDevice->PciIo),\r
+                             EfiPciIoAttributeOperationEnable,\r
+                             Supports,\r
+                             NULL\r
+                             );\r
 \r
         return Status;\r
       } else {\r
@@ -754,112 +714,86 @@ Returns:
       // try to enable all the pci devices under this bridge\r
       //\r
 \r
-      if (!Temp->Registered && Temp->Allocated) {\r
-\r
-        PciIoDevice = Temp;\r
-\r
+      if (!PciIoDevice->Registered && PciIoDevice->Allocated) {\r
         Status = RegisterPciDevice (\r
-                  Controller,\r
-                  PciIoDevice,\r
-                  NULL\r
-                  );\r
+                   Controller,\r
+                   PciIoDevice,\r
+                   NULL\r
+                   );\r
 \r
       }\r
 \r
-      if (NumberOfChildren != NULL && ChildHandleBuffer != NULL && Temp->Registered) {\r
-        ChildHandleBuffer[*NumberOfChildren] = Temp->Handle;\r
+      if (NumberOfChildren != NULL && ChildHandleBuffer != NULL && PciIoDevice->Registered) {\r
+        ChildHandleBuffer[*NumberOfChildren] = PciIoDevice->Handle;\r
         (*NumberOfChildren)++;\r
       }\r
 \r
-      if (!IsListEmpty (&Temp->ChildList)) {\r
+      if (!IsListEmpty (&PciIoDevice->ChildList)) {\r
         Status = StartPciDevicesOnBridge (\r
-                  Controller,\r
-                  Temp,\r
-                  RemainingDevicePath,\r
-                  NumberOfChildren,\r
-                  ChildHandleBuffer\r
-                  );\r
-\r
-        Temp->PciIo.Attributes (\r
-                      &(Temp->PciIo),\r
-                      EfiPciIoAttributeOperationSupported,\r
-                      0,\r
-                      &Supports\r
-                      );\r
+                   Controller,\r
+                   PciIoDevice,\r
+                   RemainingDevicePath,\r
+                   NumberOfChildren,\r
+                   ChildHandleBuffer\r
+                   );\r
+\r
+        PciIoDevice->PciIo.Attributes (\r
+                             &(PciIoDevice->PciIo),\r
+                             EfiPciIoAttributeOperationSupported,\r
+                             0,\r
+                             &Supports\r
+                             );\r
         Supports &= EFI_PCI_DEVICE_ENABLE;\r
-        Temp->PciIo.Attributes (\r
-                      &(Temp->PciIo),\r
-                      EfiPciIoAttributeOperationEnable,\r
-                      Supports,\r
-                      NULL\r
-                      );\r
+        PciIoDevice->PciIo.Attributes (\r
+                             &(PciIoDevice->PciIo),\r
+                             EfiPciIoAttributeOperationEnable,\r
+                             Supports,\r
+                             NULL\r
+                             );\r
 \r
       }\r
 \r
       CurrentLink = CurrentLink->ForwardLink;\r
-      continue;\r
     }\r
   }\r
 \r
   return EFI_NOT_FOUND;\r
 }\r
 \r
+/**\r
+  Start to manage all the PCI devices it found previously under \r
+  the entire host bridge.\r
+\r
+  @param Controller          - root bridge handle.\r
+\r
+**/\r
 EFI_STATUS\r
 StartPciDevices (\r
-  IN EFI_HANDLE                         Controller,\r
-  IN EFI_DEVICE_PATH_PROTOCOL           *RemainingDevicePath\r
+  IN EFI_HANDLE                         Controller\r
   )\r
-/*++\r
-\r
-Routine Description:\r
 \r
-  Start to manage the PCI device according to RemainingDevicePath\r
-  If RemainingDevicePath == NULL, the PCI bus driver will start\r
-  to manage all the PCI devices it found previously\r
-\r
-Arguments:\r
-  Controller          - An efi handle.\r
-  RemainingDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.\r
-\r
-Returns:\r
-\r
-  None\r
-\r
---*/\r
-// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
-// TODO:    EFI_SUCCESS - add return value to function comment\r
 {\r
-  EFI_DEV_PATH_PTR  Node;\r
   PCI_IO_DEVICE     *RootBridge;\r
+  EFI_HANDLE        ThisHostBridge;\r
   LIST_ENTRY        *CurrentLink;\r
 \r
-  if (RemainingDevicePath != NULL) {\r
-\r
-    //\r
-    // Check if the RemainingDevicePath is valid\r
-    //\r
-    Node.DevPath = RemainingDevicePath;\r
-    if ((Node.DevPath->Type != HARDWARE_DEVICE_PATH) ||\r
-        ((Node.DevPath->SubType != HW_PCI_DP)         &&\r
-         (DevicePathNodeLength (Node.DevPath) != sizeof (PCI_DEVICE_PATH)))\r
-        ) {\r
-      return EFI_UNSUPPORTED;\r
-    }\r
-  }\r
+  RootBridge = GetRootBridgeByHandle (Controller);\r
+  ASSERT (RootBridge != NULL);\r
+  ThisHostBridge = RootBridge->PciRootBridgeIo->ParentHandle;\r
 \r
   CurrentLink = gPciDevicePool.ForwardLink;\r
 \r
-  while (CurrentLink && CurrentLink != &gPciDevicePool) {\r
+  while (CurrentLink != NULL && CurrentLink != &gPciDevicePool) {\r
 \r
     RootBridge = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
     //\r
     // Locate the right root bridge to start\r
     //\r
-    if (RootBridge->Handle == Controller) {\r
+    if (RootBridge->PciRootBridgeIo->ParentHandle == ThisHostBridge) {\r
       StartPciDevicesOnBridge (\r
-        Controller,\r
+        RootBridge->Handle,\r
         RootBridge,\r
-        RemainingDevicePath,\r
+        NULL,\r
         NULL,\r
         NULL\r
         );\r
@@ -871,23 +805,17 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Create root bridge device\r
+\r
+  @param RootBridgeHandle   - Parent bridge handle.\r
+\r
+  @return pointer to new root bridge \r
+**/\r
 PCI_IO_DEVICE *\r
 CreateRootBridge (\r
   IN EFI_HANDLE RootBridgeHandle\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-\r
-Arguments:\r
-  RootBridgeHandle   - An efi handle.\r
-\r
-Returns:\r
-\r
-  None\r
-\r
---*/\r
 {\r
 \r
   EFI_STATUS                      Status;\r
@@ -952,8 +880,9 @@ Returns:
   //\r
   // Initialize the PCI I/O instance structure\r
   //\r
-  Status  = InitializePciIoInstance (Dev);\r
-  Status  = InitializePciDriverOverrideInstance (Dev);\r
+  InitializePciIoInstance (Dev);\r
+  InitializePciDriverOverrideInstance (Dev);\r
+  InitializePciLoadFile2 (Dev);\r
 \r
   //\r
   // Initialize reserved resource list and\r
@@ -965,31 +894,24 @@ Returns:
   return Dev;\r
 }\r
 \r
+/**\r
+  Get root bridge device instance by specific handle.\r
+\r
+  @param RootBridgeHandle    Given root bridge handle.\r
+\r
+  @return root bridge device instance.\r
+**/\r
 PCI_IO_DEVICE *\r
 GetRootBridgeByHandle (\r
   EFI_HANDLE RootBridgeHandle\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-\r
-Arguments:\r
-\r
-  RootBridgeHandle    - An efi handle.\r
-\r
-Returns:\r
-\r
-  None\r
-\r
---*/\r
 {\r
   PCI_IO_DEVICE   *RootBridgeDev;\r
   LIST_ENTRY      *CurrentLink;\r
 \r
   CurrentLink = gPciDevicePool.ForwardLink;\r
 \r
-  while (CurrentLink && CurrentLink != &gPciDevicePool) {\r
+  while (CurrentLink != NULL && CurrentLink != &gPciDevicePool) {\r
 \r
     RootBridgeDev = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
     if (RootBridgeDev->Handle == RootBridgeHandle) {\r
@@ -1002,59 +924,19 @@ Returns:
   return NULL;\r
 }\r
 \r
-BOOLEAN\r
-RootBridgeExisted (\r
-  IN EFI_HANDLE RootBridgeHandle\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  This function searches if RootBridgeHandle has already existed\r
-  in current device pool.\r
-\r
-  If so, it means the given root bridge has been already enumerated.\r
-\r
-Arguments:\r
-\r
-  RootBridgeHandle   - An efi handle.\r
-\r
-Returns:\r
-\r
-  None\r
-\r
---*/\r
-{\r
-  PCI_IO_DEVICE *Bridge;\r
-\r
-  Bridge = GetRootBridgeByHandle (RootBridgeHandle);\r
-\r
-  if (Bridge != NULL) {\r
-    return TRUE;\r
-  }\r
-\r
-  return FALSE;\r
-}\r
-\r
+/**\r
+  Judege whether Pci device existed.\r
+  \r
+  @param Bridge       Parent bridege instance.\r
+  @param PciIoDevice  Device instance.\r
+  \r
+  @return whether Pci device existed.\r
+**/\r
 BOOLEAN\r
 PciDeviceExisted (\r
   IN PCI_IO_DEVICE    *Bridge,\r
   IN PCI_IO_DEVICE    *PciIoDevice\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-  Bridge       - A pointer to the PCI_IO_DEVICE.\r
-  PciIoDevice  - A pointer to the PCI_IO_DEVICE.\r
-\r
-Returns:\r
-\r
-  None\r
-\r
---*/\r
 {\r
 \r
   PCI_IO_DEVICE   *Temp;\r
@@ -1062,7 +944,7 @@ Returns:
 \r
   CurrentLink = Bridge->ChildList.ForwardLink;\r
 \r
-  while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
+  while (CurrentLink != NULL && CurrentLink != &Bridge->ChildList) {\r
 \r
     Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
 \r
@@ -1082,30 +964,24 @@ Returns:
   return FALSE;\r
 }\r
 \r
+/**\r
+  Active VGA device.\r
+  \r
+  @param VgaDevice device instance for VGA.\r
+  \r
+  @return device instance.\r
+**/\r
 PCI_IO_DEVICE *\r
 ActiveVGADeviceOnTheSameSegment (\r
   IN PCI_IO_DEVICE        *VgaDevice\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-  VgaDevice    - A pointer to the PCI_IO_DEVICE.\r
-\r
-Returns:\r
-\r
-  None\r
-\r
---*/\r
 {\r
   LIST_ENTRY      *CurrentLink;\r
   PCI_IO_DEVICE   *Temp;\r
 \r
   CurrentLink = gPciDevicePool.ForwardLink;\r
 \r
-  while (CurrentLink && CurrentLink != &gPciDevicePool) {\r
+  while (CurrentLink != NULL && CurrentLink != &gPciDevicePool) {\r
 \r
     Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
 \r
@@ -1124,30 +1000,24 @@ Returns:
   return NULL;\r
 }\r
 \r
+/**\r
+  Active VGA device on root bridge.\r
+  \r
+  @param RootBridge  Root bridge device instance.\r
+  \r
+  @return VGA device instance.\r
+**/\r
 PCI_IO_DEVICE *\r
 ActiveVGADeviceOnTheRootBridge (\r
   IN PCI_IO_DEVICE        *RootBridge\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-  RootBridge    - A pointer to the PCI_IO_DEVICE.\r
-\r
-Returns:\r
-\r
-  None\r
-\r
---*/\r
 {\r
   LIST_ENTRY      *CurrentLink;\r
   PCI_IO_DEVICE   *Temp;\r
 \r
   CurrentLink = RootBridge->ChildList.ForwardLink;\r
 \r
-  while (CurrentLink && CurrentLink != &RootBridge->ChildList) {\r
+  while (CurrentLink != NULL && CurrentLink != &RootBridge->ChildList) {\r
 \r
     Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
 \r
@@ -1155,7 +1025,7 @@ Returns:
         (Temp->Attributes &\r
          (EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY |\r
           EFI_PCI_IO_ATTRIBUTE_VGA_IO     |\r
-          EFI_PCI_IO_ATTRIBUTE_VGA_IO_16))) {\r
+          EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) != 0) {\r
       return Temp;\r
     }\r
 \r
@@ -1174,31 +1044,21 @@ Returns:
   return NULL;\r
 }\r
 \r
+/**\r
+  Get HPC PCI address according to its device path.\r
+  @param PciRootBridgeIo   Root bridege Io instance.\r
+  @param HpcDevicePath     Given searching device path.\r
+  @param PciAddress        Buffer holding searched result.\r
+  \r
+  @retval EFI_NOT_FOUND Can not find the specific device path.\r
+  @retval EFI_SUCCESS   Success to get the device path.\r
+**/\r
 EFI_STATUS\r
 GetHpcPciAddress (\r
   IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo,\r
   IN  EFI_DEVICE_PATH_PROTOCOL         *HpcDevicePath,\r
   OUT UINT64                           *PciAddress\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-  PciRootBridgeIo       - A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
-  HpcDevicePath         - A pointer to the EFI_DEVICE_PATH_PROTOCL.\r
-  PciAddress            - A pointer to the pci address.\r
-\r
-Returns:\r
-\r
-  None\r
-\r
---*/\r
-// TODO:    EFI_NOT_FOUND - add return value to function comment\r
-// TODO:    EFI_NOT_FOUND - add return value to function comment\r
-// TODO:    EFI_SUCCESS - add return value to function comment\r
-// TODO:    EFI_NOT_FOUND - add return value to function comment\r
 {\r
   EFI_DEVICE_PATH_PROTOCOL  *CurrentDevicePath;\r
   EFI_DEV_PATH_PTR          Node;\r
@@ -1211,7 +1071,7 @@ Returns:
   //\r
   // Get the remaining device path for this PCI device, if it is a PCI device\r
   //\r
-  while (!EfiIsDevicePathEnd (CurrentDevicePath)) {\r
+  while (!IsDevicePathEnd (CurrentDevicePath)) {\r
 \r
     Node.DevPath = CurrentDevicePath;\r
 \r
@@ -1221,7 +1081,7 @@ Returns:
     if ((Node.DevPath->Type != HARDWARE_DEVICE_PATH) ||\r
         ((Node.DevPath->SubType != HW_PCI_DP)         &&\r
          (DevicePathNodeLength (Node.DevPath) != sizeof (PCI_DEVICE_PATH)))) {\r
-      CurrentDevicePath = EfiNextDevicePathNode (CurrentDevicePath);\r
+      CurrentDevicePath = NextDevicePathNode (CurrentDevicePath);\r
       continue;\r
     }\r
 \r
@@ -1231,13 +1091,13 @@ Returns:
   //\r
   // Check if it is not PCI device path\r
   //\r
-  if (EfiIsDevicePathEnd (CurrentDevicePath)) {\r
+  if (IsDevicePathEnd (CurrentDevicePath)) {\r
     return EFI_NOT_FOUND;\r
   }\r
 \r
   CurrentLink = gPciDevicePool.ForwardLink;\r
 \r
-  while (CurrentLink && CurrentLink != &gPciDevicePool) {\r
+  while (CurrentLink != NULL && CurrentLink != &gPciDevicePool) {\r
 \r
     RootBridge = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
     //\r
@@ -1263,32 +1123,20 @@ Returns:
   return EFI_NOT_FOUND;\r
 }\r
 \r
+/**\r
+  Get HPC PCI address according to its device path.\r
+  @param RootBridge           Root bridege Io instance.\r
+  @param RemainingDevicePath  Given searching device path.\r
+  @param PciAddress           Buffer holding searched result.\r
+  \r
+  @retval EFI_NOT_FOUND Can not find the specific device path.\r
+**/\r
 EFI_STATUS\r
 GetHpcPciAddressFromRootBridge (\r
   IN  PCI_IO_DEVICE                    *RootBridge,\r
   IN  EFI_DEVICE_PATH_PROTOCOL         *RemainingDevicePath,\r
   OUT UINT64                           *PciAddress\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-  PciRootBridgeIo       - A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
-  HpcDevicePath         - A pointer to the EFI_DEVICE_PATH_PROTOCL.\r
-  PciAddress            - A pointer to the pci address.\r
-\r
-Returns:\r
-\r
-  None\r
-\r
---*/\r
-// TODO:    RootBridge - add argument and description to function comment\r
-// TODO:    RemainingDevicePath - add argument and description to function comment\r
-// TODO:    EFI_SUCCESS - add return value to function comment\r
-// TODO:    EFI_NOT_FOUND - add return value to function comment\r
-// TODO:    EFI_SUCCESS - add return value to function comment\r
 {\r
   EFI_DEV_PATH_PTR          Node;\r
   PCI_IO_DEVICE             *Temp;\r
@@ -1302,12 +1150,12 @@ Returns:
   Node.DevPath      = CurrentDevicePath;\r
   Temp              = NULL;\r
 \r
-  while (!EfiIsDevicePathEnd (CurrentDevicePath)) {\r
+  while (!IsDevicePathEnd (CurrentDevicePath)) {\r
 \r
     CurrentLink   = RootBridge->ChildList.ForwardLink;\r
     Node.DevPath  = CurrentDevicePath;\r
 \r
-    while (CurrentLink && CurrentLink != &RootBridge->ChildList) {\r
+    while (CurrentLink != NULL && CurrentLink != &RootBridge->ChildList) {\r
       Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
 \r
       if (Node.Pci->Device   == Temp->DeviceNumber &&\r
@@ -1329,14 +1177,14 @@ Returns:
 \r
     }\r
 \r
-    CurrentDevicePath = EfiNextDevicePathNode (CurrentDevicePath);\r
+    CurrentDevicePath = NextDevicePathNode (CurrentDevicePath);\r
   }\r
 \r
   if (MisMatch) {\r
 \r
-    CurrentDevicePath = EfiNextDevicePathNode (CurrentDevicePath);\r
+    CurrentDevicePath = NextDevicePathNode (CurrentDevicePath);\r
 \r
-    if (EfiIsDevicePathEnd (CurrentDevicePath)) {\r
+    if (IsDevicePathEnd (CurrentDevicePath)) {\r
       *PciAddress = EFI_PCI_ADDRESS (RootBridge->BusNumber, Node.Pci->Device, Node.Pci->Function, 0);\r
       return EFI_SUCCESS;\r
     }\r
@@ -1344,8 +1192,13 @@ Returns:
     return EFI_NOT_FOUND;\r
   }\r
 \r
-  *PciAddress = EFI_PCI_ADDRESS (Temp->BusNumber, Temp->DeviceNumber, Temp->FunctionNumber, 0);\r
+  if (Temp != NULL) {\r
+    *PciAddress = EFI_PCI_ADDRESS (Temp->BusNumber, Temp->DeviceNumber, Temp->FunctionNumber, 0);\r
+  } else {\r
+    return EFI_NOT_FOUND;\r
+  }\r
 \r
   return EFI_SUCCESS;\r
 \r
 }\r
+\r