1 /*++ 2 3 Copyright (c) 2005 - 2006, Intel Corporation. All rights reserved.<BR> 4 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 UINT64 gAllOne = 0xFFFFFFFFFFFFFFFFULL; 79 UINT64 gAllZero = 0; 80 81 // 82 // PCI Bus Driver Support Functions 83 // 84 EFI_STATUS 85 EFIAPI 86 PciBusEntryPoint ( 87 IN EFI_HANDLE ImageHandle, 88 IN EFI_SYSTEM_TABLE *SystemTable 89 ) 90 /*++ 91 92 Routine Description: 93 94 Initialize the global variables 95 publish the driver binding protocol 96 97 Arguments: 98 99 IN EFI_HANDLE ImageHandle, 100 IN EFI_SYSTEM_TABLE *SystemTable 101 102 Returns: 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 131 EFI_STATUS 132 EFIAPI 133 PciBusDriverBindingSupported ( 134 IN EFI_DRIVER_BINDING_PROTOCOL *This, 135 IN EFI_HANDLE Controller, 136 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath 137 ) 138 /*++ 139 140 Routine Description: 141 142 Check to see if pci bus driver supports the given controller 143 144 Arguments: 145 146 IN EFI_DRIVER_BINDING_PROTOCOL *This, 147 IN EFI_HANDLE Controller, 148 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath 149 150 Returns: 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 221 EFI_STATUS 222 EFIAPI 223 PciBusDriverBindingStart ( 224 IN EFI_DRIVER_BINDING_PROTOCOL *This, 225 IN EFI_HANDLE Controller, 226 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath 227 ) 228 /*++ 229 230 Routine Description: 231 232 Start to management the controller passed in 233 234 Arguments: 235 236 IN EFI_DRIVER_BINDING_PROTOCOL *This, 237 IN EFI_HANDLE Controller, 238 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath 239 240 Returns: 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 268 EFI_STATUS 269 EFIAPI 270 PciBusDriverBindingStop ( 271 IN EFI_DRIVER_BINDING_PROTOCOL *This, 272 IN EFI_HANDLE Controller, 273 IN UINTN NumberOfChildren, 274 IN EFI_HANDLE *ChildHandleBuffer 275 ) 276 /*++ 277 278 Routine 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 283 Arguments: 284 285 IN EFI_DRIVER_BINDING_PROTOCOL *This, 286 IN EFI_HANDLE Controller, 287 IN UINTN NumberOfChildren, 288 IN EFI_HANDLE *ChildHandleBuffer 289 290 Returns: 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