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