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