]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Pci/PciBusDxe/PciDriverOverride.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / PciBusDxe / PciDriverOverride.c
CommitLineData
9060e3ec 1/** @file\r
fcdfcdbf 2 Functions implementation for Bus Specific Driver Override protocol.\r
9060e3ec 3\r
fcdfcdbf 4Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
9d510e61 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
9060e3ec 6\r
7**/\r
8\r
9#include "PciBus.h"\r
10\r
11/**\r
12 Initializes a PCI Driver Override Instance.\r
13\r
14 @param PciIoDevice PCI Device instance.\r
15\r
16**/\r
17VOID\r
18InitializePciDriverOverrideInstance (\r
19 IN OUT PCI_IO_DEVICE *PciIoDevice\r
20 )\r
21{\r
22 PciIoDevice->PciDriverOverride.GetDriver = GetDriver;\r
23}\r
24\r
b5cbef4e
RN
25/**\r
26 Find the image handle whose path equals to ImagePath.\r
27\r
28 @param ImagePath Image path.\r
29\r
30 @return Image handle.\r
31**/\r
32EFI_HANDLE\r
33LocateImageHandle (\r
34 IN EFI_DEVICE_PATH_PROTOCOL *ImagePath\r
35 )\r
36{\r
37 EFI_STATUS Status;\r
38 EFI_HANDLE *Handles;\r
39 UINTN Index;\r
40 UINTN HandleNum;\r
41 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
42 UINTN ImagePathSize;\r
43 EFI_HANDLE ImageHandle;\r
44\r
45 Status = gBS->LocateHandleBuffer (\r
46 ByProtocol,\r
47 &gEfiLoadedImageDevicePathProtocolGuid,\r
48 NULL,\r
49 &HandleNum,\r
50 &Handles\r
51 );\r
52 if (EFI_ERROR (Status)) {\r
53 return NULL;\r
54 }\r
55\r
56 ImageHandle = NULL;\r
57 ImagePathSize = GetDevicePathSize (ImagePath);\r
58\r
59 for (Index = 0; Index < HandleNum; Index++) {\r
60 Status = gBS->HandleProtocol (Handles[Index], &gEfiLoadedImageDevicePathProtocolGuid, (VOID **) &DevicePath);\r
61 if (EFI_ERROR (Status)) {\r
62 continue;\r
63 }\r
64 if ((ImagePathSize == GetDevicePathSize (DevicePath)) &&\r
65 (CompareMem (ImagePath, DevicePath, ImagePathSize) == 0)\r
66 ) {\r
67 ImageHandle = Handles[Index];\r
68 break;\r
69 }\r
70 }\r
71\r
72 FreePool (Handles);\r
73 return ImageHandle;\r
74}\r
9060e3ec 75\r
76/**\r
77 Uses a bus specific algorithm to retrieve a driver image handle for a controller.\r
78\r
79 @param This A pointer to the EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL instance.\r
80 @param DriverImageHandle On input, a pointer to the previous driver image handle returned\r
81 by GetDriver(). On output, a pointer to the next driver\r
82 image handle. Passing in a NULL, will return the first driver\r
83 image handle.\r
84\r
85 @retval EFI_SUCCESS A bus specific override driver is returned in DriverImageHandle.\r
86 @retval EFI_NOT_FOUND The end of the list of override drivers was reached.\r
87 A bus specific override driver is not returned in DriverImageHandle.\r
88 @retval EFI_INVALID_PARAMETER DriverImageHandle is not a handle that was returned on a\r
89 previous call to GetDriver().\r
90\r
91**/\r
92EFI_STATUS\r
93EFIAPI\r
94GetDriver (\r
95 IN EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *This,\r
96 IN OUT EFI_HANDLE *DriverImageHandle\r
97 )\r
98{\r
99 PCI_IO_DEVICE *PciIoDevice;\r
b5cbef4e
RN
100 LIST_ENTRY *Link;\r
101 PCI_DRIVER_OVERRIDE_LIST *Override;\r
102 BOOLEAN ReturnNext;\r
9060e3ec 103\r
b5cbef4e 104 Override = NULL;\r
9060e3ec 105 PciIoDevice = PCI_IO_DEVICE_FROM_PCI_DRIVER_OVERRIDE_THIS (This);\r
b5cbef4e
RN
106 ReturnNext = (BOOLEAN) (*DriverImageHandle == NULL);\r
107 for ( Link = GetFirstNode (&PciIoDevice->OptionRomDriverList)\r
108 ; !IsNull (&PciIoDevice->OptionRomDriverList, Link)\r
109 ; Link = GetNextNode (&PciIoDevice->OptionRomDriverList, Link)\r
110 ) {\r
9060e3ec 111\r
b5cbef4e 112 Override = DRIVER_OVERRIDE_FROM_LINK (Link);\r
9060e3ec 113\r
b5cbef4e
RN
114 if (ReturnNext) {\r
115 if (Override->DriverImageHandle == NULL) {\r
116 Override->DriverImageHandle = LocateImageHandle (Override->DriverImagePath);\r
9060e3ec 117 }\r
118\r
b5cbef4e
RN
119 if (Override->DriverImageHandle == NULL) {\r
120 //\r
121 // The Option ROM identified by Override->DriverImagePath is not loaded.\r
122 //\r
123 continue;\r
124 } else {\r
125 *DriverImageHandle = Override->DriverImageHandle;\r
126 return EFI_SUCCESS;\r
127 }\r
9060e3ec 128 }\r
129\r
b5cbef4e
RN
130 if (*DriverImageHandle == Override->DriverImageHandle) {\r
131 ReturnNext = TRUE;\r
132 }\r
9060e3ec 133 }\r
134\r
b5cbef4e
RN
135 ASSERT (IsNull (&PciIoDevice->OptionRomDriverList, Link));\r
136 //\r
137 // ReturnNext indicates a handle match happens.\r
138 // If all nodes are checked without handle match happening,\r
139 // the DriverImageHandle should be a invalid handle.\r
140 //\r
141 if (ReturnNext) {\r
142 return EFI_NOT_FOUND;\r
143 } else {\r
144 return EFI_INVALID_PARAMETER;\r
145 }\r
9060e3ec 146}\r
147\r
148/**\r
149 Add an overriding driver image.\r
150\r
151 @param PciIoDevice Instance of PciIo device.\r
b5cbef4e
RN
152 @param DriverImageHandle Image handle of newly added driver image.\r
153 @param DriverImagePath Device path of newly added driver image.\r
9060e3ec 154\r
155 @retval EFI_SUCCESS Successfully added driver.\r
156 @retval EFI_OUT_OF_RESOURCES No memory resource for new driver instance.\r
157 @retval other Some error occurred when locating gEfiLoadedImageProtocolGuid.\r
158\r
159**/\r
160EFI_STATUS\r
161AddDriver (\r
b5cbef4e
RN
162 IN PCI_IO_DEVICE *PciIoDevice,\r
163 IN EFI_HANDLE DriverImageHandle,\r
164 IN EFI_DEVICE_PATH_PROTOCOL *DriverImagePath\r
9060e3ec 165 )\r
166{\r
9060e3ec 167 PCI_DRIVER_OVERRIDE_LIST *Node;\r
168\r
b5cbef4e
RN
169 //\r
170 // Caller should pass in either Image Handle or Image Path, but not both.\r
171 //\r
172 ASSERT ((DriverImageHandle == NULL) || (DriverImagePath == NULL));\r
9060e3ec 173\r
b5cbef4e 174 Node = AllocateZeroPool (sizeof (PCI_DRIVER_OVERRIDE_LIST));\r
9060e3ec 175 if (Node == NULL) {\r
176 return EFI_OUT_OF_RESOURCES;\r
177 }\r
178\r
179 Node->Signature = DRIVER_OVERRIDE_SIGNATURE;\r
180 Node->DriverImageHandle = DriverImageHandle;\r
b5cbef4e 181 Node->DriverImagePath = DuplicateDevicePath (DriverImagePath);\r
9060e3ec 182\r
b5cbef4e 183 InsertTailList (&PciIoDevice->OptionRomDriverList, &Node->Link);\r
9060e3ec 184\r
185 PciIoDevice->BusOverride = TRUE;\r
9060e3ec 186 return EFI_SUCCESS;\r
187}\r
188\r