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