2 Connect to and disconnect from the various network layers
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
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.
19 Connect to the network service bindings
21 Walk the network service protocols on the controller handle and
22 locate any that are not in use. Create ::ESL_SERVICE structures to
23 manage the network layer interfaces for the socket driver. Tag
24 each of the network interfaces that are being used. Finally, this
25 routine calls ESL_SOCKET_BINDING::pfnInitialize to prepare the network
26 interface for use by the socket layer.
28 @param [in] BindingHandle Handle for protocol binding.
29 @param [in] Controller Handle of device to work with.
31 @retval EFI_SUCCESS This driver is added to Controller.
32 @retval other This driver does not support this device.
38 IN EFI_HANDLE BindingHandle
,
39 IN EFI_HANDLE Controller
45 CONST ESL_SOCKET_BINDING
* pEnd
;
47 ESL_SERVICE
** ppServiceListHead
;
48 ESL_SERVICE
* pService
;
49 CONST ESL_SOCKET_BINDING
* pSocketBinding
;
50 EFI_SERVICE_BINDING_PROTOCOL
* pServiceBinding
;
57 // Assume the list is empty
59 Status
= EFI_UNSUPPORTED
;
63 // Walk the list of network connection points
65 pSocketBinding
= &cEslSocketBinding
[0];
66 pEnd
= &pSocketBinding
[ cEslSocketBindingEntries
];
67 while ( pEnd
> pSocketBinding
) {
69 // Determine if the controller supports the network protocol
71 Status
= gBS
->OpenProtocol (
73 pSocketBinding
->pNetworkBinding
,
74 (VOID
**)&pServiceBinding
,
77 EFI_OPEN_PROTOCOL_GET_PROTOCOL
79 if ( !EFI_ERROR ( Status
)) {
81 // Determine if the socket layer is already connected
83 Status
= gBS
->OpenProtocol (
85 (EFI_GUID
*)pSocketBinding
->pTagGuid
,
89 EFI_OPEN_PROTOCOL_GET_PROTOCOL
91 if ( EFI_UNSUPPORTED
== Status
) {
93 // Allocate a service structure since the tag is not present
95 LengthInBytes
= sizeof ( *pService
);
96 Status
= gBS
->AllocatePool (
97 EfiRuntimeServicesData
,
101 if ( !EFI_ERROR ( Status
)) {
102 DEBUG (( DEBUG_POOL
| DEBUG_INIT
,
103 "0x%08x: Allocate pService, %d bytes\r\n",
108 // Set the structure signature and service binding
110 ZeroMem ( pService
, LengthInBytes
);
111 pService
->Signature
= SERVICE_SIGNATURE
;
112 pService
->pSocketBinding
= pSocketBinding
;
113 pService
->Controller
= Controller
;
114 pService
->pServiceBinding
= pServiceBinding
;
117 // Mark the controller in use
120 Status
= gBS
->InstallMultipleProtocolInterfaces (
126 if ( !EFI_ERROR ( Status
)) {
127 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
128 "Installed: gEfiCallerIdGuid on 0x%08x\r\n",
133 if ( EFI_INVALID_PARAMETER
== Status
) {
134 Status
= EFI_SUCCESS
;
138 if ( !EFI_ERROR ( Status
)) {
140 // Mark the network service protocol in use
142 Status
= gBS
->InstallMultipleProtocolInterfaces (
144 pSocketBinding
->pTagGuid
,
148 if ( !EFI_ERROR ( Status
)) {
149 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
150 "Installed: %s TagGuid on 0x%08x\r\n",
151 pSocketBinding
->pName
,
155 // Synchronize with the socket layer
157 RAISE_TPL ( TplPrevious
, TPL_SOCKETS
);
160 // Connect the service to the list
162 pBuffer
= (UINT8
*)&mEslLayer
;
163 pBuffer
= &pBuffer
[ pSocketBinding
->ServiceListOffset
];
164 ppServiceListHead
= (ESL_SERVICE
**)pBuffer
;
165 pService
->pNext
= *ppServiceListHead
;
166 *ppServiceListHead
= pService
;
169 // Release the socket layer synchronization
171 RESTORE_TPL ( TplPrevious
);
174 // Determine if the initialization was successful
176 if ( EFI_ERROR ( Status
)) {
177 DEBUG (( DEBUG_ERROR
| DEBUG_POOL
| DEBUG_INIT
,
178 "ERROR - Failed to initialize service %s on 0x%08x, Status: %r\r\n",
179 pSocketBinding
->pName
,
184 // Free the network service binding if necessary
186 gBS
->UninstallMultipleProtocolInterfaces (
188 pSocketBinding
->pTagGuid
,
191 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
192 "Removed: %s TagGuid from 0x%08x\r\n",
193 pSocketBinding
->pName
,
198 DEBUG (( DEBUG_ERROR
| DEBUG_POOL
| DEBUG_INIT
,
199 "ERROR - Failed to install %s TagGuid on 0x%08x, Status: %r\r\n",
200 pSocketBinding
->pName
,
205 if ( EFI_ERROR ( Status
)) {
207 // The controller is no longer in use
210 gBS
->UninstallMultipleProtocolInterfaces (
215 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
216 "Removed: gEfiCallerIdGuid from 0x%08x\r\n",
222 DEBUG (( DEBUG_ERROR
| DEBUG_INIT
,
223 "ERROR - Failed to install gEfiCallerIdGuid on 0x%08x, Status: %r\r\n",
229 // Release the service if necessary
231 if ( EFI_ERROR ( Status
)) {
232 gBS
->FreePool ( pService
);
233 DEBUG (( DEBUG_POOL
| DEBUG_INIT
,
234 "0x%08x: Free pService, %d bytes\r\n",
236 sizeof ( *pService
)));
241 DEBUG (( DEBUG_ERROR
| DEBUG_INIT
,
242 "ERROR - Failed service allocation, Status: %r\r\n",
249 // Set the next network protocol
255 // Display the driver start status
257 DBG_EXIT_STATUS ( Status
);
263 Shutdown the connections to the network layer by locating the
264 tags on the network interfaces established by ::EslServiceConnect.
265 This routine shutdowns any activity on the network interface and
266 then frees the ::ESL_SERVICE structures.
268 @param [in] BindingHandle Handle for protocol binding.
269 @param [in] Controller Handle of device to stop driver on.
271 @retval EFI_SUCCESS This driver is removed Controller.
272 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
273 @retval other This driver was not removed from this device.
278 EslServiceDisconnect (
279 IN EFI_HANDLE BindingHandle
,
280 IN EFI_HANDLE Controller
284 CONST ESL_SOCKET_BINDING
* pEnd
;
286 ESL_SERVICE
* pPreviousService
;
287 ESL_SERVICE
* pService
;
288 ESL_SERVICE
** ppServiceListHead
;
289 CONST ESL_SOCKET_BINDING
* pSocketBinding
;
296 // Walk the list of network connection points in reverse order
298 pEnd
= &cEslSocketBinding
[0];
299 pSocketBinding
= &pEnd
[ cEslSocketBindingEntries
];
300 while ( pEnd
< pSocketBinding
) {
302 // Set the next network protocol
307 // Determine if the driver connected
309 Status
= gBS
->OpenProtocol (
311 (EFI_GUID
*)pSocketBinding
->pTagGuid
,
315 EFI_OPEN_PROTOCOL_GET_PROTOCOL
317 if ( !EFI_ERROR ( Status
)) {
320 // Synchronize with the socket layer
322 RAISE_TPL ( TplPrevious
, TPL_SOCKETS
);
325 // Walk the list of ports
327 pPort
= pService
->pPortList
;
328 while ( NULL
!= pPort
) {
330 // Remove the port from the port list
332 pPort
->pService
= NULL
;
333 pService
->pPortList
= pPort
->pLinkService
;
338 EslSocketPortCloseStart ( pPort
,
340 DEBUG_POOL
| DEBUG_INIT
);
345 pPort
= pService
->pPortList
;
349 // Remove the service from the service list
351 pBuffer
= (UINT8
*)&mEslLayer
;
352 pBuffer
= &pBuffer
[ pService
->pSocketBinding
->ServiceListOffset
];
353 ppServiceListHead
= (ESL_SERVICE
**)pBuffer
;
354 pPreviousService
= *ppServiceListHead
;
355 if ( pService
== pPreviousService
) {
357 // Remove the service from the beginning of the list
359 *ppServiceListHead
= pService
->pNext
;
363 // Remove the service from the middle of the list
365 while ( NULL
!= pPreviousService
) {
366 if ( pService
== pPreviousService
->pNext
) {
367 pPreviousService
->pNext
= pService
->pNext
;
370 pPreviousService
= pPreviousService
->pNext
;
375 // Release the socket layer synchronization
377 RESTORE_TPL ( TplPrevious
);
380 // Break the driver connection
382 Status
= gBS
->UninstallMultipleProtocolInterfaces (
384 pSocketBinding
->pTagGuid
,
387 if ( !EFI_ERROR ( Status
)) {
388 DEBUG (( DEBUG_POOL
| DEBUG_INIT
,
389 "Removed: %s TagGuid from 0x%08x\r\n",
390 pSocketBinding
->pName
,
394 DEBUG (( DEBUG_ERROR
| DEBUG_POOL
| DEBUG_INIT
,
395 "ERROR - Failed to removed %s TagGuid from 0x%08x, Status: %r\r\n",
396 pSocketBinding
->pName
,
402 // Free the service structure
404 Status
= gBS
->FreePool ( pService
);
405 if ( !EFI_ERROR ( Status
)) {
406 DEBUG (( DEBUG_POOL
| DEBUG_INIT
,
407 "0x%08x: Free pService, %d bytes\r\n",
409 sizeof ( *pService
)));
412 DEBUG (( DEBUG_POOL
| DEBUG_INIT
,
413 "ERROR - Failed to free pService 0x%08x, Status: %r\r\n",
422 // The controller is no longer in use
424 gBS
->UninstallMultipleProtocolInterfaces (
429 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
430 "Removed: gEfiCallerIdGuid from 0x%08x\r\n",
434 // The driver is disconnected from the network controller
436 Status
= EFI_SUCCESS
;
439 // Display the driver start status
441 DBG_EXIT_STATUS ( Status
);
448 Initialize the service layer
450 @param [in] ImageHandle Handle for the image.
456 IN EFI_HANDLE ImageHandle
462 // Save the image handle
465 ZeroMem ( pLayer
, sizeof ( *pLayer
));
466 pLayer
->Signature
= LAYER_SIGNATURE
;
467 pLayer
->ImageHandle
= ImageHandle
;
470 // Connect the service binding protocol to the image handle
472 pLayer
->pServiceBinding
= &mEfiServiceBinding
;
477 Shutdown the service layer
489 // Undo the work by ServiceLoad
492 pLayer
->ImageHandle
= NULL
;
493 pLayer
->pServiceBinding
= NULL
;