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