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