Home | History | Annotate | Download | only in PciBusDxe
      1 /** @file
      2   Functions implementation for Bus Specific Driver Override protoocl.
      3 
      4 Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
      5 This program and the accompanying materials
      6 are licensed and made available under the terms and conditions of the BSD License
      7 which accompanies this distribution.  The full text of the license may be found at
      8 http://opensource.org/licenses/bsd-license.php
      9 
     10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include "PciBus.h"
     16 
     17 /**
     18   Initializes a PCI Driver Override Instance.
     19 
     20   @param  PciIoDevice   PCI Device instance.
     21 
     22 **/
     23 VOID
     24 InitializePciDriverOverrideInstance (
     25   IN OUT PCI_IO_DEVICE          *PciIoDevice
     26   )
     27 {
     28   PciIoDevice->PciDriverOverride.GetDriver = GetDriver;
     29 }
     30 
     31 
     32 /**
     33   Uses a bus specific algorithm to retrieve a driver image handle for a controller.
     34 
     35   @param  This                  A pointer to the EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL instance.
     36   @param  DriverImageHandle     On input, a pointer to the previous driver image handle returned
     37                                 by GetDriver(). On output, a pointer to the next driver
     38                                 image handle. Passing in a NULL, will return the first driver
     39                                 image handle.
     40 
     41   @retval EFI_SUCCESS           A bus specific override driver is returned in DriverImageHandle.
     42   @retval EFI_NOT_FOUND         The end of the list of override drivers was reached.
     43                                 A bus specific override driver is not returned in DriverImageHandle.
     44   @retval EFI_INVALID_PARAMETER DriverImageHandle is not a handle that was returned on a
     45                                 previous call to GetDriver().
     46 
     47 **/
     48 EFI_STATUS
     49 EFIAPI
     50 GetDriver (
     51   IN EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL              *This,
     52   IN OUT EFI_HANDLE                                         *DriverImageHandle
     53   )
     54 {
     55   PCI_IO_DEVICE             *PciIoDevice;
     56   LIST_ENTRY                *CurrentLink;
     57   PCI_DRIVER_OVERRIDE_LIST  *Node;
     58 
     59   PciIoDevice = PCI_IO_DEVICE_FROM_PCI_DRIVER_OVERRIDE_THIS (This);
     60 
     61   CurrentLink = PciIoDevice->OptionRomDriverList.ForwardLink;
     62 
     63   while (CurrentLink != NULL && CurrentLink != &PciIoDevice->OptionRomDriverList) {
     64 
     65     Node = DRIVER_OVERRIDE_FROM_LINK (CurrentLink);
     66 
     67     if (*DriverImageHandle == NULL) {
     68 
     69       *DriverImageHandle = Node->DriverImageHandle;
     70       return EFI_SUCCESS;
     71     }
     72 
     73     if (*DriverImageHandle == Node->DriverImageHandle) {
     74 
     75       if (CurrentLink->ForwardLink == &PciIoDevice->OptionRomDriverList ||
     76           CurrentLink->ForwardLink == NULL) {
     77         return EFI_NOT_FOUND;
     78       }
     79 
     80       //
     81       // Get next node
     82       //
     83       Node                = DRIVER_OVERRIDE_FROM_LINK (CurrentLink->ForwardLink);
     84       *DriverImageHandle  = Node->DriverImageHandle;
     85       return EFI_SUCCESS;
     86     }
     87 
     88     CurrentLink = CurrentLink->ForwardLink;
     89   }
     90 
     91   return EFI_INVALID_PARAMETER;
     92 }
     93 
     94 /**
     95   Add an overriding driver image.
     96 
     97   @param PciIoDevice        Instance of PciIo device.
     98   @param DriverImageHandle  new added driver image.
     99 
    100   @retval EFI_SUCCESS          Successfully added driver.
    101   @retval EFI_OUT_OF_RESOURCES No memory resource for new driver instance.
    102   @retval other                Some error occurred when locating gEfiLoadedImageProtocolGuid.
    103 
    104 **/
    105 EFI_STATUS
    106 AddDriver (
    107   IN PCI_IO_DEVICE     *PciIoDevice,
    108   IN EFI_HANDLE        DriverImageHandle
    109   )
    110 {
    111   EFI_STATUS                    Status;
    112   EFI_LOADED_IMAGE_PROTOCOL     *LoadedImage;
    113   PE_COFF_LOADER_IMAGE_CONTEXT  ImageContext;
    114   PCI_DRIVER_OVERRIDE_LIST      *Node;
    115 
    116   Status = gBS->HandleProtocol (DriverImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage);
    117   if (EFI_ERROR (Status)) {
    118     return Status;
    119   }
    120 
    121   Node = AllocatePool (sizeof (PCI_DRIVER_OVERRIDE_LIST));
    122   if (Node == NULL) {
    123     return EFI_OUT_OF_RESOURCES;
    124   }
    125 
    126   Node->Signature         = DRIVER_OVERRIDE_SIGNATURE;
    127   Node->DriverImageHandle = DriverImageHandle;
    128 
    129   InsertTailList (&PciIoDevice->OptionRomDriverList, &(Node->Link));
    130 
    131   PciIoDevice->BusOverride  = TRUE;
    132 
    133   ImageContext.Handle    = LoadedImage->ImageBase;
    134   ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
    135 
    136   //
    137   // Get information about the image
    138   //
    139   PeCoffLoaderGetImageInfo (&ImageContext);
    140 
    141   return EFI_SUCCESS;
    142 }
    143 
    144