REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the NetworkPkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Maciej Rabeda <maciej.rabeda@linux.intel.com>
		
			
				
	
	
		
			738 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			738 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Driver Binding functions and Service Binding functions
 | 
						|
  implementation for Mtftp6 Driver.
 | 
						|
 | 
						|
  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
 | 
						|
 | 
						|
  SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "Mtftp6Impl.h"
 | 
						|
 | 
						|
EFI_DRIVER_BINDING_PROTOCOL  gMtftp6DriverBinding = {
 | 
						|
  Mtftp6DriverBindingSupported,
 | 
						|
  Mtftp6DriverBindingStart,
 | 
						|
  Mtftp6DriverBindingStop,
 | 
						|
  0xa,
 | 
						|
  NULL,
 | 
						|
  NULL
 | 
						|
};
 | 
						|
 | 
						|
EFI_SERVICE_BINDING_PROTOCOL  gMtftp6ServiceBindingTemplate = {
 | 
						|
  Mtftp6ServiceBindingCreateChild,
 | 
						|
  Mtftp6ServiceBindingDestroyChild
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
  Destroy the MTFTP6 service. The MTFTP6 service may be partly initialized,
 | 
						|
  or partly destroyed. If a resource is destroyed, it is marked as such in
 | 
						|
  case the destroy failed and is called again later.
 | 
						|
 | 
						|
  @param[in]  Service            The MTFTP6 service to be destroyed.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
Mtftp6DestroyService (
 | 
						|
  IN MTFTP6_SERVICE  *Service
 | 
						|
  )
 | 
						|
{
 | 
						|
  //
 | 
						|
  // Make sure all children instances have been already destroyed.
 | 
						|
  //
 | 
						|
  ASSERT (Service->ChildrenNum == 0);
 | 
						|
 | 
						|
  if (Service->DummyUdpIo != NULL) {
 | 
						|
    UdpIoFreeIo (Service->DummyUdpIo);
 | 
						|
  }
 | 
						|
 | 
						|
  if (Service->Timer != NULL) {
 | 
						|
    gBS->CloseEvent (Service->Timer);
 | 
						|
  }
 | 
						|
 | 
						|
  FreePool (Service);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Create then initialize a MTFTP6 service binding instance.
 | 
						|
 | 
						|
  @param[in]  Controller             The controller to install the MTFTP6 service
 | 
						|
                                     binding on.
 | 
						|
  @param[in]  Image                  The driver binding image of the MTFTP6 driver.
 | 
						|
  @param[out] Service                The variable to receive the created service
 | 
						|
                                     binding instance.
 | 
						|
 | 
						|
  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources to create the instance
 | 
						|
  @retval EFI_DEVICE_ERROR       Failed to create a NULL UDP port to keep connection with UDP.
 | 
						|
  @retval EFI_SUCCESS            The service instance is created for the controller.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
Mtftp6CreateService (
 | 
						|
  IN  EFI_HANDLE      Controller,
 | 
						|
  IN  EFI_HANDLE      Image,
 | 
						|
  OUT MTFTP6_SERVICE  **Service
 | 
						|
  )
 | 
						|
{
 | 
						|
  MTFTP6_SERVICE  *Mtftp6Srv;
 | 
						|
  EFI_STATUS      Status;
 | 
						|
 | 
						|
  ASSERT (Service != NULL);
 | 
						|
 | 
						|
  *Service  = NULL;
 | 
						|
  Mtftp6Srv = AllocateZeroPool (sizeof (MTFTP6_SERVICE));
 | 
						|
 | 
						|
  if (Mtftp6Srv == NULL) {
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  Mtftp6Srv->Signature   = MTFTP6_SERVICE_SIGNATURE;
 | 
						|
  Mtftp6Srv->Controller  = Controller;
 | 
						|
  Mtftp6Srv->Image       = Image;
 | 
						|
  Mtftp6Srv->ChildrenNum = 0;
 | 
						|
 | 
						|
  CopyMem (
 | 
						|
    &Mtftp6Srv->ServiceBinding,
 | 
						|
    &gMtftp6ServiceBindingTemplate,
 | 
						|
    sizeof (EFI_SERVICE_BINDING_PROTOCOL)
 | 
						|
    );
 | 
						|
 | 
						|
  InitializeListHead (&Mtftp6Srv->Children);
 | 
						|
 | 
						|
  //
 | 
						|
  // Create a internal timer for all instances.
 | 
						|
  //
 | 
						|
  Status = gBS->CreateEvent (
 | 
						|
                  EVT_NOTIFY_SIGNAL | EVT_TIMER,
 | 
						|
                  TPL_CALLBACK,
 | 
						|
                  Mtftp6OnTimerTick,
 | 
						|
                  Mtftp6Srv,
 | 
						|
                  &Mtftp6Srv->Timer
 | 
						|
                  );
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    FreePool (Mtftp6Srv);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Create a dummy Udp6Io to build parent-child relationship between Udp6 driver
 | 
						|
  // and Mtftp6 driver.
 | 
						|
  //
 | 
						|
  Mtftp6Srv->DummyUdpIo = UdpIoCreateIo (
 | 
						|
                            Controller,
 | 
						|
                            Image,
 | 
						|
                            Mtftp6ConfigDummyUdpIo,
 | 
						|
                            UDP_IO_UDP6_VERSION,
 | 
						|
                            NULL
 | 
						|
                            );
 | 
						|
 | 
						|
  if (Mtftp6Srv->DummyUdpIo == NULL) {
 | 
						|
    gBS->CloseEvent (Mtftp6Srv->Timer);
 | 
						|
    FreePool (Mtftp6Srv);
 | 
						|
    return EFI_DEVICE_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  *Service = Mtftp6Srv;
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Destroy the MTFTP6 instance and recycle the resources.
 | 
						|
 | 
						|
  @param[in]  Instance        The pointer to the MTFTP6 instance.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
Mtftp6DestroyInstance (
 | 
						|
  IN MTFTP6_INSTANCE  *Instance
 | 
						|
  )
 | 
						|
{
 | 
						|
  LIST_ENTRY          *Entry;
 | 
						|
  LIST_ENTRY          *Next;
 | 
						|
  MTFTP6_BLOCK_RANGE  *Block;
 | 
						|
 | 
						|
  if (Instance->Config != NULL) {
 | 
						|
    FreePool (Instance->Config);
 | 
						|
  }
 | 
						|
 | 
						|
  if ((Instance->Token != NULL) && (Instance->Token->Event != NULL)) {
 | 
						|
    gBS->SignalEvent (Instance->Token->Event);
 | 
						|
  }
 | 
						|
 | 
						|
  if (Instance->LastPacket != NULL) {
 | 
						|
    NetbufFree (Instance->LastPacket);
 | 
						|
  }
 | 
						|
 | 
						|
  if (Instance->UdpIo != NULL) {
 | 
						|
    UdpIoFreeIo (Instance->UdpIo);
 | 
						|
  }
 | 
						|
 | 
						|
  if (Instance->McastUdpIo != NULL) {
 | 
						|
    UdpIoFreeIo (Instance->McastUdpIo);
 | 
						|
  }
 | 
						|
 | 
						|
  NET_LIST_FOR_EACH_SAFE (Entry, Next, &Instance->BlkList) {
 | 
						|
    Block = NET_LIST_USER_STRUCT (Entry, MTFTP6_BLOCK_RANGE, Link);
 | 
						|
    RemoveEntryList (Entry);
 | 
						|
    FreePool (Block);
 | 
						|
  }
 | 
						|
 | 
						|
  FreePool (Instance);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Create the MTFTP6 instance and initialize it.
 | 
						|
 | 
						|
  @param[in]  Service              The pointer to the MTFTP6 service.
 | 
						|
  @param[out] Instance             The pointer to the MTFTP6 instance.
 | 
						|
 | 
						|
  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources.
 | 
						|
  @retval EFI_SUCCESS            The MTFTP6 instance is created.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
Mtftp6CreateInstance (
 | 
						|
  IN  MTFTP6_SERVICE   *Service,
 | 
						|
  OUT MTFTP6_INSTANCE  **Instance
 | 
						|
  )
 | 
						|
{
 | 
						|
  MTFTP6_INSTANCE  *Mtftp6Ins;
 | 
						|
 | 
						|
  *Instance = NULL;
 | 
						|
  Mtftp6Ins = AllocateZeroPool (sizeof (MTFTP6_INSTANCE));
 | 
						|
 | 
						|
  if (Mtftp6Ins == NULL) {
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  Mtftp6Ins->Signature = MTFTP6_INSTANCE_SIGNATURE;
 | 
						|
  Mtftp6Ins->InDestroy = FALSE;
 | 
						|
  Mtftp6Ins->Service   = Service;
 | 
						|
 | 
						|
  CopyMem (
 | 
						|
    &Mtftp6Ins->Mtftp6,
 | 
						|
    &gMtftp6ProtocolTemplate,
 | 
						|
    sizeof (EFI_MTFTP6_PROTOCOL)
 | 
						|
    );
 | 
						|
 | 
						|
  InitializeListHead (&Mtftp6Ins->Link);
 | 
						|
  InitializeListHead (&Mtftp6Ins->BlkList);
 | 
						|
 | 
						|
  *Instance = Mtftp6Ins;
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  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
 | 
						|
Mtftp6DestroyChildEntryInHandleBuffer (
 | 
						|
  IN LIST_ENTRY  *Entry,
 | 
						|
  IN VOID        *Context
 | 
						|
  )
 | 
						|
{
 | 
						|
  MTFTP6_INSTANCE               *Instance;
 | 
						|
  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;
 | 
						|
  UINTN                         NumberOfChildren;
 | 
						|
  EFI_HANDLE                    *ChildHandleBuffer;
 | 
						|
 | 
						|
  if ((Entry == NULL) || (Context == NULL)) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  Instance          = NET_LIST_USER_STRUCT_S (Entry, MTFTP6_INSTANCE, Link, MTFTP6_INSTANCE_SIGNATURE);
 | 
						|
  ServiceBinding    = ((MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *)Context)->ServiceBinding;
 | 
						|
  NumberOfChildren  = ((MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *)Context)->NumberOfChildren;
 | 
						|
  ChildHandleBuffer = ((MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *)Context)->ChildHandleBuffer;
 | 
						|
 | 
						|
  if (!NetIsInHandleBuffer (Instance->Handle, NumberOfChildren, ChildHandleBuffer)) {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  This is the declaration of an EFI image entry point. This entry point is
 | 
						|
  the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including
 | 
						|
  both device drivers and bus drivers.
 | 
						|
 | 
						|
  Entry point of the MTFTP6 driver to install various protocols.
 | 
						|
 | 
						|
  @param[in]  ImageHandle           The firmware allocated handle for the UEFI image.
 | 
						|
  @param[in]  SystemTable           The pointer to the EFI System Table.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           The operation completed successfully.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
Mtftp6DriverEntryPoint (
 | 
						|
  IN EFI_HANDLE        ImageHandle,
 | 
						|
  IN EFI_SYSTEM_TABLE  *SystemTable
 | 
						|
  )
 | 
						|
{
 | 
						|
  return EfiLibInstallDriverBindingComponentName2 (
 | 
						|
           ImageHandle,
 | 
						|
           SystemTable,
 | 
						|
           &gMtftp6DriverBinding,
 | 
						|
           ImageHandle,
 | 
						|
           &gMtftp6ComponentName,
 | 
						|
           &gMtftp6ComponentName2
 | 
						|
           );
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Test to see if this driver supports Controller. This service
 | 
						|
  is called by the EFI boot service ConnectController(). In
 | 
						|
  order to make drivers as small as possible, there are calling
 | 
						|
  restrictions for this service. ConnectController() must
 | 
						|
  follow these calling restrictions. If any other agent wishes to call
 | 
						|
  Supported(), it must also follow these calling restrictions.
 | 
						|
 | 
						|
  @param[in]  This                Protocol instance pointer.
 | 
						|
  @param[in]  Controller          Handle of device to test
 | 
						|
  @param[in]  RemainingDevicePath Optional parameter use to pick a specific child.
 | 
						|
                                  device to start.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS         This driver supports this device.
 | 
						|
  @retval Others              This driver does not support this device.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
Mtftp6DriverBindingSupported (
 | 
						|
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
 | 
						|
  IN EFI_HANDLE                   Controller,
 | 
						|
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
 | 
						|
  )
 | 
						|
{
 | 
						|
  return gBS->OpenProtocol (
 | 
						|
                Controller,
 | 
						|
                &gEfiUdp6ServiceBindingProtocolGuid,
 | 
						|
                NULL,
 | 
						|
                This->DriverBindingHandle,
 | 
						|
                Controller,
 | 
						|
                EFI_OPEN_PROTOCOL_TEST_PROTOCOL
 | 
						|
                );
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Start this driver on Controller. This service is called by the
 | 
						|
  EFI boot service ConnectController(). In order to make
 | 
						|
  drivers as small as possible, there are calling restrictions for
 | 
						|
  this service. ConnectController() must follow these
 | 
						|
  calling restrictions. If any other agent wishes to call Start() it
 | 
						|
  must also follow these calling restrictions.
 | 
						|
 | 
						|
  @param[in]  This                 Protocol instance pointer.
 | 
						|
  @param[in]  Controller           Handle of device to bind driver to.
 | 
						|
  @param[in]  RemainingDevicePath  Optional parameter use to pick a specific child
 | 
						|
                                   device to start.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS          This driver is added to Controller.
 | 
						|
  @retval EFI_ALREADY_STARTED  This driver is already running on Controller.
 | 
						|
  @retval Others               This driver does not support this device.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
Mtftp6DriverBindingStart (
 | 
						|
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
 | 
						|
  IN EFI_HANDLE                   Controller,
 | 
						|
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
 | 
						|
  )
 | 
						|
{
 | 
						|
  MTFTP6_SERVICE  *Service;
 | 
						|
  EFI_STATUS      Status;
 | 
						|
 | 
						|
  //
 | 
						|
  // Directly return if driver is already running on this Nic handle.
 | 
						|
  //
 | 
						|
  Status = gBS->OpenProtocol (
 | 
						|
                  Controller,
 | 
						|
                  &gEfiMtftp6ServiceBindingProtocolGuid,
 | 
						|
                  NULL,
 | 
						|
                  This->DriverBindingHandle,
 | 
						|
                  Controller,
 | 
						|
                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
 | 
						|
                  );
 | 
						|
 | 
						|
  if (!EFI_ERROR (Status)) {
 | 
						|
    return EFI_ALREADY_STARTED;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Create Mtftp6 service for this Nic handle
 | 
						|
  //
 | 
						|
  Status = Mtftp6CreateService (
 | 
						|
             Controller,
 | 
						|
             This->DriverBindingHandle,
 | 
						|
             &Service
 | 
						|
             );
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  ASSERT (Service != NULL);
 | 
						|
 | 
						|
  //
 | 
						|
  // Start the internal timer to track the packet retransmission.
 | 
						|
  //
 | 
						|
  Status = gBS->SetTimer (
 | 
						|
                  Service->Timer,
 | 
						|
                  TimerPeriodic,
 | 
						|
                  TICKS_PER_SECOND
 | 
						|
                  );
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    goto ON_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Install the Mtftp6 service on the Nic handle.
 | 
						|
  //
 | 
						|
  Status = gBS->InstallMultipleProtocolInterfaces (
 | 
						|
                  &Controller,
 | 
						|
                  &gEfiMtftp6ServiceBindingProtocolGuid,
 | 
						|
                  &Service->ServiceBinding,
 | 
						|
                  NULL
 | 
						|
                  );
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    goto ON_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
 | 
						|
ON_ERROR:
 | 
						|
 | 
						|
  Mtftp6DestroyService (Service);
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Stop this driver on Controller. This service is called by the
 | 
						|
  EFI boot service DisconnectController(). In order to
 | 
						|
  make drivers as small as possible, there are calling
 | 
						|
  restrictions for this service. DisconnectController()
 | 
						|
  must follow these calling restrictions. If any other agent wishes
 | 
						|
  to call Stop(), it must also follow these calling restrictions.
 | 
						|
 | 
						|
  @param[in]  This              Protocol instance pointer.
 | 
						|
  @param[in]  Controller        Handle of device to stop driver on
 | 
						|
  @param[in]  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of
 | 
						|
                                children is zero, stop the entire bus driver.
 | 
						|
  @param[in]  ChildHandleBuffer List of Child Handles to Stop.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       This driver is removed Controller.
 | 
						|
  @retval EFI_DEVICE_ERROR  An unexpected error.
 | 
						|
  @retval Others            This driver was not removed from this device.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
Mtftp6DriverBindingStop (
 | 
						|
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
 | 
						|
  IN  EFI_HANDLE                   Controller,
 | 
						|
  IN  UINTN                        NumberOfChildren,
 | 
						|
  IN  EFI_HANDLE                   *ChildHandleBuffer
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_SERVICE_BINDING_PROTOCOL                *ServiceBinding;
 | 
						|
  MTFTP6_SERVICE                              *Service;
 | 
						|
  EFI_HANDLE                                  NicHandle;
 | 
						|
  EFI_STATUS                                  Status;
 | 
						|
  LIST_ENTRY                                  *List;
 | 
						|
  MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT  Context;
 | 
						|
 | 
						|
  //
 | 
						|
  // Locate the Nic handle to retrieve the Mtftp6 private data.
 | 
						|
  //
 | 
						|
  NicHandle = NetLibGetNicHandle (Controller, &gEfiUdp6ProtocolGuid);
 | 
						|
 | 
						|
  if (NicHandle == NULL) {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = gBS->OpenProtocol (
 | 
						|
                  NicHandle,
 | 
						|
                  &gEfiMtftp6ServiceBindingProtocolGuid,
 | 
						|
                  (VOID **)&ServiceBinding,
 | 
						|
                  This->DriverBindingHandle,
 | 
						|
                  NicHandle,
 | 
						|
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
 | 
						|
                  );
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return EFI_DEVICE_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  Service = MTFTP6_SERVICE_FROM_THIS (ServiceBinding);
 | 
						|
 | 
						|
  if (!IsListEmpty (&Service->Children)) {
 | 
						|
    //
 | 
						|
    // Destroy the Mtftp6 child instance in ChildHandleBuffer.
 | 
						|
    //
 | 
						|
    List                      = &Service->Children;
 | 
						|
    Context.ServiceBinding    = ServiceBinding;
 | 
						|
    Context.NumberOfChildren  = NumberOfChildren;
 | 
						|
    Context.ChildHandleBuffer = ChildHandleBuffer;
 | 
						|
    Status                    = NetDestroyLinkList (
 | 
						|
                                  List,
 | 
						|
                                  Mtftp6DestroyChildEntryInHandleBuffer,
 | 
						|
                                  &Context,
 | 
						|
                                  NULL
 | 
						|
                                  );
 | 
						|
  }
 | 
						|
 | 
						|
  if ((NumberOfChildren == 0) && IsListEmpty (&Service->Children)) {
 | 
						|
    //
 | 
						|
    // Destroy the Mtftp6 service if there is no Mtftp6 child instance left.
 | 
						|
    //
 | 
						|
    gBS->UninstallProtocolInterface (
 | 
						|
           NicHandle,
 | 
						|
           &gEfiMtftp6ServiceBindingProtocolGuid,
 | 
						|
           ServiceBinding
 | 
						|
           );
 | 
						|
 | 
						|
    Mtftp6DestroyService (Service);
 | 
						|
    Status = EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  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[in]      This        Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
 | 
						|
  @param[in, out] 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 Others                The child handle was not created.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
Mtftp6ServiceBindingCreateChild (
 | 
						|
  IN     EFI_SERVICE_BINDING_PROTOCOL  *This,
 | 
						|
  IN OUT EFI_HANDLE                    *ChildHandle
 | 
						|
  )
 | 
						|
{
 | 
						|
  MTFTP6_SERVICE   *Service;
 | 
						|
  MTFTP6_INSTANCE  *Instance;
 | 
						|
  EFI_STATUS       Status;
 | 
						|
  EFI_TPL          OldTpl;
 | 
						|
  VOID             *Udp6;
 | 
						|
 | 
						|
  if ((This == NULL) || (ChildHandle == NULL)) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  Service = MTFTP6_SERVICE_FROM_THIS (This);
 | 
						|
 | 
						|
  Status = Mtftp6CreateInstance (Service, &Instance);
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  ASSERT (Instance != NULL);
 | 
						|
 | 
						|
  //
 | 
						|
  // Install the Mtftp6 protocol on the new child handle.
 | 
						|
  //
 | 
						|
  Status = gBS->InstallMultipleProtocolInterfaces (
 | 
						|
                  ChildHandle,
 | 
						|
                  &gEfiMtftp6ProtocolGuid,
 | 
						|
                  &Instance->Mtftp6,
 | 
						|
                  NULL
 | 
						|
                  );
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    goto ON_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  Instance->Handle = *ChildHandle;
 | 
						|
 | 
						|
  //
 | 
						|
  // Open the Udp6 protocol by child.
 | 
						|
  //
 | 
						|
  Status = gBS->OpenProtocol (
 | 
						|
                  Service->DummyUdpIo->UdpHandle,
 | 
						|
                  &gEfiUdp6ProtocolGuid,
 | 
						|
                  (VOID **)&Udp6,
 | 
						|
                  gMtftp6DriverBinding.DriverBindingHandle,
 | 
						|
                  Instance->Handle,
 | 
						|
                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
 | 
						|
                  );
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    gBS->UninstallMultipleProtocolInterfaces (
 | 
						|
           Instance->Handle,
 | 
						|
           &gEfiMtftp6ProtocolGuid,
 | 
						|
           &Instance->Mtftp6,
 | 
						|
           NULL
 | 
						|
           );
 | 
						|
 | 
						|
    goto ON_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Add the new Mtftp6 instance into the children list of Mtftp6 service.
 | 
						|
  //
 | 
						|
  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
 | 
						|
 | 
						|
  InsertTailList (&Service->Children, &Instance->Link);
 | 
						|
  Service->ChildrenNum++;
 | 
						|
 | 
						|
  gBS->RestoreTPL (OldTpl);
 | 
						|
  return EFI_SUCCESS;
 | 
						|
 | 
						|
ON_ERROR:
 | 
						|
 | 
						|
  Mtftp6DestroyInstance (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[in]  This        Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
 | 
						|
  @param[in]  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 Others                The child handle was not destroyed
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
Mtftp6ServiceBindingDestroyChild (
 | 
						|
  IN EFI_SERVICE_BINDING_PROTOCOL  *This,
 | 
						|
  IN EFI_HANDLE                    ChildHandle
 | 
						|
  )
 | 
						|
{
 | 
						|
  MTFTP6_SERVICE       *Service;
 | 
						|
  MTFTP6_INSTANCE      *Instance;
 | 
						|
  EFI_MTFTP6_PROTOCOL  *Mtftp6;
 | 
						|
  EFI_STATUS           Status;
 | 
						|
  EFI_TPL              OldTpl;
 | 
						|
 | 
						|
  if ((This == NULL) || (ChildHandle == NULL)) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Locate the Nic handle to retrieve the Mtftp6 private data.
 | 
						|
  //
 | 
						|
  Status = gBS->OpenProtocol (
 | 
						|
                  ChildHandle,
 | 
						|
                  &gEfiMtftp6ProtocolGuid,
 | 
						|
                  (VOID **)&Mtftp6,
 | 
						|
                  gMtftp6DriverBinding.DriverBindingHandle,
 | 
						|
                  ChildHandle,
 | 
						|
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
 | 
						|
                  );
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  Instance = MTFTP6_INSTANCE_FROM_THIS (Mtftp6);
 | 
						|
  Service  = MTFTP6_SERVICE_FROM_THIS (This);
 | 
						|
 | 
						|
  if (Instance->Service != Service) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Check whether the instance already in Destroy state.
 | 
						|
  //
 | 
						|
  if (Instance->InDestroy) {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
 | 
						|
 | 
						|
  Instance->InDestroy = TRUE;
 | 
						|
 | 
						|
  gBS->CloseProtocol (
 | 
						|
         Service->DummyUdpIo->UdpHandle,
 | 
						|
         &gEfiUdp6ProtocolGuid,
 | 
						|
         gMtftp6DriverBinding.DriverBindingHandle,
 | 
						|
         ChildHandle
 | 
						|
         );
 | 
						|
 | 
						|
  if (Instance->UdpIo != NULL) {
 | 
						|
    gBS->CloseProtocol (
 | 
						|
           Instance->UdpIo->UdpHandle,
 | 
						|
           &gEfiUdp6ProtocolGuid,
 | 
						|
           gMtftp6DriverBinding.DriverBindingHandle,
 | 
						|
           Instance->Handle
 | 
						|
           );
 | 
						|
  }
 | 
						|
 | 
						|
  if (Instance->McastUdpIo != NULL) {
 | 
						|
    gBS->CloseProtocol (
 | 
						|
           Instance->McastUdpIo->UdpHandle,
 | 
						|
           &gEfiUdp6ProtocolGuid,
 | 
						|
           gMtftp6DriverBinding.DriverBindingHandle,
 | 
						|
           Instance->Handle
 | 
						|
           );
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Uninstall the MTFTP6 protocol first to enable a top down destruction.
 | 
						|
  //
 | 
						|
  gBS->RestoreTPL (OldTpl);
 | 
						|
  Status = gBS->UninstallProtocolInterface (
 | 
						|
                  ChildHandle,
 | 
						|
                  &gEfiMtftp6ProtocolGuid,
 | 
						|
                  Mtftp6
 | 
						|
                  );
 | 
						|
  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    Instance->InDestroy = FALSE;
 | 
						|
    gBS->RestoreTPL (OldTpl);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Remove the Mtftp6 instance from the children list of Mtftp6 service.
 | 
						|
  //
 | 
						|
  RemoveEntryList (&Instance->Link);
 | 
						|
  Service->ChildrenNum--;
 | 
						|
 | 
						|
  gBS->RestoreTPL (OldTpl);
 | 
						|
 | 
						|
  Mtftp6DestroyInstance (Instance);
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 |