]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/ArpDxe/ArpDriver.c
Initialize lists ArpService->PendingRequestTable/DeniedCacheTable/ResolvedCacheTable...
[mirror_edk2.git] / MdeModulePkg / Universal / Network / ArpDxe / ArpDriver.c
CommitLineData
772db4bb 1/** @file\r
0c323d07 2 ARP driver functions.\r
c6d0ee4b 3 \r
b24633c7 4Copyright (c) 2006 - 2010, 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
772db4bb 244/**\r
0c323d07 245 Tests to see if this driver supports a given controller. \r
c6d0ee4b 246 \r
0c323d07 247 If a child device is provided, it further tests to see if this driver supports \r
248 creating a handle for the specified child device.\r
249\r
250 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
251 @param[in] ControllerHandle The handle of the controller to test. This handle \r
252 must support a protocol interface that supplies \r
253 an I/O abstraction to the driver.\r
254 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. \r
255 This parameter is ignored by device drivers, \r
256 and is optional for bus drivers.\r
257\r
258 @retval EFI_SUCCESS The device specified by ControllerHandle and\r
259 RemainingDevicePath is supported by the driver \r
260 specified by This.\r
261 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and\r
262 RemainingDevicePath is already being managed \r
263 by the driver specified by This.\r
264 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and\r
265 RemainingDevicePath is already being managed by \r
266 a different driver or an application that \r
267 requires exclusive acces. Currently not implemented.\r
268 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and\r
269 RemainingDevicePath is not supported by the \r
270 driver specified by This.\r
772db4bb 271\r
272**/\r
273EFI_STATUS\r
274EFIAPI\r
275ArpDriverBindingSupported (\r
276 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
277 IN EFI_HANDLE ControllerHandle,\r
278 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
279 )\r
280{\r
281 EFI_STATUS Status;\r
282\r
283 //\r
284 // Test to see if Arp SB is already installed.\r
285 //\r
286 Status = gBS->OpenProtocol (\r
287 ControllerHandle,\r
288 &gEfiArpServiceBindingProtocolGuid,\r
289 NULL,\r
290 This->DriverBindingHandle,\r
291 ControllerHandle,\r
292 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
293 );\r
294 if (Status == EFI_SUCCESS) {\r
295 return EFI_ALREADY_STARTED;\r
296 }\r
297\r
298 //\r
299 // Test to see if MNP SB is installed.\r
300 //\r
301 Status = gBS->OpenProtocol (\r
302 ControllerHandle,\r
303 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
304 NULL,\r
305 This->DriverBindingHandle,\r
306 ControllerHandle,\r
307 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
308 );\r
309\r
310 return Status;\r
311}\r
312\r
313\r
314/**\r
0c323d07 315 Start this driver on ControllerHandle. \r
c6d0ee4b 316 \r
0c323d07 317 The Start() function is designed to be invoked from the EFI boot service ConnectController(). \r
318 As a result, much of the error checking on the parameters to Start() has been \r
319 moved into this common boot service. It is legal to call Start() from other locations, \r
320 but the following calling restrictions must be followed or the system behavior \r
321 will not be deterministic.\r
322 1. ControllerHandle must be a valid EFI_HANDLE.\r
323 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally \r
324 aligned EFI_DEVICE_PATH_PROTOCOL.\r
325 3. Prior to calling Start(), the Supported() function for the driver specified \r
326 by This must have been called with the same calling parameters, and Supported() \r
327 must have returned EFI_SUCCESS. \r
328\r
329 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
330 @param[in] ControllerHandle The handle of the controller to start. This handle \r
331 must support a protocol interface that supplies \r
332 an I/O abstraction to the driver.\r
333 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. \r
334 This parameter is ignored by device drivers, \r
335 and is optional for bus drivers.\r
336\r
337 @retval EFI_SUCCESS The device was started.\r
338 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.\r
339 Currently not implemented.\r
340 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of \r
341 resources.\r
342 @retval Others The driver failded to start the device.\r
772db4bb 343\r
344**/\r
345EFI_STATUS\r
346EFIAPI\r
347ArpDriverBindingStart (\r
348 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
349 IN EFI_HANDLE ControllerHandle,\r
350 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
351 )\r
352{\r
353 EFI_STATUS Status;\r
354 ARP_SERVICE_DATA *ArpService;\r
355\r
356 //\r
357 // Allocate a zero pool for ArpService.\r
358 //\r
e48e37fc 359 ArpService = AllocateZeroPool (sizeof(ARP_SERVICE_DATA));\r
772db4bb 360 if (ArpService == NULL) {\r
361 return EFI_OUT_OF_RESOURCES;\r
362 }\r
363\r
364 //\r
365 // Initialize the arp service context data.\r
366 //\r
367 Status = ArpCreateService (This->DriverBindingHandle, ControllerHandle, ArpService);\r
368 if (EFI_ERROR (Status)) {\r
369 goto ERROR;\r
370 }\r
371\r
372 //\r
373 // Install the ARP service binding protocol.\r
374 //\r
375 Status = gBS->InstallMultipleProtocolInterfaces (\r
376 &ControllerHandle,\r
377 &gEfiArpServiceBindingProtocolGuid,\r
378 &ArpService->ServiceBinding,\r
379 NULL\r
380 );\r
381 if (EFI_ERROR (Status)) {\r
382 goto ERROR;\r
383 }\r
384\r
385 //\r
386 // OK, start to receive arp packets from Mnp.\r
387 //\r
388 Status = ArpService->Mnp->Receive (ArpService->Mnp, &ArpService->RxToken);\r
389 if (EFI_ERROR (Status)) {\r
390 goto ERROR;\r
391 }\r
392\r
393 return Status;\r
394\r
395ERROR:\r
396\r
397 //\r
398 // On error, clean the arp service context data, and free the memory allocated.\r
399 //\r
400 ArpCleanService (ArpService);\r
766c7483 401 FreePool (ArpService);\r
772db4bb 402\r
403 return Status;\r
404}\r
405\r
406\r
407/**\r
0c323d07 408 Stop this driver on ControllerHandle. \r
c6d0ee4b 409 \r
0c323d07 410 Release the control of this controller and remove the IScsi functions. The Stop()\r
411 function is designed to be invoked from the EFI boot service DisconnectController(). \r
412 As a result, much of the error checking on the parameters to Stop() has been moved \r
413 into this common boot service. It is legal to call Stop() from other locations, \r
414 but the following calling restrictions must be followed or the system behavior \r
415 will not be deterministic.\r
416 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this\r
417 same driver's Start() function.\r
418 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid\r
419 EFI_HANDLE. In addition, all of these handles must have been created in this driver's\r
420 Start() function, and the Start() function must have called OpenProtocol() on\r
421 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.\r
c6d0ee4b 422 \r
0c323d07 423 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
424 @param[in] ControllerHandle A handle to the device being stopped. The handle must \r
425 support a bus specific I/O protocol for the driver \r
426 to use to stop the device.\r
427 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.\r
428 Not used.\r
429 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL \r
430 if NumberOfChildren is 0.Not used.\r
431\r
432 @retval EFI_SUCCESS The device was stopped.\r
433 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.\r
772db4bb 434\r
435**/\r
436EFI_STATUS\r
437EFIAPI\r
438ArpDriverBindingStop (\r
439 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
440 IN EFI_HANDLE ControllerHandle,\r
441 IN UINTN NumberOfChildren,\r
442 IN EFI_HANDLE *ChildHandleBuffer\r
443 )\r
444{\r
445 EFI_STATUS Status;\r
446 EFI_HANDLE NicHandle;\r
447 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;\r
448 ARP_SERVICE_DATA *ArpService;\r
449 ARP_INSTANCE_DATA *Instance;\r
450\r
451 //\r
452 // Get the NicHandle which the arp servicebinding is installed on.\r
453 //\r
454 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);\r
455 if (NicHandle == NULL) {\r
c4a62a12 456 return EFI_DEVICE_ERROR;\r
772db4bb 457 }\r
458\r
459 //\r
460 // Try to get the arp servicebinding protocol on the NicHandle.\r
461 //\r
462 Status = gBS->OpenProtocol (\r
463 NicHandle,\r
464 &gEfiArpServiceBindingProtocolGuid,\r
465 (VOID **)&ServiceBinding,\r
466 This->DriverBindingHandle,\r
467 ControllerHandle,\r
468 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
469 );\r
470 if (EFI_ERROR (Status)) {\r
e48e37fc 471 DEBUG ((EFI_D_ERROR, "ArpDriverBindingStop: Open ArpSb failed, %r.\n", Status));\r
c4a62a12 472 return EFI_DEVICE_ERROR;\r
772db4bb 473 }\r
474\r
475 ArpService = ARP_SERVICE_DATA_FROM_THIS (ServiceBinding);\r
476\r
c4a62a12 477 if (NumberOfChildren == 0) {\r
772db4bb 478 //\r
c4a62a12 479 // Uninstall the ARP ServiceBinding protocol.\r
772db4bb 480 //\r
c4a62a12 481 gBS->UninstallMultipleProtocolInterfaces (\r
482 NicHandle,\r
483 &gEfiArpServiceBindingProtocolGuid,\r
484 &ArpService->ServiceBinding,\r
485 NULL\r
486 );\r
772db4bb 487\r
488 //\r
c4a62a12 489 // Clean the arp servicebinding context data and free the memory allocated.\r
772db4bb 490 //\r
c4a62a12 491 ArpCleanService (ArpService);\r
772db4bb 492\r
766c7483 493 FreePool (ArpService);\r
c4a62a12 494 } else {\r
772db4bb 495\r
e48e37fc 496 while (!IsListEmpty (&ArpService->ChildrenList)) {\r
c4a62a12 497 Instance = NET_LIST_HEAD (&ArpService->ChildrenList, ARP_INSTANCE_DATA, List);\r
772db4bb 498\r
c4a62a12 499 ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);\r
500 }\r
772db4bb 501\r
e48e37fc 502 ASSERT (IsListEmpty (&ArpService->PendingRequestTable));\r
503 ASSERT (IsListEmpty (&ArpService->DeniedCacheTable));\r
504 ASSERT (IsListEmpty (&ArpService->ResolvedCacheTable));\r
c4a62a12 505 }\r
772db4bb 506\r
c4a62a12 507 return EFI_SUCCESS;\r
508}\r
772db4bb 509\r
510/**\r
0c323d07 511 Creates a child handle and installs a protocol.\r
512 \r
513 The CreateChild() function installs a protocol on ChildHandle. \r
514 If ChildHandle is a pointer to NULL, then a new handle is created and returned \r
515 in ChildHandle. If ChildHandle is not a pointer to NULL, then the protocol \r
516 installs on the existing ChildHandle.\r
517\r
518 @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.\r
519 @param ChildHandle Pointer to the handle of the child to create. If it is NULL,\r
520 then a new handle is created. If it is a pointer to an existing \r
521 UEFI handle, then the protocol is added to the existing UEFI handle.\r
522\r
523 @retval EFI_SUCCES The protocol was added to ChildHandle.\r
524 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.\r
525 @retval EFI_OUT_OF_RESOURCES There are not enough resources availabe to create\r
526 the child\r
527 @retval other The child handle was not created\r
772db4bb 528\r
529**/\r
530EFI_STATUS\r
531EFIAPI\r
532ArpServiceBindingCreateChild (\r
533 IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
534 IN EFI_HANDLE *ChildHandle\r
535 )\r
536{\r
537 EFI_STATUS Status;\r
538 ARP_SERVICE_DATA *ArpService;\r
539 ARP_INSTANCE_DATA *Instance;\r
540 VOID *Mnp;\r
36ee91ca 541 EFI_TPL OldTpl;\r
772db4bb 542\r
543 if ((This == NULL) || (ChildHandle == NULL)) {\r
544 return EFI_INVALID_PARAMETER;\r
545 }\r
546\r
547 ArpService = ARP_SERVICE_DATA_FROM_THIS (This);\r
548\r
549 //\r
550 // Allocate memory for the instance context data.\r
551 //\r
e48e37fc 552 Instance = AllocateZeroPool (sizeof(ARP_INSTANCE_DATA));\r
772db4bb 553 if (Instance == NULL) {\r
e48e37fc 554 DEBUG ((EFI_D_ERROR, "ArpSBCreateChild: Failed to allocate memory for Instance.\n"));\r
772db4bb 555\r
556 return EFI_OUT_OF_RESOURCES;\r
557 }\r
558\r
559 //\r
560 // Init the instance context data.\r
561 //\r
562 ArpInitInstance (ArpService, Instance);\r
563\r
564 //\r
565 // Install the ARP protocol onto the ChildHandle.\r
566 //\r
567 Status = gBS->InstallMultipleProtocolInterfaces (\r
568 ChildHandle,\r
569 &gEfiArpProtocolGuid,\r
570 (VOID *)&Instance->ArpProto,\r
571 NULL\r
572 );\r
573 if (EFI_ERROR (Status)) {\r
e48e37fc 574 DEBUG ((EFI_D_ERROR, "ArpSBCreateChild: faild to install ARP protocol, %r.\n", Status));\r
772db4bb 575\r
766c7483 576 FreePool (Instance);\r
772db4bb 577 return Status;\r
578 }\r
579\r
580 //\r
581 // Save the ChildHandle.\r
582 //\r
583 Instance->Handle = *ChildHandle;\r
584\r
585 //\r
586 // Open the Managed Network protocol BY_CHILD.\r
587 //\r
588 Status = gBS->OpenProtocol (\r
589 ArpService->MnpChildHandle,\r
590 &gEfiManagedNetworkProtocolGuid,\r
591 (VOID **) &Mnp,\r
592 gArpDriverBinding.DriverBindingHandle,\r
593 Instance->Handle,\r
594 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
595 );\r
596 if (EFI_ERROR (Status)) {\r
597 goto ERROR;\r
598 }\r
599\r
e48e37fc 600 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
772db4bb 601\r
602 //\r
603 // Insert the instance into children list managed by the arp service context data.\r
604 //\r
e48e37fc 605 InsertTailList (&ArpService->ChildrenList, &Instance->List);\r
772db4bb 606 ArpService->ChildrenNumber++;\r
607\r
e48e37fc 608 gBS->RestoreTPL (OldTpl);\r
772db4bb 609\r
610ERROR:\r
611\r
612 if (EFI_ERROR (Status)) {\r
613\r
614 gBS->CloseProtocol (\r
615 ArpService->MnpChildHandle,\r
616 &gEfiManagedNetworkProtocolGuid,\r
617 gArpDriverBinding.DriverBindingHandle,\r
618 Instance->Handle\r
619 );\r
620\r
621 gBS->UninstallMultipleProtocolInterfaces (\r
622 Instance->Handle,\r
623 &gEfiArpProtocolGuid,\r
624 &Instance->ArpProto,\r
625 NULL\r
626 );\r
627\r
628 //\r
629 // Free the allocated memory.\r
630 //\r
766c7483 631 FreePool (Instance);\r
772db4bb 632 }\r
633\r
634 return Status;\r
635}\r
636\r
637\r
638/**\r
0c323d07 639 Destroys a child handle with a protocol installed on it.\r
640 \r
641 The DestroyChild() function does the opposite of CreateChild(). It removes a protocol \r
642 that was installed by CreateChild() from ChildHandle. If the removed protocol is the \r
643 last protocol on ChildHandle, then ChildHandle is destroyed.\r
772db4bb 644\r
0c323d07 645 @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.\r
646 @param ChildHandle Handle of the child to destroy\r
772db4bb 647\r
0c323d07 648 @retval EFI_SUCCES The protocol was removed from ChildHandle.\r
649 @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is \r
650 being removed.\r
651 @retval EFI_INVALID_PARAMETER Child handle is not a valid UEFI Handle.\r
652 @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle\r
653 because its services are being used.\r
654 @retval other The child handle was not destroyed\r
772db4bb 655\r
656**/\r
657EFI_STATUS\r
658EFIAPI\r
659ArpServiceBindingDestroyChild (\r
660 IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
661 IN EFI_HANDLE ChildHandle\r
662 )\r
663{\r
664 EFI_STATUS Status;\r
665 ARP_SERVICE_DATA *ArpService;\r
666 ARP_INSTANCE_DATA *Instance;\r
667 EFI_ARP_PROTOCOL *Arp;\r
36ee91ca 668 EFI_TPL OldTpl;\r
772db4bb 669\r
670 if ((This == NULL) || (ChildHandle == NULL)) {\r
671 return EFI_INVALID_PARAMETER;\r
672 }\r
673\r
674 ArpService = ARP_SERVICE_DATA_FROM_THIS (This);\r
675\r
676 //\r
677 // Get the arp protocol.\r
678 //\r
679 Status = gBS->OpenProtocol (\r
680 ChildHandle,\r
681 &gEfiArpProtocolGuid,\r
682 (VOID **)&Arp,\r
683 ArpService->ImageHandle,\r
684 ChildHandle,\r
685 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
686 );\r
687 if (EFI_ERROR (Status)) {\r
688 return EFI_UNSUPPORTED;\r
689 }\r
690\r
691 Instance = ARP_INSTANCE_DATA_FROM_THIS (Arp);\r
692\r
693 if (Instance->Destroyed) {\r
694 return EFI_SUCCESS;\r
695 }\r
696\r
697 //\r
698 // Use the Destroyed as a flag to avoid re-entrance.\r
699 //\r
700 Instance->Destroyed = TRUE;\r
701\r
702 //\r
703 // Close the Managed Network protocol.\r
704 //\r
705 gBS->CloseProtocol (\r
706 ArpService->MnpChildHandle,\r
707 &gEfiManagedNetworkProtocolGuid,\r
708 gArpDriverBinding.DriverBindingHandle,\r
709 ChildHandle\r
710 );\r
711\r
712 //\r
713 // Uninstall the ARP protocol.\r
714 //\r
715 Status = gBS->UninstallMultipleProtocolInterfaces (\r
716 ChildHandle,\r
717 &gEfiArpProtocolGuid,\r
718 &Instance->ArpProto,\r
719 NULL\r
720 );\r
721 if (EFI_ERROR (Status)) {\r
e48e37fc 722 DEBUG ((EFI_D_ERROR, "ArpSBDestroyChild: Failed to uninstall the arp protocol, %r.\n",\r
772db4bb 723 Status));\r
724\r
725 Instance->Destroyed = FALSE;\r
726 return Status;\r
727 }\r
728\r
e48e37fc 729 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
772db4bb 730\r
731 if (Instance->Configured) {\r
732 //\r
733 // Delete the related cache entry.\r
734 //\r
735 ArpDeleteCacheEntry (Instance, FALSE, NULL, TRUE);\r
736\r
737 //\r
738 // Reset the instance configuration.\r
739 //\r
740 ArpConfigureInstance (Instance, NULL);\r
741 }\r
742\r
743 //\r
744 // Remove this instance from the ChildrenList.\r
745 //\r
e48e37fc 746 RemoveEntryList (&Instance->List);\r
772db4bb 747 ArpService->ChildrenNumber--;\r
748\r
e48e37fc 749 gBS->RestoreTPL (OldTpl);\r
772db4bb 750\r
766c7483 751 FreePool (Instance);\r
772db4bb 752\r
753 return Status;\r
754}\r
755\r
7bce0c5a 756/**\r
757 The entry point for Arp driver which installs the driver binding and component name\r
758 protocol on its ImageHandle.\r
759\r
c6d0ee4b 760 @param[in] ImageHandle The image handle of the driver.\r
761 @param[in] SystemTable The system table.\r
772db4bb 762\r
0c323d07 763 @retval EFI_SUCCESS if the driver binding and component name protocols \r
764 are successfully\r
7bce0c5a 765 @retval Others Failed to install the protocols.\r
766\r
767**/\r
772db4bb 768EFI_STATUS\r
769EFIAPI\r
770ArpDriverEntryPoint (\r
771 IN EFI_HANDLE ImageHandle,\r
772 IN EFI_SYSTEM_TABLE *SystemTable\r
773 )\r
772db4bb 774{\r
83cbd279 775 return EfiLibInstallDriverBindingComponentName2 (\r
772db4bb 776 ImageHandle,\r
777 SystemTable,\r
778 &gArpDriverBinding,\r
779 ImageHandle,\r
780 &gArpComponentName,\r
83cbd279 781 &gArpComponentName2\r
772db4bb 782 );\r
783}\r
784\r