Home | History | Annotate | Download | only in SocketDxe
      1 /** @file
      2   Implement the driver binding protocol for the socket layer.
      3 
      4   Copyright (c) 2011, Intel Corporation
      5   All rights reserved. This program and the accompanying materials
      6   are licensed and made available under the terms and conditions of the BSD License
      7   which accompanies this distribution.  The full text of the license may be found at
      8   http://opensource.org/licenses/bsd-license.php
      9 
     10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 
     14   \section NetworkAdapterManagement Network Adapter Management
     15   Network adapters may come and go over the life if a system running
     16   UEFI.  The SocketDxe driver uses the driver binding API to manage
     17   the connections to network adapters.
     18 
     19   The ::DriverSupported routine selects network adapters that the
     20   socket layer is not using.  This determination by the lack of the
     21   tag GUID associated with the network protocol in the
     22   ::cEslSocketBinding array.  The selected network adapters are
     23   passed to the ::DriverStart routine.
     24 
     25   The ::DriverStart routine calls the ::EslServiceConnect routine
     26   to create an ::ESL_SERVICE structure to manage the network adapter
     27   for the socket layer.  EslServiceConnect also installs the tag
     28   GUID on the network adapter to prevent future calls from
     29   ::DriverSupported.  EslService also calls the network specific
     30   initialization routine listed in ESL_SOCKET_BINDING::pfnInitialize
     31   field of the ::cEslSocketBinding entry.
     32 
     33   The ::DriverStop routine calls the ::EslServiceDisconnect routine
     34   to undo the work done by ::DriverStart.  The socket layer must break
     35   the active network connections, then remove the tag GUIDs from the
     36   controller handle and free ::ESL_SERVICE structure.
     37 
     38 **/
     39 
     40 #include "Socket.h"
     41 
     42 /**
     43   Verify the controller type
     44 
     45   This routine walks the cEslSocketBinding array to determines if
     46   the controller is a network adapter by supporting any of the
     47   network protocols required by the sockets layer.  If so, the
     48   routine verifies that the socket layer is not already using the
     49   support by looking for the tag GUID listed in the corresponding
     50   array entry.  The controller handle is passed to the ::DriverStart
     51   routine if sockets can use the network adapter.
     52   See the \ref NetworkAdapterManagement section.
     53 
     54   This routine is called by the UEFI driver framework during connect
     55   processing.
     56 
     57   @param [in] pThis                Protocol instance pointer.
     58   @param [in] Controller           Handle of device to test.
     59   @param [in] pRemainingDevicePath Not used.
     60 
     61   @retval EFI_SUCCESS          This driver supports this device.
     62   @retval other                This driver does not support this device.
     63 
     64 **/
     65 EFI_STATUS
     66 EFIAPI
     67 DriverSupported (
     68   IN EFI_DRIVER_BINDING_PROTOCOL * pThis,
     69   IN EFI_HANDLE Controller,
     70   IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath
     71   )
     72 {
     73   CONST ESL_SOCKET_BINDING * pEnd;
     74   VOID * pInterface;
     75   CONST ESL_SOCKET_BINDING * pSocketBinding;
     76   EFI_STATUS Status;
     77 
     78   //
     79   //  Assume the list is empty
     80   //
     81   Status = EFI_UNSUPPORTED;
     82 
     83   //
     84   //  Walk the list of network connection points
     85   //
     86   pSocketBinding = &cEslSocketBinding[0];
     87   pEnd = &pSocketBinding[ cEslSocketBindingEntries ];
     88   while ( pEnd > pSocketBinding ) {
     89     //
     90     //  Determine if the controller supports the network protocol
     91     //
     92     Status = gBS->OpenProtocol (
     93                     Controller,
     94                     pSocketBinding->pNetworkBinding,
     95                     &pInterface,
     96                     pThis->DriverBindingHandle,
     97                     Controller,
     98                     EFI_OPEN_PROTOCOL_GET_PROTOCOL
     99                     );
    100     if ( !EFI_ERROR ( Status )) {
    101       //
    102       //  Determine if the driver is already connected
    103       //
    104       Status = gBS->OpenProtocol (
    105                       Controller,
    106                       (EFI_GUID *)pSocketBinding->pTagGuid,
    107                       &pInterface,
    108                       pThis->DriverBindingHandle,
    109                       Controller,
    110                       EFI_OPEN_PROTOCOL_GET_PROTOCOL
    111                       );
    112       if ( !EFI_ERROR ( Status )) {
    113         Status = EFI_ALREADY_STARTED;
    114       }
    115       else {
    116         if ( EFI_UNSUPPORTED == Status ) {
    117           //
    118           //  Connect the driver since the tag is not present
    119           //
    120           Status = EFI_SUCCESS;
    121         }
    122       }
    123     }
    124 
    125     //
    126     //  Set the next network protocol
    127     //
    128     pSocketBinding += 1;
    129   }
    130 
    131   //
    132   //  Return the device supported status
    133   //
    134   return Status;
    135 }
    136 
    137 
    138 /**
    139   Connect to a network adapter
    140 
    141   This routine calls ::EslServiceConnect to connect the socket
    142   layer to the network adapters.  See the \ref NetworkAdapterManagement
    143   section.
    144 
    145   This routine is called by the UEFI driver framework during connect
    146   processing if the controller passes the tests in ::DriverSupported.
    147 
    148   @param [in] pThis                Protocol instance pointer.
    149   @param [in] Controller           Handle of device to work with.
    150   @param [in] pRemainingDevicePath Not used, always produce all possible children.
    151 
    152   @retval EFI_SUCCESS          This driver is added to Controller.
    153   @retval other                This driver does not support this device.
    154 
    155 **/
    156 EFI_STATUS
    157 EFIAPI
    158 DriverStart (
    159   IN EFI_DRIVER_BINDING_PROTOCOL * pThis,
    160   IN EFI_HANDLE Controller,
    161   IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath
    162   )
    163 {
    164   EFI_STATUS Status;
    165 
    166   DBG_ENTER ( );
    167 
    168   //
    169   //  Connect to this network adapter
    170   //
    171   Status = EslServiceConnect ( pThis->DriverBindingHandle,
    172                                Controller );
    173 
    174   //
    175   //  Display the driver start status
    176   //
    177   DBG_EXIT_STATUS ( Status );
    178   return Status;
    179 }
    180 
    181 
    182 /**
    183   Disconnect from a network adapter
    184 
    185   This routine calls ::EslServiceDisconnect to disconnect the socket
    186   layer from the network adapters.  See the \ref NetworkAdapterManagement
    187   section.
    188 
    189   This routine is called by ::DriverUnload when the socket layer
    190   is being unloaded.  This routine should also called by the UEFI
    191   driver framework when a network adapter is being unloaded from
    192   the system.
    193 
    194   @param [in] pThis                Protocol instance pointer.
    195   @param [in] Controller           Handle of device to stop driver on.
    196   @param [in] NumberOfChildren     How many children need to be stopped.
    197   @param [in] pChildHandleBuffer   Not used.
    198 
    199   @retval EFI_SUCCESS          This driver is removed Controller.
    200   @retval EFI_DEVICE_ERROR     The device could not be stopped due to a device error.
    201   @retval other                This driver was not removed from this device.
    202 
    203 **/
    204 EFI_STATUS
    205 EFIAPI
    206 DriverStop (
    207   IN  EFI_DRIVER_BINDING_PROTOCOL * pThis,
    208   IN  EFI_HANDLE Controller,
    209   IN  UINTN NumberOfChildren,
    210   IN  EFI_HANDLE * pChildHandleBuffer
    211   )
    212 {
    213   EFI_STATUS Status;
    214 
    215   DBG_ENTER ( );
    216 
    217   //
    218   //  Disconnect the network adapters
    219   //
    220   Status = EslServiceDisconnect ( pThis->DriverBindingHandle,
    221                                   Controller );
    222 
    223   //
    224   //  Display the driver start status
    225   //
    226   DBG_EXIT_STATUS ( Status );
    227   return Status;
    228 }
    229 
    230 
    231 /**
    232   Driver binding protocol for the SocketDxe driver.
    233 **/
    234 EFI_DRIVER_BINDING_PROTOCOL  mDriverBinding = {
    235   DriverSupported,
    236   DriverStart,
    237   DriverStop,
    238   0xa,
    239   NULL,
    240   NULL
    241 };
    242