]> git.proxmox.com Git - mirror_edk2.git/blob - EdkModulePkg/Bus/Pci/PciBus/Dxe/pcibus.c
ed56578757d9a2dbc161e6bb9e80742504a8768f
[mirror_edk2.git] / EdkModulePkg / Bus / Pci / PciBus / Dxe / pcibus.c
1 /*++
2
3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 PciBus.c
15
16 Abstract:
17
18 PCI Bus Driver
19
20 Revision History
21
22 --*/
23
24 #include "pcibus.h"
25
26 //
27 // PCI Bus Support Function Prototypes
28 //
29
30 EFI_STATUS
31 EFIAPI
32 PciBusEntryPoint (
33 IN EFI_HANDLE ImageHandle,
34 IN EFI_SYSTEM_TABLE *SystemTable
35 );
36
37 EFI_STATUS
38 EFIAPI
39 PciBusDriverBindingSupported (
40 IN EFI_DRIVER_BINDING_PROTOCOL *This,
41 IN EFI_HANDLE Controller,
42 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
43 );
44
45 EFI_STATUS
46 EFIAPI
47 PciBusDriverBindingStart (
48 IN EFI_DRIVER_BINDING_PROTOCOL *This,
49 IN EFI_HANDLE Controller,
50 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
51 );
52
53 EFI_STATUS
54 EFIAPI
55 PciBusDriverBindingStop (
56 IN EFI_DRIVER_BINDING_PROTOCOL *This,
57 IN EFI_HANDLE Controller,
58 IN UINTN NumberOfChildren,
59 IN EFI_HANDLE *ChildHandleBuffer
60 );
61
62 //
63 // PCI Bus Driver Global Variables
64 //
65
66 EFI_DRIVER_BINDING_PROTOCOL gPciBusDriverBinding = {
67 PciBusDriverBindingSupported,
68 PciBusDriverBindingStart,
69 PciBusDriverBindingStop,
70 0x10,
71 NULL,
72 NULL
73 };
74
75 EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL *gEfiIncompatiblePciDeviceSupport = NULL;
76 EFI_HANDLE gPciHostBrigeHandles[PCI_MAX_HOST_BRIDGE_NUM];
77 UINTN gPciHostBridgeNumber;
78 BOOLEAN gFullEnumeration;
79 UINT64 gAllOne = 0xFFFFFFFFFFFFFFFFULL;
80 UINT64 gAllZero = 0;
81
82 EFI_PCI_PLATFORM_PROTOCOL *gPciPlatformProtocol;
83
84 //
85 // PCI Bus Driver Support Functions
86 //
87 EFI_STATUS
88 EFIAPI
89 PciBusEntryPoint (
90 IN EFI_HANDLE ImageHandle,
91 IN EFI_SYSTEM_TABLE *SystemTable
92 )
93 /*++
94
95 Routine Description:
96
97 Initialize the global variables
98 publish the driver binding protocol
99
100 Arguments:
101
102 IN EFI_HANDLE ImageHandle,
103 IN EFI_SYSTEM_TABLE *SystemTable
104
105 Returns:
106
107 EFI_SUCCESS
108 EFI_DEVICE_ERROR
109
110 --*/
111 // TODO: ImageHandle - add argument and description to function comment
112 // TODO: SystemTable - add argument and description to function comment
113 {
114 EFI_STATUS Status;
115
116 InitializePciDevicePool ();
117
118 gFullEnumeration = TRUE;
119
120 gPciHostBridgeNumber = 0;
121
122 InstallHotPlugRequestProtocol (&Status);
123 return Status;
124 }
125
126 EFI_STATUS
127 EFIAPI
128 PciBusDriverBindingSupported (
129 IN EFI_DRIVER_BINDING_PROTOCOL *This,
130 IN EFI_HANDLE Controller,
131 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
132 )
133 /*++
134
135 Routine Description:
136
137 Check to see if pci bus driver supports the given controller
138
139 Arguments:
140
141 IN EFI_DRIVER_BINDING_PROTOCOL *This,
142 IN EFI_HANDLE Controller,
143 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
144
145 Returns:
146
147 EFI_SUCCESS
148
149 --*/
150 // TODO: This - add argument and description to function comment
151 // TODO: Controller - add argument and description to function comment
152 // TODO: RemainingDevicePath - add argument and description to function comment
153 // TODO: EFI_UNSUPPORTED - add return value to function comment
154 {
155 EFI_STATUS Status;
156 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
157 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
158 EFI_DEV_PATH_PTR Node;
159
160 if (RemainingDevicePath != NULL) {
161 Node.DevPath = RemainingDevicePath;
162 if (Node.DevPath->Type != HARDWARE_DEVICE_PATH ||
163 Node.DevPath->SubType != HW_PCI_DP ||
164 DevicePathNodeLength(Node.DevPath) != sizeof(PCI_DEVICE_PATH)) {
165 return EFI_UNSUPPORTED;
166 }
167 }
168 //
169 // Open the IO Abstraction(s) needed to perform the supported test
170 //
171 Status = gBS->OpenProtocol (
172 Controller,
173 &gEfiDevicePathProtocolGuid,
174 (VOID **) &ParentDevicePath,
175 This->DriverBindingHandle,
176 Controller,
177 EFI_OPEN_PROTOCOL_BY_DRIVER
178 );
179 if (Status == EFI_ALREADY_STARTED) {
180 return EFI_SUCCESS;
181 }
182
183 if (EFI_ERROR (Status)) {
184 return Status;
185 }
186
187 gBS->CloseProtocol (
188 Controller,
189 &gEfiDevicePathProtocolGuid,
190 This->DriverBindingHandle,
191 Controller
192 );
193
194 Status = gBS->OpenProtocol (
195 Controller,
196 &gEfiPciRootBridgeIoProtocolGuid,
197 (VOID **) &PciRootBridgeIo,
198 This->DriverBindingHandle,
199 Controller,
200 EFI_OPEN_PROTOCOL_BY_DRIVER
201 );
202 if (Status == EFI_ALREADY_STARTED) {
203 return EFI_SUCCESS;
204 }
205
206 if (EFI_ERROR (Status)) {
207 return Status;
208 }
209
210 gBS->CloseProtocol (
211 Controller,
212 &gEfiPciRootBridgeIoProtocolGuid,
213 This->DriverBindingHandle,
214 Controller
215 );
216
217 return EFI_SUCCESS;
218 }
219
220 EFI_STATUS
221 EFIAPI
222 PciBusDriverBindingStart (
223 IN EFI_DRIVER_BINDING_PROTOCOL *This,
224 IN EFI_HANDLE Controller,
225 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
226 )
227 /*++
228
229 Routine Description:
230
231 Start to management the controller passed in
232
233 Arguments:
234
235 IN EFI_DRIVER_BINDING_PROTOCOL *This,
236 IN EFI_HANDLE Controller,
237 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
238
239 Returns:
240
241
242 --*/
243 // TODO: This - add argument and description to function comment
244 // TODO: Controller - add argument and description to function comment
245 // TODO: RemainingDevicePath - add argument and description to function comment
246 // TODO: EFI_SUCCESS - add return value to function comment
247 {
248 EFI_STATUS Status;
249
250 Status = gBS->LocateProtocol (
251 &gEfiIncompatiblePciDeviceSupportProtocolGuid,
252 NULL,
253 (VOID **) &gEfiIncompatiblePciDeviceSupport
254 );
255
256 //
257 // If PCI Platform protocol is available, get it now.
258 // If the platform implements this, it must be installed before BDS phase
259 //
260 gPciPlatformProtocol = NULL;
261 gBS->LocateProtocol (
262 &gEfiPciPlatformProtocolGuid,
263 NULL,
264 (VOID **) &gPciPlatformProtocol
265 );
266
267 gFullEnumeration = (BOOLEAN) ((SearchHostBridgeHandle (Controller) ? FALSE : TRUE));
268
269 //
270 // Enumerate the entire host bridge
271 // After enumeration, a database that records all the device information will be created
272 //
273 //
274 Status = PciEnumerator (Controller);
275
276 if (EFI_ERROR (Status)) {
277 return Status;
278 }
279
280 //
281 // Enable PCI device specified by remaining device path. BDS or other driver can call the
282 // start more than once.
283 //
284
285 StartPciDevices (Controller, RemainingDevicePath);
286
287 return EFI_SUCCESS;
288 }
289
290 EFI_STATUS
291 EFIAPI
292 PciBusDriverBindingStop (
293 IN EFI_DRIVER_BINDING_PROTOCOL *This,
294 IN EFI_HANDLE Controller,
295 IN UINTN NumberOfChildren,
296 IN EFI_HANDLE *ChildHandleBuffer
297 )
298 /*++
299
300 Routine Description:
301
302 Stop one or more children created at start of pci bus driver
303 if all the the children get closed, close the protocol
304
305 Arguments:
306
307 IN EFI_DRIVER_BINDING_PROTOCOL *This,
308 IN EFI_HANDLE Controller,
309 IN UINTN NumberOfChildren,
310 IN EFI_HANDLE *ChildHandleBuffer
311
312 Returns:
313
314
315 --*/
316 // TODO: This - add argument and description to function comment
317 // TODO: Controller - add argument and description to function comment
318 // TODO: NumberOfChildren - add argument and description to function comment
319 // TODO: ChildHandleBuffer - add argument and description to function comment
320 // TODO: EFI_SUCCESS - add return value to function comment
321 // TODO: EFI_DEVICE_ERROR - add return value to function comment
322 // TODO: EFI_SUCCESS - add return value to function comment
323 {
324 EFI_STATUS Status;
325 UINTN Index;
326 BOOLEAN AllChildrenStopped;
327
328 if (NumberOfChildren == 0) {
329 //
330 // Close the bus driver
331 //
332 gBS->CloseProtocol (
333 Controller,
334 &gEfiDevicePathProtocolGuid,
335 This->DriverBindingHandle,
336 Controller
337 );
338 gBS->CloseProtocol (
339 Controller,
340 &gEfiPciRootBridgeIoProtocolGuid,
341 This->DriverBindingHandle,
342 Controller
343 );
344
345 DestroyRootBridgeByHandle (
346 Controller
347 );
348
349 return EFI_SUCCESS;
350 }
351
352 //
353 // Stop all the children
354 //
355
356 AllChildrenStopped = TRUE;
357
358 for (Index = 0; Index < NumberOfChildren; Index++) {
359
360 //
361 // De register all the pci device
362 //
363 Status = DeRegisterPciDevice (Controller, ChildHandleBuffer[Index]);
364
365 if (EFI_ERROR (Status)) {
366 AllChildrenStopped = FALSE;
367 }
368 }
369
370 if (!AllChildrenStopped) {
371 return EFI_DEVICE_ERROR;
372 }
373
374 return EFI_SUCCESS;
375 }