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