]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/Pcibus.c
sync filename exactly.
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Pci / PciBusDxe / Pcibus.c
CommitLineData
3db51098 1/**@file\r
a3b8e257 2 Driver Binding functions for PCI bus module.\r
3 \r
3db51098 4Copyright (c) 2006, Intel Corporation \r
5All rights reserved. This program and the accompanying materials \r
6are licensed and made available under the terms and conditions of the BSD License \r
7which accompanies this distribution. The full text of the license may be found at \r
8http://opensource.org/licenses/bsd-license.php \r
9 \r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
ead42efc 12\r
3db51098 13**/\r
ead42efc 14\r
ead42efc 15\r
03417d8d 16#include "Pcibus.h"\r
ead42efc 17\r
18//\r
19// PCI Bus Driver Global Variables\r
20//\r
21\r
22EFI_DRIVER_BINDING_PROTOCOL gPciBusDriverBinding = {\r
23 PciBusDriverBindingSupported,\r
24 PciBusDriverBindingStart,\r
25 PciBusDriverBindingStop,\r
26 0xa,\r
27 NULL,\r
28 NULL\r
29};\r
30\r
ea5632e5 31EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL *gEfiIncompatiblePciDeviceSupport = NULL;\r
ead42efc 32EFI_HANDLE gPciHostBrigeHandles[PCI_MAX_HOST_BRIDGE_NUM];\r
33UINTN gPciHostBridgeNumber;\r
34BOOLEAN gFullEnumeration;\r
35UINT64 gAllOne = 0xFFFFFFFFFFFFFFFFULL;\r
36UINT64 gAllZero = 0;\r
37\r
38EFI_PCI_PLATFORM_PROTOCOL *gPciPlatformProtocol;\r
39\r
40//\r
41// PCI Bus Driver Support Functions\r
42//\r
bcd70414 43/**\r
ead42efc 44 Initialize the global variables\r
45 publish the driver binding protocol\r
46\r
a3b8e257 47 @param[IN] ImageHandle,\r
48 @param[IN] *SystemTable\r
ead42efc 49\r
a3b8e257 50 @retval status of installing driver binding component name protocol.\r
ead42efc 51\r
bcd70414 52**/\r
a3b8e257 53EFI_STATUS\r
54EFIAPI\r
55PciBusEntryPoint (\r
56 IN EFI_HANDLE ImageHandle,\r
57 IN EFI_SYSTEM_TABLE *SystemTable\r
58 )\r
ead42efc 59{\r
60 EFI_STATUS Status;\r
61\r
62 InitializePciDevicePool ();\r
63\r
64 gFullEnumeration = TRUE;\r
65\r
66 gPciHostBridgeNumber = 0;\r
67 \r
68 //\r
69 // Install driver model protocol(s).\r
70 //\r
733f03aa 71 Status = EfiLibInstallDriverBindingComponentName2 (\r
ead42efc 72 ImageHandle,\r
73 SystemTable,\r
74 &gPciBusDriverBinding,\r
75 ImageHandle,\r
76 &gPciBusComponentName,\r
733f03aa 77 &gPciBusComponentName2\r
ead42efc 78 );\r
79 ASSERT_EFI_ERROR (Status);\r
80\r
81 InstallHotPlugRequestProtocol (&Status);\r
82 \r
83 return Status;\r
84}\r
85\r
bcd70414 86/**\r
a3b8e257 87 Test to see if this driver supports ControllerHandle. Any ControllerHandle\r
88 than contains a gEfiPciRootBridgeIoProtocolGuid protocol can be supported.\r
ead42efc 89\r
a3b8e257 90 @param This Protocol instance pointer.\r
91 @param ControllerHandle Handle of device to test\r
92 @param RemainingDevicePath Optional parameter use to pick a specific child\r
93 device to start.\r
ead42efc 94\r
a3b8e257 95 @retval EFI_SUCCESS This driver supports this device\r
96 @retval EFI_ALREADY_STARTED This driver is already running on this device\r
97 @retval other This driver does not support this device\r
ead42efc 98\r
a3b8e257 99**/\r
100EFI_STATUS\r
101EFIAPI\r
102PciBusDriverBindingSupported (\r
ead42efc 103 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
104 IN EFI_HANDLE Controller,\r
105 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
a3b8e257 106 )\r
ead42efc 107{\r
108 EFI_STATUS Status;\r
109 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
110 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
111 EFI_DEV_PATH_PTR Node;\r
112\r
113 if (RemainingDevicePath != NULL) {\r
114 Node.DevPath = RemainingDevicePath;\r
115 if (Node.DevPath->Type != HARDWARE_DEVICE_PATH ||\r
116 Node.DevPath->SubType != HW_PCI_DP ||\r
117 DevicePathNodeLength(Node.DevPath) != sizeof(PCI_DEVICE_PATH)) {\r
118 return EFI_UNSUPPORTED;\r
119 }\r
120 }\r
121 //\r
122 // Open the IO Abstraction(s) needed to perform the supported test\r
123 //\r
124 Status = gBS->OpenProtocol (\r
125 Controller,\r
126 &gEfiDevicePathProtocolGuid,\r
127 (VOID **) &ParentDevicePath,\r
128 This->DriverBindingHandle,\r
129 Controller,\r
130 EFI_OPEN_PROTOCOL_BY_DRIVER\r
131 );\r
132 if (Status == EFI_ALREADY_STARTED) {\r
133 return EFI_SUCCESS;\r
134 }\r
135\r
136 if (EFI_ERROR (Status)) {\r
137 return Status;\r
138 }\r
139\r
140 gBS->CloseProtocol (\r
141 Controller,\r
142 &gEfiDevicePathProtocolGuid,\r
143 This->DriverBindingHandle,\r
144 Controller\r
145 );\r
146\r
147 Status = gBS->OpenProtocol (\r
148 Controller,\r
149 &gEfiPciRootBridgeIoProtocolGuid,\r
150 (VOID **) &PciRootBridgeIo,\r
151 This->DriverBindingHandle,\r
152 Controller,\r
153 EFI_OPEN_PROTOCOL_BY_DRIVER\r
154 );\r
155 if (Status == EFI_ALREADY_STARTED) {\r
156 return EFI_SUCCESS;\r
157 }\r
158\r
159 if (EFI_ERROR (Status)) {\r
160 return Status;\r
161 }\r
162\r
163 gBS->CloseProtocol (\r
164 Controller,\r
165 &gEfiPciRootBridgeIoProtocolGuid,\r
166 This->DriverBindingHandle,\r
167 Controller\r
168 );\r
169\r
170 return EFI_SUCCESS;\r
171}\r
172\r
bcd70414 173/**\r
a3b8e257 174 Start this driver on ControllerHandle and enumerate Pci bus and start\r
175 all device under PCI bus.\r
ead42efc 176\r
a3b8e257 177 @param This Protocol instance pointer.\r
178 @param ControllerHandle Handle of device to bind driver to\r
179 @param RemainingDevicePath Optional parameter use to pick a specific child\r
180 device to start.\r
ead42efc 181\r
a3b8e257 182 @retval EFI_SUCCESS This driver is added to ControllerHandle\r
183 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle\r
184 @retval other This driver does not support this device\r
ead42efc 185\r
a3b8e257 186**/\r
187EFI_STATUS\r
188EFIAPI\r
189PciBusDriverBindingStart (\r
ead42efc 190 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
191 IN EFI_HANDLE Controller,\r
192 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
a3b8e257 193 )\r
ead42efc 194{\r
195 EFI_STATUS Status;\r
196\r
ea5632e5 197 Status = gBS->LocateProtocol (\r
198 &gEfiIncompatiblePciDeviceSupportProtocolGuid,\r
199 NULL,\r
200 (VOID **) &gEfiIncompatiblePciDeviceSupport\r
201 );\r
202\r
ead42efc 203 //\r
204 // If PCI Platform protocol is available, get it now.\r
205 // If the platform implements this, it must be installed before BDS phase\r
206 //\r
207 gPciPlatformProtocol = NULL;\r
208 gBS->LocateProtocol (\r
209 &gEfiPciPlatformProtocolGuid,\r
210 NULL,\r
211 (VOID **) &gPciPlatformProtocol\r
212 );\r
213\r
214 gFullEnumeration = (BOOLEAN) ((SearchHostBridgeHandle (Controller) ? FALSE : TRUE));\r
215\r
216 //\r
217 // Enumerate the entire host bridge\r
218 // After enumeration, a database that records all the device information will be created\r
219 //\r
220 //\r
221 Status = PciEnumerator (Controller);\r
222\r
223 if (EFI_ERROR (Status)) {\r
224 return Status;\r
225 }\r
eb9a9a5e 226 \r
ead42efc 227 //\r
eb9a9a5e 228 // Start all the devices under the entire host bridge.\r
ead42efc 229 //\r
eb9a9a5e 230 StartPciDevices (Controller);\r
ead42efc 231\r
232 return EFI_SUCCESS;\r
233}\r
234\r
bcd70414 235/**\r
a3b8e257 236 Stop this driver on ControllerHandle. Support stoping any child handles\r
237 created by this driver.\r
ead42efc 238\r
a3b8e257 239 @param This Protocol instance pointer.\r
240 @param ControllerHandle Handle of device to stop driver on\r
241 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
242 children is zero stop the entire bus driver.\r
243 @param ChildHandleBuffer List of Child Handles to Stop.\r
ead42efc 244\r
a3b8e257 245 @retval EFI_SUCCESS This driver is removed ControllerHandle\r
246 @retval other This driver was not removed from this device\r
ead42efc 247\r
a3b8e257 248**/\r
249EFI_STATUS\r
250EFIAPI\r
251PciBusDriverBindingStop (\r
ead42efc 252 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
253 IN EFI_HANDLE Controller,\r
254 IN UINTN NumberOfChildren,\r
255 IN EFI_HANDLE *ChildHandleBuffer\r
a3b8e257 256 )\r
ead42efc 257{\r
258 EFI_STATUS Status;\r
259 UINTN Index;\r
260 BOOLEAN AllChildrenStopped;\r
261\r
262 if (NumberOfChildren == 0) {\r
263 //\r
264 // Close the bus driver\r
265 //\r
266 gBS->CloseProtocol (\r
267 Controller,\r
268 &gEfiDevicePathProtocolGuid,\r
269 This->DriverBindingHandle,\r
270 Controller\r
271 );\r
272 gBS->CloseProtocol (\r
273 Controller,\r
274 &gEfiPciRootBridgeIoProtocolGuid,\r
275 This->DriverBindingHandle,\r
276 Controller\r
277 );\r
278\r
279 DestroyRootBridgeByHandle (\r
280 Controller\r
281 );\r
282\r
283 return EFI_SUCCESS;\r
284 }\r
285\r
286 //\r
287 // Stop all the children\r
288 //\r
289\r
290 AllChildrenStopped = TRUE;\r
291\r
292 for (Index = 0; Index < NumberOfChildren; Index++) {\r
293\r
294 //\r
295 // De register all the pci device\r
296 //\r
297 Status = DeRegisterPciDevice (Controller, ChildHandleBuffer[Index]);\r
298\r
299 if (EFI_ERROR (Status)) {\r
300 AllChildrenStopped = FALSE;\r
301 }\r
302 }\r
303\r
304 if (!AllChildrenStopped) {\r
305 return EFI_DEVICE_ERROR;\r
306 }\r
307\r
308 return EFI_SUCCESS;\r
309}\r
a3b8e257 310\r