]> git.proxmox.com Git - mirror_edk2.git/blob - NetworkPkg/ArpDxe/ArpDriver.c
NetworkPkg: Apply uncrustify changes
[mirror_edk2.git] / NetworkPkg / ArpDxe / ArpDriver.c
1 /** @file
2 ARP driver functions.
3
4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include "ArpDriver.h"
10 #include "ArpImpl.h"
11
12 EFI_DRIVER_BINDING_PROTOCOL gArpDriverBinding = {
13 ArpDriverBindingSupported,
14 ArpDriverBindingStart,
15 ArpDriverBindingStop,
16 0xa,
17 NULL,
18 NULL
19 };
20
21 /**
22 Create and initialize the arp service context data.
23
24 @param[in] ImageHandle The image handle representing the loaded driver
25 image.
26 @param[in] ControllerHandle The controller handle the driver binds to.
27 @param[in, out] ArpService Pointer to the buffer containing the arp service
28 context data.
29
30 @retval EFI_SUCCESS The arp service context is initialized.
31
32 @retval EFI_UNSUPPORTED The underlayer Snp mode type is not ethernet.
33 Failed to initialize the service context.
34 @retval other Failed to initialize the arp service context.
35
36 **/
37 EFI_STATUS
38 ArpCreateService (
39 IN EFI_HANDLE ImageHandle,
40 IN EFI_HANDLE ControllerHandle,
41 IN OUT ARP_SERVICE_DATA *ArpService
42 )
43 {
44 EFI_STATUS Status;
45
46 ASSERT (ArpService != NULL);
47
48 ArpService->Signature = ARP_SERVICE_DATA_SIGNATURE;
49
50 //
51 // Init the lists.
52 //
53 InitializeListHead (&ArpService->ChildrenList);
54 InitializeListHead (&ArpService->PendingRequestTable);
55 InitializeListHead (&ArpService->DeniedCacheTable);
56 InitializeListHead (&ArpService->ResolvedCacheTable);
57
58 //
59 // Init the servicebinding protocol members.
60 //
61 ArpService->ServiceBinding.CreateChild = ArpServiceBindingCreateChild;
62 ArpService->ServiceBinding.DestroyChild = ArpServiceBindingDestroyChild;
63
64 //
65 // Save the handles.
66 //
67 ArpService->ImageHandle = ImageHandle;
68 ArpService->ControllerHandle = ControllerHandle;
69
70 //
71 // Create a MNP child instance.
72 //
73 Status = NetLibCreateServiceChild (
74 ControllerHandle,
75 ImageHandle,
76 &gEfiManagedNetworkServiceBindingProtocolGuid,
77 &ArpService->MnpChildHandle
78 );
79 if (EFI_ERROR (Status)) {
80 return Status;
81 }
82
83 //
84 // Open the MNP protocol.
85 //
86 Status = gBS->OpenProtocol (
87 ArpService->MnpChildHandle,
88 &gEfiManagedNetworkProtocolGuid,
89 (VOID **)&ArpService->Mnp,
90 ImageHandle,
91 ControllerHandle,
92 EFI_OPEN_PROTOCOL_BY_DRIVER
93 );
94 if (EFI_ERROR (Status)) {
95 goto ERROR_EXIT;
96 }
97
98 //
99 // Get the underlayer Snp mode data.
100 //
101 Status = ArpService->Mnp->GetModeData (ArpService->Mnp, NULL, &ArpService->SnpMode);
102 if ((Status != EFI_NOT_STARTED) && EFI_ERROR (Status)) {
103 goto ERROR_EXIT;
104 }
105
106 if (ArpService->SnpMode.IfType != NET_IFTYPE_ETHERNET) {
107 //
108 // Only support the ethernet.
109 //
110 Status = EFI_UNSUPPORTED;
111 goto ERROR_EXIT;
112 }
113
114 //
115 // Set the Mnp config parameters.
116 //
117 ArpService->MnpConfigData.ReceivedQueueTimeoutValue = 0;
118 ArpService->MnpConfigData.TransmitQueueTimeoutValue = 0;
119 ArpService->MnpConfigData.ProtocolTypeFilter = ARP_ETHER_PROTO_TYPE;
120 ArpService->MnpConfigData.EnableUnicastReceive = TRUE;
121 ArpService->MnpConfigData.EnableMulticastReceive = FALSE;
122 ArpService->MnpConfigData.EnableBroadcastReceive = TRUE;
123 ArpService->MnpConfigData.EnablePromiscuousReceive = FALSE;
124 ArpService->MnpConfigData.FlushQueuesOnReset = TRUE;
125 ArpService->MnpConfigData.EnableReceiveTimestamps = FALSE;
126 ArpService->MnpConfigData.DisableBackgroundPolling = FALSE;
127
128 //
129 // Configure the Mnp child.
130 //
131 Status = ArpService->Mnp->Configure (ArpService->Mnp, &ArpService->MnpConfigData);
132 if (EFI_ERROR (Status)) {
133 goto ERROR_EXIT;
134 }
135
136 //
137 // Create the event used in the RxToken.
138 //
139 Status = gBS->CreateEvent (
140 EVT_NOTIFY_SIGNAL,
141 TPL_NOTIFY,
142 ArpOnFrameRcvd,
143 ArpService,
144 &ArpService->RxToken.Event
145 );
146 if (EFI_ERROR (Status)) {
147 goto ERROR_EXIT;
148 }
149
150 //
151 // Create the Arp heartbeat timer.
152 //
153 Status = gBS->CreateEvent (
154 EVT_NOTIFY_SIGNAL | EVT_TIMER,
155 TPL_CALLBACK,
156 ArpTimerHandler,
157 ArpService,
158 &ArpService->PeriodicTimer
159 );
160 if (EFI_ERROR (Status)) {
161 goto ERROR_EXIT;
162 }
163
164 //
165 // Start the heartbeat timer.
166 //
167 Status = gBS->SetTimer (
168 ArpService->PeriodicTimer,
169 TimerPeriodic,
170 ARP_PERIODIC_TIMER_INTERVAL
171 );
172
173 ERROR_EXIT:
174
175 return Status;
176 }
177
178 /**
179 Clean the arp service context data.
180
181 @param[in, out] ArpService Pointer to the buffer containing the arp service
182 context data.
183
184 @return None.
185
186 **/
187 VOID
188 ArpCleanService (
189 IN OUT ARP_SERVICE_DATA *ArpService
190 )
191 {
192 NET_CHECK_SIGNATURE (ArpService, ARP_SERVICE_DATA_SIGNATURE);
193
194 if (ArpService->PeriodicTimer != NULL) {
195 //
196 // Cancel and close the PeriodicTimer.
197 //
198 gBS->SetTimer (ArpService->PeriodicTimer, TimerCancel, 0);
199 gBS->CloseEvent (ArpService->PeriodicTimer);
200 }
201
202 if (ArpService->RxToken.Event != NULL) {
203 //
204 // Cancel the RxToken and close the event in the RxToken.
205 //
206 ArpService->Mnp->Cancel (ArpService->Mnp, NULL);
207 gBS->CloseEvent (ArpService->RxToken.Event);
208 }
209
210 if (ArpService->Mnp != NULL) {
211 //
212 // Reset the Mnp child and close the Mnp protocol.
213 //
214 ArpService->Mnp->Configure (ArpService->Mnp, NULL);
215 gBS->CloseProtocol (
216 ArpService->MnpChildHandle,
217 &gEfiManagedNetworkProtocolGuid,
218 ArpService->ImageHandle,
219 ArpService->ControllerHandle
220 );
221 }
222
223 if (ArpService->MnpChildHandle != NULL) {
224 //
225 // Destroy the mnp child.
226 //
227 NetLibDestroyServiceChild (
228 ArpService->ControllerHandle,
229 ArpService->ImageHandle,
230 &gEfiManagedNetworkServiceBindingProtocolGuid,
231 ArpService->MnpChildHandle
232 );
233 }
234 }
235
236 /**
237 Callback function which provided by user to remove one node in NetDestroyLinkList process.
238
239 @param[in] Entry The entry to be removed.
240 @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
241
242 @retval EFI_SUCCESS The entry has been removed successfully.
243 @retval Others Fail to remove the entry.
244
245 **/
246 EFI_STATUS
247 EFIAPI
248 ArpDestroyChildEntryInHandleBuffer (
249 IN LIST_ENTRY *Entry,
250 IN VOID *Context
251 )
252 {
253 ARP_INSTANCE_DATA *Instance;
254 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
255
256 if ((Entry == NULL) || (Context == NULL)) {
257 return EFI_INVALID_PARAMETER;
258 }
259
260 Instance = NET_LIST_USER_STRUCT_S (Entry, ARP_INSTANCE_DATA, List, ARP_INSTANCE_DATA_SIGNATURE);
261 ServiceBinding = (EFI_SERVICE_BINDING_PROTOCOL *)Context;
262
263 return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
264 }
265
266 /**
267 Tests to see if this driver supports a given controller.
268
269 If a child device is provided, it further tests to see if this driver supports
270 creating a handle for the specified child device.
271
272 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
273 @param[in] ControllerHandle The handle of the controller to test. This handle
274 must support a protocol interface that supplies
275 an I/O abstraction to the driver.
276 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path.
277 This parameter is ignored by device drivers,
278 and is optional for bus drivers.
279
280 @retval EFI_SUCCESS The device specified by ControllerHandle and
281 RemainingDevicePath is supported by the driver
282 specified by This.
283 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
284 RemainingDevicePath is already being managed
285 by the driver specified by This.
286 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
287 RemainingDevicePath is already being managed by
288 a different driver or an application that
289 requires exclusive access. Currently not implemented.
290 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
291 RemainingDevicePath is not supported by the
292 driver specified by This.
293
294 **/
295 EFI_STATUS
296 EFIAPI
297 ArpDriverBindingSupported (
298 IN EFI_DRIVER_BINDING_PROTOCOL *This,
299 IN EFI_HANDLE ControllerHandle,
300 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
301 )
302 {
303 EFI_STATUS Status;
304
305 //
306 // Test to see if Arp SB is already installed.
307 //
308 Status = gBS->OpenProtocol (
309 ControllerHandle,
310 &gEfiArpServiceBindingProtocolGuid,
311 NULL,
312 This->DriverBindingHandle,
313 ControllerHandle,
314 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
315 );
316 if (Status == EFI_SUCCESS) {
317 return EFI_ALREADY_STARTED;
318 }
319
320 //
321 // Test to see if MNP SB is installed.
322 //
323 Status = gBS->OpenProtocol (
324 ControllerHandle,
325 &gEfiManagedNetworkServiceBindingProtocolGuid,
326 NULL,
327 This->DriverBindingHandle,
328 ControllerHandle,
329 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
330 );
331
332 return Status;
333 }
334
335 /**
336 Start this driver on ControllerHandle.
337
338 The Start() function is designed to be invoked from the EFI boot service ConnectController().
339 As a result, much of the error checking on the parameters to Start() has been
340 moved into this common boot service. It is legal to call Start() from other locations,
341 but the following calling restrictions must be followed or the system behavior
342 will not be deterministic.
343 1. ControllerHandle must be a valid EFI_HANDLE.
344 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally
345 aligned EFI_DEVICE_PATH_PROTOCOL.
346 3. Prior to calling Start(), the Supported() function for the driver specified
347 by This must have been called with the same calling parameters, and Supported()
348 must have returned EFI_SUCCESS.
349
350 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
351 @param[in] ControllerHandle The handle of the controller to start. This handle
352 must support a protocol interface that supplies
353 an I/O abstraction to the driver.
354 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path.
355 This parameter is ignored by device drivers,
356 and is optional for bus drivers.
357
358 @retval EFI_SUCCESS The device was started.
359 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.
360 Currently not implemented.
361 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of
362 resources.
363 @retval Others The driver failed to start the device.
364
365 **/
366 EFI_STATUS
367 EFIAPI
368 ArpDriverBindingStart (
369 IN EFI_DRIVER_BINDING_PROTOCOL *This,
370 IN EFI_HANDLE ControllerHandle,
371 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
372 )
373 {
374 EFI_STATUS Status;
375 ARP_SERVICE_DATA *ArpService;
376
377 //
378 // Allocate a zero pool for ArpService.
379 //
380 ArpService = AllocateZeroPool (sizeof (ARP_SERVICE_DATA));
381 if (ArpService == NULL) {
382 return EFI_OUT_OF_RESOURCES;
383 }
384
385 //
386 // Initialize the arp service context data.
387 //
388 Status = ArpCreateService (This->DriverBindingHandle, ControllerHandle, ArpService);
389 if (EFI_ERROR (Status)) {
390 goto ERROR;
391 }
392
393 //
394 // Install the ARP service binding protocol.
395 //
396 Status = gBS->InstallMultipleProtocolInterfaces (
397 &ControllerHandle,
398 &gEfiArpServiceBindingProtocolGuid,
399 &ArpService->ServiceBinding,
400 NULL
401 );
402 if (EFI_ERROR (Status)) {
403 goto ERROR;
404 }
405
406 //
407 // OK, start to receive arp packets from Mnp.
408 //
409 Status = ArpService->Mnp->Receive (ArpService->Mnp, &ArpService->RxToken);
410 if (EFI_ERROR (Status)) {
411 goto ERROR;
412 }
413
414 return Status;
415
416 ERROR:
417
418 //
419 // On error, clean the arp service context data, and free the memory allocated.
420 //
421 ArpCleanService (ArpService);
422 FreePool (ArpService);
423
424 return Status;
425 }
426
427 /**
428 Stop this driver on ControllerHandle.
429
430 Release the control of this controller and remove the IScsi functions. The Stop()
431 function is designed to be invoked from the EFI boot service DisconnectController().
432 As a result, much of the error checking on the parameters to Stop() has been moved
433 into this common boot service. It is legal to call Stop() from other locations,
434 but the following calling restrictions must be followed or the system behavior
435 will not be deterministic.
436 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
437 same driver's Start() function.
438 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
439 EFI_HANDLE. In addition, all of these handles must have been created in this driver's
440 Start() function, and the Start() function must have called OpenProtocol() on
441 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
442
443 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
444 @param[in] ControllerHandle A handle to the device being stopped. The handle must
445 support a bus specific I/O protocol for the driver
446 to use to stop the device.
447 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
448 Not used.
449 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
450 if NumberOfChildren is 0.Not used.
451
452 @retval EFI_SUCCESS The device was stopped.
453 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
454
455 **/
456 EFI_STATUS
457 EFIAPI
458 ArpDriverBindingStop (
459 IN EFI_DRIVER_BINDING_PROTOCOL *This,
460 IN EFI_HANDLE ControllerHandle,
461 IN UINTN NumberOfChildren,
462 IN EFI_HANDLE *ChildHandleBuffer
463 )
464 {
465 EFI_STATUS Status;
466 EFI_HANDLE NicHandle;
467 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
468 ARP_SERVICE_DATA *ArpService;
469 LIST_ENTRY *List;
470
471 //
472 // Get the NicHandle which the arp servicebinding is installed on.
473 //
474 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);
475 if (NicHandle == NULL) {
476 return EFI_SUCCESS;
477 }
478
479 //
480 // Try to get the arp servicebinding protocol on the NicHandle.
481 //
482 Status = gBS->OpenProtocol (
483 NicHandle,
484 &gEfiArpServiceBindingProtocolGuid,
485 (VOID **)&ServiceBinding,
486 This->DriverBindingHandle,
487 ControllerHandle,
488 EFI_OPEN_PROTOCOL_GET_PROTOCOL
489 );
490 if (EFI_ERROR (Status)) {
491 DEBUG ((DEBUG_ERROR, "ArpDriverBindingStop: Open ArpSb failed, %r.\n", Status));
492 return EFI_DEVICE_ERROR;
493 }
494
495 ArpService = ARP_SERVICE_DATA_FROM_THIS (ServiceBinding);
496
497 if (NumberOfChildren != 0) {
498 //
499 // NumberOfChildren is not zero, destroy all the ARP children instances.
500 //
501 List = &ArpService->ChildrenList;
502 Status = NetDestroyLinkList (
503 List,
504 ArpDestroyChildEntryInHandleBuffer,
505 ServiceBinding,
506 NULL
507 );
508 ASSERT (IsListEmpty (&ArpService->PendingRequestTable));
509 ASSERT (IsListEmpty (&ArpService->DeniedCacheTable));
510 ASSERT (IsListEmpty (&ArpService->ResolvedCacheTable));
511 } else if (IsListEmpty (&ArpService->ChildrenList)) {
512 //
513 // Uninstall the ARP ServiceBinding protocol.
514 //
515 gBS->UninstallMultipleProtocolInterfaces (
516 NicHandle,
517 &gEfiArpServiceBindingProtocolGuid,
518 &ArpService->ServiceBinding,
519 NULL
520 );
521
522 //
523 // Clean the arp servicebinding context data and free the memory allocated.
524 //
525 ArpCleanService (ArpService);
526
527 FreePool (ArpService);
528 }
529
530 return EFI_SUCCESS;
531 }
532
533 /**
534 Creates a child handle and installs a protocol.
535
536 The CreateChild() function installs a protocol on ChildHandle.
537 If ChildHandle is a pointer to NULL, then a new handle is created and returned
538 in ChildHandle. If ChildHandle is not a pointer to NULL, then the protocol
539 installs on the existing ChildHandle.
540
541 @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
542 @param ChildHandle Pointer to the handle of the child to create. If it is NULL,
543 then a new handle is created. If it is a pointer to an existing
544 UEFI handle, then the protocol is added to the existing UEFI handle.
545
546 @retval EFI_SUCCESS The protocol was added to ChildHandle.
547 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
548 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
549 the child
550 @retval other The child handle was not created
551
552 **/
553 EFI_STATUS
554 EFIAPI
555 ArpServiceBindingCreateChild (
556 IN EFI_SERVICE_BINDING_PROTOCOL *This,
557 IN EFI_HANDLE *ChildHandle
558 )
559 {
560 EFI_STATUS Status;
561 ARP_SERVICE_DATA *ArpService;
562 ARP_INSTANCE_DATA *Instance;
563 VOID *Mnp;
564 EFI_TPL OldTpl;
565
566 if ((This == NULL) || (ChildHandle == NULL)) {
567 return EFI_INVALID_PARAMETER;
568 }
569
570 ArpService = ARP_SERVICE_DATA_FROM_THIS (This);
571
572 //
573 // Allocate memory for the instance context data.
574 //
575 Instance = AllocateZeroPool (sizeof (ARP_INSTANCE_DATA));
576 if (Instance == NULL) {
577 DEBUG ((DEBUG_ERROR, "ArpSBCreateChild: Failed to allocate memory for Instance.\n"));
578
579 return EFI_OUT_OF_RESOURCES;
580 }
581
582 //
583 // Init the instance context data.
584 //
585 ArpInitInstance (ArpService, Instance);
586
587 //
588 // Install the ARP protocol onto the ChildHandle.
589 //
590 Status = gBS->InstallMultipleProtocolInterfaces (
591 ChildHandle,
592 &gEfiArpProtocolGuid,
593 (VOID *)&Instance->ArpProto,
594 NULL
595 );
596 if (EFI_ERROR (Status)) {
597 DEBUG ((DEBUG_ERROR, "ArpSBCreateChild: failed to install ARP protocol, %r.\n", Status));
598
599 FreePool (Instance);
600 return Status;
601 }
602
603 //
604 // Save the ChildHandle.
605 //
606 Instance->Handle = *ChildHandle;
607
608 //
609 // Open the Managed Network protocol BY_CHILD.
610 //
611 Status = gBS->OpenProtocol (
612 ArpService->MnpChildHandle,
613 &gEfiManagedNetworkProtocolGuid,
614 (VOID **)&Mnp,
615 gArpDriverBinding.DriverBindingHandle,
616 Instance->Handle,
617 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
618 );
619 if (EFI_ERROR (Status)) {
620 goto ERROR;
621 }
622
623 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
624
625 //
626 // Insert the instance into children list managed by the arp service context data.
627 //
628 InsertTailList (&ArpService->ChildrenList, &Instance->List);
629 ArpService->ChildrenNumber++;
630
631 gBS->RestoreTPL (OldTpl);
632
633 ERROR:
634
635 if (EFI_ERROR (Status)) {
636 gBS->CloseProtocol (
637 ArpService->MnpChildHandle,
638 &gEfiManagedNetworkProtocolGuid,
639 gArpDriverBinding.DriverBindingHandle,
640 Instance->Handle
641 );
642
643 gBS->UninstallMultipleProtocolInterfaces (
644 Instance->Handle,
645 &gEfiArpProtocolGuid,
646 &Instance->ArpProto,
647 NULL
648 );
649
650 //
651 // Free the allocated memory.
652 //
653 FreePool (Instance);
654 }
655
656 return Status;
657 }
658
659 /**
660 Destroys a child handle with a protocol installed on it.
661
662 The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
663 that was installed by CreateChild() from ChildHandle. If the removed protocol is the
664 last protocol on ChildHandle, then ChildHandle is destroyed.
665
666 @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
667 @param ChildHandle Handle of the child to destroy
668
669 @retval EFI_SUCCESS The protocol was removed from ChildHandle.
670 @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is
671 being removed.
672 @retval EFI_INVALID_PARAMETER Child handle is NULL.
673 @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
674 because its services are being used.
675 @retval other The child handle was not destroyed
676
677 **/
678 EFI_STATUS
679 EFIAPI
680 ArpServiceBindingDestroyChild (
681 IN EFI_SERVICE_BINDING_PROTOCOL *This,
682 IN EFI_HANDLE ChildHandle
683 )
684 {
685 EFI_STATUS Status;
686 ARP_SERVICE_DATA *ArpService;
687 ARP_INSTANCE_DATA *Instance;
688 EFI_ARP_PROTOCOL *Arp;
689 EFI_TPL OldTpl;
690
691 if ((This == NULL) || (ChildHandle == NULL)) {
692 return EFI_INVALID_PARAMETER;
693 }
694
695 ArpService = ARP_SERVICE_DATA_FROM_THIS (This);
696
697 //
698 // Get the arp protocol.
699 //
700 Status = gBS->OpenProtocol (
701 ChildHandle,
702 &gEfiArpProtocolGuid,
703 (VOID **)&Arp,
704 ArpService->ImageHandle,
705 ChildHandle,
706 EFI_OPEN_PROTOCOL_GET_PROTOCOL
707 );
708 if (EFI_ERROR (Status)) {
709 return EFI_UNSUPPORTED;
710 }
711
712 Instance = ARP_INSTANCE_DATA_FROM_THIS (Arp);
713
714 if (Instance->InDestroy) {
715 return EFI_SUCCESS;
716 }
717
718 //
719 // Use the InDestroy as a flag to avoid re-entrance.
720 //
721 Instance->InDestroy = TRUE;
722
723 //
724 // Close the Managed Network protocol.
725 //
726 gBS->CloseProtocol (
727 ArpService->MnpChildHandle,
728 &gEfiManagedNetworkProtocolGuid,
729 gArpDriverBinding.DriverBindingHandle,
730 ChildHandle
731 );
732
733 //
734 // Uninstall the ARP protocol.
735 //
736 Status = gBS->UninstallMultipleProtocolInterfaces (
737 ChildHandle,
738 &gEfiArpProtocolGuid,
739 &Instance->ArpProto,
740 NULL
741 );
742 if (EFI_ERROR (Status)) {
743 DEBUG ((
744 DEBUG_ERROR,
745 "ArpSBDestroyChild: Failed to uninstall the arp protocol, %r.\n",
746 Status
747 ));
748
749 Instance->InDestroy = FALSE;
750 return Status;
751 }
752
753 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
754
755 if (Instance->Configured) {
756 //
757 // Delete the related cache entry.
758 //
759 ArpDeleteCacheEntry (Instance, FALSE, NULL, TRUE);
760
761 //
762 // Reset the instance configuration.
763 //
764 ArpConfigureInstance (Instance, NULL);
765 }
766
767 //
768 // Remove this instance from the ChildrenList.
769 //
770 RemoveEntryList (&Instance->List);
771 ArpService->ChildrenNumber--;
772
773 gBS->RestoreTPL (OldTpl);
774
775 FreePool (Instance);
776
777 return Status;
778 }
779
780 /**
781 The entry point for Arp driver which installs the driver binding and component name
782 protocol on its ImageHandle.
783
784 @param[in] ImageHandle The image handle of the driver.
785 @param[in] SystemTable The system table.
786
787 @retval EFI_SUCCESS if the driver binding and component name protocols
788 are successfully
789 @retval Others Failed to install the protocols.
790
791 **/
792 EFI_STATUS
793 EFIAPI
794 ArpDriverEntryPoint (
795 IN EFI_HANDLE ImageHandle,
796 IN EFI_SYSTEM_TABLE *SystemTable
797 )
798 {
799 return EfiLibInstallDriverBindingComponentName2 (
800 ImageHandle,
801 SystemTable,
802 &gArpDriverBinding,
803 ImageHandle,
804 &gArpComponentName,
805 &gArpComponentName2
806 );
807 }