]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciBus.c
rename
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Pci / PciBusDxe / PciBus.c
1 /**@file
2 Driver Binding functions for PCI bus module.
3
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
9
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.
12
13 **/
14
15
16 #include "Pcibus.h"
17
18 //
19 // PCI Bus Driver Global Variables
20 //
21
22 EFI_DRIVER_BINDING_PROTOCOL gPciBusDriverBinding = {
23 PciBusDriverBindingSupported,
24 PciBusDriverBindingStart,
25 PciBusDriverBindingStop,
26 0xa,
27 NULL,
28 NULL
29 };
30
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;
36 UINT64 gAllZero = 0;
37
38 EFI_PCI_PLATFORM_PROTOCOL *gPciPlatformProtocol;
39
40 //
41 // PCI Bus Driver Support Functions
42 //
43 /**
44 Initialize the global variables
45 publish the driver binding protocol
46
47 @param[IN] ImageHandle,
48 @param[IN] *SystemTable
49
50 @retval status of installing driver binding component name protocol.
51
52 **/
53 EFI_STATUS
54 EFIAPI
55 PciBusEntryPoint (
56 IN EFI_HANDLE ImageHandle,
57 IN EFI_SYSTEM_TABLE *SystemTable
58 )
59 {
60 EFI_STATUS Status;
61
62 InitializePciDevicePool ();
63
64 gFullEnumeration = TRUE;
65
66 gPciHostBridgeNumber = 0;
67
68 //
69 // Install driver model protocol(s).
70 //
71 Status = EfiLibInstallDriverBindingComponentName2 (
72 ImageHandle,
73 SystemTable,
74 &gPciBusDriverBinding,
75 ImageHandle,
76 &gPciBusComponentName,
77 &gPciBusComponentName2
78 );
79 ASSERT_EFI_ERROR (Status);
80
81 InstallHotPlugRequestProtocol (&Status);
82
83 return Status;
84 }
85
86 /**
87 Test to see if this driver supports ControllerHandle. Any ControllerHandle
88 than contains a gEfiPciRootBridgeIoProtocolGuid protocol can be supported.
89
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
93 device to start.
94
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
98
99 **/
100 EFI_STATUS
101 EFIAPI
102 PciBusDriverBindingSupported (
103 IN EFI_DRIVER_BINDING_PROTOCOL *This,
104 IN EFI_HANDLE Controller,
105 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
106 )
107 {
108 EFI_STATUS Status;
109 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
110 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
111 EFI_DEV_PATH_PTR Node;
112
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;
119 }
120 }
121 //
122 // Open the IO Abstraction(s) needed to perform the supported test
123 //
124 Status = gBS->OpenProtocol (
125 Controller,
126 &gEfiDevicePathProtocolGuid,
127 (VOID **) &ParentDevicePath,
128 This->DriverBindingHandle,
129 Controller,
130 EFI_OPEN_PROTOCOL_BY_DRIVER
131 );
132 if (Status == EFI_ALREADY_STARTED) {
133 return EFI_SUCCESS;
134 }
135
136 if (EFI_ERROR (Status)) {
137 return Status;
138 }
139
140 gBS->CloseProtocol (
141 Controller,
142 &gEfiDevicePathProtocolGuid,
143 This->DriverBindingHandle,
144 Controller
145 );
146
147 Status = gBS->OpenProtocol (
148 Controller,
149 &gEfiPciRootBridgeIoProtocolGuid,
150 (VOID **) &PciRootBridgeIo,
151 This->DriverBindingHandle,
152 Controller,
153 EFI_OPEN_PROTOCOL_BY_DRIVER
154 );
155 if (Status == EFI_ALREADY_STARTED) {
156 return EFI_SUCCESS;
157 }
158
159 if (EFI_ERROR (Status)) {
160 return Status;
161 }
162
163 gBS->CloseProtocol (
164 Controller,
165 &gEfiPciRootBridgeIoProtocolGuid,
166 This->DriverBindingHandle,
167 Controller
168 );
169
170 return EFI_SUCCESS;
171 }
172
173 /**
174 Start this driver on ControllerHandle and enumerate Pci bus and start
175 all device under PCI bus.
176
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
180 device to start.
181
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
185
186 **/
187 EFI_STATUS
188 EFIAPI
189 PciBusDriverBindingStart (
190 IN EFI_DRIVER_BINDING_PROTOCOL *This,
191 IN EFI_HANDLE Controller,
192 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
193 )
194 {
195 EFI_STATUS Status;
196
197 Status = gBS->LocateProtocol (
198 &gEfiIncompatiblePciDeviceSupportProtocolGuid,
199 NULL,
200 (VOID **) &gEfiIncompatiblePciDeviceSupport
201 );
202
203 //
204 // If PCI Platform protocol is available, get it now.
205 // If the platform implements this, it must be installed before BDS phase
206 //
207 gPciPlatformProtocol = NULL;
208 gBS->LocateProtocol (
209 &gEfiPciPlatformProtocolGuid,
210 NULL,
211 (VOID **) &gPciPlatformProtocol
212 );
213
214 gFullEnumeration = (BOOLEAN) ((SearchHostBridgeHandle (Controller) ? FALSE : TRUE));
215
216 //
217 // Enumerate the entire host bridge
218 // After enumeration, a database that records all the device information will be created
219 //
220 //
221 Status = PciEnumerator (Controller);
222
223 if (EFI_ERROR (Status)) {
224 return Status;
225 }
226
227 //
228 // Start all the devices under the entire host bridge.
229 //
230 StartPciDevices (Controller);
231
232 return EFI_SUCCESS;
233 }
234
235 /**
236 Stop this driver on ControllerHandle. Support stoping any child handles
237 created by this driver.
238
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.
244
245 @retval EFI_SUCCESS This driver is removed ControllerHandle
246 @retval other This driver was not removed from this device
247
248 **/
249 EFI_STATUS
250 EFIAPI
251 PciBusDriverBindingStop (
252 IN EFI_DRIVER_BINDING_PROTOCOL *This,
253 IN EFI_HANDLE Controller,
254 IN UINTN NumberOfChildren,
255 IN EFI_HANDLE *ChildHandleBuffer
256 )
257 {
258 EFI_STATUS Status;
259 UINTN Index;
260 BOOLEAN AllChildrenStopped;
261
262 if (NumberOfChildren == 0) {
263 //
264 // Close the bus driver
265 //
266 gBS->CloseProtocol (
267 Controller,
268 &gEfiDevicePathProtocolGuid,
269 This->DriverBindingHandle,
270 Controller
271 );
272 gBS->CloseProtocol (
273 Controller,
274 &gEfiPciRootBridgeIoProtocolGuid,
275 This->DriverBindingHandle,
276 Controller
277 );
278
279 DestroyRootBridgeByHandle (
280 Controller
281 );
282
283 return EFI_SUCCESS;
284 }
285
286 //
287 // Stop all the children
288 //
289
290 AllChildrenStopped = TRUE;
291
292 for (Index = 0; Index < NumberOfChildren; Index++) {
293
294 //
295 // De register all the pci device
296 //
297 Status = DeRegisterPciDevice (Controller, ChildHandleBuffer[Index]);
298
299 if (EFI_ERROR (Status)) {
300 AllChildrenStopped = FALSE;
301 }
302 }
303
304 if (!AllChildrenStopped) {
305 return EFI_DEVICE_ERROR;
306 }
307
308 return EFI_SUCCESS;
309 }
310