]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/ArpDxe/ArpDriver.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Universal / Network / ArpDxe / ArpDriver.c
CommitLineData
772db4bb 1/** @file\r
0c323d07 2 ARP driver functions.\r
d1102dba
LG
3\r
4Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
9d510e61 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
772db4bb 6\r
772db4bb 7**/\r
8\r
772db4bb 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
0c323d07 25 @param[in] ImageHandle The image handle representing the loaded driver\r
c6d0ee4b 26 image.\r
0c323d07 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
c6d0ee4b 29 context data.\r
772db4bb 30\r
c6d0ee4b 31 @retval EFI_SUCCESS The arp service context is initialized.\r
d1102dba 32\r
0c323d07 33 @retval EFI_UNSUPPORTED The underlayer Snp mode type is not ethernet.\r
34 Failed to initialize the service context.\r
c6d0ee4b 35 @retval other Failed to initialize the arp service context.\r
772db4bb 36\r
37**/\r
772db4bb 38EFI_STATUS\r
39ArpCreateService (\r
40 IN EFI_HANDLE ImageHandle,\r
41 IN EFI_HANDLE ControllerHandle,\r
0c323d07 42 IN OUT ARP_SERVICE_DATA *ArpService\r
772db4bb 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
b24633c7 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
772db4bb 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
e48e37fc 142 TPL_NOTIFY,\r
772db4bb 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
e48e37fc 156 TPL_CALLBACK,\r
772db4bb 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
772db4bb 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
0c323d07 183 @param[in, out] ArpService Pointer to the buffer containing the arp service\r
c6d0ee4b 184 context data.\r
772db4bb 185\r
186 @return None.\r
187\r
188**/\r
772db4bb 189VOID\r
190ArpCleanService (\r
0c323d07 191 IN OUT ARP_SERVICE_DATA *ArpService\r
772db4bb 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
216f7970 238/**\r
239 Callback function which provided by user to remove one node in NetDestroyLinkList process.\r
d1102dba 240\r
216f7970 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
1f7eb561 249EFIAPI\r
216f7970 250ArpDestroyChildEntryInHandleBuffer (\r
251 IN LIST_ENTRY *Entry,\r
252 IN VOID *Context\r
1f7eb561 253 )\r
216f7970 254{\r
255 ARP_INSTANCE_DATA *Instance;\r
256 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;\r
d1102dba 257\r
216f7970 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
772db4bb 268/**\r
d1102dba
LG
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
0c323d07 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
d1102dba
LG
275 @param[in] ControllerHandle The handle of the controller to test. This handle\r
276 must support a protocol interface that supplies\r
0c323d07 277 an I/O abstraction to the driver.\r
d1102dba
LG
278 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path.\r
279 This parameter is ignored by device drivers,\r
0c323d07 280 and is optional for bus drivers.\r
281\r
282 @retval EFI_SUCCESS The device specified by ControllerHandle and\r
d1102dba 283 RemainingDevicePath is supported by the driver\r
0c323d07 284 specified by This.\r
285 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and\r
d1102dba 286 RemainingDevicePath is already being managed\r
0c323d07 287 by the driver specified by This.\r
288 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and\r
d1102dba
LG
289 RemainingDevicePath is already being managed by\r
290 a different driver or an application that\r
0c323d07 291 requires exclusive acces. Currently not implemented.\r
292 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and\r
d1102dba 293 RemainingDevicePath is not supported by the\r
0c323d07 294 driver specified by This.\r
772db4bb 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
d1102dba
LG
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
0c323d07 345 will not be deterministic.\r
346 1. ControllerHandle must be a valid EFI_HANDLE.\r
d1102dba 347 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally\r
0c323d07 348 aligned EFI_DEVICE_PATH_PROTOCOL.\r
d1102dba
LG
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
0c323d07 352\r
353 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
d1102dba
LG
354 @param[in] ControllerHandle The handle of the controller to start. This handle\r
355 must support a protocol interface that supplies\r
0c323d07 356 an I/O abstraction to the driver.\r
d1102dba
LG
357 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path.\r
358 This parameter is ignored by device drivers,\r
0c323d07 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
d1102dba 364 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of\r
0c323d07 365 resources.\r
366 @retval Others The driver failded to start the device.\r
772db4bb 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
e48e37fc 383 ArpService = AllocateZeroPool (sizeof(ARP_SERVICE_DATA));\r
772db4bb 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
766c7483 425 FreePool (ArpService);\r
772db4bb 426\r
427 return Status;\r
428}\r
429\r
430\r
431/**\r
d1102dba
LG
432 Stop this driver on ControllerHandle.\r
433\r
0c323d07 434 Release the control of this controller and remove the IScsi functions. The Stop()\r
d1102dba
LG
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
0c323d07 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
d1102dba 446\r
0c323d07 447 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
d1102dba
LG
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
0c323d07 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
d1102dba 453 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL\r
0c323d07 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
772db4bb 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
216f7970 473 LIST_ENTRY *List;\r
772db4bb 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
216f7970 480 return EFI_SUCCESS;\r
772db4bb 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
e48e37fc 495 DEBUG ((EFI_D_ERROR, "ArpDriverBindingStop: Open ArpSb failed, %r.\n", Status));\r
c4a62a12 496 return EFI_DEVICE_ERROR;\r
772db4bb 497 }\r
498\r
499 ArpService = ARP_SERVICE_DATA_FROM_THIS (ServiceBinding);\r
500\r
216f7970 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
772db4bb 516 //\r
c4a62a12 517 // Uninstall the ARP ServiceBinding protocol.\r
772db4bb 518 //\r
c4a62a12 519 gBS->UninstallMultipleProtocolInterfaces (\r
520 NicHandle,\r
521 &gEfiArpServiceBindingProtocolGuid,\r
522 &ArpService->ServiceBinding,\r
523 NULL\r
524 );\r
772db4bb 525\r
526 //\r
c4a62a12 527 // Clean the arp servicebinding context data and free the memory allocated.\r
772db4bb 528 //\r
c4a62a12 529 ArpCleanService (ArpService);\r
772db4bb 530\r
766c7483 531 FreePool (ArpService);\r
c4a62a12 532 }\r
772db4bb 533\r
c4a62a12 534 return EFI_SUCCESS;\r
535}\r
772db4bb 536\r
537/**\r
0c323d07 538 Creates a child handle and installs a protocol.\r
d1102dba
LG
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
0c323d07 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
d1102dba 547 then a new handle is created. If it is a pointer to an existing\r
0c323d07 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
2048c585 552 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create\r
0c323d07 553 the child\r
554 @retval other The child handle was not created\r
772db4bb 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
36ee91ca 568 EFI_TPL OldTpl;\r
772db4bb 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
e48e37fc 579 Instance = AllocateZeroPool (sizeof(ARP_INSTANCE_DATA));\r
772db4bb 580 if (Instance == NULL) {\r
e48e37fc 581 DEBUG ((EFI_D_ERROR, "ArpSBCreateChild: Failed to allocate memory for Instance.\n"));\r
772db4bb 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
e48e37fc 601 DEBUG ((EFI_D_ERROR, "ArpSBCreateChild: faild to install ARP protocol, %r.\n", Status));\r
772db4bb 602\r
766c7483 603 FreePool (Instance);\r
772db4bb 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
e48e37fc 627 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
772db4bb 628\r
629 //\r
630 // Insert the instance into children list managed by the arp service context data.\r
631 //\r
e48e37fc 632 InsertTailList (&ArpService->ChildrenList, &Instance->List);\r
772db4bb 633 ArpService->ChildrenNumber++;\r
634\r
e48e37fc 635 gBS->RestoreTPL (OldTpl);\r
772db4bb 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
766c7483 658 FreePool (Instance);\r
772db4bb 659 }\r
660\r
661 return Status;\r
662}\r
663\r
664\r
665/**\r
0c323d07 666 Destroys a child handle with a protocol installed on it.\r
d1102dba
LG
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
0c323d07 670 last protocol on ChildHandle, then ChildHandle is destroyed.\r
772db4bb 671\r
0c323d07 672 @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.\r
673 @param ChildHandle Handle of the child to destroy\r
772db4bb 674\r
0c323d07 675 @retval EFI_SUCCES The protocol was removed from ChildHandle.\r
d1102dba 676 @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is\r
0c323d07 677 being removed.\r
284ee2e8 678 @retval EFI_INVALID_PARAMETER Child handle is NULL.\r
0c323d07 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
772db4bb 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
36ee91ca 695 EFI_TPL OldTpl;\r
772db4bb 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
216f7970 720 if (Instance->InDestroy) {\r
772db4bb 721 return EFI_SUCCESS;\r
722 }\r
723\r
724 //\r
216f7970 725 // Use the InDestroy as a flag to avoid re-entrance.\r
772db4bb 726 //\r
216f7970 727 Instance->InDestroy = TRUE;\r
772db4bb 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
e48e37fc 749 DEBUG ((EFI_D_ERROR, "ArpSBDestroyChild: Failed to uninstall the arp protocol, %r.\n",\r
772db4bb 750 Status));\r
751\r
216f7970 752 Instance->InDestroy = FALSE;\r
772db4bb 753 return Status;\r
754 }\r
755\r
e48e37fc 756 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
772db4bb 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
e48e37fc 773 RemoveEntryList (&Instance->List);\r
772db4bb 774 ArpService->ChildrenNumber--;\r
775\r
e48e37fc 776 gBS->RestoreTPL (OldTpl);\r
772db4bb 777\r
766c7483 778 FreePool (Instance);\r
772db4bb 779\r
780 return Status;\r
781}\r
782\r
7bce0c5a 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
c6d0ee4b 787 @param[in] ImageHandle The image handle of the driver.\r
788 @param[in] SystemTable The system table.\r
772db4bb 789\r
d1102dba 790 @retval EFI_SUCCESS if the driver binding and component name protocols\r
0c323d07 791 are successfully\r
7bce0c5a 792 @retval Others Failed to install the protocols.\r
793\r
794**/\r
772db4bb 795EFI_STATUS\r
796EFIAPI\r
797ArpDriverEntryPoint (\r
798 IN EFI_HANDLE ImageHandle,\r
799 IN EFI_SYSTEM_TABLE *SystemTable\r
800 )\r
772db4bb 801{\r
83cbd279 802 return EfiLibInstallDriverBindingComponentName2 (\r
772db4bb 803 ImageHandle,\r
804 SystemTable,\r
805 &gArpDriverBinding,\r
806 ImageHandle,\r
807 &gArpComponentName,\r
83cbd279 808 &gArpComponentName2\r
772db4bb 809 );\r
810}\r
811\r