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