-/*++\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
//\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
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
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
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
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
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
\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
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
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
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
&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
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
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
\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
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
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
\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
//\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
// 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
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
//\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
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
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
\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
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
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
(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
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
//\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
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
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
}\r
+\r