git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1245 6f19259b...
[mirror_edk2.git] / MdePkg / Library / UefiDriverModelLib / UefiDriverModelLib.c
CommitLineData
878ddf1f 1/** @file\r
2 EFI Driver Model Library.\r
3\r
4 Copyright (c) 2006, Intel Corporation<BR>\r
5 All rights reserved. This program and the accompanying materials \r
6 are licensed and made available under the terms and conditions of the BSD License \r
7 which accompanies this distribution. The full text of the license may be found at \r
8 http://opensource.org/licenses/bsd-license.php \r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
12\r
b059e411 13 Module Name: UefiDriverModelLib.c\r
878ddf1f 14\r
15**/\r
16\r
17\r
18\r
19/**\r
b059e411 20 The constructor function installs the standard EFI Driver Model Protocols.\r
21\r
22 @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
23 @param[in] SystemTable A pointer to the EFI System Table.\r
24 \r
25 @retval EFI_SUCCESS The constructor always return EFI_SUCCESS.\r
26\r
878ddf1f 27**/\r
28EFI_STATUS\r
29UefiDriverModelLibConstructor (\r
30 IN EFI_HANDLE ImageHandle,\r
31 IN EFI_SYSTEM_TABLE *SystemTable\r
32 )\r
33{\r
34 EFI_STATUS Status;\r
35 UINTN Index;\r
36 EFI_HANDLE DriverBindingHandle;\r
37 EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;\r
38\r
39 //\r
40 // If no Driver Binding Protocols are advertised by the driver then simply return\r
41 //\r
42 if (_gDriverModelProtocolListEntries == 0) {\r
43 return EFI_SUCCESS;\r
44 }\r
45\r
46 //\r
47 // Install the first Driver Bindng Protocol onto ImageHandle\r
48 //\r
49 DriverBindingHandle = ImageHandle;\r
50\r
51 //\r
52 // See if onle one Driver Binding Protocol is advertised by the driver\r
53 //\r
54 if (_gDriverModelProtocolListEntries == 1) {\r
55 //\r
56 // The Driver Binding Protocol must never be NULL\r
57 //\r
58 ASSERT(_gDriverModelProtocolList[0].DriverBinding != NULL);\r
59\r
60 //\r
61 // Check for all 8 possible combinations of the ComponentName, DriverConfiguration, and DriverDiagnostics Protocol\r
62 // These are all checks against const pointers, so the optimizing compiler will only select one of the \r
63 // calls to InstallMultipleProtocolInterfaces()\r
64 //\r
65 if (_gDriverModelProtocolList[0].DriverDiagnostics == NULL) {\r
66 if (_gDriverModelProtocolList[0].DriverConfiguration == NULL) {\r
67 if (_gDriverModelProtocolList[0].ComponentName == NULL) {\r
68 Status = gBS->InstallMultipleProtocolInterfaces (\r
69 &DriverBindingHandle,\r
70 &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
71 NULL\r
72 );\r
73 } else {\r
74 Status = gBS->InstallMultipleProtocolInterfaces (\r
75 &DriverBindingHandle,\r
76 &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
77 &gEfiComponentNameProtocolGuid, (EFI_COMPONENT_NAME_PROTOCOL *)_gDriverModelProtocolList[0].ComponentName,\r
78 NULL\r
79 );\r
80 }\r
81 } else {\r
82 if (_gDriverModelProtocolList[0].ComponentName == NULL) {\r
83 Status = gBS->InstallMultipleProtocolInterfaces (\r
84 &DriverBindingHandle,\r
85 &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
86 &gEfiDriverConfigurationProtocolGuid, (EFI_DRIVER_CONFIGURATION_PROTOCOL *)_gDriverModelProtocolList[0].DriverConfiguration,\r
87 NULL\r
88 );\r
89 } else {\r
90 Status = gBS->InstallMultipleProtocolInterfaces (\r
91 &DriverBindingHandle,\r
92 &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
93 &gEfiComponentNameProtocolGuid, (EFI_COMPONENT_NAME_PROTOCOL *)_gDriverModelProtocolList[0].ComponentName,\r
94 &gEfiDriverConfigurationProtocolGuid, (EFI_DRIVER_CONFIGURATION_PROTOCOL *)_gDriverModelProtocolList[0].DriverConfiguration,\r
95 NULL\r
96 );\r
97 }\r
98 }\r
99 } else {\r
100 if (_gDriverModelProtocolList[0].DriverConfiguration == NULL) {\r
101 if (_gDriverModelProtocolList[0].ComponentName == NULL) {\r
102 Status = gBS->InstallMultipleProtocolInterfaces (\r
103 &DriverBindingHandle,\r
104 &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
105 &gEfiDriverDiagnosticsProtocolGuid, (EFI_DRIVER_DIAGNOSTICS_PROTOCOL *)_gDriverModelProtocolList[0].DriverDiagnostics,\r
106 NULL\r
107 );\r
108 } else {\r
109 Status = gBS->InstallMultipleProtocolInterfaces (\r
110 &DriverBindingHandle,\r
111 &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
112 &gEfiComponentNameProtocolGuid, (EFI_COMPONENT_NAME_PROTOCOL *)_gDriverModelProtocolList[0].ComponentName,\r
113 &gEfiDriverDiagnosticsProtocolGuid, (EFI_DRIVER_DIAGNOSTICS_PROTOCOL *)_gDriverModelProtocolList[0].DriverDiagnostics,\r
114 NULL\r
115 );\r
116 }\r
117 } else {\r
118 if (_gDriverModelProtocolList[0].ComponentName == NULL) {\r
119 Status = gBS->InstallMultipleProtocolInterfaces (\r
120 &DriverBindingHandle,\r
121 &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
122 &gEfiDriverConfigurationProtocolGuid, (EFI_DRIVER_CONFIGURATION_PROTOCOL *)_gDriverModelProtocolList[0].DriverConfiguration,\r
123 &gEfiDriverDiagnosticsProtocolGuid, (EFI_DRIVER_DIAGNOSTICS_PROTOCOL *)_gDriverModelProtocolList[0].DriverDiagnostics,\r
124 NULL\r
125 );\r
126 } else {\r
127 Status = gBS->InstallMultipleProtocolInterfaces (\r
128 &DriverBindingHandle,\r
129 &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
130 &gEfiComponentNameProtocolGuid, (EFI_COMPONENT_NAME_PROTOCOL *)_gDriverModelProtocolList[0].ComponentName,\r
131 &gEfiDriverConfigurationProtocolGuid, (EFI_DRIVER_CONFIGURATION_PROTOCOL *)_gDriverModelProtocolList[0].DriverConfiguration,\r
132 &gEfiDriverDiagnosticsProtocolGuid, (EFI_DRIVER_DIAGNOSTICS_PROTOCOL *)_gDriverModelProtocolList[0].DriverDiagnostics,\r
133 NULL\r
134 );\r
135 }\r
136 }\r
137 }\r
138\r
139 //\r
140 // ASSERT if the call to InstallMultipleProtocolInterfaces() failed\r
141 //\r
142 ASSERT_EFI_ERROR (Status);\r
143\r
144 //\r
145 // Update the ImageHandle and DriverBindingHandle fields of the Driver Binding Protocol\r
146 //\r
147 DriverBinding = (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding;\r
148 DriverBinding->ImageHandle = ImageHandle;\r
149 DriverBinding->DriverBindingHandle = DriverBindingHandle;\r
150\r
151 } else {\r
152 for (Index = 0; Index < _gDriverModelProtocolListEntries; Index++) {\r
153 //\r
154 // The Driver Binding Protocol must never be NULL\r
155 //\r
156 ASSERT(_gDriverModelProtocolList[Index].DriverBinding != NULL);\r
157\r
158 //\r
159 // Install the Driver Binding Protocol and ASSERT() if the installation fails\r
160 //\r
161 Status = gBS->InstallProtocolInterface (\r
162 &DriverBindingHandle,\r
163 &gEfiDriverBindingProtocolGuid,\r
164 EFI_NATIVE_INTERFACE,\r
165 (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[Index].DriverBinding\r
166 );\r
167 ASSERT_EFI_ERROR (Status);\r
168\r
169 //\r
170 // Update the ImageHandle and DriverBindingHandle fields of the Driver Binding Protocol\r
171 //\r
172 DriverBinding = (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[Index].DriverBinding;\r
173 DriverBinding->ImageHandle = ImageHandle;\r
174 DriverBinding->DriverBindingHandle = DriverBindingHandle;\r
175\r
176 //\r
177 // If Component Name Protocol is specified then install it and ASSERT() if the installation fails\r
178 //\r
179 if ((_gDriverModelProtocolBitmask & UEFI_DRIVER_MODEL_LIBRARY_COMPONENT_NAME_PROTOCOL_ENABLED) != 0) {\r
180 if (_gDriverModelProtocolList[Index].ComponentName != NULL) {\r
181 Status = gBS->InstallProtocolInterface (\r
182 &DriverBindingHandle,\r
183 &gEfiComponentNameProtocolGuid,\r
184 EFI_NATIVE_INTERFACE,\r
185 (EFI_COMPONENT_NAME_PROTOCOL *)_gDriverModelProtocolList[Index].ComponentName\r
186 );\r
187 ASSERT_EFI_ERROR (Status);\r
188 }\r
189 }\r
190\r
191 //\r
192 // If Driver Configuration Protocol is specified then install it and ASSERT() if the installation fails\r
193 //\r
194 if ((_gDriverModelProtocolBitmask & UEFI_DRIVER_MODEL_LIBRARY_DRIVER_CONFIGURATION_PROTOCOL_ENABLED) != 0) {\r
195 if (_gDriverModelProtocolList[Index].DriverConfiguration != NULL) {\r
196 Status = gBS->InstallProtocolInterface (\r
197 &DriverBindingHandle,\r
198 &gEfiDriverConfigurationProtocolGuid,\r
199 EFI_NATIVE_INTERFACE,\r
200 (EFI_DRIVER_CONFIGURATION_PROTOCOL *)_gDriverModelProtocolList[Index].DriverConfiguration\r
201 );\r
202 ASSERT_EFI_ERROR (Status);\r
203 }\r
204 }\r
205\r
206 //\r
207 // If Driver Diagnostics Protocol is specified then install it and ASSERT() if the installation fails\r
208 //\r
209 if ((_gDriverModelProtocolBitmask & UEFI_DRIVER_MODEL_LIBRARY_DRIVER_DIAGNOSTICS_PROTOCOL_ENABLED) != 0) {\r
210 if (_gDriverModelProtocolList[Index].DriverDiagnostics != NULL) {\r
211 Status = gBS->InstallProtocolInterface (\r
212 &DriverBindingHandle,\r
213 &gEfiDriverDiagnosticsProtocolGuid,\r
214 EFI_NATIVE_INTERFACE,\r
215 (EFI_DRIVER_DIAGNOSTICS_PROTOCOL *)_gDriverModelProtocolList[Index].DriverDiagnostics\r
216 );\r
217 ASSERT_EFI_ERROR (Status);\r
218 }\r
219 }\r
220\r
221 //\r
222 // Install subsequent Driver Bindng Protocols onto new handles\r
223 //\r
224 DriverBindingHandle = NULL;\r
225 }\r
226 }\r
227 return EFI_SUCCESS;\r
228}\r
229\r
230/**\r
b059e411 231 The destructor function uninstalls the standard EFI Driver Model Protocols.\r
232\r
233 @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
234 @param[in] SystemTable A pointer to the EFI System Table.\r
235 \r
af796435 236 @retval EFI_SUCCESS The destructor always return EFI_SUCCESS.\r
b059e411 237\r
878ddf1f 238**/\r
239EFI_STATUS\r
240UefiDriverModelLibDestructor (\r
241 IN EFI_HANDLE ImageHandle,\r
242 IN EFI_SYSTEM_TABLE *SystemTable\r
243 )\r
244{\r
245 EFI_STATUS Status;\r
246 UINTN Index;\r
247 EFI_HANDLE DriverBindingHandle;\r
248\r
249 //\r
250 // If no Driver Binding Protocols are advertised by the driver then simply return\r
251 //\r
252 if (_gDriverModelProtocolListEntries == 0) {\r
253 return EFI_SUCCESS;\r
254 }\r
255\r
256 //\r
257 // See if onle one Driver Binding Protocol is advertised by the driver\r
258 //\r
259 if (_gDriverModelProtocolListEntries == 1) {\r
260 //\r
261 // The Driver Binding Protocol must never be NULL\r
262 //\r
263 ASSERT(_gDriverModelProtocolList[0].DriverBinding != NULL);\r
264\r
265 //\r
266 // Retrieve the DriverBindingHandle from the Driver Binding Protocol\r
267 //\r
268 DriverBindingHandle = _gDriverModelProtocolList[0].DriverBinding->DriverBindingHandle;\r
269\r
270 //\r
271 // Check for all 8 possible combinations of the ComponentName, DriverConfiguration, and DriverDiagnostics Protocol\r
272 // These are all checks against const pointers, so the optimizing compiler will only select one of the \r
273 // calls to InstallMultipleProtocolInterfaces()\r
274 //\r
275 if (_gDriverModelProtocolList[0].DriverDiagnostics == NULL) {\r
276 if (_gDriverModelProtocolList[0].DriverConfiguration == NULL) {\r
277 if (_gDriverModelProtocolList[0].ComponentName == NULL) {\r
278 Status = gBS->UninstallMultipleProtocolInterfaces (\r
279 DriverBindingHandle,\r
280 &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
281 NULL\r
282 );\r
283 } else {\r
284 Status = gBS->UninstallMultipleProtocolInterfaces (\r
285 &DriverBindingHandle,\r
286 &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
287 &gEfiComponentNameProtocolGuid, (EFI_COMPONENT_NAME_PROTOCOL *)_gDriverModelProtocolList[0].ComponentName,\r
288 NULL\r
289 );\r
290 }\r
291 } else {\r
292 if (_gDriverModelProtocolList[0].ComponentName == NULL) {\r
293 Status = gBS->UninstallMultipleProtocolInterfaces (\r
294 &DriverBindingHandle,\r
295 &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
296 &gEfiDriverConfigurationProtocolGuid, (EFI_DRIVER_CONFIGURATION_PROTOCOL *)_gDriverModelProtocolList[0].DriverConfiguration,\r
297 NULL\r
298 );\r
299 } else {\r
300 Status = gBS->UninstallMultipleProtocolInterfaces (\r
301 &DriverBindingHandle,\r
302 &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
303 &gEfiComponentNameProtocolGuid, (EFI_COMPONENT_NAME_PROTOCOL *)_gDriverModelProtocolList[0].ComponentName,\r
304 &gEfiDriverConfigurationProtocolGuid, (EFI_DRIVER_CONFIGURATION_PROTOCOL *)_gDriverModelProtocolList[0].DriverConfiguration,\r
305 NULL\r
306 );\r
307 }\r
308 }\r
309 } else {\r
310 if (_gDriverModelProtocolList[0].DriverConfiguration == NULL) {\r
311 if (_gDriverModelProtocolList[0].ComponentName == NULL) {\r
312 Status = gBS->UninstallMultipleProtocolInterfaces (\r
313 &DriverBindingHandle,\r
314 &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
315 &gEfiDriverDiagnosticsProtocolGuid, (EFI_DRIVER_DIAGNOSTICS_PROTOCOL *)_gDriverModelProtocolList[0].DriverDiagnostics,\r
316 NULL\r
317 );\r
318 } else {\r
319 Status = gBS->UninstallMultipleProtocolInterfaces (\r
320 &DriverBindingHandle,\r
321 &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
322 &gEfiComponentNameProtocolGuid, (EFI_COMPONENT_NAME_PROTOCOL *)_gDriverModelProtocolList[0].ComponentName,\r
323 &gEfiDriverDiagnosticsProtocolGuid, (EFI_DRIVER_DIAGNOSTICS_PROTOCOL *)_gDriverModelProtocolList[0].DriverDiagnostics,\r
324 NULL\r
325 );\r
326 }\r
327 } else {\r
328 if (_gDriverModelProtocolList[0].ComponentName == NULL) {\r
329 Status = gBS->UninstallMultipleProtocolInterfaces (\r
330 &DriverBindingHandle,\r
331 &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
332 &gEfiDriverConfigurationProtocolGuid, (EFI_DRIVER_CONFIGURATION_PROTOCOL *)_gDriverModelProtocolList[0].DriverConfiguration,\r
333 &gEfiDriverDiagnosticsProtocolGuid, (EFI_DRIVER_DIAGNOSTICS_PROTOCOL *)_gDriverModelProtocolList[0].DriverDiagnostics,\r
334 NULL\r
335 );\r
336 } else {\r
337 Status = gBS->UninstallMultipleProtocolInterfaces (\r
338 &DriverBindingHandle,\r
339 &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
340 &gEfiComponentNameProtocolGuid, (EFI_COMPONENT_NAME_PROTOCOL *)_gDriverModelProtocolList[0].ComponentName,\r
341 &gEfiDriverConfigurationProtocolGuid, (EFI_DRIVER_CONFIGURATION_PROTOCOL *)_gDriverModelProtocolList[0].DriverConfiguration,\r
342 &gEfiDriverDiagnosticsProtocolGuid, (EFI_DRIVER_DIAGNOSTICS_PROTOCOL *)_gDriverModelProtocolList[0].DriverDiagnostics,\r
343 NULL\r
344 );\r
345 }\r
346 }\r
347 }\r
348\r
349 //\r
350 // ASSERT if the call to UninstallMultipleProtocolInterfaces() failed\r
351 //\r
352 ASSERT_EFI_ERROR (Status);\r
353 } else {\r
354 for (Index = 0; Index < _gDriverModelProtocolListEntries; Index++) {\r
355 //\r
356 // The Driver Binding Protocol must never be NULL\r
357 //\r
358 ASSERT(_gDriverModelProtocolList[Index].DriverBinding != NULL);\r
359\r
360 //\r
361 // Retrieve the DriverBindingHandle from the Driver Binding Protocol\r
362 //\r
363 DriverBindingHandle = _gDriverModelProtocolList[0].DriverBinding->DriverBindingHandle;\r
364\r
365 //\r
366 // Uninstall the Driver Binding Protocol and ASSERT() if the installation fails\r
367 //\r
368 Status = gBS->UninstallProtocolInterface (\r
369 DriverBindingHandle,\r
370 &gEfiDriverBindingProtocolGuid,\r
371 (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[Index].DriverBinding\r
372 );\r
373 ASSERT_EFI_ERROR (Status);\r
374\r
375 //\r
376 // If Component Name Protocol is specified then uninstall it and ASSERT() if the uninstallation fails\r
377 //\r
378 if ((_gDriverModelProtocolBitmask & UEFI_DRIVER_MODEL_LIBRARY_COMPONENT_NAME_PROTOCOL_ENABLED) != 0) {\r
379 if (_gDriverModelProtocolList[Index].ComponentName != NULL) {\r
380 Status = gBS->UninstallProtocolInterface (\r
381 DriverBindingHandle,\r
382 &gEfiComponentNameProtocolGuid,\r
383 (EFI_COMPONENT_NAME_PROTOCOL *)_gDriverModelProtocolList[Index].ComponentName\r
384 );\r
385 ASSERT_EFI_ERROR (Status);\r
386 }\r
387 }\r
388\r
389 //\r
390 // If Driver Configuration Protocol is specified then uninstall it and ASSERT() if the uninstallation fails\r
391 //\r
392 if ((_gDriverModelProtocolBitmask & UEFI_DRIVER_MODEL_LIBRARY_DRIVER_CONFIGURATION_PROTOCOL_ENABLED) != 0) {\r
393 if (_gDriverModelProtocolList[Index].DriverConfiguration != NULL) {\r
394 Status = gBS->UninstallProtocolInterface (\r
395 DriverBindingHandle,\r
396 &gEfiDriverConfigurationProtocolGuid,\r
397 (EFI_DRIVER_CONFIGURATION_PROTOCOL *)_gDriverModelProtocolList[Index].DriverConfiguration\r
398 );\r
399 ASSERT_EFI_ERROR (Status);\r
400 }\r
401 }\r
402\r
403 //\r
404 // If Driver Diagnostics Protocol is specified then uninstall it and ASSERT() if the uninstallation fails\r
405 //\r
406 if ((_gDriverModelProtocolBitmask & UEFI_DRIVER_MODEL_LIBRARY_DRIVER_DIAGNOSTICS_PROTOCOL_ENABLED) != 0) {\r
407 if (_gDriverModelProtocolList[Index].DriverDiagnostics != NULL) {\r
408 Status = gBS->UninstallProtocolInterface (\r
409 DriverBindingHandle,\r
410 &gEfiDriverDiagnosticsProtocolGuid,\r
411 (EFI_DRIVER_DIAGNOSTICS_PROTOCOL *)_gDriverModelProtocolList[Index].DriverDiagnostics\r
412 );\r
413 ASSERT_EFI_ERROR (Status);\r
414 }\r
415 }\r
416 }\r
417 }\r
418 return EFI_SUCCESS;\r
419}\r