mirror of
				https://git.proxmox.com/git/mirror_edk2
				synced 2025-11-04 03:57:26 +00:00 
			
		
		
		
	* Passes conformance and functional tests. * Builds with GCC 4.4 compiler. Signed-off by: lpleahy git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12497 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			242 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			242 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Implement the driver binding protocol for the socket layer.
 | 
						|
 | 
						|
  Copyright (c) 2011, Intel Corporation
 | 
						|
  All rights reserved. This program and the accompanying materials
 | 
						|
  are licensed and made available under the terms and conditions of the BSD License
 | 
						|
  which accompanies this distribution.  The full text of the license may be found at
 | 
						|
  http://opensource.org/licenses/bsd-license.php
 | 
						|
 | 
						|
  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | 
						|
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | 
						|
 | 
						|
 | 
						|
  \section NetworkAdapterManagement Network Adapter Management
 | 
						|
  Network adapters may come and go over the life if a system running
 | 
						|
  UEFI.  The SocketDxe driver uses the driver binding API to manage
 | 
						|
  the connections to network adapters.
 | 
						|
 | 
						|
  The ::DriverSupported routine selects network adapters that the
 | 
						|
  socket layer is not using.  This determination by the lack of the
 | 
						|
  tag GUID associated with the network protocol in the
 | 
						|
  ::cEslSocketBinding array.  The selected network adapters are 
 | 
						|
  passed to the ::DriverStart routine.
 | 
						|
 | 
						|
  The ::DriverStart routine calls the ::EslServiceConnect routine
 | 
						|
  to create an ::ESL_SERVICE structure to manage the network adapter
 | 
						|
  for the socket layer.  EslServiceConnect also installs the tag
 | 
						|
  GUID on the network adapter to prevent future calls from
 | 
						|
  ::DriverSupported.  EslService also calls the network specific
 | 
						|
  initialization routine listed in ESL_SOCKET_BINDING::pfnInitialize
 | 
						|
  field of the ::cEslSocketBinding entry.
 | 
						|
 | 
						|
  The ::DriverStop routine calls the ::EslServiceDisconnect routine
 | 
						|
  to undo the work done by ::DriverStart.  The socket layer must break
 | 
						|
  the active network connections, then remove the tag GUIDs from the
 | 
						|
  controller handle and free ::ESL_SERVICE structure.
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "Socket.h"
 | 
						|
 | 
						|
