VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/NetworkPkg/Dhcp4Dxe/Dhcp4Driver.c@ 107932

Last change on this file since 107932 was 105670, checked in by vboxsync, 9 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: 20.4 KB
Line 
1/** @file
2
3Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
4Copyright (c) Microsoft Corporation
5SPDX-License-Identifier: BSD-2-Clause-Patent
6
7**/
8
9#include "Dhcp4Impl.h"
10#include "Dhcp4Driver.h"
11
12EFI_DRIVER_BINDING_PROTOCOL gDhcp4DriverBinding = {
13 Dhcp4DriverBindingSupported,
14 Dhcp4DriverBindingStart,
15 Dhcp4DriverBindingStop,
16 0xa,
17 NULL,
18 NULL
19};
20
21EFI_SERVICE_BINDING_PROTOCOL mDhcp4ServiceBindingTemplate = {
22 Dhcp4ServiceBindingCreateChild,
23 Dhcp4ServiceBindingDestroyChild
24};
25
26/**
27 This is the declaration of an EFI image entry point. This entry point is
28 the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
29 both device drivers and bus drivers.
30
31 Entry point of the DHCP driver to install various protocols.
32
33 @param[in] ImageHandle The firmware allocated handle for the UEFI image.
34 @param[in] SystemTable A pointer to the EFI System Table.
35
36 @retval EFI_SUCCESS The operation completed successfully.
37 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
38
39**/
40EFI_STATUS
41EFIAPI
42Dhcp4DriverEntryPoint (
43 IN EFI_HANDLE ImageHandle,
44 IN EFI_SYSTEM_TABLE *SystemTable
45 )
46{
47 return EfiLibInstallDriverBindingComponentName2 (
48 ImageHandle,
49 SystemTable,
50 &gDhcp4DriverBinding,
51 ImageHandle,
52 &gDhcp4ComponentName,
53 &gDhcp4ComponentName2
54 );
55}
56
57/**
58 Test to see if this driver supports ControllerHandle. This service
59 is called by the EFI boot service ConnectController(). In
60 order to make drivers as small as possible, there are a few calling
61 restrictions for this service. ConnectController() must
62 follow these calling restrictions. If any other agent wishes to call
63 Supported() it must also follow these calling restrictions.
64
65 @param[in] This Protocol instance pointer.
66 @param[in] ControllerHandle Handle of device to test
67 @param[in] RemainingDevicePath Optional parameter use to pick a specific child
68 device to start.
69
70 @retval EFI_SUCCESS This driver supports this device
71 @retval EFI_ALREADY_STARTED This driver is already running on this device
72 @retval other This driver does not support this device
73
74**/
75EFI_STATUS
76EFIAPI
77Dhcp4DriverBindingSupported (
78 IN EFI_DRIVER_BINDING_PROTOCOL *This,
79 IN EFI_HANDLE ControllerHandle,
80 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
81 )
82{
83 EFI_STATUS Status;
84
85 Status = gBS->OpenProtocol (
86 ControllerHandle,
87 &gEfiUdp4ServiceBindingProtocolGuid,
88 NULL,
89 This->DriverBindingHandle,
90 ControllerHandle,
91 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
92 );
93
94 return Status;
95}
96
97/**
98 Configure the default UDP child to receive all the DHCP traffics
99 on this network interface.
100
101 @param[in] UdpIo The UDP IO to configure
102 @param[in] Context The context to the function
103
104 @retval EFI_SUCCESS The UDP IO is successfully configured.
105 @retval Others Failed to configure the UDP child.
106
107**/
108EFI_STATUS
109EFIAPI
110DhcpConfigUdpIo (
111 IN UDP_IO *UdpIo,
112 IN VOID *Context
113 )
114{
115 EFI_UDP4_CONFIG_DATA UdpConfigData;
116
117 UdpConfigData.AcceptBroadcast = TRUE;
118 UdpConfigData.AcceptPromiscuous = FALSE;
119 UdpConfigData.AcceptAnyPort = FALSE;
120 UdpConfigData.AllowDuplicatePort = TRUE;
121 UdpConfigData.TypeOfService = 0;
122 UdpConfigData.TimeToLive = 64;
123 UdpConfigData.DoNotFragment = FALSE;
124 UdpConfigData.ReceiveTimeout = 0;
125 UdpConfigData.TransmitTimeout = 0;
126
127 UdpConfigData.UseDefaultAddress = FALSE;
128 UdpConfigData.StationPort = DHCP_CLIENT_PORT;
129 UdpConfigData.RemotePort = DHCP_SERVER_PORT;
130
131 ZeroMem (&UdpConfigData.StationAddress, sizeof (EFI_IPv4_ADDRESS));
132 ZeroMem (&UdpConfigData.SubnetMask, sizeof (EFI_IPv4_ADDRESS));
133 ZeroMem (&UdpConfigData.RemoteAddress, sizeof (EFI_IPv4_ADDRESS));
134
135 return UdpIo->Protocol.Udp4->Configure (UdpIo->Protocol.Udp4, &UdpConfigData);
136}
137
138/**
139 Destroy the DHCP service. The Dhcp4 service may be partly initialized,
140 or partly destroyed. If a resource is destroyed, it is marked as so in
141 case the destroy failed and being called again later.
142
143 @param[in] DhcpSb The DHCP service instance to destroy.
144
145 @retval EFI_SUCCESS Always return success.
146
147**/
148EFI_STATUS
149Dhcp4CloseService (
150 IN DHCP_SERVICE *DhcpSb
151 )
152{
153 DhcpCleanLease (DhcpSb);
154
155 if (DhcpSb->UdpIo != NULL) {
156 UdpIoFreeIo (DhcpSb->UdpIo);
157 DhcpSb->UdpIo = NULL;
158 }
159
160 if (DhcpSb->Timer != NULL) {
161 gBS->SetTimer (DhcpSb->Timer, TimerCancel, 0);
162 gBS->CloseEvent (DhcpSb->Timer);
163
164 DhcpSb->Timer = NULL;
165 }
166
167 return EFI_SUCCESS;
168}
169
170/**
171 Create a new DHCP service binding instance for the controller.
172
173 @param[in] Controller The controller to install DHCP service binding
174 protocol onto
175 @param[in] ImageHandle The driver's image handle
176 @param[out] Service The variable to receive the created DHCP service
177 instance.
178
179 @retval EFI_OUT_OF_RESOURCES Failed to allocate resource .
180 @retval EFI_SUCCESS The DHCP service instance is created.
181 @retval other Other error occurs.
182
183**/
184EFI_STATUS
185Dhcp4CreateService (
186 IN EFI_HANDLE Controller,
187 IN EFI_HANDLE ImageHandle,
188 OUT DHCP_SERVICE **Service
189 )
190{
191 DHCP_SERVICE *DhcpSb;
192 EFI_STATUS Status;
193 UINT32 Random;
194
195 Status = PseudoRandomU32 (&Random);
196 if (EFI_ERROR (Status)) {
197 DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));
198 return Status;
199 }
200
201 *Service = NULL;
202 DhcpSb = AllocateZeroPool (sizeof (DHCP_SERVICE));
203
204 if (DhcpSb == NULL) {
205 return EFI_OUT_OF_RESOURCES;
206 }
207
208 DhcpSb->Signature = DHCP_SERVICE_SIGNATURE;
209 DhcpSb->ServiceState = DHCP_UNCONFIGED;
210 DhcpSb->Controller = Controller;
211 DhcpSb->Image = ImageHandle;
212 InitializeListHead (&DhcpSb->Children);
213 DhcpSb->DhcpState = Dhcp4Stopped;
214 DhcpSb->Xid = Random;
215 CopyMem (
216 &DhcpSb->ServiceBinding,
217 &mDhcp4ServiceBindingTemplate,
218 sizeof (EFI_SERVICE_BINDING_PROTOCOL)
219 );
220 //
221 // Create various resources, UdpIo, Timer, and get Mac address
222 //
223 Status = gBS->CreateEvent (
224 EVT_NOTIFY_SIGNAL | EVT_TIMER,
225 TPL_CALLBACK,
226 DhcpOnTimerTick,
227 DhcpSb,
228 &DhcpSb->Timer
229 );
230
231 if (EFI_ERROR (Status)) {
232 goto ON_ERROR;
233 }
234
235 DhcpSb->UdpIo = UdpIoCreateIo (
236 Controller,
237 ImageHandle,
238 DhcpConfigUdpIo,
239 UDP_IO_UDP4_VERSION,
240 NULL
241 );
242
243 if (DhcpSb->UdpIo == NULL) {
244 Status = EFI_OUT_OF_RESOURCES;
245 goto ON_ERROR;
246 }
247
248 DhcpSb->HwLen = (UINT8)DhcpSb->UdpIo->SnpMode.HwAddressSize;
249 DhcpSb->HwType = DhcpSb->UdpIo->SnpMode.IfType;
250 CopyMem (&DhcpSb->Mac, &DhcpSb->UdpIo->SnpMode.CurrentAddress, sizeof (DhcpSb->Mac));
251
252 *Service = DhcpSb;
253 return EFI_SUCCESS;
254
255ON_ERROR:
256 Dhcp4CloseService (DhcpSb);
257 FreePool (DhcpSb);
258
259 return Status;
260}
261
262/**
263 Start this driver on ControllerHandle. This service is called by the
264 EFI boot service ConnectController(). In order to make
265 drivers as small as possible, there are a few calling restrictions for
266 this service. ConnectController() must follow these
267 calling restrictions. If any other agent wishes to call Start() it
268 must also follow these calling restrictions.
269
270 @param[in] This Protocol instance pointer.
271 @param[in] ControllerHandle Handle of device to bind driver to
272 @param[in] RemainingDevicePath Optional parameter use to pick a specific child
273 device to start.
274
275 @retval EFI_SUCCESS This driver is added to ControllerHandle
276 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
277 @retval other This driver does not support this device
278
279**/
280EFI_STATUS
281EFIAPI
282Dhcp4DriverBindingStart (
283 IN EFI_DRIVER_BINDING_PROTOCOL *This,
284 IN EFI_HANDLE ControllerHandle,
285 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
286 )
287{
288 DHCP_SERVICE *DhcpSb;
289 EFI_STATUS Status;
290
291 //
292 // First: test for the DHCP4 Protocol
293 //
294 Status = gBS->OpenProtocol (
295 ControllerHandle,
296 &gEfiDhcp4ServiceBindingProtocolGuid,
297 NULL,
298 This->DriverBindingHandle,
299 ControllerHandle,
300 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
301 );
302
303 if (Status == EFI_SUCCESS) {
304 return EFI_ALREADY_STARTED;
305 }
306
307 Status = Dhcp4CreateService (ControllerHandle, This->DriverBindingHandle, &DhcpSb);
308
309 if (EFI_ERROR (Status)) {
310 return Status;
311 }
312
313 ASSERT (DhcpSb != NULL);
314
315 //
316 // Start the receiving
317 //
318 Status = UdpIoRecvDatagram (DhcpSb->UdpIo, DhcpInput, DhcpSb, 0);
319
320 if (EFI_ERROR (Status)) {
321 goto ON_ERROR;
322 }
323
324 Status = gBS->SetTimer (DhcpSb->Timer, TimerPeriodic, TICKS_PER_SECOND);
325
326 if (EFI_ERROR (Status)) {
327 goto ON_ERROR;
328 }
329
330 //
331 // Install the Dhcp4ServiceBinding Protocol onto ControllerHandle
332 //
333 Status = gBS->InstallMultipleProtocolInterfaces (
334 &ControllerHandle,
335 &gEfiDhcp4ServiceBindingProtocolGuid,
336 &DhcpSb->ServiceBinding,
337 NULL
338 );
339
340 if (EFI_ERROR (Status)) {
341 goto ON_ERROR;
342 }
343
344 return Status;
345
346ON_ERROR:
347 Dhcp4CloseService (DhcpSb);
348 FreePool (DhcpSb);
349 return Status;
350}
351
352/**
353 Callback function which provided by user to remove one node in NetDestroyLinkList process.
354
355 @param[in] Entry The entry to be removed.
356 @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
357
358 @retval EFI_SUCCESS The entry has been removed successfully.
359 @retval Others Fail to remove the entry.
360
361**/
362EFI_STATUS
363EFIAPI
364Dhcp4DestroyChildEntry (
365 IN LIST_ENTRY *Entry,
366 IN VOID *Context
367 )
368{
369 DHCP_PROTOCOL *Instance;
370 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
371
372 if ((Entry == NULL) || (Context == NULL)) {
373 return EFI_INVALID_PARAMETER;
374 }
375
376 Instance = NET_LIST_USER_STRUCT_S (Entry, DHCP_PROTOCOL, Link, DHCP_PROTOCOL_SIGNATURE);
377 ServiceBinding = (EFI_SERVICE_BINDING_PROTOCOL *)Context;
378
379 return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
380}
381
382/**
383 Stop this driver on ControllerHandle. This service is called by the
384 EFI boot service DisconnectController(). In order to
385 make drivers as small as possible, there are a few calling
386 restrictions for this service. DisconnectController()
387 must follow these calling restrictions. If any other agent wishes
388 to call Stop() it must also follow these calling restrictions.
389
390 @param[in] This Protocol instance pointer.
391 @param[in] ControllerHandle Handle of device to stop driver on
392 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
393 children is zero stop the entire bus driver.
394 @param[in] ChildHandleBuffer List of Child Handles to Stop.
395
396 @retval EFI_SUCCESS This driver is removed ControllerHandle
397 @retval other This driver was not removed from this device
398
399**/
400EFI_STATUS
401EFIAPI
402Dhcp4DriverBindingStop (
403 IN EFI_DRIVER_BINDING_PROTOCOL *This,
404 IN EFI_HANDLE ControllerHandle,
405 IN UINTN NumberOfChildren,
406 IN EFI_HANDLE *ChildHandleBuffer
407 )
408{
409 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
410 DHCP_SERVICE *DhcpSb;
411 EFI_HANDLE NicHandle;
412 EFI_STATUS Status;
413 LIST_ENTRY *List;
414 UINTN ListLength;
415
416 //
417 // DHCP driver opens UDP child, So, the ControllerHandle is the
418 // UDP child handle. locate the Nic handle first.
419 //
420 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp4ProtocolGuid);
421
422 if (NicHandle == NULL) {
423 return EFI_SUCCESS;
424 }
425
426 Status = gBS->OpenProtocol (
427 NicHandle,
428 &gEfiDhcp4ServiceBindingProtocolGuid,
429 (VOID **)&ServiceBinding,
430 This->DriverBindingHandle,
431 NicHandle,
432 EFI_OPEN_PROTOCOL_GET_PROTOCOL
433 );
434
435 if (EFI_ERROR (Status)) {
436 return EFI_DEVICE_ERROR;
437 }
438
439 DhcpSb = DHCP_SERVICE_FROM_THIS (ServiceBinding);
440 if (!IsListEmpty (&DhcpSb->Children)) {
441 //
442 // Destroy all the children instances before destroy the service.
443 //
444 List = &DhcpSb->Children;
445 Status = NetDestroyLinkList (
446 List,
447 Dhcp4DestroyChildEntry,
448 ServiceBinding,
449 &ListLength
450 );
451 if (EFI_ERROR (Status) || (ListLength != 0)) {
452 Status = EFI_DEVICE_ERROR;
453 }
454 }
455
456 if ((NumberOfChildren == 0) && !IsListEmpty (&DhcpSb->Children)) {
457 Status = EFI_DEVICE_ERROR;
458 }
459
460 if ((NumberOfChildren == 0) && IsListEmpty (&DhcpSb->Children)) {
461 //
462 // Destroy the service itself if no child instance left.
463 //
464 DhcpSb->ServiceState = DHCP_DESTROY;
465
466 gBS->UninstallProtocolInterface (
467 NicHandle,
468 &gEfiDhcp4ServiceBindingProtocolGuid,
469 ServiceBinding
470 );
471
472 Dhcp4CloseService (DhcpSb);
473
474 if (gDhcpControllerNameTable != NULL) {
475 FreeUnicodeStringTable (gDhcpControllerNameTable);
476 gDhcpControllerNameTable = NULL;
477 }
478
479 FreePool (DhcpSb);
480
481 Status = EFI_SUCCESS;
482 }
483
484 return Status;
485}
486
487/**
488 Initialize a new DHCP instance.
489
490 @param DhcpSb The dhcp service instance
491 @param Instance The dhcp instance to initialize
492
493**/
494VOID
495DhcpInitProtocol (
496 IN DHCP_SERVICE *DhcpSb,
497 IN OUT DHCP_PROTOCOL *Instance
498 )
499{
500 Instance->Signature = DHCP_PROTOCOL_SIGNATURE;
501 CopyMem (&Instance->Dhcp4Protocol, &mDhcp4ProtocolTemplate, sizeof (Instance->Dhcp4Protocol));
502 InitializeListHead (&Instance->Link);
503 Instance->Handle = NULL;
504 Instance->Service = DhcpSb;
505 Instance->InDestroy = FALSE;
506 Instance->CompletionEvent = NULL;
507 Instance->RenewRebindEvent = NULL;
508 Instance->Token = NULL;
509 Instance->UdpIo = NULL;
510 Instance->ElaspedTime = 0;
511 NetbufQueInit (&Instance->ResponseQueue);
512}
513
514/**
515 Creates a child handle and installs a protocol.
516
517 The CreateChild() function installs a protocol on ChildHandle.
518 If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
519 If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
520
521 @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
522 @param ChildHandle Pointer to the handle of the child to create. If it is NULL,
523 then a new handle is created. If it is a pointer to an existing UEFI handle,
524 then the protocol is added to the existing UEFI handle.
525
526 @retval EFI_SUCCESS The protocol was added to ChildHandle.
527 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
528 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
529 the child
530 @retval other The child handle was not created
531
532**/
533EFI_STATUS
534EFIAPI
535Dhcp4ServiceBindingCreateChild (
536 IN EFI_SERVICE_BINDING_PROTOCOL *This,
537 IN EFI_HANDLE *ChildHandle
538 )
539{
540 DHCP_SERVICE *DhcpSb;
541 DHCP_PROTOCOL *Instance;
542 EFI_STATUS Status;
543 EFI_TPL OldTpl;
544 VOID *Udp4;
545
546 if ((This == NULL) || (ChildHandle == NULL)) {
547 return EFI_INVALID_PARAMETER;
548 }
549
550 Instance = AllocatePool (sizeof (*Instance));
551
552 if (Instance == NULL) {
553 return EFI_OUT_OF_RESOURCES;
554 }
555
556 DhcpSb = DHCP_SERVICE_FROM_THIS (This);
557 DhcpInitProtocol (DhcpSb, Instance);
558
559 //
560 // Install DHCP4 onto ChildHandle
561 //
562 Status = gBS->InstallMultipleProtocolInterfaces (
563 ChildHandle,
564 &gEfiDhcp4ProtocolGuid,
565 &Instance->Dhcp4Protocol,
566 NULL
567 );
568
569 if (EFI_ERROR (Status)) {
570 FreePool (Instance);
571 return Status;
572 }
573
574 Instance->Handle = *ChildHandle;
575
576 //
577 // Open the Udp4 protocol BY_CHILD.
578 //
579 Status = gBS->OpenProtocol (
580 DhcpSb->UdpIo->UdpHandle,
581 &gEfiUdp4ProtocolGuid,
582 (VOID **)&Udp4,
583 gDhcp4DriverBinding.DriverBindingHandle,
584 Instance->Handle,
585 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
586 );
587 if (EFI_ERROR (Status)) {
588 gBS->UninstallMultipleProtocolInterfaces (
589 Instance->Handle,
590 &gEfiDhcp4ProtocolGuid,
591 &Instance->Dhcp4Protocol,
592 NULL
593 );
594
595 FreePool (Instance);
596 return Status;
597 }
598
599 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
600
601 InsertTailList (&DhcpSb->Children, &Instance->Link);
602 DhcpSb->NumChildren++;
603
604 gBS->RestoreTPL (OldTpl);
605
606 return EFI_SUCCESS;
607}
608
609/**
610 Destroys a child handle with a protocol installed on it.
611
612 The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
613 that was installed by CreateChild() from ChildHandle. If the removed protocol is the
614 last protocol on ChildHandle, then ChildHandle is destroyed.
615
616 @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
617 @param ChildHandle Handle of the child to destroy
618
619 @retval EFI_SUCCESS The protocol was removed from ChildHandle.
620 @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
621 @retval EFI_INVALID_PARAMETER Child handle is NULL.
622 @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
623 because its services are being used.
624 @retval other The child handle was not destroyed
625
626**/
627EFI_STATUS
628EFIAPI
629Dhcp4ServiceBindingDestroyChild (
630 IN EFI_SERVICE_BINDING_PROTOCOL *This,
631 IN EFI_HANDLE ChildHandle
632 )
633{
634 DHCP_SERVICE *DhcpSb;
635 DHCP_PROTOCOL *Instance;
636 EFI_DHCP4_PROTOCOL *Dhcp;
637 EFI_TPL OldTpl;
638 EFI_STATUS Status;
639
640 if ((This == NULL) || (ChildHandle == NULL)) {
641 return EFI_INVALID_PARAMETER;
642 }
643
644 //
645 // Retrieve the private context data structures
646 //
647 Status = gBS->OpenProtocol (
648 ChildHandle,
649 &gEfiDhcp4ProtocolGuid,
650 (VOID **)&Dhcp,
651 gDhcp4DriverBinding.DriverBindingHandle,
652 ChildHandle,
653 EFI_OPEN_PROTOCOL_GET_PROTOCOL
654 );
655
656 if (EFI_ERROR (Status)) {
657 return EFI_UNSUPPORTED;
658 }
659
660 Instance = DHCP_INSTANCE_FROM_THIS (Dhcp);
661 DhcpSb = DHCP_SERVICE_FROM_THIS (This);
662
663 if (Instance->Service != DhcpSb) {
664 return EFI_INVALID_PARAMETER;
665 }
666
667 //
668 // A child can be destroyed more than once. For example,
669 // Dhcp4DriverBindingStop will destroy all of its children.
670 // when caller driver is being stopped, it will destroy the
671 // dhcp child it opens.
672 //
673 if (Instance->InDestroy) {
674 return EFI_SUCCESS;
675 }
676
677 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
678 Instance->InDestroy = TRUE;
679
680 //
681 // Close the Udp4 protocol.
682 //
683 gBS->CloseProtocol (
684 DhcpSb->UdpIo->UdpHandle,
685 &gEfiUdp4ProtocolGuid,
686 gDhcp4DriverBinding.DriverBindingHandle,
687 ChildHandle
688 );
689
690 //
691 // Uninstall the DHCP4 protocol first to enable a top down destruction.
692 //
693 gBS->RestoreTPL (OldTpl);
694 Status = gBS->UninstallProtocolInterface (
695 ChildHandle,
696 &gEfiDhcp4ProtocolGuid,
697 Dhcp
698 );
699 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
700 if (EFI_ERROR (Status)) {
701 Instance->InDestroy = FALSE;
702
703 gBS->RestoreTPL (OldTpl);
704 return Status;
705 }
706
707 if (DhcpSb->ActiveChild == Instance) {
708 DhcpYieldControl (DhcpSb);
709 }
710
711 RemoveEntryList (&Instance->Link);
712 DhcpSb->NumChildren--;
713
714 if (Instance->UdpIo != NULL) {
715 UdpIoCleanIo (Instance->UdpIo);
716 gBS->CloseProtocol (
717 Instance->UdpIo->UdpHandle,
718 &gEfiUdp4ProtocolGuid,
719 Instance->Service->Image,
720 Instance->Handle
721 );
722 UdpIoFreeIo (Instance->UdpIo);
723 Instance->UdpIo = NULL;
724 Instance->Token = NULL;
725 }
726
727 gBS->RestoreTPL (OldTpl);
728
729 FreePool (Instance);
730 return EFI_SUCCESS;
731}
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