-/**@file\r
+/** @file\r
\r
-Copyright (c) 2006, Intel Corporation \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
**/\r
\r
\r
-#include "Pcibus.h"\r
+#include "PciBus.h"\r
#include "PciDeviceSupport.h"\r
\r
//\r
LIST_ENTRY gPciDevicePool;\r
\r
/**\r
- Initialize the gPciDevicePool\r
+ Initialize the gPciDevicePool.\r
**/\r
EFI_STATUS\r
InitializePciDevicePool (\r
/**\r
Destroy root bridge and remove it from deivce tree.\r
\r
- @param RootBridge The bridge want to be removed\r
+ @param RootBridge The bridge want to be removed.\r
\r
**/\r
EFI_STATUS\r
\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
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
// Process OpRom\r
//\r
if (!PciIoDevice->AllOpRomProcessed) {\r
- PciIoDevice->AllOpRomProcessed = TRUE;\r
\r
//\r
// Get the OpRom provided by platform\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
+ // Add the Rom Image to internal database for later PCI light enumeration\r
//\r
PciRomAddImageMapping (\r
NULL,\r
(UINT64) (UINTN) PciIoDevice->PciIo.RomImage,\r
PciIoDevice->PciIo.RomSize\r
);\r
- \r
}\r
}\r
+ }\r
+\r
+ //\r
+ // Determine if there are EFI images in the option rom\r
+ //\r
+ HasEfiImage = ContainEfiImage (PciIoDevice->PciIo.RomImage, PciIoDevice->PciIo.RomSize);\r
+\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
+ 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 previous bus enumeration\r
+ // or loaded from device in the previous round of bus enumeration\r
//\r
- if (PciIoDevice->RomSize > 0) {\r
+ if (HasEfiImage) {\r
ProcessOpRomImage (PciIoDevice);\r
}\r
}\r
&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
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
\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
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
);\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
\r
CurrentLink = RootBridge->ChildList.ForwardLink;\r
\r
- while (CurrentLink && CurrentLink != &RootBridge->ChildList) {\r
+ while (CurrentLink != NULL && CurrentLink != &RootBridge->ChildList) {\r
\r
PciIoDevice = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
if (RemainingDevicePath != NULL) {\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
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
//\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
}\r
\r
/**\r
- Get root bridge device instance by specific handle\r
+ Get root bridge device instance by specific handle.\r
\r
- @param RootBridgeHandle Given root bridge handle\r
+ @param RootBridgeHandle Given root bridge handle.\r
\r
- @return root bridge device instance\r
+ @return root bridge device instance.\r
**/\r
PCI_IO_DEVICE *\r
GetRootBridgeByHandle (\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
}\r
\r
/**\r
- Judege whether Pci device existed\r
+ Judege whether Pci device existed.\r
\r
- @param Bridge Parent bridege instance \r
- @param PciIoDevice Device instance\r
+ @param Bridge Parent bridege instance.\r
+ @param PciIoDevice Device instance.\r
\r
- @return whether Pci device existed\r
+ @return whether Pci device existed.\r
**/\r
BOOLEAN\r
PciDeviceExisted (\r
\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
}\r
\r
/**\r
- Active VGA device\r
+ Active VGA device.\r
\r
- @param VgaDevice device instance for VGA\r
+ @param VgaDevice device instance for VGA.\r
\r
- @return device instance\r
+ @return device instance.\r
**/\r
PCI_IO_DEVICE *\r
ActiveVGADeviceOnTheSameSegment (\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
}\r
\r
/**\r
- Active VGA device on root bridge\r
+ Active VGA device on root bridge.\r
\r
- @param RootBridge Root bridge device instance\r
+ @param RootBridge Root bridge device instance.\r
\r
- @return VGA device instance\r
+ @return VGA device instance.\r
**/\r
PCI_IO_DEVICE *\r
ActiveVGADeviceOnTheRootBridge (\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
(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
}\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
+ 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
+ @retval EFI_SUCCESS Success to get the device path.\r
**/\r
EFI_STATUS\r
GetHpcPciAddress (\r
//\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
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
//\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
}\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
+ 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
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
\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
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