/** @file\r
+ Supporting functions implementaion for PCI devices management.\r
\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
+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
-**/\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
\r
#include "PciBus.h"\r
-#include "PciDeviceSupport.h"\r
\r
//\r
// This device structure is serviced as a header.\r
-// Its Next field points to the first root bridge device node\r
+// Its next field points to the first root bridge device node.\r
//\r
-LIST_ENTRY gPciDevicePool;\r
+LIST_ENTRY mPciDevicePool;\r
\r
/**\r
- Initialize the gPciDevicePool.\r
+ Initialize the PCI devices pool.\r
+\r
**/\r
-EFI_STATUS\r
+VOID\r
InitializePciDevicePool (\r
VOID\r
)\r
{\r
- InitializeListHead (&gPciDevicePool);\r
-\r
- return EFI_SUCCESS;\r
+ InitializeListHead (&mPciDevicePool);\r
}\r
\r
/**\r
- Insert a root bridge into PCI device pool\r
+ Insert a root bridge into PCI device pool.\r
\r
- @param RootBridge - A pointer to the PCI_IO_DEVICE.\r
+ @param RootBridge A pointer to the PCI_IO_DEVICE.\r
\r
**/\r
-EFI_STATUS\r
+VOID\r
InsertRootBridge (\r
- PCI_IO_DEVICE *RootBridge\r
+ IN PCI_IO_DEVICE *RootBridge\r
)\r
{\r
-\r
- InsertTailList (&gPciDevicePool, &(RootBridge->Link));\r
-\r
- return EFI_SUCCESS;\r
+ InsertTailList (&mPciDevicePool, &(RootBridge->Link));\r
}\r
\r
/**\r
This function is used to insert a PCI device node under\r
- a bridge\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
+ @param Bridge The PCI bridge.\r
+ @param PciDeviceNode The PCI device needs inserting.\r
\r
**/\r
-EFI_STATUS\r
+VOID\r
InsertPciDevice (\r
- PCI_IO_DEVICE *Bridge,\r
- PCI_IO_DEVICE *PciDeviceNode\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN PCI_IO_DEVICE *PciDeviceNode\r
)\r
{\r
-\r
InsertTailList (&Bridge->ChildList, &(PciDeviceNode->Link));\r
PciDeviceNode->Parent = Bridge;\r
-\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
+ @param RootBridge The bridge want to be removed.\r
+\r
**/\r
-EFI_STATUS\r
+VOID\r
DestroyRootBridge (\r
- IN PCI_IO_DEVICE *RootBridge\r
+ IN PCI_IO_DEVICE *RootBridge\r
)\r
{\r
DestroyPciDeviceTree (RootBridge);\r
\r
FreePciDevice (RootBridge);\r
-\r
- return EFI_SUCCESS;\r
}\r
\r
/**\r
Destroy a pci device node.\r
- Also all direct or indirect allocated resource for this node will be freed.\r
\r
- @param PciIoDevice A pointer to the PCI_IO_DEVICE.\r
+ All direct or indirect allocated resource for this node will be freed.\r
+\r
+ @param PciIoDevice A pointer to the PCI_IO_DEVICE to be destoried.\r
\r
**/\r
-EFI_STATUS\r
+VOID\r
FreePciDevice (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
)\r
{\r
-\r
+ ASSERT (PciIoDevice != NULL);\r
//\r
// Assume all children have been removed underneath this device\r
//\r
if (PciIoDevice->ResourcePaddingDescriptors != NULL) {\r
- gBS->FreePool (PciIoDevice->ResourcePaddingDescriptors);\r
+ FreePool (PciIoDevice->ResourcePaddingDescriptors);\r
}\r
\r
if (PciIoDevice->DevicePath != NULL) {\r
- gBS->FreePool (PciIoDevice->DevicePath);\r
+ FreePool (PciIoDevice->DevicePath);\r
}\r
\r
- gBS->FreePool (PciIoDevice);\r
-\r
- return EFI_SUCCESS;\r
+ FreePool (PciIoDevice);\r
}\r
\r
/**\r
Destroy all the pci device node under the bridge.\r
Bridge itself is not included.\r
\r
- @param Bridge A pointer to the PCI_IO_DEVICE.\r
+ @param Bridge A pointer to the PCI_IO_DEVICE.\r
\r
**/\r
-EFI_STATUS\r
+VOID\r
DestroyPciDeviceTree (\r
- IN PCI_IO_DEVICE *Bridge\r
+ IN PCI_IO_DEVICE *Bridge\r
)\r
{\r
LIST_ENTRY *CurrentLink;\r
\r
FreePciDevice (Temp);\r
}\r
-\r
- return EFI_SUCCESS;\r
}\r
\r
/**\r
Destroy all device nodes under the root bridge\r
specified by Controller.\r
+\r
The root bridge itself is also included.\r
\r
- @param Controller An efi handle.\r
+ @param Controller Root bridge handle.\r
+\r
+ @retval EFI_SUCCESS Destory all devcie nodes successfully.\r
+ @retval EFI_NOT_FOUND Cannot find any PCI device under specified\r
+ root bridge.\r
\r
**/\r
EFI_STATUS\r
DestroyRootBridgeByHandle (\r
- EFI_HANDLE Controller\r
+ IN EFI_HANDLE Controller\r
)\r
{\r
\r
LIST_ENTRY *CurrentLink;\r
PCI_IO_DEVICE *Temp;\r
\r
- CurrentLink = gPciDevicePool.ForwardLink;\r
+ CurrentLink = mPciDevicePool.ForwardLink;\r
\r
- while (CurrentLink != NULL && CurrentLink != &gPciDevicePool) {\r
+ while (CurrentLink != NULL && CurrentLink != &mPciDevicePool) {\r
Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
\r
if (Temp->Handle == Controller) {\r
}\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
+ This function registers the PCI IO device.\r
+\r
+ It creates a handle for this PCI IO device (if the handle does not exist), attaches\r
+ appropriate protocols onto the handle, does necessary initialization, and sets up\r
+ parent/child relationship with its bus controller.\r
\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
+ @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 returned EFI handle for the PCI IO device.\r
\r
- @retval EFI_SUCCESS - The PCI device is successfully registered.\r
- @retval Others - An error occurred when registering the PCI device.\r
+ @retval EFI_SUCCESS The PCI device is successfully registered.\r
+ @retval other An error occurred when registering the PCI device.\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
+ IN EFI_HANDLE Controller,\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ OUT EFI_HANDLE *Handle OPTIONAL\r
)\r
{\r
EFI_STATUS Status;\r
if (!EFI_ERROR (Status)) {\r
PciIoDevice->IsPciExp = TRUE;\r
}\r
- \r
+\r
//\r
// Force Interrupt line to "Unknown" or "No Connection"\r
//\r
PciIo = &(PciIoDevice->PciIo);\r
Data8 = PCI_INT_LINE_UNKNOWN;\r
- PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &Data8);\r
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &Data8);\r
\r
//\r
// Process OpRom\r
\r
if (PciIoDevice->BusOverride) {\r
//\r
- // Install BusSpecificDriverOverride Protocol\r
+ // Install Bus Specific Driver Override Protocol\r
//\r
Status = gBS->InstallMultipleProtocolInterfaces (\r
&PciIoDevice->Handle,\r
}\r
\r
/**\r
- This function is used to remove the whole PCI devices from the bridge.\r
+ This function is used to remove the whole PCI devices on the specified bridge from\r
+ the root bridge.\r
\r
- @param RootBridgeHandle An efi handle.\r
- @param Bridge A pointer to the PCI_IO_DEVICE.\r
+ @param RootBridgeHandle The root bridge device handle.\r
+ @param Bridge The bridge device to be removed.\r
\r
- @retval EFI_SUCCESS\r
**/\r
-EFI_STATUS\r
+VOID\r
RemoveAllPciDeviceOnBridge (\r
EFI_HANDLE RootBridgeHandle,\r
PCI_IO_DEVICE *Bridge\r
)\r
-\r
{\r
-\r
LIST_ENTRY *CurrentLink;\r
PCI_IO_DEVICE *Temp;\r
\r
\r
FreePciDevice (Temp);\r
}\r
-\r
- return EFI_SUCCESS;\r
}\r
\r
/**\r
+ This function is used to de-register the PCI IO device.\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
- @param Controller - controller handle\r
- @param Handle - device handle\r
+ @param Controller An EFI handle for the PCI bus controller.\r
+ @param Handle PCI device handle.\r
+\r
+ @retval EFI_SUCCESS The PCI device is successfully de-registered.\r
+ @retval other An error occurred when de-registering the PCI device.\r
\r
- @return Status of de-register pci device\r
**/\r
EFI_STATUS\r
DeRegisterPciDevice (\r
);\r
\r
//\r
- // Un-install the device path protocol and pci io protocol\r
+ // Un-install the Device Path protocol and PCI I/O protocol\r
+ // and Bus Specific Driver Override protocol if needed.\r
//\r
if (PciIoDevice->BusOverride) {\r
Status = gBS->UninstallMultipleProtocolInterfaces (\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 Controller The root bridge 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_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
+ @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
\r
Node.DevPath = RemainingDevicePath;\r
\r
- if (Node.Pci->Device != PciIoDevice->DeviceNumber || \r
+ if (Node.Pci->Device != PciIoDevice->DeviceNumber ||\r
Node.Pci->Function != PciIoDevice->FunctionNumber) {\r
CurrentLink = CurrentLink->ForwardLink;\r
continue;\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
ChildHandleBuffer[*NumberOfChildren] = PciIoDevice->Handle;\r
(*NumberOfChildren)++;\r
}\r
- \r
+\r
//\r
// Get the next device path\r
//\r
// If remaining device path is NULL,\r
// try to enable all the pci devices under this bridge\r
//\r
-\r
if (!PciIoDevice->Registered && PciIoDevice->Allocated) {\r
Status = RegisterPciDevice (\r
Controller,\r
}\r
\r
/**\r
- Start to manage all the PCI devices it found previously under \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
+ @param Controller The root bridge handle.\r
+\r
+ @retval EFI_NOT_READY Device is not allocated.\r
+ @retval EFI_SUCCESS Success to start Pci device on host bridge.\r
\r
**/\r
EFI_STATUS\r
StartPciDevices (\r
IN EFI_HANDLE Controller\r
)\r
-\r
{\r
+ EFI_STATUS Status;\r
PCI_IO_DEVICE *RootBridge;\r
EFI_HANDLE ThisHostBridge;\r
LIST_ENTRY *CurrentLink;\r
ASSERT (RootBridge != NULL);\r
ThisHostBridge = RootBridge->PciRootBridgeIo->ParentHandle;\r
\r
- CurrentLink = gPciDevicePool.ForwardLink;\r
+ CurrentLink = mPciDevicePool.ForwardLink;\r
\r
- while (CurrentLink != NULL && CurrentLink != &gPciDevicePool) {\r
+ while (CurrentLink != NULL && CurrentLink != &mPciDevicePool) {\r
\r
RootBridge = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
//\r
// Locate the right root bridge to start\r
//\r
if (RootBridge->PciRootBridgeIo->ParentHandle == ThisHostBridge) {\r
- StartPciDevicesOnBridge (\r
- RootBridge->Handle,\r
- RootBridge,\r
- NULL,\r
- NULL,\r
- NULL\r
- );\r
+ Status = StartPciDevicesOnBridge (\r
+ RootBridge->Handle,\r
+ RootBridge,\r
+ NULL,\r
+ NULL,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
}\r
\r
CurrentLink = CurrentLink->ForwardLink;\r
}\r
\r
/**\r
- Create root bridge device\r
+ Create root bridge device.\r
+\r
+ @param RootBridgeHandle Specified root bridge hanle.\r
\r
- @param RootBridgeHandle - Parent bridge handle.\r
+ @return The crated root bridge device instance, NULL means no\r
+ root bridge device instance created.\r
\r
- @return pointer to new root bridge \r
**/\r
PCI_IO_DEVICE *\r
CreateRootBridge (\r
- IN EFI_HANDLE RootBridgeHandle\r
+ IN EFI_HANDLE RootBridgeHandle\r
)\r
{\r
-\r
EFI_STATUS Status;\r
PCI_IO_DEVICE *Dev;\r
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
\r
- Dev = NULL;\r
- Status = gBS->AllocatePool (\r
- EfiBootServicesData,\r
- sizeof (PCI_IO_DEVICE),\r
- (VOID **) &Dev\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
+ Dev = AllocateZeroPool (sizeof (PCI_IO_DEVICE));\r
+ if (Dev == NULL) {\r
return NULL;\r
}\r
\r
- ZeroMem (Dev, sizeof (PCI_IO_DEVICE));\r
Dev->Signature = PCI_IO_DEVICE_SIGNATURE;\r
Dev->Handle = RootBridgeHandle;\r
InitializeListHead (&Dev->ChildList);\r
);\r
\r
if (EFI_ERROR (Status)) {\r
- gBS->FreePool (Dev);\r
+ FreePool (Dev);\r
return NULL;\r
}\r
\r
}\r
\r
/**\r
- Get root bridge device instance by specific handle.\r
+ Get root bridge device instance by specific root bridge handle.\r
\r
@param RootBridgeHandle Given root bridge handle.\r
\r
- @return root bridge device instance.\r
+ @return The root bridge device instance, NULL means no root bridge\r
+ device instance found.\r
+\r
**/\r
PCI_IO_DEVICE *\r
GetRootBridgeByHandle (\r
PCI_IO_DEVICE *RootBridgeDev;\r
LIST_ENTRY *CurrentLink;\r
\r
- CurrentLink = gPciDevicePool.ForwardLink;\r
+ CurrentLink = mPciDevicePool.ForwardLink;\r
\r
- while (CurrentLink != NULL && CurrentLink != &gPciDevicePool) {\r
+ while (CurrentLink != NULL && CurrentLink != &mPciDevicePool) {\r
\r
RootBridgeDev = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
if (RootBridgeDev->Handle == RootBridgeHandle) {\r
\r
/**\r
Judege whether Pci device existed.\r
- \r
+\r
@param Bridge Parent bridege instance.\r
@param PciIoDevice Device instance.\r
- \r
- @return whether Pci device existed.\r
+\r
+ @retval TRUE Pci device existed.\r
+ @retval FALSE Pci device did not exist.\r
+\r
**/\r
BOOLEAN\r
PciDeviceExisted (\r
}\r
\r
/**\r
- Active VGA device.\r
- \r
- @param VgaDevice device instance for VGA.\r
- \r
- @return device instance.\r
+ Get the active VGA device on the same segment.\r
+\r
+ @param VgaDevice PCI IO instance for the VGA device.\r
+\r
+ @return The active VGA device on the same segment.\r
+\r
**/\r
PCI_IO_DEVICE *\r
ActiveVGADeviceOnTheSameSegment (\r
LIST_ENTRY *CurrentLink;\r
PCI_IO_DEVICE *Temp;\r
\r
- CurrentLink = gPciDevicePool.ForwardLink;\r
+ CurrentLink = mPciDevicePool.ForwardLink;\r
\r
- while (CurrentLink != NULL && CurrentLink != &gPciDevicePool) {\r
+ while (CurrentLink != NULL && CurrentLink != &mPciDevicePool) {\r
\r
Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
\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
+ Get the active VGA device on the root bridge.\r
+\r
+ @param RootBridge PCI IO instance for the root bridge.\r
+\r
+ @return The active VGA device.\r
+\r
**/\r
PCI_IO_DEVICE *\r
ActiveVGADeviceOnTheRootBridge (\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
- EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath;\r
- EFI_DEV_PATH_PTR Node;\r
- LIST_ENTRY *CurrentLink;\r
- PCI_IO_DEVICE *RootBridge;\r
- EFI_STATUS Status;\r
-\r
- CurrentDevicePath = HpcDevicePath;\r
-\r
- //\r
- // Get the remaining device path for this PCI device, if it is a PCI device\r
- //\r
- while (!IsDevicePathEnd (CurrentDevicePath)) {\r
-\r
- Node.DevPath = CurrentDevicePath;\r
-\r
- //\r
- // Check if it is PCI device Path?\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 = NextDevicePathNode (CurrentDevicePath);\r
- continue;\r
- }\r
-\r
- break;\r
- }\r
-\r
- //\r
- // Check if it is not PCI device path\r
- //\r
- if (IsDevicePathEnd (CurrentDevicePath)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- CurrentLink = gPciDevicePool.ForwardLink;\r
-\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->PciRootBridgeIo == PciRootBridgeIo) {\r
- Status = GetHpcPciAddressFromRootBridge (\r
- RootBridge,\r
- CurrentDevicePath,\r
- PciAddress\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- return EFI_NOT_FOUND;\r
-}\r
\r
/**\r
Get HPC PCI address according to its device path.\r
+\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
+ @retval EFI_SUCCESS PCI address was stored in PciAddress\r
+ @retval EFI_NOT_FOUND Can not find the specific device path.\r
+\r
**/\r
EFI_STATUS\r
GetHpcPciAddressFromRootBridge (\r