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