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