--- /dev/null
+/** @file\r
+\r
+Copyright (c) 2006, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+ ArpDriver.c\r
+\r
+Abstract:\r
+\r
+\r
+**/\r
+\r
+\r
+#include "ArpDriver.h"\r
+#include "ArpImpl.h"\r
+\r
+EFI_DRIVER_BINDING_PROTOCOL gArpDriverBinding = {\r
+ ArpDriverBindingSupported,\r
+ ArpDriverBindingStart,\r
+ ArpDriverBindingStop,\r
+ 0xa,\r
+ NULL,\r
+ NULL\r
+};\r
+\r
+\r
+/**\r
+ Create and initialize the arp service context data.\r
+\r
+ @param ImageHandle The image handle representing the loaded driver\r
+ image.\r
+ @param ControllerHandle The controller handle the driver binds to.\r
+ @param ArpService Pointer to the buffer containing the arp service\r
+ context data.\r
+\r
+ @retval EFI_SUCCESS The arp service context is initialized.\r
+ @retval other Failed to initialize the arp service context.\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+ArpCreateService (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN ARP_SERVICE_DATA *ArpService\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ ASSERT (ArpService != NULL);\r
+\r
+ ArpService->Signature = ARP_SERVICE_DATA_SIGNATURE;\r
+\r
+ //\r
+ // Init the servicebinding protocol members.\r
+ //\r
+ ArpService->ServiceBinding.CreateChild = ArpServiceBindingCreateChild;\r
+ ArpService->ServiceBinding.DestroyChild = ArpServiceBindingDestroyChild;\r
+\r
+ //\r
+ // Save the handles.\r
+ //\r
+ ArpService->ImageHandle = ImageHandle;\r
+ ArpService->ControllerHandle = ControllerHandle;\r
+\r
+ //\r
+ // Create a MNP child instance.\r
+ //\r
+ Status = NetLibCreateServiceChild (\r
+ ControllerHandle,\r
+ ImageHandle,\r
+ &gEfiManagedNetworkServiceBindingProtocolGuid,\r
+ &ArpService->MnpChildHandle\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Open the MNP protocol.\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ ArpService->MnpChildHandle,\r
+ &gEfiManagedNetworkProtocolGuid,\r
+ (VOID **)&ArpService->Mnp,\r
+ ImageHandle,\r
+ ControllerHandle,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ERROR_EXIT;\r
+ }\r
+\r
+ //\r
+ // Get the underlayer Snp mode data.\r
+ //\r
+ Status = ArpService->Mnp->GetModeData (ArpService->Mnp, NULL, &ArpService->SnpMode);\r
+ if ((Status != EFI_NOT_STARTED) && EFI_ERROR (Status)) {\r
+ goto ERROR_EXIT;\r
+ }\r
+\r
+ if (ArpService->SnpMode.IfType != NET_IFTYPE_ETHERNET) {\r
+ //\r
+ // Only support the ethernet.\r
+ //\r
+ Status = EFI_UNSUPPORTED;\r
+ goto ERROR_EXIT;\r
+ }\r
+\r
+ //\r
+ // Set the Mnp config parameters.\r
+ //\r
+ ArpService->MnpConfigData.ReceivedQueueTimeoutValue = 0;\r
+ ArpService->MnpConfigData.TransmitQueueTimeoutValue = 0;\r
+ ArpService->MnpConfigData.ProtocolTypeFilter = ARP_ETHER_PROTO_TYPE;\r
+ ArpService->MnpConfigData.EnableUnicastReceive = TRUE;\r
+ ArpService->MnpConfigData.EnableMulticastReceive = FALSE;\r
+ ArpService->MnpConfigData.EnableBroadcastReceive = TRUE;\r
+ ArpService->MnpConfigData.EnablePromiscuousReceive = FALSE;\r
+ ArpService->MnpConfigData.FlushQueuesOnReset = TRUE;\r
+ ArpService->MnpConfigData.EnableReceiveTimestamps = FALSE;\r
+ ArpService->MnpConfigData.DisableBackgroundPolling = FALSE;\r
+\r
+ //\r
+ // Configure the Mnp child.\r
+ //\r
+ Status = ArpService->Mnp->Configure (ArpService->Mnp, &ArpService->MnpConfigData);\r
+ if (EFI_ERROR (Status)) {\r
+ goto ERROR_EXIT;\r
+ }\r
+\r
+ //\r
+ // Create the event used in the RxToken.\r
+ //\r
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_SIGNAL,\r
+ NET_TPL_EVENT,\r
+ ArpOnFrameRcvd,\r
+ ArpService,\r
+ &ArpService->RxToken.Event\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ERROR_EXIT;\r
+ }\r
+\r
+ //\r
+ // Create the Arp heartbeat timer.\r
+ //\r
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_SIGNAL | EVT_TIMER,\r
+ NET_TPL_TIMER,\r
+ ArpTimerHandler,\r
+ ArpService,\r
+ &ArpService->PeriodicTimer\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ERROR_EXIT;\r
+ }\r
+\r
+ //\r
+ // Start the heartbeat timer.\r
+ //\r
+ Status = gBS->SetTimer (\r
+ ArpService->PeriodicTimer,\r
+ TimerPeriodic,\r
+ ARP_PERIODIC_TIMER_INTERVAL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ERROR_EXIT;\r
+ }\r
+\r
+ //\r
+ // Init the lock.\r
+ //\r
+ NET_LOCK_INIT (&ArpService->Lock);\r
+\r
+ //\r
+ // Init the lists.\r
+ //\r
+ NetListInit (&ArpService->ChildrenList);\r
+ NetListInit (&ArpService->PendingRequestTable);\r
+ NetListInit (&ArpService->DeniedCacheTable);\r
+ NetListInit (&ArpService->ResolvedCacheTable);\r
+\r
+ERROR_EXIT:\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ Clean the arp service context data.\r
+\r
+ @param ArpService Pointer to the buffer containing the arp service\r
+ context data.\r
+\r
+ @return None.\r
+\r
+**/\r
+STATIC\r
+VOID\r
+ArpCleanService (\r
+ IN ARP_SERVICE_DATA *ArpService\r
+ )\r
+{\r
+ NET_CHECK_SIGNATURE (ArpService, ARP_SERVICE_DATA_SIGNATURE);\r
+\r
+ if (ArpService->PeriodicTimer != NULL) {\r
+ //\r
+ // Cancle and close the PeriodicTimer.\r
+ //\r
+ gBS->SetTimer (ArpService->PeriodicTimer, TimerCancel, 0);\r
+ gBS->CloseEvent (ArpService->PeriodicTimer);\r
+ }\r
+\r
+ if (ArpService->RxToken.Event != NULL) {\r
+ //\r
+ // Cancle the RxToken and close the event in the RxToken.\r
+ //\r
+ ArpService->Mnp->Cancel (ArpService->Mnp, NULL);\r
+ gBS->CloseEvent (ArpService->RxToken.Event);\r
+ }\r
+\r
+ if (ArpService->Mnp != NULL) {\r
+ //\r
+ // Reset the Mnp child and close the Mnp protocol.\r
+ //\r
+ ArpService->Mnp->Configure (ArpService->Mnp, NULL);\r
+ gBS->CloseProtocol (\r
+ ArpService->MnpChildHandle,\r
+ &gEfiManagedNetworkProtocolGuid,\r
+ ArpService->ImageHandle,\r
+ ArpService->ControllerHandle\r
+ );\r
+ }\r
+\r
+ if (ArpService->MnpChildHandle != NULL) {\r
+ //\r
+ // Destroy the mnp child.\r
+ //\r
+ NetLibDestroyServiceChild(\r
+ ArpService->ControllerHandle,\r
+ ArpService->ImageHandle,\r
+ &gEfiManagedNetworkServiceBindingProtocolGuid,\r
+ ArpService->MnpChildHandle\r
+ );\r
+ }\r
+}\r
+\r
+\r
+/**\r
+ Test to see if this driver supports ControllerHandle.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param ControllerHandle Handle of device to test.\r
+ @param RemainingDevicePath Optional parameter use to pick a specific child\r
+ device to start.\r
+\r
+ @retval EFI_SUCCES This driver supports this device\r
+ @retval EFI_ALREADY_STARTED This driver is already running on this device.\r
+ @retval other This driver does not support this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ArpDriverBindingSupported (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Test to see if Arp SB is already installed.\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ ControllerHandle,\r
+ &gEfiArpServiceBindingProtocolGuid,\r
+ NULL,\r
+ This->DriverBindingHandle,\r
+ ControllerHandle,\r
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+ );\r
+ if (Status == EFI_SUCCESS) {\r
+ return EFI_ALREADY_STARTED;\r
+ }\r
+\r
+ //\r
+ // Test to see if MNP SB is installed.\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ ControllerHandle,\r
+ &gEfiManagedNetworkServiceBindingProtocolGuid,\r
+ NULL,\r
+ This->DriverBindingHandle,\r
+ ControllerHandle,\r
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ Start this driver on ControllerHandle.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param ControllerHandle Handle of device to bind driver to\r
+ @param RemainingDevicePath Optional parameter use to pick a specific child\r
+ device to start.\r
+\r
+ @retval EFI_SUCCES This driver is added to ControllerHandle\r
+ @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle\r
+ @retval other This driver does not support this device\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ArpDriverBindingStart (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ ARP_SERVICE_DATA *ArpService;\r
+\r
+ //\r
+ // Allocate a zero pool for ArpService.\r
+ //\r
+ ArpService = NetAllocateZeroPool (sizeof(ARP_SERVICE_DATA));\r
+ if (ArpService == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ //\r
+ // Initialize the arp service context data.\r
+ //\r
+ Status = ArpCreateService (This->DriverBindingHandle, ControllerHandle, ArpService);\r
+ if (EFI_ERROR (Status)) {\r
+ goto ERROR;\r
+ }\r
+\r
+ //\r
+ // Install the ARP service binding protocol.\r
+ //\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &ControllerHandle,\r
+ &gEfiArpServiceBindingProtocolGuid,\r
+ &ArpService->ServiceBinding,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ERROR;\r
+ }\r
+\r
+ //\r
+ // OK, start to receive arp packets from Mnp.\r
+ //\r
+ Status = ArpService->Mnp->Receive (ArpService->Mnp, &ArpService->RxToken);\r
+ if (EFI_ERROR (Status)) {\r
+ goto ERROR;\r
+ }\r
+\r
+ return Status;\r
+\r
+ERROR:\r
+\r
+ //\r
+ // On error, clean the arp service context data, and free the memory allocated.\r
+ //\r
+ ArpCleanService (ArpService);\r
+ NetFreePool (ArpService);\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ Stop this driver on ControllerHandle.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param ControllerHandle Handle of device to stop driver on\r
+ @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number\r
+ of children is zero stop the entire bus driver.\r
+ @param ChildHandleBuffer List of Child Handles to Stop.\r
+\r
+ @retval EFI_SUCCES This driver is removed ControllerHandle\r
+ @retval other This driver was not removed from this device\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ArpDriverBindingStop (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE *ChildHandleBuffer\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HANDLE NicHandle;\r
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;\r
+ ARP_SERVICE_DATA *ArpService;\r
+ ARP_INSTANCE_DATA *Instance;\r
+\r
+ //\r
+ // Get the NicHandle which the arp servicebinding is installed on.\r
+ //\r
+ NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);\r
+ if (NicHandle == NULL) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Try to get the arp servicebinding protocol on the NicHandle.\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ NicHandle,\r
+ &gEfiArpServiceBindingProtocolGuid,\r
+ (VOID **)&ServiceBinding,\r
+ This->DriverBindingHandle,\r
+ ControllerHandle,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ ARP_DEBUG_ERROR (("ArpDriverBindingStop: Open ArpSb failed, %r.\n", Status));\r
+ return Status;\r
+ }\r
+\r
+ ArpService = ARP_SERVICE_DATA_FROM_THIS (ServiceBinding);\r
+\r
+ while (!NetListIsEmpty (&ArpService->ChildrenList)) {\r
+ //\r
+ // Iterate all the instances.\r
+ //\r
+ Instance = NET_LIST_HEAD (&ArpService->ChildrenList, ARP_INSTANCE_DATA, List);\r
+\r
+ //\r
+ // Destroy this arp child.\r
+ //\r
+ ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);\r
+ }\r
+\r
+ ASSERT (NetListIsEmpty (&ArpService->PendingRequestTable));\r
+ ASSERT (NetListIsEmpty (&ArpService->DeniedCacheTable));\r
+ ASSERT (NetListIsEmpty (&ArpService->ResolvedCacheTable));\r
+\r
+ //\r
+ // Uninstall the ARP ServiceBinding protocol.\r
+ //\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ NicHandle,\r
+ &gEfiArpServiceBindingProtocolGuid,\r
+ &ArpService->ServiceBinding,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ ARP_DEBUG_ERROR (("ArpDriverBindingStop: Failed to uninstall ArpSb, %r.\n", Status));\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Clean the arp servicebinding context data and free the memory allocated.\r
+ //\r
+ ArpCleanService (ArpService);\r
+ NetFreePool (ArpService);\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ Creates a child handle with a set of I/O services.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param ChildHandle Pointer to the handle of the child to create. If\r
+ it is NULL, then a new handle is created. If it is\r
+ not NULL, then the I/O services are added to the\r
+ existing child handle.\r
+\r
+ @retval EFI_SUCCES The child handle was created with the I/O\r
+ services.\r
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources availabe to create\r
+ the child.\r
+ @retval other The child handle was not created.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ArpServiceBindingCreateChild (\r
+ IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE *ChildHandle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ ARP_SERVICE_DATA *ArpService;\r
+ ARP_INSTANCE_DATA *Instance;\r
+ VOID *Mnp;\r
+\r
+ if ((This == NULL) || (ChildHandle == NULL)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ ArpService = ARP_SERVICE_DATA_FROM_THIS (This);\r
+\r
+ //\r
+ // Allocate memory for the instance context data.\r
+ //\r
+ Instance = NetAllocateZeroPool (sizeof(ARP_INSTANCE_DATA));\r
+ if (Instance == NULL) {\r
+ ARP_DEBUG_ERROR (("ArpSBCreateChild: Failed to allocate memory for Instance.\n"));\r
+\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ //\r
+ // Init the instance context data.\r
+ //\r
+ ArpInitInstance (ArpService, Instance);\r
+\r
+ //\r
+ // Install the ARP protocol onto the ChildHandle.\r
+ //\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ ChildHandle,\r
+ &gEfiArpProtocolGuid,\r
+ (VOID *)&Instance->ArpProto,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ ARP_DEBUG_ERROR (("ArpSBCreateChild: faild to install ARP protocol, %r.\n", Status));\r
+\r
+ NetFreePool (Instance);\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Save the ChildHandle.\r
+ //\r
+ Instance->Handle = *ChildHandle;\r
+\r
+ //\r
+ // Open the Managed Network protocol BY_CHILD.\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ ArpService->MnpChildHandle,\r
+ &gEfiManagedNetworkProtocolGuid,\r
+ (VOID **) &Mnp,\r
+ gArpDriverBinding.DriverBindingHandle,\r
+ Instance->Handle,\r
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ERROR;\r
+ }\r
+\r
+ if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) {\r
+\r
+ Status = EFI_ACCESS_DENIED;\r
+ goto ERROR;\r
+ }\r
+\r
+ //\r
+ // Insert the instance into children list managed by the arp service context data.\r
+ //\r
+ NetListInsertTail (&ArpService->ChildrenList, &Instance->List);\r
+ ArpService->ChildrenNumber++;\r
+\r
+ NET_UNLOCK (&ArpService->Lock);\r
+\r
+ERROR:\r
+\r
+ if (EFI_ERROR (Status)) {\r
+\r
+ gBS->CloseProtocol (\r
+ ArpService->MnpChildHandle,\r
+ &gEfiManagedNetworkProtocolGuid,\r
+ gArpDriverBinding.DriverBindingHandle,\r
+ Instance->Handle\r
+ );\r
+\r
+ gBS->UninstallMultipleProtocolInterfaces (\r
+ Instance->Handle,\r
+ &gEfiArpProtocolGuid,\r
+ &Instance->ArpProto,\r
+ NULL\r
+ );\r
+\r
+ //\r
+ // Free the allocated memory.\r
+ //\r
+ NetFreePool (Instance);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ Destroys a child handle with a set of I/O services.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param ChildHandle Handle of the child to destroy.\r
+\r
+ @retval EFI_SUCCES The I/O services were removed from the child\r
+ handle.\r
+ @retval EFI_UNSUPPORTED The child handle does not support the I/O services\r
+ that are being removed.\r
+ @retval EFI_INVALID_PARAMETER Child handle is not a valid EFI Handle.\r
+ @retval EFI_ACCESS_DENIED The child handle could not be destroyed because\r
+ its I/O services are being used.\r
+ @retval other The child handle was not destroyed.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ArpServiceBindingDestroyChild (\r
+ IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ChildHandle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ ARP_SERVICE_DATA *ArpService;\r
+ ARP_INSTANCE_DATA *Instance;\r
+ EFI_ARP_PROTOCOL *Arp;\r
+\r
+ if ((This == NULL) || (ChildHandle == NULL)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ ArpService = ARP_SERVICE_DATA_FROM_THIS (This);\r
+\r
+ //\r
+ // Get the arp protocol.\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ ChildHandle,\r
+ &gEfiArpProtocolGuid,\r
+ (VOID **)&Arp,\r
+ ArpService->ImageHandle,\r
+ ChildHandle,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ Instance = ARP_INSTANCE_DATA_FROM_THIS (Arp);\r
+\r
+ if (Instance->Destroyed) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Use the Destroyed as a flag to avoid re-entrance.\r
+ //\r
+ Instance->Destroyed = TRUE;\r
+\r
+ //\r
+ // Close the Managed Network protocol.\r
+ //\r
+ gBS->CloseProtocol (\r
+ ArpService->MnpChildHandle,\r
+ &gEfiManagedNetworkProtocolGuid,\r
+ gArpDriverBinding.DriverBindingHandle,\r
+ ChildHandle\r
+ );\r
+\r
+ //\r
+ // Uninstall the ARP protocol.\r
+ //\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ ChildHandle,\r
+ &gEfiArpProtocolGuid,\r
+ &Instance->ArpProto,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ ARP_DEBUG_ERROR (("ArpSBDestroyChild: Failed to uninstall the arp protocol, %r.\n",\r
+ Status));\r
+\r
+ Instance->Destroyed = FALSE;\r
+ return Status;\r
+ }\r
+\r
+ if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) {\r
+ Instance->Destroyed = FALSE;\r
+ return EFI_ACCESS_DENIED;\r
+ }\r
+\r
+ if (Instance->Configured) {\r
+ //\r
+ // Delete the related cache entry.\r
+ //\r
+ ArpDeleteCacheEntry (Instance, FALSE, NULL, TRUE);\r
+\r
+ //\r
+ // Reset the instance configuration.\r
+ //\r
+ ArpConfigureInstance (Instance, NULL);\r
+ }\r
+\r
+ //\r
+ // Remove this instance from the ChildrenList.\r
+ //\r
+ NetListRemoveEntry (&Instance->List);\r
+ ArpService->ChildrenNumber--;\r
+\r
+ NET_UNLOCK (&ArpService->Lock);\r
+\r
+ NetFreePool (Instance);\r
+\r
+ return Status;\r
+}\r
+\r
+//@MT: EFI_DRIVER_ENTRY_POINT (ArpDriverEntryPoint)\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+ArpDriverEntryPoint (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ The entry point for Arp driver which installs the driver binding and component name\r
+ protocol on its ImageHandle.\r
+\r
+Arguments:\r
+\r
+ ImageHandle - The image handle of the driver.\r
+ SystemTable - The system table.\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - if the driver binding and component name protocols are successfully\r
+ installed, otherwise if failed.\r
+\r
+--*/\r
+{\r
+ return NetLibInstallAllDriverProtocols (\r
+ ImageHandle,\r
+ SystemTable,\r
+ &gArpDriverBinding,\r
+ ImageHandle,\r
+ &gArpComponentName,\r
+ NULL,\r
+ NULL\r
+ );\r
+}\r
+\r