• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
DriverSupported(IN EFI_DRIVER_BINDING_PROTOCOL * pThis,IN EFI_HANDLE Controller,IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath)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
DriverStart(IN EFI_DRIVER_BINDING_PROTOCOL * pThis,IN EFI_HANDLE Controller,IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath)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
DriverStop(IN EFI_DRIVER_BINDING_PROTOCOL * pThis,IN EFI_HANDLE Controller,IN UINTN NumberOfChildren,IN EFI_HANDLE * pChildHandleBuffer)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