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