2 Driver Binding functions for PCI bus module.
4 Copyright (c) 2006, Intel Corporation
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 // PCI Bus Driver Global Variables
22 EFI_DRIVER_BINDING_PROTOCOL gPciBusDriverBinding
= {
23 PciBusDriverBindingSupported
,
24 PciBusDriverBindingStart
,
25 PciBusDriverBindingStop
,
31 EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL
*gEfiIncompatiblePciDeviceSupport
= NULL
;
32 EFI_HANDLE gPciHostBrigeHandles
[PCI_MAX_HOST_BRIDGE_NUM
];
33 UINTN gPciHostBridgeNumber
;
34 BOOLEAN gFullEnumeration
;
35 UINT64 gAllOne
= 0xFFFFFFFFFFFFFFFFULL
;
38 EFI_PCI_PLATFORM_PROTOCOL
*gPciPlatformProtocol
;
41 // PCI Bus Driver Support Functions
44 Initialize the global variables
45 publish the driver binding protocol
47 @param[IN] ImageHandle,
48 @param[IN] *SystemTable
50 @retval status of installing driver binding component name protocol.
56 IN EFI_HANDLE ImageHandle
,
57 IN EFI_SYSTEM_TABLE
*SystemTable
62 InitializePciDevicePool ();
64 gFullEnumeration
= TRUE
;
66 gPciHostBridgeNumber
= 0;
69 // Install driver model protocol(s).
71 Status
= EfiLibInstallDriverBindingComponentName2 (
74 &gPciBusDriverBinding
,
76 &gPciBusComponentName
,
77 &gPciBusComponentName2
79 ASSERT_EFI_ERROR (Status
);
81 InstallHotPlugRequestProtocol (&Status
);
87 Test to see if this driver supports ControllerHandle. Any ControllerHandle
88 than contains a gEfiPciRootBridgeIoProtocolGuid protocol can be supported.
90 @param This Protocol instance pointer.
91 @param ControllerHandle Handle of device to test
92 @param RemainingDevicePath Optional parameter use to pick a specific child
95 @retval EFI_SUCCESS This driver supports this device
96 @retval EFI_ALREADY_STARTED This driver is already running on this device
97 @retval other This driver does not support this device
102 PciBusDriverBindingSupported (
103 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
104 IN EFI_HANDLE Controller
,
105 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
109 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
110 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
111 EFI_DEV_PATH_PTR Node
;
113 if (RemainingDevicePath
!= NULL
) {
114 Node
.DevPath
= RemainingDevicePath
;
115 if (Node
.DevPath
->Type
!= HARDWARE_DEVICE_PATH
||
116 Node
.DevPath
->SubType
!= HW_PCI_DP
||
117 DevicePathNodeLength(Node
.DevPath
) != sizeof(PCI_DEVICE_PATH
)) {
118 return EFI_UNSUPPORTED
;
122 // Open the IO Abstraction(s) needed to perform the supported test
124 Status
= gBS
->OpenProtocol (
126 &gEfiDevicePathProtocolGuid
,
127 (VOID
**) &ParentDevicePath
,
128 This
->DriverBindingHandle
,
130 EFI_OPEN_PROTOCOL_BY_DRIVER
132 if (Status
== EFI_ALREADY_STARTED
) {
136 if (EFI_ERROR (Status
)) {
142 &gEfiDevicePathProtocolGuid
,
143 This
->DriverBindingHandle
,
147 Status
= gBS
->OpenProtocol (
149 &gEfiPciRootBridgeIoProtocolGuid
,
150 (VOID
**) &PciRootBridgeIo
,
151 This
->DriverBindingHandle
,
153 EFI_OPEN_PROTOCOL_BY_DRIVER
155 if (Status
== EFI_ALREADY_STARTED
) {
159 if (EFI_ERROR (Status
)) {
165 &gEfiPciRootBridgeIoProtocolGuid
,
166 This
->DriverBindingHandle
,
174 Start this driver on ControllerHandle and enumerate Pci bus and start
175 all device under PCI bus.
177 @param This Protocol instance pointer.
178 @param ControllerHandle Handle of device to bind driver to
179 @param RemainingDevicePath Optional parameter use to pick a specific child
182 @retval EFI_SUCCESS This driver is added to ControllerHandle
183 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
184 @retval other This driver does not support this device
189 PciBusDriverBindingStart (
190 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
191 IN EFI_HANDLE Controller
,
192 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
197 Status
= gBS
->LocateProtocol (
198 &gEfiIncompatiblePciDeviceSupportProtocolGuid
,
200 (VOID
**) &gEfiIncompatiblePciDeviceSupport
204 // If PCI Platform protocol is available, get it now.
205 // If the platform implements this, it must be installed before BDS phase
207 gPciPlatformProtocol
= NULL
;
208 gBS
->LocateProtocol (
209 &gEfiPciPlatformProtocolGuid
,
211 (VOID
**) &gPciPlatformProtocol
214 gFullEnumeration
= (BOOLEAN
) ((SearchHostBridgeHandle (Controller
) ? FALSE
: TRUE
));
217 // Enumerate the entire host bridge
218 // After enumeration, a database that records all the device information will be created
221 Status
= PciEnumerator (Controller
);
223 if (EFI_ERROR (Status
)) {
228 // Start all the devices under the entire host bridge.
230 StartPciDevices (Controller
);
236 Stop this driver on ControllerHandle. Support stoping any child handles
237 created by this driver.
239 @param This Protocol instance pointer.
240 @param ControllerHandle Handle of device to stop driver on
241 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
242 children is zero stop the entire bus driver.
243 @param ChildHandleBuffer List of Child Handles to Stop.
245 @retval EFI_SUCCESS This driver is removed ControllerHandle
246 @retval other This driver was not removed from this device
251 PciBusDriverBindingStop (
252 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
253 IN EFI_HANDLE Controller
,
254 IN UINTN NumberOfChildren
,
255 IN EFI_HANDLE
*ChildHandleBuffer
260 BOOLEAN AllChildrenStopped
;
262 if (NumberOfChildren
== 0) {
264 // Close the bus driver
268 &gEfiDevicePathProtocolGuid
,
269 This
->DriverBindingHandle
,
274 &gEfiPciRootBridgeIoProtocolGuid
,
275 This
->DriverBindingHandle
,
279 DestroyRootBridgeByHandle (
287 // Stop all the children
290 AllChildrenStopped
= TRUE
;
292 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
295 // De register all the pci device
297 Status
= DeRegisterPciDevice (Controller
, ChildHandleBuffer
[Index
]);
299 if (EFI_ERROR (Status
)) {
300 AllChildrenStopped
= FALSE
;
304 if (!AllChildrenStopped
) {
305 return EFI_DEVICE_ERROR
;