VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/RedfishPkg/RedfishRestExDxe/RedfishRestExDriver.c

Last change on this file was 105670, checked in by vboxsync, 7 months ago

Devices/EFI/FirmwareNew: Merge edk2-stable-202405 and make it build on aarch64, bugref:4643

  • Property svn:eol-style set to native
File size: 30.2 KB
Line 
1/** @file
2 The driver binding and service binding protocol for Redfish RestExDxe driver.
3
4 Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
5 (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
6 Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
7 Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
8
9 SPDX-License-Identifier: BSD-2-Clause-Patent
10
11**/
12
13#include <Uefi.h>
14#include "RedfishRestExDriver.h"
15
16EFI_DRIVER_BINDING_PROTOCOL gRedfishRestExDriverBinding = {
17 RedfishRestExDriverBindingSupported,
18 RedfishRestExDriverBindingStart,
19 RedfishRestExDriverBindingStop,
20 REDFISH_RESTEX_DRIVER_VERSION,
21 NULL,
22 NULL
23};
24
25EFI_SERVICE_BINDING_PROTOCOL mRedfishRestExServiceBinding = {
26 RedfishRestExServiceBindingCreateChild,
27 RedfishRestExServiceBindingDestroyChild
28};
29
30/**
31 Callback function which provided by user to remove one node in NetDestroyLinkList process.
32
33 @param[in] Entry The entry to be removed.
34 @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
35
36 @retval EFI_SUCCESS The entry has been removed successfully.
37 @retval Others Fail to remove the entry.
38
39**/
40EFI_STATUS
41EFIAPI
42RestExDestroyChildEntryInHandleBuffer (
43 IN LIST_ENTRY *Entry,
44 IN VOID *Context
45 )
46{
47 RESTEX_INSTANCE *Instance;
48 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
49 UINTN NumberOfChildren;
50 EFI_HANDLE *ChildHandleBuffer;
51
52 if ((Entry == NULL) || (Context == NULL)) {
53 return EFI_INVALID_PARAMETER;
54 }
55
56 Instance = NET_LIST_USER_STRUCT_S (Entry, RESTEX_INSTANCE, Link, RESTEX_INSTANCE_SIGNATURE);
57 ServiceBinding = ((RESTEX_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *)Context)->ServiceBinding;
58 NumberOfChildren = ((RESTEX_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *)Context)->NumberOfChildren;
59 ChildHandleBuffer = ((RESTEX_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *)Context)->ChildHandleBuffer;
60
61 if (!NetIsInHandleBuffer (Instance->ChildHandle, NumberOfChildren, ChildHandleBuffer)) {
62 RemoveEntryList (&Instance->Link);
63 return EFI_SUCCESS;
64 }
65
66 return ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle);
67}
68
69/**
70 Destroy the RestEx instance and recycle the resources.
71
72 @param[in] Instance The pointer to the RestEx instance.
73
74**/
75VOID
76RestExDestroyInstance (
77 IN RESTEX_INSTANCE *Instance
78 )
79{
80 HttpIoDestroyIo (&(Instance->HttpIo));
81
82 FreePool (Instance);
83}
84
85/**
86 Create the RestEx instance and initialize it.
87
88 @param[in] Service The pointer to the RestEx service.
89 @param[out] Instance The pointer to the RestEx instance.
90
91 @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
92 @retval EFI_SUCCESS The RestEx instance is created.
93
94**/
95EFI_STATUS
96RestExCreateInstance (
97 IN RESTEX_SERVICE *Service,
98 OUT RESTEX_INSTANCE **Instance
99 )
100{
101 RESTEX_INSTANCE *RestExIns;
102 EFI_STATUS Status;
103
104 *Instance = NULL;
105 Status = EFI_SUCCESS;
106
107 RestExIns = AllocateZeroPool (sizeof (RESTEX_INSTANCE));
108 if (RestExIns == NULL) {
109 return EFI_OUT_OF_RESOURCES;
110 }
111
112 RestExIns->Signature = RESTEX_INSTANCE_SIGNATURE;
113 InitializeListHead (&RestExIns->Link);
114 RestExIns->InDestroy = FALSE;
115 RestExIns->Service = Service;
116
117 CopyMem (&RestExIns->RestEx, &mRedfishRestExProtocol, sizeof (RestExIns->RestEx));
118
119 //
120 // Create a HTTP_IO to access the HTTP service.
121 //
122 Status = HttpIoCreateIo (
123 RestExIns->Service->ImageHandle,
124 RestExIns->Service->ControllerHandle,
125 IP_VERSION_4,
126 NULL,
127 NULL,
128 NULL,
129 &(RestExIns->HttpIo)
130 );
131 if (EFI_ERROR (Status)) {
132 FreePool (RestExIns);
133 return Status;
134 }
135
136 *Instance = RestExIns;
137
138 return EFI_SUCCESS;
139}
140
141/**
142 Release all the resource used the RestEx service binding instance.
143
144 @param[in] RestExSb The RestEx service binding instance.
145
146**/
147VOID
148RestExDestroyService (
149 IN RESTEX_SERVICE *RestExSb
150 )
151{
152 if (RestExSb->HttpChildHandle != NULL) {
153 gBS->CloseProtocol (
154 RestExSb->HttpChildHandle,
155 &gEfiHttpProtocolGuid,
156 RestExSb->ImageHandle,
157 RestExSb->ControllerHandle
158 );
159
160 NetLibDestroyServiceChild (
161 RestExSb->ControllerHandle,
162 RestExSb->ImageHandle,
163 &gEfiHttpServiceBindingProtocolGuid,
164 RestExSb->HttpChildHandle
165 );
166
167 RestExSb->HttpChildHandle = NULL;
168 }
169
170 gBS->UninstallProtocolInterface (
171 RestExSb->ControllerHandle,
172 &gEfiCallerIdGuid,
173 &RestExSb->Id
174 );
175
176 FreePool (RestExSb);
177}
178
179/**
180 Check the NIC controller handle represents an in-band or out-of-band Redfish host
181 interface device. If not in-band, treat it as out-of-band interface device.
182
183 @param[in] Controller The NIC controller handle needs to be checked.
184
185 @return EFI_REST_EX_SERVICE_ACCESS_MODE of the device.
186
187**/
188EFI_REST_EX_SERVICE_ACCESS_MODE
189RestExServiceAccessMode (
190 IN EFI_HANDLE Controller
191 )
192{
193 //
194 // This is EFI REST EX driver instance to connect
195 // to Redfish service using HTTP in out of band.
196 //
197 if (FixedPcdGetBool (PcdRedfishRestExServiceAccessModeInBand)) {
198 return EfiRestExServiceInBandAccess;
199 } else {
200 return EfiRestExServiceOutOfBandAccess;
201 }
202}
203
204/**
205 Create then initialize a RestEx service binding instance.
206
207 @param[in] Controller The controller to install the RestEx service
208 binding on.
209 @param[in] Image The driver binding image of the RestEx driver.
210 @param[out] Service The variable to receive the created service
211 binding instance.
212
213 @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create the instance.
214 @retval EFI_SUCCESS The service instance is created for the controller.
215
216**/
217EFI_STATUS
218RestExCreateService (
219 IN EFI_HANDLE Controller,
220 IN EFI_HANDLE Image,
221 OUT RESTEX_SERVICE **Service
222 )
223{
224 EFI_STATUS Status;
225 RESTEX_SERVICE *RestExSb;
226
227 Status = EFI_SUCCESS;
228 RestExSb = NULL;
229
230 *Service = NULL;
231
232 RestExSb = AllocateZeroPool (sizeof (RESTEX_SERVICE));
233 if (RestExSb == NULL) {
234 return EFI_OUT_OF_RESOURCES;
235 }
236
237 RestExSb->Signature = RESTEX_SERVICE_SIGNATURE;
238
239 RestExSb->ServiceBinding = mRedfishRestExServiceBinding;
240
241 RestExSb->RestExChildrenNum = 0;
242 InitializeListHead (&RestExSb->RestExChildrenList);
243
244 RestExSb->ControllerHandle = Controller;
245 RestExSb->ImageHandle = Image;
246
247 RestExSb->RestExServiceInfo.EfiRestExServiceInfoV10.EfiRestExServiceInfoHeader.Length = sizeof (EFI_REST_EX_SERVICE_INFO);
248 RestExSb->RestExServiceInfo.EfiRestExServiceInfoV10.EfiRestExServiceInfoHeader.RestServiceInfoVer.Major = 1;
249 RestExSb->RestExServiceInfo.EfiRestExServiceInfoV10.EfiRestExServiceInfoHeader.RestServiceInfoVer.Minor = 0;
250 RestExSb->RestExServiceInfo.EfiRestExServiceInfoV10.RestServiceType = EfiRestExServiceRedfish;
251 RestExSb->RestExServiceInfo.EfiRestExServiceInfoV10.RestServiceAccessMode = RestExServiceAccessMode (Controller);
252 RestExSb->RestExServiceInfo.EfiRestExServiceInfoV10.RestExConfigType = EfiRestExConfigHttp;
253 RestExSb->RestExServiceInfo.EfiRestExServiceInfoV10.RestExConfigDataLength = sizeof (EFI_REST_EX_HTTP_CONFIG_DATA);
254
255 Status = gBS->InstallProtocolInterface (
256 &Controller,
257 &gEfiCallerIdGuid,
258 EFI_NATIVE_INTERFACE,
259 &RestExSb->Id
260 );
261 if (EFI_ERROR (Status)) {
262 FreePool (RestExSb);
263 RestExSb = NULL;
264 }
265
266 *Service = RestExSb;
267 return Status;
268}
269
270/**
271 This is the declaration of an EFI image entry point. This entry point is
272 the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
273 both device drivers and bus drivers.
274
275 @param[in] ImageHandle The firmware allocated handle for the UEFI image.
276 @param[in] SystemTable A pointer to the EFI System Table.
277
278 @retval EFI_SUCCESS The operation completed successfully.
279 @retval Others An unexpected error occurred.
280**/
281EFI_STATUS
282EFIAPI
283RedfishRestExDriverEntryPoint (
284 IN EFI_HANDLE ImageHandle,
285 IN EFI_SYSTEM_TABLE *SystemTable
286 )
287{
288 EFI_STATUS Status;
289
290 Status = EFI_SUCCESS;
291
292 //
293 // Install the RestEx Driver Binding Protocol.
294 //
295 Status = EfiLibInstallDriverBindingComponentName2 (
296 ImageHandle,
297 SystemTable,
298 &gRedfishRestExDriverBinding,
299 ImageHandle,
300 &gRedfishRestExComponentName,
301 &gRedfishRestExComponentName2
302 );
303 if (EFI_ERROR (Status)) {
304 return Status;
305 }
306
307 return Status;
308}
309
310/**
311 Tests to see if this driver supports a given controller. If a child device is provided,
312 it further tests to see if this driver supports creating a handle for the specified child device.
313
314 This function checks to see if the driver specified by This supports the device specified by
315 ControllerHandle. Drivers will typically use the device path attached to
316 ControllerHandle and/or the services from the bus I/O abstraction attached to
317 ControllerHandle to determine if the driver supports ControllerHandle. This function
318 may be called many times during platform initialization. In order to reduce boot times, the tests
319 performed by this function must be very small, and take as little time as possible to execute. This
320 function must not change the state of any hardware devices, and this function must be aware that the
321 device specified by ControllerHandle may already be managed by the same driver or a
322 different driver. This function must match its calls to AllocatePages() with FreePages(),
323 AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
324 Because ControllerHandle may have been previously started by the same driver, if a protocol is
325 already in the opened state, then it must not be closed with CloseProtocol(). This is required
326 to guarantee the state of ControllerHandle is not modified by this function.
327
328 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
329 @param[in] ControllerHandle The handle of the controller to test. This handle
330 must support a protocol interface that supplies
331 an I/O abstraction to the driver.
332 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
333 parameter is ignored by device drivers, and is optional for bus
334 drivers. For bus drivers, if this parameter is not NULL, then
335 the bus driver must determine if the bus controller specified
336 by ControllerHandle and the child controller specified
337 by RemainingDevicePath are both supported by this
338 bus driver.
339
340 @retval EFI_SUCCESS The device specified by ControllerHandle and
341 RemainingDevicePath is supported by the driver specified by This.
342 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
343 RemainingDevicePath is already being managed by the driver
344 specified by This.
345 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
346 RemainingDevicePath is already being managed by a different
347 driver or an application that requires exclusive access.
348 Currently not implemented.
349 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
350 RemainingDevicePath is not supported by the driver specified by This.
351**/
352EFI_STATUS
353EFIAPI
354RedfishRestExDriverBindingSupported (
355 IN EFI_DRIVER_BINDING_PROTOCOL *This,
356 IN EFI_HANDLE ControllerHandle,
357 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
358 )
359{
360 EFI_STATUS Status;
361 UINT32 *Id;
362
363 Status = gBS->OpenProtocol (
364 ControllerHandle,
365 &gEfiCallerIdGuid,
366 (VOID **)&Id,
367 This->DriverBindingHandle,
368 ControllerHandle,
369 EFI_OPEN_PROTOCOL_GET_PROTOCOL
370 );
371 if (!EFI_ERROR (Status)) {
372 return EFI_ALREADY_STARTED;
373 }
374
375 //
376 // Test for the HttpServiceBinding Protocol.
377 //
378 return gBS->OpenProtocol (
379 ControllerHandle,
380 &gEfiHttpServiceBindingProtocolGuid,
381 NULL,
382 This->DriverBindingHandle,
383 ControllerHandle,
384 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
385 );
386}
387
388/**
389 Starts a device controller or a bus controller.
390
391 The Start() function is designed to be invoked from the EFI boot service ConnectController().
392 As a result, much of the error checking on the parameters to Start() has been moved into this
393 common boot service. It is legal to call Start() from other locations,
394 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
395 1. ControllerHandle must be a valid EFI_HANDLE.
396 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
397 EFI_DEVICE_PATH_PROTOCOL.
398 3. Prior to calling Start(), the Supported() function for the driver specified by This must
399 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
400
401 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
402 @param[in] ControllerHandle The handle of the controller to start. This handle
403 must support a protocol interface that supplies
404 an I/O abstraction to the driver.
405 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
406 parameter is ignored by device drivers, and is optional for bus
407 drivers. For a bus driver, if this parameter is NULL, then handles
408 for all the children of Controller are created by this driver.
409 If this parameter is not NULL and the first Device Path Node is
410 not the End of Device Path Node, then only the handle for the
411 child device specified by the first Device Path Node of
412 RemainingDevicePath is created by this driver.
413 If the first Device Path Node of RemainingDevicePath is
414 the End of Device Path Node, no child handle is created by this
415 driver.
416
417 @retval EFI_SUCCESS The device was started.
418 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
419 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
420 @retval Others The driver failded to start the device.
421
422**/
423EFI_STATUS
424EFIAPI
425RedfishRestExDriverBindingStart (
426 IN EFI_DRIVER_BINDING_PROTOCOL *This,
427 IN EFI_HANDLE ControllerHandle,
428 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
429 )
430{
431 RESTEX_SERVICE *RestExSb;
432 EFI_STATUS Status;
433 UINT32 *Id;
434 VOID *Interface;
435
436 Status = gBS->OpenProtocol (
437 ControllerHandle,
438 &gEfiCallerIdGuid,
439 (VOID **)&Id,
440 This->DriverBindingHandle,
441 ControllerHandle,
442 EFI_OPEN_PROTOCOL_GET_PROTOCOL
443 );
444 if (!EFI_ERROR (Status)) {
445 return EFI_ALREADY_STARTED;
446 }
447
448 Status = RestExCreateService (ControllerHandle, This->DriverBindingHandle, &RestExSb);
449 if (EFI_ERROR (Status)) {
450 return Status;
451 }
452
453 ASSERT (RestExSb != NULL);
454
455 //
456 // Create a Http child instance, but do not configure it.
457 // This will establish the parent-child relationship.
458 //
459 Status = NetLibCreateServiceChild (
460 ControllerHandle,
461 This->DriverBindingHandle,
462 &gEfiHttpServiceBindingProtocolGuid,
463 &RestExSb->HttpChildHandle
464 );
465 if (EFI_ERROR (Status)) {
466 goto ON_ERROR;
467 }
468
469 Status = gBS->OpenProtocol (
470 RestExSb->HttpChildHandle,
471 &gEfiHttpProtocolGuid,
472 &Interface,
473 This->DriverBindingHandle,
474 ControllerHandle,
475 EFI_OPEN_PROTOCOL_BY_DRIVER
476 );
477 if (EFI_ERROR (Status)) {
478 goto ON_ERROR;
479 }
480
481 //
482 // Install the RestEx ServiceBinding Protocol onto ControllerHandle.
483 //
484 Status = gBS->InstallMultipleProtocolInterfaces (
485 &ControllerHandle,
486 &gEfiRestExServiceBindingProtocolGuid,
487 &RestExSb->ServiceBinding,
488 NULL
489 );
490 if (EFI_ERROR (Status)) {
491 goto ON_ERROR;
492 }
493
494 return EFI_SUCCESS;
495
496ON_ERROR:
497 RestExDestroyService (RestExSb);
498
499 return Status;
500}
501
502/**
503 Stops a device controller or a bus controller.
504
505 The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
506 As a result, much of the error checking on the parameters to Stop() has been moved
507 into this common boot service. It is legal to call Stop() from other locations,
508 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
509 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
510 same driver's Start() function.
511 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
512 EFI_HANDLE. In addition, all of these handles must have been created in this driver's
513 Start() function, and the Start() function must have called OpenProtocol() on
514 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
515
516 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
517 @param[in] ControllerHandle A handle to the device being stopped. The handle must
518 support a bus specific I/O protocol for the driver
519 to use to stop the device.
520 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
521 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
522 if NumberOfChildren is 0.
523
524 @retval EFI_SUCCESS The device was stopped.
525 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
526
527**/
528EFI_STATUS
529EFIAPI
530RedfishRestExDriverBindingStop (
531 IN EFI_DRIVER_BINDING_PROTOCOL *This,
532 IN EFI_HANDLE ControllerHandle,
533 IN UINTN NumberOfChildren,
534 IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
535 )
536{
537 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
538 RESTEX_SERVICE *RestExSb;
539 EFI_HANDLE NicHandle;
540 EFI_STATUS Status;
541 LIST_ENTRY *List;
542 RESTEX_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;
543
544 //
545 // RestEx driver opens HTTP child, So, Controller is a HTTP
546 // child handle. Locate the Nic handle first. Then get the
547 // RestEx private data back.
548 //
549 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiHttpProtocolGuid);
550 if (NicHandle == NULL) {
551 return EFI_SUCCESS;
552 }
553
554 Status = gBS->OpenProtocol (
555 NicHandle,
556 &gEfiRestExServiceBindingProtocolGuid,
557 (VOID **)&ServiceBinding,
558 This->DriverBindingHandle,
559 NicHandle,
560 EFI_OPEN_PROTOCOL_GET_PROTOCOL
561 );
562 if (EFI_ERROR (Status)) {
563 return EFI_DEVICE_ERROR;
564 }
565
566 RestExSb = RESTEX_SERVICE_FROM_THIS (ServiceBinding);
567
568 if (!IsListEmpty (&RestExSb->RestExChildrenList)) {
569 //
570 // Destroy the RestEx child instance in ChildHandleBuffer.
571 //
572 List = &RestExSb->RestExChildrenList;
573 Context.ServiceBinding = ServiceBinding;
574 Context.NumberOfChildren = NumberOfChildren;
575 Context.ChildHandleBuffer = ChildHandleBuffer;
576 Status = NetDestroyLinkList (
577 List,
578 RestExDestroyChildEntryInHandleBuffer,
579 &Context,
580 NULL
581 );
582 }
583
584 if (IsListEmpty (&RestExSb->RestExChildrenList)) {
585 gBS->UninstallProtocolInterface (
586 NicHandle,
587 &gEfiRestExServiceBindingProtocolGuid,
588 ServiceBinding
589 );
590
591 RestExDestroyService (RestExSb);
592
593 if (gRedfishRestExControllerNameTable != NULL) {
594 FreeUnicodeStringTable (gRedfishRestExControllerNameTable);
595 gRedfishRestExControllerNameTable = NULL;
596 }
597
598 Status = EFI_SUCCESS;
599 }
600
601 return Status;
602}
603
604/**
605 Callback function that is invoked when HTTP event occurs.
606
607 @param[in] This Pointer to the EDKII_HTTP_CALLBACK_PROTOCOL instance.
608 @param[in] Event The event that occurs in the current state.
609 @param[in] EventStatus The Status of Event, EFI_SUCCESS or other errors.
610**/
611VOID
612EFIAPI
613RestExHttpCallback (
614 IN EDKII_HTTP_CALLBACK_PROTOCOL *This,
615 IN EDKII_HTTP_CALLBACK_EVENT Event,
616 IN EFI_STATUS EventStatus
617 )
618{
619 EFI_STATUS Status;
620 EFI_TLS_PROTOCOL *TlsProtocol;
621 RESTEX_INSTANCE *Instance;
622 EFI_TLS_VERIFY TlsVerifyMethod;
623
624 if ((Event == HttpEventTlsConfigured) && (EventStatus == EFI_SUCCESS)) {
625 // Reconfigure TLS configuration data.
626 Instance = RESTEX_INSTANCE_FROM_HTTP_CALLBACK (This);
627 Status = gBS->HandleProtocol (
628 Instance->HttpIo.Handle,
629 &gEfiTlsProtocolGuid,
630 (VOID **)&TlsProtocol
631 );
632 if (EFI_ERROR (Status)) {
633 return;
634 }
635
636 TlsVerifyMethod = EFI_TLS_VERIFY_NONE;
637 Status = TlsProtocol->SetSessionData (
638 TlsProtocol,
639 EfiTlsVerifyMethod,
640 &TlsVerifyMethod,
641 sizeof (EFI_TLS_VERIFY)
642 );
643 if (!EFI_ERROR (Status)) {
644 DEBUG ((DEBUG_MANAGEABILITY, "%a: REST EX reconfigures TLS verify method.\n", __func__));
645 }
646 }
647
648 return;
649}
650
651/**
652 Creates a child handle and installs a protocol.
653
654 The CreateChild() function installs a protocol on ChildHandle.
655 If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
656 If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
657
658 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
659 @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL,
660 then a new handle is created. If it is a pointer to an existing UEFI handle,
661 then the protocol is added to the existing UEFI handle.
662
663 @retval EFI_SUCCES The protocol was added to ChildHandle.
664 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
665 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
666 the child
667 @retval other The child handle was not created
668
669**/
670EFI_STATUS
671EFIAPI
672RedfishRestExServiceBindingCreateChild (
673 IN EFI_SERVICE_BINDING_PROTOCOL *This,
674 IN EFI_HANDLE *ChildHandle
675 )
676{
677 RESTEX_SERVICE *RestExSb;
678 RESTEX_INSTANCE *Instance;
679 EFI_STATUS Status;
680 EFI_TPL OldTpl;
681 VOID *Http;
682
683 if ((This == NULL) || (ChildHandle == NULL)) {
684 return EFI_INVALID_PARAMETER;
685 }
686
687 RestExSb = RESTEX_SERVICE_FROM_THIS (This);
688
689 Status = RestExCreateInstance (RestExSb, &Instance);
690 if (EFI_ERROR (Status)) {
691 return Status;
692 }
693
694 ASSERT (Instance != NULL);
695
696 //
697 // Install the RestEx protocol onto ChildHandle
698 //
699 Status = gBS->InstallMultipleProtocolInterfaces (
700 ChildHandle,
701 &gEfiRestExProtocolGuid,
702 &Instance->RestEx,
703 NULL
704 );
705 if (EFI_ERROR (Status)) {
706 goto ON_ERROR;
707 }
708
709 Instance->ChildHandle = *ChildHandle;
710
711 //
712 // Open the Http protocol BY_CHILD.
713 //
714 Status = gBS->OpenProtocol (
715 RestExSb->HttpChildHandle,
716 &gEfiHttpProtocolGuid,
717 (VOID **)&Http,
718 gRedfishRestExDriverBinding.DriverBindingHandle,
719 Instance->ChildHandle,
720 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
721 );
722 if (EFI_ERROR (Status)) {
723 gBS->UninstallMultipleProtocolInterfaces (
724 Instance->ChildHandle,
725 &gEfiRestExProtocolGuid,
726 &Instance->RestEx,
727 NULL
728 );
729
730 goto ON_ERROR;
731 }
732
733 //
734 // Open the Http protocol by child.
735 //
736 Status = gBS->OpenProtocol (
737 Instance->HttpIo.Handle,
738 &gEfiHttpProtocolGuid,
739 (VOID **)&Http,
740 gRedfishRestExDriverBinding.DriverBindingHandle,
741 Instance->ChildHandle,
742 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
743 );
744 if (EFI_ERROR (Status)) {
745 //
746 // Close the Http protocol.
747 //
748 gBS->CloseProtocol (
749 RestExSb->HttpChildHandle,
750 &gEfiHttpProtocolGuid,
751 gRedfishRestExDriverBinding.DriverBindingHandle,
752 ChildHandle
753 );
754
755 gBS->UninstallMultipleProtocolInterfaces (
756 Instance->ChildHandle,
757 &gEfiRestExProtocolGuid,
758 &Instance->RestEx,
759 NULL
760 );
761
762 goto ON_ERROR;
763 }
764
765 // Initial HTTP callback funciton on this REST EX instance
766 Instance->HttpCallbakFunction.Callback = RestExHttpCallback;
767 Status = gBS->InstallProtocolInterface (
768 &Instance->HttpIo.Handle,
769 &gEdkiiHttpCallbackProtocolGuid,
770 EFI_NATIVE_INTERFACE,
771 &Instance->HttpCallbakFunction
772 );
773 if (EFI_ERROR (Status)) {
774 DEBUG ((DEBUG_ERROR, "%a: Fail to install HttpCallbakFunction.\n", __func__));
775 goto ON_ERROR;
776 }
777
778 //
779 // Add it to the parent's child list.
780 //
781 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
782
783 InsertTailList (&RestExSb->RestExChildrenList, &Instance->Link);
784 RestExSb->RestExChildrenNum++;
785
786 gBS->RestoreTPL (OldTpl);
787
788 return EFI_SUCCESS;
789
790ON_ERROR:
791
792 RestExDestroyInstance (Instance);
793 return Status;
794}
795
796/**
797 Destroys a child handle with a protocol installed on it.
798
799 The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
800 that was installed by CreateChild() from ChildHandle. If the removed protocol is the
801 last protocol on ChildHandle, then ChildHandle is destroyed.
802
803 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
804 @param[in] ChildHandle Handle of the child to destroy
805
806 @retval EFI_SUCCES The protocol was removed from ChildHandle.
807 @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
808 @retval EFI_INVALID_PARAMETER Child handle is NULL.
809 @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
810 because its services are being used.
811 @retval other The child handle was not destroyed
812
813**/
814EFI_STATUS
815EFIAPI
816RedfishRestExServiceBindingDestroyChild (
817 IN EFI_SERVICE_BINDING_PROTOCOL *This,
818 IN EFI_HANDLE ChildHandle
819 )
820{
821 RESTEX_SERVICE *RestExSb;
822 RESTEX_INSTANCE *Instance;
823
824 EFI_REST_EX_PROTOCOL *RestEx;
825 EFI_STATUS Status;
826 EFI_TPL OldTpl;
827
828 if ((This == NULL) || (ChildHandle == NULL)) {
829 return EFI_INVALID_PARAMETER;
830 }
831
832 //
833 // Retrieve the private context data structures
834 //
835 Status = gBS->OpenProtocol (
836 ChildHandle,
837 &gEfiRestExProtocolGuid,
838 (VOID **)&RestEx,
839 NULL,
840 NULL,
841 EFI_OPEN_PROTOCOL_GET_PROTOCOL
842 );
843
844 if (EFI_ERROR (Status)) {
845 return EFI_UNSUPPORTED;
846 }
847
848 Instance = RESTEX_INSTANCE_FROM_THIS (RestEx);
849 RestExSb = RESTEX_SERVICE_FROM_THIS (This);
850
851 if (Instance->Service != RestExSb) {
852 return EFI_INVALID_PARAMETER;
853 }
854
855 if (Instance->InDestroy) {
856 return EFI_SUCCESS;
857 }
858
859 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
860
861 Instance->InDestroy = TRUE;
862
863 //
864 // Close the Http protocol.
865 //
866 gBS->CloseProtocol (
867 RestExSb->HttpChildHandle,
868 &gEfiHttpProtocolGuid,
869 gRedfishRestExDriverBinding.DriverBindingHandle,
870 ChildHandle
871 );
872
873 gBS->CloseProtocol (
874 Instance->HttpIo.Handle,
875 &gEfiHttpProtocolGuid,
876 gRedfishRestExDriverBinding.DriverBindingHandle,
877 ChildHandle
878 );
879
880 gBS->RestoreTPL (OldTpl);
881
882 //
883 // Uninstall the RestEx protocol first to enable a top down destruction.
884 //
885 Status = gBS->UninstallProtocolInterface (
886 ChildHandle,
887 &gEfiRestExProtocolGuid,
888 RestEx
889 );
890
891 //
892 // Uninstall the HTTP callback protocol.
893 //
894 Status = gBS->UninstallProtocolInterface (
895 Instance->HttpIo.Handle,
896 &gEdkiiHttpCallbackProtocolGuid,
897 &Instance->HttpCallbakFunction
898 );
899
900 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
901
902 if (EFI_ERROR (Status)) {
903 Instance->InDestroy = FALSE;
904 gBS->RestoreTPL (OldTpl);
905 return Status;
906 }
907
908 RemoveEntryList (&Instance->Link);
909 RestExSb->RestExChildrenNum--;
910
911 gBS->RestoreTPL (OldTpl);
912
913 RestExDestroyInstance (Instance);
914 return EFI_SUCCESS;
915}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette