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