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