]> git.proxmox.com Git - mirror_edk2.git/blob - EdkModulePkg/Bus/Pci/PciBus/Dxe/pcibus.c
eb6713f4dd1eb0645289954b957f3afd9cbc1d20
[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 Driver Global Variables
28 //
29
30 EFI_DRIVER_BINDING_PROTOCOL gPciBusDriverBinding = {
31 PciBusDriverBindingSupported,
32 PciBusDriverBindingStart,
33 PciBusDriverBindingStop,
34 0xa,
35 NULL,
36 NULL
37 };
38
39 EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL *gEfiIncompatiblePciDeviceSupport = NULL;
40 EFI_HANDLE gPciHostBrigeHandles[PCI_MAX_HOST_BRIDGE_NUM];
41 UINTN gPciHostBridgeNumber;
42 BOOLEAN gFullEnumeration;
43 UINT64 gAllOne = 0xFFFFFFFFFFFFFFFFULL;
44 UINT64 gAllZero = 0;
45
46 EFI_PCI_PLATFORM_PROTOCOL *gPciPlatformProtocol;
47
48 //
49 // PCI Bus Driver Support Functions
50 //
51 EFI_STATUS
52 EFIAPI
53 PciBusEntryPoint (
54 IN EFI_HANDLE ImageHandle,
55 IN EFI_SYSTEM_TABLE *SystemTable
56 )
57 /*++
58
59 Routine Description:
60
61 Initialize the global variables
62 publish the driver binding protocol
63
64 Arguments:
65
66 IN EFI_HANDLE ImageHandle,
67 IN EFI_SYSTEM_TABLE *SystemTable
68
69 Returns:
70
71 EFI_SUCCESS
72 EFI_DEVICE_ERROR
73
74 --*/
75 // TODO: ImageHandle - add argument and description to function comment
76 // TODO: SystemTable - add argument and description to function comment
77 {
78 EFI_STATUS Status;
79
80 InitializePciDevicePool ();
81
82 gFullEnumeration = TRUE;
83
84 gPciHostBridgeNumber = 0;
85
86 InstallHotPlugRequestProtocol (&Status);
87 return Status;
88 }
89
90 EFI_STATUS
91 EFIAPI
92 PciBusDriverBindingSupported (
93 IN EFI_DRIVER_BINDING_PROTOCOL *This,
94 IN EFI_HANDLE Controller,
95 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
96 )
97 /*++
98
99 Routine Description:
100
101 Check to see if pci bus driver supports the given controller
102
103 Arguments:
104
105 IN EFI_DRIVER_BINDING_PROTOCOL *This,
106 IN EFI_HANDLE Controller,
107 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
108
109 Returns:
110
111 EFI_SUCCESS
112
113 --*/
114 // TODO: This - add argument and description to function comment
115 // TODO: Controller - add argument and description to function comment
116 // TODO: RemainingDevicePath - add argument and description to function comment
117 // TODO: EFI_UNSUPPORTED - add return value to function comment
118 {
119 EFI_STATUS Status;
120 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
121 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
122 EFI_DEV_PATH_PTR Node;
123
124 if (RemainingDevicePath != NULL) {
125 Node.DevPath = RemainingDevicePath;
126 if (Node.DevPath->Type != HARDWARE_DEVICE_PATH ||
127 Node.DevPath->SubType != HW_PCI_DP ||
128 DevicePathNodeLength(Node.DevPath) != sizeof(PCI_DEVICE_PATH)) {
129 return EFI_UNSUPPORTED;
130 }
131 }
132 //
133 // Open the IO Abstraction(s) needed to perform the supported test
134 //
135 Status = gBS->OpenProtocol (
136 Controller,
137 &gEfiDevicePathProtocolGuid,
138 (VOID **) &ParentDevicePath,
139 This->DriverBindingHandle,
140 Controller,
141 EFI_OPEN_PROTOCOL_BY_DRIVER
142 );
143 if (Status == EFI_ALREADY_STARTED) {
144 return EFI_SUCCESS;
145 }
146
147 if (EFI_ERROR (Status)) {
148 return Status;
149 }
150
151 gBS->CloseProtocol (
152 Controller,
153 &gEfiDevicePathProtocolGuid,
154 This->DriverBindingHandle,
155 Controller
156 );
157
158 Status = gBS->OpenProtocol (
159 Controller,
160 &gEfiPciRootBridgeIoProtocolGuid,
161 (VOID **) &PciRootBridgeIo,
162 This->DriverBindingHandle,
163 Controller,
164 EFI_OPEN_PROTOCOL_BY_DRIVER
165 );
166 if (Status == EFI_ALREADY_STARTED) {
167 return EFI_SUCCESS;
168 }
169
170 if (EFI_ERROR (Status)) {
171 return Status;
172 }
173
174 gBS->CloseProtocol (
175 Controller,
176 &gEfiPciRootBridgeIoProtocolGuid,
177 This->DriverBindingHandle,
178 Controller
179 );
180
181 return EFI_SUCCESS;
182 }
183
184 EFI_STATUS
185 EFIAPI
186 PciBusDriverBindingStart (
187 IN EFI_DRIVER_BINDING_PROTOCOL *This,
188 IN EFI_HANDLE Controller,
189 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
190 )
191 /*++
192
193 Routine Description:
194
195 Start to management the controller passed in
196
197 Arguments:
198
199 IN EFI_DRIVER_BINDING_PROTOCOL *This,
200 IN EFI_HANDLE Controller,
201 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
202
203 Returns:
204
205
206 --*/
207 // TODO: This - add argument and description to function comment
208 // TODO: Controller - add argument and description to function comment
209 // TODO: RemainingDevicePath - add argument and description to function comment
210 // TODO: EFI_SUCCESS - add return value to function comment
211 {
212 EFI_STATUS Status;
213
214 Status = gBS->LocateProtocol (
215 &gEfiIncompatiblePciDeviceSupportProtocolGuid,
216 NULL,
217 (VOID **) &gEfiIncompatiblePciDeviceSupport
218 );
219
220 //
221 // If PCI Platform protocol is available, get it now.
222 // If the platform implements this, it must be installed before BDS phase
223 //
224 gPciPlatformProtocol = NULL;
225 gBS->LocateProtocol (
226 &gEfiPciPlatformProtocolGuid,
227 NULL,
228 (VOID **) &gPciPlatformProtocol
229 );
230
231 gFullEnumeration = (BOOLEAN) ((SearchHostBridgeHandle (Controller) ? FALSE : TRUE));
232
233 //
234 // Enumerate the entire host bridge
235 // After enumeration, a database that records all the device information will be created
236 //
237 //
238 Status = PciEnumerator (Controller);
239
240 if (EFI_ERROR (Status)) {
241 return Status;
242 }
243
244 //
245 // Enable PCI device specified by remaining device path. BDS or other driver can call the
246 // start more than once.
247 //
248
249 StartPciDevices (Controller, RemainingDevicePath);
250
251 return EFI_SUCCESS;
252 }
253
254 EFI_STATUS
255 EFIAPI
256 PciBusDriverBindingStop (
257 IN EFI_DRIVER_BINDING_PROTOCOL *This,
258 IN EFI_HANDLE Controller,
259 IN UINTN NumberOfChildren,
260 IN EFI_HANDLE *ChildHandleBuffer
261 )
262 /*++
263
264 Routine Description:
265
266 Stop one or more children created at start of pci bus driver
267 if all the the children get closed, close the protocol
268
269 Arguments:
270
271 IN EFI_DRIVER_BINDING_PROTOCOL *This,
272 IN EFI_HANDLE Controller,
273 IN UINTN NumberOfChildren,
274 IN EFI_HANDLE *ChildHandleBuffer
275
276 Returns:
277
278
279 --*/
280 // TODO: This - add argument and description to function comment
281 // TODO: Controller - add argument and description to function comment
282 // TODO: NumberOfChildren - add argument and description to function comment
283 // TODO: ChildHandleBuffer - add argument and description to function comment
284 // TODO: EFI_SUCCESS - add return value to function comment
285 // TODO: EFI_DEVICE_ERROR - add return value to function comment
286 // TODO: EFI_SUCCESS - add return value to function comment
287 {
288 EFI_STATUS Status;
289 UINTN Index;
290 BOOLEAN AllChildrenStopped;
291
292 if (NumberOfChildren == 0) {
293 //
294 // Close the bus driver
295 //
296 gBS->CloseProtocol (
297 Controller,
298 &gEfiDevicePathProtocolGuid,
299 This->DriverBindingHandle,
300 Controller
301 );
302 gBS->CloseProtocol (
303 Controller,
304 &gEfiPciRootBridgeIoProtocolGuid,
305 This->DriverBindingHandle,
306 Controller
307 );
308
309 DestroyRootBridgeByHandle (
310 Controller
311 );
312
313 return EFI_SUCCESS;
314 }
315
316 //
317 // Stop all the children
318 //
319
320 AllChildrenStopped = TRUE;
321
322 for (Index = 0; Index < NumberOfChildren; Index++) {
323
324 //
325 // De register all the pci device
326 //
327 Status = DeRegisterPciDevice (Controller, ChildHandleBuffer[Index]);
328
329 if (EFI_ERROR (Status)) {
330 AllChildrenStopped = FALSE;
331 }
332 }
333
334 if (!AllChildrenStopped) {
335 return EFI_DEVICE_ERROR;
336 }
337
338 return EFI_SUCCESS;
339 }