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