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