]> git.proxmox.com Git - mirror_edk2.git/blame - RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.c
RedfishPkg/RedfishConfigHandler: EDKII RedfishConfigHandler Protocol
[mirror_edk2.git] / RedfishPkg / RedfishConfigHandler / RedfishConfigHandlerDriver.c
CommitLineData
2072c22a
AC
1/** @file\r
2 The UEFI driver model driver which is responsible for locating the\r
3 Redfish service through Redfish host interface and executing EDKII\r
4 Redfish feature drivers.\r
5\r
6 Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>\r
7 (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>\r
8\r
9 SPDX-License-Identifier: BSD-2-Clause-Patent\r
10\r
11**/\r
12\r
13#include "RedfishConfigHandlerDriver.h"\r
14\r
15EFI_EVENT gEfiRedfishDiscoverProtocolEvent = NULL;\r
16\r
17//\r
18// Variables for using RFI Redfish Discover Protocol\r
19//\r
20VOID *gEfiRedfishDiscoverRegistration;\r
21EFI_HANDLE gEfiRedfishDiscoverControllerHandle = NULL;\r
22EFI_REDFISH_DISCOVER_PROTOCOL *gEfiRedfishDiscoverProtocol = NULL;\r
23BOOLEAN gRedfishDiscoverActivated = FALSE;\r
24BOOLEAN gRedfishServiceDiscovered = FALSE;\r
25//\r
26// Network interfaces discovered by EFI Redfish Discover Protocol.\r
27//\r
28UINTN gNumberOfNetworkInterfaces;\r
29EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *gNetworkInterfaceInstances = NULL;\r
30EFI_REDFISH_DISCOVERED_TOKEN *gRedfishDiscoveredToken = NULL;\r
31\r
32///\r
33/// Driver Binding Protocol instance\r
34///\r
35EFI_DRIVER_BINDING_PROTOCOL gRedfishConfigDriverBinding = {\r
36 RedfishConfigDriverBindingSupported,\r
37 RedfishConfigDriverBindingStart,\r
38 RedfishConfigDriverBindingStop,\r
39 REDFISH_CONFIG_VERSION,\r
40 NULL,\r
41 NULL\r
42};\r
43\r
44/**\r
45 Stop acquiring Redfish service.\r
46\r
47**/\r
48VOID\r
49RedfishConfigStopRedfishDiscovery (\r
50 VOID\r
51)\r
52{\r
53 if (gRedfishDiscoverActivated) {\r
54 //\r
55 // No more EFI Discover Protocol.\r
56 //\r
57 if (gEfiRedfishDiscoverProtocolEvent != NULL) {\r
58 gBS->CloseEvent (gEfiRedfishDiscoverProtocolEvent);\r
59 }\r
60 //\r
61 // Stop Redfish service discovery.\r
62 //\r
63 gEfiRedfishDiscoverProtocol->AbortAcquireRedfishService (\r
64 gEfiRedfishDiscoverProtocol,\r
65 gNetworkInterfaceInstances\r
66 );\r
67 gEfiRedfishDiscoverControllerHandle = NULL;\r
68 gEfiRedfishDiscoverProtocol = NULL;\r
69 gRedfishDiscoverActivated = FALSE;\r
70 gRedfishServiceDiscovered = FALSE;\r
71 }\r
72}\r
73\r
74/**\r
75 Callback function executed when a Redfish Config Handler Protocol is installed.\r
76\r
77 @param[in] Event Event whose notification function is being invoked.\r
78 @param[in] Context Pointer to the REDFISH_CONFIG_DRIVER_DATA buffer.\r
79\r
80**/\r
81VOID\r
82EFIAPI\r
83RedfishConfigHandlerInstalledCallback (\r
84 IN EFI_EVENT Event,\r
85 IN VOID *Context\r
86 )\r
87{\r
88 if (!gRedfishDiscoverActivated) {\r
89 //\r
90 // No Redfish service is discovered yet.\r
91 //\r
92 return;\r
93 }\r
94\r
95 RedfishConfigHandlerInitialization ();\r
96}\r
97\r
98/**\r
99 Tests to see if this driver supports a given controller. If a child device is provided,\r
100 it further tests to see if this driver supports creating a handle for the specified child device.\r
101\r
102 This function checks to see if the driver specified by This supports the device specified by\r
103 ControllerHandle. Drivers will typically use the device path attached to\r
104 ControllerHandle and/or the services from the bus I/O abstraction attached to\r
105 ControllerHandle to determine if the driver supports ControllerHandle. This function\r
106 may be called many times during platform initialization. In order to reduce boot times, the tests\r
107 performed by this function must be very small, and take as little time as possible to execute. This\r
108 function must not change the state of any hardware devices, and this function must be aware that the\r
109 device specified by ControllerHandle may already be managed by the same driver or a\r
110 different driver. This function must match its calls to AllocatePages() with FreePages(),\r
111 AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().\r
112 Because ControllerHandle may have been previously started by the same driver, if a protocol is\r
113 already in the opened state, then it must not be closed with CloseProtocol(). This is required\r
114 to guarantee the state of ControllerHandle is not modified by this function.\r
115\r
116 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
117 @param[in] ControllerHandle The handle of the controller to test. This handle\r
118 must support a protocol interface that supplies\r
119 an I/O abstraction to the driver.\r
120 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This\r
121 parameter is ignored by device drivers, and is optional for bus\r
122 drivers. For bus drivers, if this parameter is not NULL, then\r
123 the bus driver must determine if the bus controller specified\r
124 by ControllerHandle and the child controller specified\r
125 by RemainingDevicePath are both supported by this\r
126 bus driver.\r
127\r
128 @retval EFI_SUCCESS The device specified by ControllerHandle and\r
129 RemainingDevicePath is supported by the driver specified by This.\r
130 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and\r
131 RemainingDevicePath is not supported by the driver specified by This.\r
132**/\r
133EFI_STATUS\r
134EFIAPI\r
135RedfishConfigDriverBindingSupported (\r
136 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
137 IN EFI_HANDLE ControllerHandle,\r
138 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
139 )\r
140{\r
141 EFI_REST_EX_PROTOCOL *RestEx;\r
142 EFI_STATUS Status;\r
143 EFI_HANDLE ChildHandle;\r
144\r
145 ChildHandle = NULL;\r
146\r
147 //\r
148 // Check if REST EX is ready. This just makes sure\r
149 // the network stack is brought up.\r
150 //\r
151 Status = NetLibCreateServiceChild (\r
152 ControllerHandle,\r
153 This->ImageHandle,\r
154 &gEfiRestExServiceBindingProtocolGuid,\r
155 &ChildHandle\r
156 );\r
157 if (EFI_ERROR (Status)) {\r
158 return EFI_UNSUPPORTED;\r
159 }\r
160\r
161 //\r
162 // Test if REST EX protocol is ready.\r
163 //\r
164 Status = gBS->OpenProtocol(\r
165 ChildHandle,\r
166 &gEfiRestExProtocolGuid,\r
167 (VOID**) &RestEx,\r
168 This->DriverBindingHandle,\r
169 ControllerHandle,\r
170 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
171 );\r
172 if (EFI_ERROR (Status)) {\r
173 Status = EFI_UNSUPPORTED;\r
174 }\r
175 NetLibDestroyServiceChild (\r
176 ControllerHandle,\r
177 This->ImageHandle,\r
178 &gEfiRestExServiceBindingProtocolGuid,\r
179 ChildHandle\r
180 );\r
181 return Status;\r
182}\r
183\r
184/**\r
185 Starts a device controller or a bus controller.\r
186\r
187 The Start() function is designed to be invoked from the EFI boot service ConnectController().\r
188 As a result, much of the error checking on the parameters to Start() has been moved into this\r
189 common boot service. It is legal to call Start() from other locations,\r
190 but the following calling restrictions must be followed, or the system behavior will not be deterministic.\r
191 1. ControllerHandle must be a valid EFI_HANDLE.\r
192 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned\r
193 EFI_DEVICE_PATH_PROTOCOL.\r
194 3. Prior to calling Start(), the Supported() function for the driver specified by This must\r
195 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.\r
196\r
197 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
198 @param[in] ControllerHandle The handle of the controller to start. This handle\r
199 must support a protocol interface that supplies\r
200 an I/O abstraction to the driver.\r
201 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This\r
202 parameter is ignored by device drivers, and is optional for bus\r
203 drivers. For a bus driver, if this parameter is NULL, then handles\r
204 for all the children of Controller are created by this driver.\r
205 If this parameter is not NULL and the first Device Path Node is\r
206 not the End of Device Path Node, then only the handle for the\r
207 child device specified by the first Device Path Node of\r
208 RemainingDevicePath is created by this driver.\r
209 If the first Device Path Node of RemainingDevicePath is\r
210 the End of Device Path Node, no child handle is created by this\r
211 driver.\r
212\r
213 @retval EFI_SUCCESS The driver is started.\r
214 @retval EFI_ALREADY_STARTED The driver was already started.\r
215\r
216**/\r
217EFI_STATUS\r
218EFIAPI\r
219RedfishConfigDriverBindingStart (\r
220 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
221 IN EFI_HANDLE ControllerHandle,\r
222 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
223 )\r
224{\r
225 VOID *ConfigHandlerRegistration;\r
226\r
227 if (gRedfishConfigData.Event != NULL) {\r
228 return EFI_ALREADY_STARTED;\r
229 }\r
230\r
231 gRedfishConfigData.Event = EfiCreateProtocolNotifyEvent (\r
232 &gEdkIIRedfishConfigHandlerProtocolGuid,\r
233 TPL_CALLBACK,\r
234 RedfishConfigHandlerInstalledCallback,\r
235 (VOID *)&gRedfishConfigData,\r
236 &ConfigHandlerRegistration\r
237 );\r
238 return EFI_SUCCESS;\r
239}\r
240\r
241/**\r
242 Stops a device controller or a bus controller.\r
243\r
244 The Stop() function is designed to be invoked from the EFI boot service DisconnectController().\r
245 As a result, much of the error checking on the parameters to Stop() has been moved\r
246 into this common boot service. It is legal to call Stop() from other locations,\r
247 but the following calling restrictions must be followed, or the system behavior will not be deterministic.\r
248 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this\r
249 same driver's Start() function.\r
250 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid\r
251 EFI_HANDLE. In addition, all of these handles must have been created in this driver's\r
252 Start() function, and the Start() function must have called OpenProtocol() on\r
253 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.\r
254\r
255 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
256 @param[in] ControllerHandle A handle to the device being stopped. The handle must\r
257 support a bus specific I/O protocol for the driver\r
258 to use to stop the device.\r
259 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.\r
260 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL\r
261 if NumberOfChildren is 0.\r
262\r
263 @retval EFI_SUCCESS The device was stopped.\r
264 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.\r
265\r
266**/\r
267EFI_STATUS\r
268EFIAPI\r
269RedfishConfigDriverBindingStop (\r
270 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
271 IN EFI_HANDLE ControllerHandle,\r
272 IN UINTN NumberOfChildren,\r
273 IN EFI_HANDLE *ChildHandleBuffer OPTIONAL\r
274 )\r
275{\r
276 EFI_STATUS Status;\r
277\r
278 if (ControllerHandle == gEfiRedfishDiscoverControllerHandle) {\r
279 RedfishConfigStopRedfishDiscovery ();\r
280 }\r
281 gBS->CloseProtocol (\r
282 ControllerHandle,\r
283 &gEfiRedfishDiscoverProtocolGuid,\r
284 gRedfishConfigData.Image,\r
285 gRedfishConfigData.Image\r
286 );\r
287\r
288 Status = RedfishConfigCommonStop ();\r
289 if (EFI_ERROR (Status)) {\r
290 return EFI_DEVICE_ERROR;\r
291 }\r
292\r
293 if (gRedfishConfigData.Event != NULL) {\r
294 gBS->CloseEvent (gRedfishConfigData.Event);\r
295 gRedfishConfigData.Event = NULL;\r
296 }\r
297 return EFI_SUCCESS;\r
298}\r
299\r
300/**\r
301 Callback function when Redfish service is discovered.\r
302\r
303 @param[in] Event Event whose notification function is being invoked.\r
304 @param[out] Context Pointer to the Context buffer\r
305\r
306**/\r
307VOID\r
308EFIAPI\r
309RedfishServiceDiscoveredCallback (\r
310 IN EFI_EVENT Event,\r
311 OUT VOID *Context\r
312 )\r
313{\r
314 EFI_REDFISH_DISCOVERED_TOKEN *RedfishDiscoveredToken;\r
315 EFI_REDFISH_DISCOVERED_INSTANCE *RedfishInstance;\r
316\r
317 if (gRedfishServiceDiscovered) {\r
318 //\r
319 // Only support one Redfish service on platform.\r
320 //\r
321 return;\r
322 }\r
323\r
324 RedfishDiscoveredToken = (EFI_REDFISH_DISCOVERED_TOKEN *)Context;\r
325 RedfishInstance = RedfishDiscoveredToken->DiscoverList.RedfishInstances;\r
326 //\r
327 // Only pick up the first found Redfish service.\r
328 //\r
329 if (RedfishInstance->Status == EFI_SUCCESS) {\r
330 gRedfishConfigData.RedfishServiceInfo.RedfishServiceRestExHandle = RedfishInstance->Information.RedfishRestExHandle;\r
331 gRedfishConfigData.RedfishServiceInfo.RedfishServiceVersion = RedfishInstance->Information.RedfishVersion;\r
332 gRedfishConfigData.RedfishServiceInfo.RedfishServiceLocation = RedfishInstance->Information.Location;\r
333 gRedfishConfigData.RedfishServiceInfo.RedfishServiceUuid = RedfishInstance->Information.Uuid;\r
334 gRedfishConfigData.RedfishServiceInfo.RedfishServiceOs = RedfishInstance->Information.Os;\r
335 gRedfishConfigData.RedfishServiceInfo.RedfishServiceOsVersion = RedfishInstance->Information.OsVersion;\r
336 gRedfishConfigData.RedfishServiceInfo.RedfishServiceProduct = RedfishInstance->Information.Product;\r
337 gRedfishConfigData.RedfishServiceInfo.RedfishServiceProductVer = RedfishInstance->Information.ProductVer;\r
338 gRedfishConfigData.RedfishServiceInfo.RedfishServiceUseHttps = RedfishInstance->Information.UseHttps;\r
339 gRedfishServiceDiscovered = TRUE;\r
340 }\r
341\r
342 //\r
343 // Invoke RedfishConfigHandlerInstalledCallback to execute\r
344 // the initialization of Redfish Configure Handler instance.\r
345 //\r
346 RedfishConfigHandlerInstalledCallback (gRedfishConfigData.Event, &gRedfishConfigData);\r
347}\r
348\r
349/**\r
350 Callback function executed when the EFI_REDFISH_DISCOVER_PROTOCOL\r
351 protocol interface is installed.\r
352\r
353 @param[in] Event Event whose notification function is being invoked.\r
354 @param[out] Context Pointer to the Context buffer\r
355\r
356**/\r
357VOID\r
358EFIAPI\r
359RedfishDiscoverProtocolInstalled (\r
360 IN EFI_EVENT Event,\r
361 OUT VOID *Context\r
362 )\r
363{\r
364 EFI_STATUS Status;\r
365 UINTN BufferSize;\r
366 EFI_HANDLE HandleBuffer;\r
367 UINTN NetworkInterfaceIndex;\r
368 EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *ThisNetworkInterface;\r
369 EFI_REDFISH_DISCOVERED_TOKEN *ThisRedfishDiscoveredToken;\r
370\r
371 DEBUG((DEBUG_INFO, "%a: New network interface is installed on system by EFI Redfish discover driver.\n", __FUNCTION__));\r
372\r
373 BufferSize = sizeof (EFI_HANDLE);\r
374 Status = gBS->LocateHandle (\r
375 ByRegisterNotify,\r
376 NULL,\r
377 gEfiRedfishDiscoverRegistration,\r
378 &BufferSize,\r
379 &HandleBuffer\r
380 );\r
381 if (EFI_ERROR (Status)) {\r
382 DEBUG((DEBUG_ERROR, "%a: Can't locate handle with EFI_REDFISH_DISCOVER_PROTOCOL installed.\n", __FUNCTION__));\r
383 }\r
384 gRedfishDiscoverActivated = TRUE;\r
385 if (gEfiRedfishDiscoverProtocol == NULL) {\r
386 gEfiRedfishDiscoverControllerHandle = HandleBuffer;\r
387 //\r
388 // First time to open EFI_REDFISH_DISCOVER_PROTOCOL.\r
389 //\r
390 Status = gBS->OpenProtocol(\r
391 gEfiRedfishDiscoverControllerHandle,\r
392 &gEfiRedfishDiscoverProtocolGuid,\r
393 (VOID **)&gEfiRedfishDiscoverProtocol,\r
394 gRedfishConfigData.Image,\r
395 gRedfishConfigData.Image,\r
396 EFI_OPEN_PROTOCOL_BY_DRIVER\r
397 );\r
398 if (EFI_ERROR (Status)) {\r
399 gEfiRedfishDiscoverProtocol = NULL;\r
400 gRedfishDiscoverActivated = FALSE;\r
401 DEBUG((DEBUG_ERROR, "%a: Can't locate EFI_REDFISH_DISCOVER_PROTOCOL.\n", __FUNCTION__));\r
402 return;\r
403 }\r
404 }\r
405 //\r
406 // Check the new found network interface.\r
407 //\r
408 if (gNetworkInterfaceInstances != NULL) {\r
409 FreePool (gNetworkInterfaceInstances);\r
410 }\r
411 Status = gEfiRedfishDiscoverProtocol->GetNetworkInterfaceList(\r
412 gEfiRedfishDiscoverProtocol,\r
413 gRedfishConfigData.Image,\r
414 &gNumberOfNetworkInterfaces,\r
415 &gNetworkInterfaceInstances\r
416 );\r
417 if (EFI_ERROR (Status) || gNumberOfNetworkInterfaces == 0) {\r
418 DEBUG((DEBUG_ERROR, "%a: No network interfaces found on the handle.\n", __FUNCTION__));\r
419 return;\r
420 }\r
421\r
422 gRedfishDiscoveredToken = AllocateZeroPool (gNumberOfNetworkInterfaces * sizeof (EFI_REDFISH_DISCOVERED_TOKEN));\r
423 if (gRedfishDiscoveredToken == NULL) {\r
424 DEBUG((DEBUG_ERROR, "%a: Not enough memory for EFI_REDFISH_DISCOVERED_TOKEN.\n", __FUNCTION__));\r
425 return;\r
426 }\r
427\r
428 ThisNetworkInterface = gNetworkInterfaceInstances;\r
429 ThisRedfishDiscoveredToken = gRedfishDiscoveredToken;\r
430 //\r
431 // Loop to discover Redfish service on each network interface.\r
432 //\r
433 for (NetworkInterfaceIndex = 0; NetworkInterfaceIndex < gNumberOfNetworkInterfaces; NetworkInterfaceIndex ++) {\r
434 //\r
435 // Initial this Redfish Discovered Token\r
436 //\r
437 Status = gBS->CreateEvent (\r
438 EVT_NOTIFY_SIGNAL,\r
439 TPL_CALLBACK,\r
440 RedfishServiceDiscoveredCallback,\r
441 (VOID *)ThisRedfishDiscoveredToken,\r
442 &ThisRedfishDiscoveredToken->Event\r
443 );\r
444 if (EFI_ERROR (Status)) {\r
445 DEBUG((DEBUG_ERROR, "%a: Failed to create event for Redfish discovered token.\n", __FUNCTION__));\r
446 goto ErrorReturn;\r
447 }\r
448 ThisRedfishDiscoveredToken->Signature = REDFISH_DISCOVER_TOKEN_SIGNATURE;\r
449 ThisRedfishDiscoveredToken->DiscoverList.NumberOfServiceFound = 0;\r
450 ThisRedfishDiscoveredToken->DiscoverList.RedfishInstances = NULL;\r
451 //\r
452 // Acquire for Redfish service which is reported by\r
453 // Redfish Host Interface.\r
454 //\r
455 Status = gEfiRedfishDiscoverProtocol->AcquireRedfishService(\r
456 gEfiRedfishDiscoverProtocol,\r
457 gRedfishConfigData.Image,\r
458 ThisNetworkInterface,\r
459 EFI_REDFISH_DISCOVER_HOST_INTERFACE,\r
460 ThisRedfishDiscoveredToken\r
461 );\r
462 ThisNetworkInterface ++;\r
463 ThisRedfishDiscoveredToken ++;\r
464 }\r
465 if (EFI_ERROR (Status)) {\r
466 DEBUG((DEBUG_ERROR, "%a: Acquire Redfish service fail.\n", __FUNCTION__));\r
467 goto ErrorReturn;\r
468 }\r
469 return;\r
470\r
471ErrorReturn:\r
472 if (gRedfishDiscoveredToken != NULL) {\r
473 FreePool(gRedfishDiscoveredToken);\r
474 }\r
475}\r
476\r
477/**\r
478 Unloads an image.\r
479\r
480 @param[in] ImageHandle Handle that identifies the image to be unloaded.\r
481\r
482 @retval EFI_SUCCESS The image has been unloaded.\r
483\r
484**/\r
485EFI_STATUS\r
486EFIAPI\r
487RedfishConfigHandlerDriverUnload (\r
488 IN EFI_HANDLE ImageHandle\r
489 )\r
490{\r
491 EFI_REDFISH_DISCOVERED_TOKEN *ThisRedfishDiscoveredToken;\r
492 UINTN NumberOfNetworkInterfacesIndex;\r
493\r
494 RedfishConfigDriverCommonUnload (ImageHandle);\r
495\r
496 RedfishConfigStopRedfishDiscovery ();\r
497 if (gRedfishDiscoveredToken != NULL) {\r
498 ThisRedfishDiscoveredToken = gRedfishDiscoveredToken;\r
499 for (NumberOfNetworkInterfacesIndex = 0; NumberOfNetworkInterfacesIndex < gNumberOfNetworkInterfaces; NumberOfNetworkInterfacesIndex ++) {\r
500 if (ThisRedfishDiscoveredToken->Event != NULL) {\r
501 gBS->CloseEvent (ThisRedfishDiscoveredToken->Event);\r
502 }\r
503 FreePool (ThisRedfishDiscoveredToken);\r
504 ThisRedfishDiscoveredToken ++;\r
505 }\r
506 gRedfishDiscoveredToken = NULL;\r
507 }\r
508 return EFI_SUCCESS;\r
509}\r
510\r
511/**\r
512 This is the declaration of an EFI image entry point. This entry point is\r
513 the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including\r
514 both device drivers and bus drivers.\r
515\r
516 @param[in] ImageHandle The firmware allocated handle for the UEFI image.\r
517 @param[in] SystemTable A pointer to the EFI System Table.\r
518\r
519 @retval EFI_SUCCESS The operation completed successfully.\r
520 @retval Others An unexpected error occurred.\r
521**/\r
522EFI_STATUS\r
523EFIAPI\r
524RedfishConfigHandlerDriverEntryPoint (\r
525 IN EFI_HANDLE ImageHandle,\r
526 IN EFI_SYSTEM_TABLE *SystemTable\r
527 )\r
528{\r
529 EFI_STATUS Status;\r
530\r
531 ZeroMem ((VOID *)&gRedfishConfigData, sizeof (REDFISH_CONFIG_DRIVER_DATA));\r
532 gRedfishConfigData.Image = ImageHandle;\r
533 //\r
534 // Register event for EFI_REDFISH_DISCOVER_PROTOCOL protocol install\r
535 // notification.\r
536 //\r
537 Status = gBS->CreateEventEx (\r
538 EVT_NOTIFY_SIGNAL,\r
539 TPL_CALLBACK,\r
540 RedfishDiscoverProtocolInstalled,\r
541 NULL,\r
542 &gEfiRedfishDiscoverProtocolGuid,\r
543 &gEfiRedfishDiscoverProtocolEvent\r
544 );\r
545 if (EFI_ERROR (Status)) {\r
546 DEBUG ((DEBUG_ERROR, "%a: Fail to create event for the installation of EFI_REDFISH_DISCOVER_PROTOCOL.", __FUNCTION__));\r
547 return Status;\r
548 }\r
549 Status = gBS->RegisterProtocolNotify (\r
550 &gEfiRedfishDiscoverProtocolGuid,\r
551 gEfiRedfishDiscoverProtocolEvent,\r
552 &gEfiRedfishDiscoverRegistration\r
553 );\r
554 if (EFI_ERROR (Status)) {\r
555 DEBUG ((DEBUG_ERROR, "%a: Fail to register event for the installation of EFI_REDFISH_DISCOVER_PROTOCOL.", __FUNCTION__));\r
556 return Status;\r
557 }\r
558\r
559 Status = RedfishConfigCommonInit (ImageHandle, SystemTable);\r
560 if (EFI_ERROR (Status)) {\r
561 gBS->CloseEvent (gEfiRedfishDiscoverProtocolEvent);\r
562 gEfiRedfishDiscoverProtocolEvent = NULL;\r
563 return Status;\r
564 }\r
565\r
566 //\r
567 // Install UEFI Driver Model protocol(s).\r
568 //\r
569 Status = EfiLibInstallDriverBinding (\r
570 ImageHandle,\r
571 SystemTable,\r
572 &gRedfishConfigDriverBinding,\r
573 ImageHandle\r
574 );\r
575 if (EFI_ERROR (Status)) {\r
576 gBS->CloseEvent (gEndOfDxeEvent);\r
577 gEndOfDxeEvent = NULL;\r
578 gBS->CloseEvent (gExitBootServiceEvent);\r
579 gExitBootServiceEvent = NULL;\r
580 gBS->CloseEvent (gEfiRedfishDiscoverProtocolEvent);\r
581 gEfiRedfishDiscoverProtocolEvent = NULL;\r
582 DEBUG ((DEBUG_ERROR, "%a: Fail to install EFI Binding Protocol of EFI Redfish Config driver.", __FUNCTION__));\r
583 return Status;\r
584 }\r
585 return Status;\r
586}\r
587\r