Home | History | Annotate | Download | only in PciBusNoEnumerationDxe
      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