123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807 |
- /** @file
- ARP driver functions.
- Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "ArpDriver.h"
- #include "ArpImpl.h"
- EFI_DRIVER_BINDING_PROTOCOL gArpDriverBinding = {
- ArpDriverBindingSupported,
- ArpDriverBindingStart,
- ArpDriverBindingStop,
- 0xa,
- NULL,
- NULL
- };
- /**
- Create and initialize the arp service context data.
- @param[in] ImageHandle The image handle representing the loaded driver
- image.
- @param[in] ControllerHandle The controller handle the driver binds to.
- @param[in, out] ArpService Pointer to the buffer containing the arp service
- context data.
- @retval EFI_SUCCESS The arp service context is initialized.
- @retval EFI_UNSUPPORTED The underlayer Snp mode type is not ethernet.
- Failed to initialize the service context.
- @retval other Failed to initialize the arp service context.
- **/
- EFI_STATUS
- ArpCreateService (
- IN EFI_HANDLE ImageHandle,
- IN EFI_HANDLE ControllerHandle,
- IN OUT ARP_SERVICE_DATA *ArpService
- )
- {
- EFI_STATUS Status;
- ASSERT (ArpService != NULL);
- ArpService->Signature = ARP_SERVICE_DATA_SIGNATURE;
- //
- // Init the lists.
- //
- InitializeListHead (&ArpService->ChildrenList);
- InitializeListHead (&ArpService->PendingRequestTable);
- InitializeListHead (&ArpService->DeniedCacheTable);
- InitializeListHead (&ArpService->ResolvedCacheTable);
- //
- // Init the servicebinding protocol members.
- //
- ArpService->ServiceBinding.CreateChild = ArpServiceBindingCreateChild;
- ArpService->ServiceBinding.DestroyChild = ArpServiceBindingDestroyChild;
- //
- // Save the handles.
- //
- ArpService->ImageHandle = ImageHandle;
- ArpService->ControllerHandle = ControllerHandle;
- //
- // Create a MNP child instance.
- //
- Status = NetLibCreateServiceChild (
- ControllerHandle,
- ImageHandle,
- &gEfiManagedNetworkServiceBindingProtocolGuid,
- &ArpService->MnpChildHandle
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- //
- // Open the MNP protocol.
- //
- Status = gBS->OpenProtocol (
- ArpService->MnpChildHandle,
- &gEfiManagedNetworkProtocolGuid,
- (VOID **)&ArpService->Mnp,
- ImageHandle,
- ControllerHandle,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
- if (EFI_ERROR (Status)) {
- goto ERROR_EXIT;
- }
- //
- // Get the underlayer Snp mode data.
- //
- Status = ArpService->Mnp->GetModeData (ArpService->Mnp, NULL, &ArpService->SnpMode);
- if ((Status != EFI_NOT_STARTED) && EFI_ERROR (Status)) {
- goto ERROR_EXIT;
- }
- if (ArpService->SnpMode.IfType != NET_IFTYPE_ETHERNET) {
- //
- // Only support the ethernet.
- //
- Status = EFI_UNSUPPORTED;
- goto ERROR_EXIT;
- }
- //
- // Set the Mnp config parameters.
- //
- ArpService->MnpConfigData.ReceivedQueueTimeoutValue = 0;
- ArpService->MnpConfigData.TransmitQueueTimeoutValue = 0;
- ArpService->MnpConfigData.ProtocolTypeFilter = ARP_ETHER_PROTO_TYPE;
- ArpService->MnpConfigData.EnableUnicastReceive = TRUE;
- ArpService->MnpConfigData.EnableMulticastReceive = FALSE;
- ArpService->MnpConfigData.EnableBroadcastReceive = TRUE;
- ArpService->MnpConfigData.EnablePromiscuousReceive = FALSE;
- ArpService->MnpConfigData.FlushQueuesOnReset = TRUE;
- ArpService->MnpConfigData.EnableReceiveTimestamps = FALSE;
- ArpService->MnpConfigData.DisableBackgroundPolling = FALSE;
- //
- // Configure the Mnp child.
- //
- Status = ArpService->Mnp->Configure (ArpService->Mnp, &ArpService->MnpConfigData);
- if (EFI_ERROR (Status)) {
- goto ERROR_EXIT;
- }
- //
- // Create the event used in the RxToken.
- //
- Status = gBS->CreateEvent (
- EVT_NOTIFY_SIGNAL,
- TPL_NOTIFY,
- ArpOnFrameRcvd,
- ArpService,
- &ArpService->RxToken.Event
- );
- if (EFI_ERROR (Status)) {
- goto ERROR_EXIT;
- }
- //
- // Create the Arp heartbeat timer.
- //
- Status = gBS->CreateEvent (
- EVT_NOTIFY_SIGNAL | EVT_TIMER,
- TPL_CALLBACK,
- ArpTimerHandler,
- ArpService,
- &ArpService->PeriodicTimer
- );
- if (EFI_ERROR (Status)) {
- goto ERROR_EXIT;
- }
- //
- // Start the heartbeat timer.
- //
- Status = gBS->SetTimer (
- ArpService->PeriodicTimer,
- TimerPeriodic,
- ARP_PERIODIC_TIMER_INTERVAL
- );
- ERROR_EXIT:
- return Status;
- }
- /**
- Clean the arp service context data.
- @param[in, out] ArpService Pointer to the buffer containing the arp service
- context data.
- @return None.
- **/
- VOID
- ArpCleanService (
- IN OUT ARP_SERVICE_DATA *ArpService
- )
- {
- NET_CHECK_SIGNATURE (ArpService, ARP_SERVICE_DATA_SIGNATURE);
- if (ArpService->PeriodicTimer != NULL) {
- //
- // Cancel and close the PeriodicTimer.
- //
- gBS->SetTimer (ArpService->PeriodicTimer, TimerCancel, 0);
- gBS->CloseEvent (ArpService->PeriodicTimer);
- }
- if (ArpService->RxToken.Event != NULL) {
- //
- // Cancel the RxToken and close the event in the RxToken.
- //
- ArpService->Mnp->Cancel (ArpService->Mnp, NULL);
- gBS->CloseEvent (ArpService->RxToken.Event);
- }
- if (ArpService->Mnp != NULL) {
- //
- // Reset the Mnp child and close the Mnp protocol.
- //
- ArpService->Mnp->Configure (ArpService->Mnp, NULL);
- gBS->CloseProtocol (
- ArpService->MnpChildHandle,
- &gEfiManagedNetworkProtocolGuid,
- ArpService->ImageHandle,
- ArpService->ControllerHandle
- );
- }
- if (ArpService->MnpChildHandle != NULL) {
- //
- // Destroy the mnp child.
- //
- NetLibDestroyServiceChild (
- ArpService->ControllerHandle,
- ArpService->ImageHandle,
- &gEfiManagedNetworkServiceBindingProtocolGuid,
- ArpService->MnpChildHandle
- );
- }
- }
- /**
- Callback function which provided by user to remove one node in NetDestroyLinkList process.
- @param[in] Entry The entry to be removed.
- @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
- @retval EFI_SUCCESS The entry has been removed successfully.
- @retval Others Fail to remove the entry.
- **/
- EFI_STATUS
- EFIAPI
- ArpDestroyChildEntryInHandleBuffer (
- IN LIST_ENTRY *Entry,
- IN VOID *Context
- )
- {
- ARP_INSTANCE_DATA *Instance;
- EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
- if ((Entry == NULL) || (Context == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
- Instance = NET_LIST_USER_STRUCT_S (Entry, ARP_INSTANCE_DATA, List, ARP_INSTANCE_DATA_SIGNATURE);
- ServiceBinding = (EFI_SERVICE_BINDING_PROTOCOL *)Context;
- return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
- }
- /**
- Tests to see if this driver supports a given controller.
- If a child device is provided, it further tests to see if this driver supports
- creating a handle for the specified child device.
- @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
- @param[in] ControllerHandle The handle of the controller to test. This handle
- must support a protocol interface that supplies
- an I/O abstraction to the driver.
- @param[in] RemainingDevicePath A pointer to the remaining portion of a device path.
- This parameter is ignored by device drivers,
- and is optional for bus drivers.
- @retval EFI_SUCCESS The device specified by ControllerHandle and
- RemainingDevicePath is supported by the driver
- specified by This.
- @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
- RemainingDevicePath is already being managed
- by the driver specified by This.
- @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
- RemainingDevicePath is already being managed by
- a different driver or an application that
- requires exclusive access. Currently not implemented.
- @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
- RemainingDevicePath is not supported by the
- driver specified by This.
- **/
- EFI_STATUS
- EFIAPI
- ArpDriverBindingSupported (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE ControllerHandle,
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
- )
- {
- EFI_STATUS Status;
- //
- // Test to see if Arp SB is already installed.
- //
- Status = gBS->OpenProtocol (
- ControllerHandle,
- &gEfiArpServiceBindingProtocolGuid,
- NULL,
- This->DriverBindingHandle,
- ControllerHandle,
- EFI_OPEN_PROTOCOL_TEST_PROTOCOL
- );
- if (Status == EFI_SUCCESS) {
- return EFI_ALREADY_STARTED;
- }
- //
- // Test to see if MNP SB is installed.
- //
- Status = gBS->OpenProtocol (
- ControllerHandle,
- &gEfiManagedNetworkServiceBindingProtocolGuid,
- NULL,
- This->DriverBindingHandle,
- ControllerHandle,
- EFI_OPEN_PROTOCOL_TEST_PROTOCOL
- );
- return Status;
- }
- /**
- Start this driver on ControllerHandle.
- The Start() function is designed to be invoked from the EFI boot service ConnectController().
- As a result, much of the error checking on the parameters to Start() has been
- moved into this common boot service. It is legal to call Start() from other locations,
- but the following calling restrictions must be followed or the system behavior
- will not be deterministic.
- 1. ControllerHandle must be a valid EFI_HANDLE.
- 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally
- aligned EFI_DEVICE_PATH_PROTOCOL.
- 3. Prior to calling Start(), the Supported() function for the driver specified
- by This must have been called with the same calling parameters, and Supported()
- must have returned EFI_SUCCESS.
- @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
- @param[in] ControllerHandle The handle of the controller to start. This handle
- must support a protocol interface that supplies
- an I/O abstraction to the driver.
- @param[in] RemainingDevicePath A pointer to the remaining portion of a device path.
- This parameter is ignored by device drivers,
- and is optional for bus drivers.
- @retval EFI_SUCCESS The device was started.
- @retval EFI_DEVICE_ERROR The device could not be started due to a device error.
- Currently not implemented.
- @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of
- resources.
- @retval Others The driver failed to start the device.
- **/
- EFI_STATUS
- EFIAPI
- ArpDriverBindingStart (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE ControllerHandle,
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
- )
- {
- EFI_STATUS Status;
- ARP_SERVICE_DATA *ArpService;
- //
- // Allocate a zero pool for ArpService.
- //
- ArpService = AllocateZeroPool (sizeof (ARP_SERVICE_DATA));
- if (ArpService == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- //
- // Initialize the arp service context data.
- //
- Status = ArpCreateService (This->DriverBindingHandle, ControllerHandle, ArpService);
- if (EFI_ERROR (Status)) {
- goto ERROR;
- }
- //
- // Install the ARP service binding protocol.
- //
- Status = gBS->InstallMultipleProtocolInterfaces (
- &ControllerHandle,
- &gEfiArpServiceBindingProtocolGuid,
- &ArpService->ServiceBinding,
- NULL
- );
- if (EFI_ERROR (Status)) {
- goto ERROR;
- }
- //
- // OK, start to receive arp packets from Mnp.
- //
- Status = ArpService->Mnp->Receive (ArpService->Mnp, &ArpService->RxToken);
- if (EFI_ERROR (Status)) {
- goto ERROR;
- }
- return Status;
- ERROR:
- //
- // On error, clean the arp service context data, and free the memory allocated.
- //
- ArpCleanService (ArpService);
- FreePool (ArpService);
- return Status;
- }
- /**
- Stop this driver on ControllerHandle.
- Release the control of this controller and remove the IScsi functions. The Stop()
- function is designed to be invoked from the EFI boot service DisconnectController().
- As a result, much of the error checking on the parameters to Stop() has been moved
- into this common boot service. It is legal to call Stop() from other locations,
- but the following calling restrictions must be followed or the system behavior
- will not be deterministic.
- 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
- same driver's Start() function.
- 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
- EFI_HANDLE. In addition, all of these handles must have been created in this driver's
- Start() function, and the Start() function must have called OpenProtocol() on
- ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
- @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
- @param[in] ControllerHandle A handle to the device being stopped. The handle must
- support a bus specific I/O protocol for the driver
- to use to stop the device.
- @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
- Not used.
- @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
- if NumberOfChildren is 0.Not used.
- @retval EFI_SUCCESS The device was stopped.
- @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
- **/
- EFI_STATUS
- EFIAPI
- ArpDriverBindingStop (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE ControllerHandle,
- IN UINTN NumberOfChildren,
- IN EFI_HANDLE *ChildHandleBuffer
- )
- {
- EFI_STATUS Status;
- EFI_HANDLE NicHandle;
- EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
- ARP_SERVICE_DATA *ArpService;
- LIST_ENTRY *List;
- //
- // Get the NicHandle which the arp servicebinding is installed on.
- //
- NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);
- if (NicHandle == NULL) {
- return EFI_SUCCESS;
- }
- //
- // Try to get the arp servicebinding protocol on the NicHandle.
- //
- Status = gBS->OpenProtocol (
- NicHandle,
- &gEfiArpServiceBindingProtocolGuid,
- (VOID **)&ServiceBinding,
- This->DriverBindingHandle,
- ControllerHandle,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "ArpDriverBindingStop: Open ArpSb failed, %r.\n", Status));
- return EFI_DEVICE_ERROR;
- }
- ArpService = ARP_SERVICE_DATA_FROM_THIS (ServiceBinding);
- if (NumberOfChildren != 0) {
- //
- // NumberOfChildren is not zero, destroy all the ARP children instances.
- //
- List = &ArpService->ChildrenList;
- Status = NetDestroyLinkList (
- List,
- ArpDestroyChildEntryInHandleBuffer,
- ServiceBinding,
- NULL
- );
- ASSERT (IsListEmpty (&ArpService->PendingRequestTable));
- ASSERT (IsListEmpty (&ArpService->DeniedCacheTable));
- ASSERT (IsListEmpty (&ArpService->ResolvedCacheTable));
- } else if (IsListEmpty (&ArpService->ChildrenList)) {
- //
- // Uninstall the ARP ServiceBinding protocol.
- //
- gBS->UninstallMultipleProtocolInterfaces (
- NicHandle,
- &gEfiArpServiceBindingProtocolGuid,
- &ArpService->ServiceBinding,
- NULL
- );
- //
- // Clean the arp servicebinding context data and free the memory allocated.
- //
- ArpCleanService (ArpService);
- FreePool (ArpService);
- }
- return EFI_SUCCESS;
- }
- /**
- Creates a child handle and installs a protocol.
- The CreateChild() function installs a protocol on ChildHandle.
- If ChildHandle is a pointer to NULL, then a new handle is created and returned
- in ChildHandle. If ChildHandle is not a pointer to NULL, then the protocol
- installs on the existing ChildHandle.
- @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
- @param ChildHandle Pointer to the handle of the child to create. If it is NULL,
- then a new handle is created. If it is a pointer to an existing
- UEFI handle, then the protocol is added to the existing UEFI handle.
- @retval EFI_SUCCESS The protocol was added to ChildHandle.
- @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
- @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
- the child
- @retval other The child handle was not created
- **/
- EFI_STATUS
- EFIAPI
- ArpServiceBindingCreateChild (
- IN EFI_SERVICE_BINDING_PROTOCOL *This,
- IN EFI_HANDLE *ChildHandle
- )
- {
- EFI_STATUS Status;
- ARP_SERVICE_DATA *ArpService;
- ARP_INSTANCE_DATA *Instance;
- VOID *Mnp;
- EFI_TPL OldTpl;
- if ((This == NULL) || (ChildHandle == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
- ArpService = ARP_SERVICE_DATA_FROM_THIS (This);
- //
- // Allocate memory for the instance context data.
- //
- Instance = AllocateZeroPool (sizeof (ARP_INSTANCE_DATA));
- if (Instance == NULL) {
- DEBUG ((DEBUG_ERROR, "ArpSBCreateChild: Failed to allocate memory for Instance.\n"));
- return EFI_OUT_OF_RESOURCES;
- }
- //
- // Init the instance context data.
- //
- ArpInitInstance (ArpService, Instance);
- //
- // Install the ARP protocol onto the ChildHandle.
- //
- Status = gBS->InstallMultipleProtocolInterfaces (
- ChildHandle,
- &gEfiArpProtocolGuid,
- (VOID *)&Instance->ArpProto,
- NULL
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "ArpSBCreateChild: failed to install ARP protocol, %r.\n", Status));
- FreePool (Instance);
- return Status;
- }
- //
- // Save the ChildHandle.
- //
- Instance->Handle = *ChildHandle;
- //
- // Open the Managed Network protocol BY_CHILD.
- //
- Status = gBS->OpenProtocol (
- ArpService->MnpChildHandle,
- &gEfiManagedNetworkProtocolGuid,
- (VOID **)&Mnp,
- gArpDriverBinding.DriverBindingHandle,
- Instance->Handle,
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
- );
- if (EFI_ERROR (Status)) {
- goto ERROR;
- }
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
- //
- // Insert the instance into children list managed by the arp service context data.
- //
- InsertTailList (&ArpService->ChildrenList, &Instance->List);
- ArpService->ChildrenNumber++;
- gBS->RestoreTPL (OldTpl);
- ERROR:
- if (EFI_ERROR (Status)) {
- gBS->CloseProtocol (
- ArpService->MnpChildHandle,
- &gEfiManagedNetworkProtocolGuid,
- gArpDriverBinding.DriverBindingHandle,
- Instance->Handle
- );
- gBS->UninstallMultipleProtocolInterfaces (
- Instance->Handle,
- &gEfiArpProtocolGuid,
- &Instance->ArpProto,
- NULL
- );
- //
- // Free the allocated memory.
- //
- FreePool (Instance);
- }
- return Status;
- }
- /**
- Destroys a child handle with a protocol installed on it.
- The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
- that was installed by CreateChild() from ChildHandle. If the removed protocol is the
- last protocol on ChildHandle, then ChildHandle is destroyed.
- @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
- @param ChildHandle Handle of the child to destroy
- @retval EFI_SUCCESS The protocol was removed from ChildHandle.
- @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is
- being removed.
- @retval EFI_INVALID_PARAMETER Child handle is NULL.
- @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
- because its services are being used.
- @retval other The child handle was not destroyed
- **/
- EFI_STATUS
- EFIAPI
- ArpServiceBindingDestroyChild (
- IN EFI_SERVICE_BINDING_PROTOCOL *This,
- IN EFI_HANDLE ChildHandle
- )
- {
- EFI_STATUS Status;
- ARP_SERVICE_DATA *ArpService;
- ARP_INSTANCE_DATA *Instance;
- EFI_ARP_PROTOCOL *Arp;
- EFI_TPL OldTpl;
- if ((This == NULL) || (ChildHandle == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
- ArpService = ARP_SERVICE_DATA_FROM_THIS (This);
- //
- // Get the arp protocol.
- //
- Status = gBS->OpenProtocol (
- ChildHandle,
- &gEfiArpProtocolGuid,
- (VOID **)&Arp,
- ArpService->ImageHandle,
- ChildHandle,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if (EFI_ERROR (Status)) {
- return EFI_UNSUPPORTED;
- }
- Instance = ARP_INSTANCE_DATA_FROM_THIS (Arp);
- if (Instance->InDestroy) {
- return EFI_SUCCESS;
- }
- //
- // Use the InDestroy as a flag to avoid re-entrance.
- //
- Instance->InDestroy = TRUE;
- //
- // Close the Managed Network protocol.
- //
- gBS->CloseProtocol (
- ArpService->MnpChildHandle,
- &gEfiManagedNetworkProtocolGuid,
- gArpDriverBinding.DriverBindingHandle,
- ChildHandle
- );
- //
- // Uninstall the ARP protocol.
- //
- Status = gBS->UninstallMultipleProtocolInterfaces (
- ChildHandle,
- &gEfiArpProtocolGuid,
- &Instance->ArpProto,
- NULL
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "ArpSBDestroyChild: Failed to uninstall the arp protocol, %r.\n",
- Status
- ));
- Instance->InDestroy = FALSE;
- return Status;
- }
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
- if (Instance->Configured) {
- //
- // Delete the related cache entry.
- //
- ArpDeleteCacheEntry (Instance, FALSE, NULL, TRUE);
- //
- // Reset the instance configuration.
- //
- ArpConfigureInstance (Instance, NULL);
- }
- //
- // Remove this instance from the ChildrenList.
- //
- RemoveEntryList (&Instance->List);
- ArpService->ChildrenNumber--;
- gBS->RestoreTPL (OldTpl);
- FreePool (Instance);
- return Status;
- }
- /**
- The entry point for Arp driver which installs the driver binding and component name
- protocol on its ImageHandle.
- @param[in] ImageHandle The image handle of the driver.
- @param[in] SystemTable The system table.
- @retval EFI_SUCCESS if the driver binding and component name protocols
- are successfully
- @retval Others Failed to install the protocols.
- **/
- EFI_STATUS
- EFIAPI
- ArpDriverEntryPoint (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
- {
- return EfiLibInstallDriverBindingComponentName2 (
- ImageHandle,
- SystemTable,
- &gArpDriverBinding,
- ImageHandle,
- &gArpComponentName,
- &gArpComponentName2
- );
- }
|