VirtualBox

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

最後變更 在這個檔案從102808是 101291,由 vboxsync 提交於 17 月 前

EFI/FirmwareNew: Make edk2-stable202308 build on all supported platforms (using gcc at least, msvc not tested yet), bugref:4643

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

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