/**
 | 
						|
  Verify the controller type
 | 
						|
 | 
						|
  This routine walks the cEslSocketBinding array to determines if
 | 
						|
  the controller is a network adapter by supporting any of the
 | 
						|
  network protocols required by the sockets layer.  If so, the
 | 
						|
  routine verifies that the socket layer is not already using the
 | 
						|
  support by looking for the tag GUID listed in the corresponding
 | 
						|
  array entry.  The controller handle is passed to the ::DriverStart
 | 
						|
  routine if sockets can use the network adapter.
 | 
						|
  See the \ref NetworkAdapterManagement section.
 | 
						|
 | 
						|
  This routine is called by the UEFI driver framework during connect
 | 
						|
  processing.
 | 
						|
 | 
						|
  @param [in] pThis                Protocol instance pointer.
 | 
						|
  @param [in] Controller           Handle of device to test.
 | 
						|
  @param [in] pRemainingDevicePath Not used.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS          This driver supports this device.
 | 
						|
  @retval other                This driver does not support this device.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
DriverSupported (
 | 
						|
  IN EFI_DRIVER_BINDING_PROTOCOL * pThis,
 | 
						|
  IN EFI_HANDLE Controller,
 | 
						|
  IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath
 | 
						|
  )
 | 
						|
{
 | 
						|
  CONST ESL_SOCKET_BINDING * pEnd;
 | 
						|
  VOID * pInterface;
 | 
						|
  CONST ESL_SOCKET_BINDING * pSocketBinding;
 | 
						|
  EFI_STATUS Status;
 | 
						|
 | 
						|
  //
 | 
						|
  //  Assume the list is empty
 | 
						|
  //
 | 
						|
  Status = EFI_UNSUPPORTED;
 | 
						|
 | 
						|
  //
 | 
						|
  //  Walk the list of network connection points
 | 
						|
  //
 | 
						|
  pSocketBinding = &cEslSocketBinding[0];
 | 
						|
  pEnd = &pSocketBinding[ cEslSocketBindingEntries ];
 | 
						|
  while ( pEnd > pSocketBinding ) {
 | 
						|
    //
 | 
						|
    //  Determine if the controller supports the network protocol
 | 
						|
    //
 | 
						|
    Status = gBS->OpenProtocol (
 | 
						|
                    Controller,
 | 
						|
                    pSocketBinding->pNetworkBinding,
 | 
						|
                    &pInterface,
 | 
						|
                    pThis->DriverBindingHandle,
 | 
						|
                    Controller,
 | 
						|
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
 | 
						|
                    );
 | 
						|
    if ( !EFI_ERROR ( Status )) {
 | 
						|
      //
 | 
						|
      //  Determine if the driver is already connected
 | 
						|
      //
 | 
						|
      Status = gBS->OpenProtocol (
 | 
						|
                      Controller,
 | 
						|
                      (EFI_GUID *)pSocketBinding->pTagGuid,
 | 
						|
                      &pInterface,
 | 
						|
                      pThis->DriverBindingHandle,
 | 
						|
                      Controller,
 | 
						|
                      EFI_OPEN_PROTOCOL_GET_PROTOCOL
 | 
						|
                      );
 | 
						|
      if ( !EFI_ERROR ( Status )) {
 | 
						|
        Status = EFI_ALREADY_STARTED;
 | 
						|
      }
 | 
						|
      else {
 | 
						|
        if ( EFI_UNSUPPORTED == Status ) {
 | 
						|
          //
 | 
						|
          //  Connect the driver since the tag is not present
 | 
						|
          //
 | 
						|
          Status = EFI_SUCCESS;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    //  Set the next network protocol
 | 
						|
    //
 | 
						|
    pSocketBinding += 1;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  //  Return the device supported status
 | 
						|
  //
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Connect to a network adapter
 | 
						|
 | 
						|
  This routine calls ::EslServiceConnect to connect the socket
 | 
						|
  layer to the network adapters.  See the \ref NetworkAdapterManagement
 | 
						|
  section.
 | 
						|
 | 
						|
  This routine is called by the UEFI driver framework during connect
 | 
						|
  processing if the controller passes the tests in ::DriverSupported.
 | 
						|
 | 
						|
  @param [in] pThis                Protocol instance pointer.
 | 
						|
  @param [in] Controller           Handle of device to work with.
 | 
						|
  @param [in] pRemainingDevicePath Not used, always produce all possible children.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS          This driver is added to Controller.
 | 
						|
  @retval other                This driver does not support this device.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
DriverStart (
 | 
						|
  IN EFI_DRIVER_BINDING_PROTOCOL * pThis,
 | 
						|
  IN EFI_HANDLE Controller,
 | 
						|
  IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS Status;
 | 
						|
 | 
						|
  DBG_ENTER ( );
 | 
						|
 | 
						|
  //
 | 
						|
  //  Connect to this network adapter
 | 
						|
  //
 | 
						|
  Status = EslServiceConnect ( pThis->DriverBindingHandle,
 | 
						|
                               Controller );
 | 
						|
 | 
						|
  //
 | 
						|
  //  Display the driver start status
 | 
						|
  //
 | 
						|
  DBG_EXIT_STATUS ( Status );
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Disconnect from a network adapter
 | 
						|
 | 
						|
  This routine calls ::EslServiceDisconnect to disconnect the socket
 | 
						|
  layer from the network adapters.  See the \ref NetworkAdapterManagement
 | 
						|
  section.
 | 
						|
 | 
						|
  This routine is called by ::DriverUnload when the socket layer
 | 
						|
  is being unloaded.  This routine should also called by the UEFI
 | 
						|
  driver framework when a network adapter is being unloaded from
 | 
						|
  the system.
 | 
						|
  
 | 
						|
  @param [in] pThis                Protocol instance pointer.
 | 
						|
  @param [in] Controller           Handle of device to stop driver on.
 | 
						|
  @param [in] NumberOfChildren     How many children need to be stopped.
 | 
						|
  @param [in] pChildHandleBuffer   Not used.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS          This driver is removed Controller.
 | 
						|
  @retval EFI_DEVICE_ERROR     The device could not be stopped due to a device error.
 | 
						|
  @retval other                This driver was not removed from this device.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
DriverStop (
 | 
						|
  IN  EFI_DRIVER_BINDING_PROTOCOL * pThis,
 | 
						|
  IN  EFI_HANDLE Controller,
 | 
						|
  IN  UINTN NumberOfChildren,
 | 
						|
  IN  EFI_HANDLE * pChildHandleBuffer
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS Status;
 | 
						|
  
 | 
						|
  DBG_ENTER ( );
 | 
						|
 | 
						|
  //
 | 
						|
  //  Disconnect the network adapters
 | 
						|
  //
 | 
						|
  Status = EslServiceDisconnect ( pThis->DriverBindingHandle,
 | 
						|
                                  Controller );
 | 
						|
 | 
						|
  //
 | 
						|
  //  Display the driver start status
 | 
						|
  //
 | 
						|
  DBG_EXIT_STATUS ( Status );
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Driver binding protocol for the SocketDxe driver.
 | 
						|
**/
 | 
						|
EFI_DRIVER_BINDING_PROTOCOL  mDriverBinding = {
 | 
						|
  DriverSupported,
 | 
						|
  DriverStart,
 | 
						|
  DriverStop,
 | 
						|
  0xa,
 | 
						|
  NULL,
 | 
						|
  NULL
 | 
						|
};
 |