2 Connect to and disconnect from the various network layers
4 Copyright (c) 2011, Intel Corporation. All rights reserved.
5 SPDX-License-Identifier: BSD-2-Clause-Patent
13 Connect to the network service bindings
15 Walk the network service protocols on the controller handle and
16 locate any that are not in use. Create ::ESL_SERVICE structures to
17 manage the network layer interfaces for the socket driver. Tag
18 each of the network interfaces that are being used. Finally, this
19 routine calls ESL_SOCKET_BINDING::pfnInitialize to prepare the network
20 interface for use by the socket layer.
22 @param [in] BindingHandle Handle for protocol binding.
23 @param [in] Controller Handle of device to work with.
25 @retval EFI_SUCCESS This driver is added to Controller.
26 @retval EFI_OUT_OF_RESOURCES No more memory available.
27 @retval EFI_UNSUPPORTED This driver does not support this device.
33 IN EFI_HANDLE BindingHandle
,
34 IN EFI_HANDLE Controller
38 EFI_STATUS ExitStatus
;
41 CONST ESL_SOCKET_BINDING
* pEnd
;
43 ESL_SERVICE
** ppServiceListHead
;
44 ESL_SERVICE
* pService
;
45 CONST ESL_SOCKET_BINDING
* pSocketBinding
;
46 EFI_SERVICE_BINDING_PROTOCOL
* pServiceBinding
;
53 // Assume the list is empty
55 ExitStatus
= EFI_UNSUPPORTED
;
59 // Walk the list of network connection points
61 pSocketBinding
= &cEslSocketBinding
[0];
62 pEnd
= &pSocketBinding
[ cEslSocketBindingEntries
];
63 while ( pEnd
> pSocketBinding
) {
65 // Determine if the controller supports the network protocol
67 Status
= gBS
->OpenProtocol (
69 pSocketBinding
->pNetworkBinding
,
70 (VOID
**)&pServiceBinding
,
73 EFI_OPEN_PROTOCOL_GET_PROTOCOL
75 if ( !EFI_ERROR ( Status
)) {
77 // Determine if the socket layer is already connected
79 Status
= gBS
->OpenProtocol (
81 (EFI_GUID
*)pSocketBinding
->pTagGuid
,
85 EFI_OPEN_PROTOCOL_GET_PROTOCOL
87 if ( EFI_UNSUPPORTED
== Status
) {
89 // Allocate a service structure since the tag is not present
91 LengthInBytes
= sizeof ( *pService
);
92 Status
= gBS
->AllocatePool (
93 EfiRuntimeServicesData
,
97 if ( !EFI_ERROR ( Status
)) {
98 DEBUG (( DEBUG_POOL
| DEBUG_INIT
,
99 "0x%08x: Allocate pService, %d bytes\r\n",
104 // Set the structure signature and service binding
106 ZeroMem ( pService
, LengthInBytes
);
107 pService
->Signature
= SERVICE_SIGNATURE
;
108 pService
->pSocketBinding
= pSocketBinding
;
109 pService
->Controller
= Controller
;
110 pService
->pServiceBinding
= pServiceBinding
;
113 // Mark the controller in use
116 Status
= gBS
->InstallMultipleProtocolInterfaces (
122 if ( !EFI_ERROR ( Status
)) {
123 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
124 "Installed: gEfiCallerIdGuid on 0x%08x\r\n",
129 if ( EFI_INVALID_PARAMETER
== Status
) {
130 Status
= EFI_SUCCESS
;
134 if ( !EFI_ERROR ( Status
)) {
136 // Mark the network service protocol in use
138 Status
= gBS
->InstallMultipleProtocolInterfaces (
140 pSocketBinding
->pTagGuid
,
144 if ( !EFI_ERROR ( Status
)) {
145 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
146 "Installed: %s TagGuid on 0x%08x\r\n",
147 pSocketBinding
->pName
,
151 // Synchronize with the socket layer
153 RAISE_TPL ( TplPrevious
, TPL_SOCKETS
);
156 // Connect the service to the list
158 pBuffer
= (UINT8
*)&mEslLayer
;
159 pBuffer
= &pBuffer
[ pSocketBinding
->ServiceListOffset
];
160 ppServiceListHead
= (ESL_SERVICE
**)pBuffer
;
161 pService
->pNext
= *ppServiceListHead
;
162 *ppServiceListHead
= pService
;
165 // Release the socket layer synchronization
167 RESTORE_TPL ( TplPrevious
);
170 // At least one service was made available
172 ExitStatus
= EFI_SUCCESS
;
175 DEBUG (( DEBUG_ERROR
| DEBUG_POOL
| DEBUG_INIT
,
176 "ERROR - Failed to install %s TagGuid on 0x%08x, Status: %r\r\n",
177 pSocketBinding
->pName
,
182 if ( EFI_ERROR ( Status
)) {
184 // The controller is no longer in use
187 gBS
->UninstallMultipleProtocolInterfaces (
192 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
193 "Removed: gEfiCallerIdGuid from 0x%08x\r\n",
199 DEBUG (( DEBUG_ERROR
| DEBUG_INIT
,
200 "ERROR - Failed to install gEfiCallerIdGuid on 0x%08x, Status: %r\r\n",
206 // Release the service if necessary
208 if ( EFI_ERROR ( Status
)) {
209 gBS
->FreePool ( pService
);
210 DEBUG (( DEBUG_POOL
| DEBUG_INIT
,
211 "0x%08x: Free pService, %d bytes\r\n",
213 sizeof ( *pService
)));
218 DEBUG (( DEBUG_ERROR
| DEBUG_INIT
,
219 "ERROR - Failed service allocation, Status: %r\r\n",
221 ExitStatus
= EFI_OUT_OF_RESOURCES
;
228 // Set the next network protocol
234 // Display the driver start status
236 DBG_EXIT_STATUS ( ExitStatus
);
242 Shutdown the connections to the network layer by locating the
243 tags on the network interfaces established by ::EslServiceConnect.
244 This routine shutdowns any activity on the network interface and
245 then frees the ::ESL_SERVICE structures.
247 @param [in] BindingHandle Handle for protocol binding.
248 @param [in] Controller Handle of device to stop driver on.
250 @retval EFI_SUCCESS This driver is removed Controller.
251 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
252 @retval other This driver was not removed from this device.
257 EslServiceDisconnect (
258 IN EFI_HANDLE BindingHandle
,
259 IN EFI_HANDLE Controller
263 CONST ESL_SOCKET_BINDING
* pEnd
;
265 ESL_SERVICE
* pPreviousService
;
266 ESL_SERVICE
* pService
;
267 ESL_SERVICE
** ppServiceListHead
;
268 CONST ESL_SOCKET_BINDING
* pSocketBinding
;
275 // Walk the list of network connection points in reverse order
277 pEnd
= &cEslSocketBinding
[0];
278 pSocketBinding
= &pEnd
[ cEslSocketBindingEntries
];
279 while ( pEnd
< pSocketBinding
) {
281 // Set the next network protocol
286 // Determine if the driver connected
288 Status
= gBS
->OpenProtocol (
290 (EFI_GUID
*)pSocketBinding
->pTagGuid
,
294 EFI_OPEN_PROTOCOL_GET_PROTOCOL
296 if ( !EFI_ERROR ( Status
)) {
299 // Synchronize with the socket layer
301 RAISE_TPL ( TplPrevious
, TPL_SOCKETS
);
304 // Walk the list of ports
306 pPort
= pService
->pPortList
;
307 while ( NULL
!= pPort
) {
309 // Remove the port from the port list
311 pPort
->pService
= NULL
;
312 pService
->pPortList
= pPort
->pLinkService
;
317 EslSocketPortCloseStart ( pPort
,
319 DEBUG_POOL
| DEBUG_INIT
);
324 pPort
= pService
->pPortList
;
328 // Remove the service from the service list
330 pBuffer
= (UINT8
*)&mEslLayer
;
331 pBuffer
= &pBuffer
[ pService
->pSocketBinding
->ServiceListOffset
];
332 ppServiceListHead
= (ESL_SERVICE
**)pBuffer
;
333 pPreviousService
= *ppServiceListHead
;
334 if ( pService
== pPreviousService
) {
336 // Remove the service from the beginning of the list
338 *ppServiceListHead
= pService
->pNext
;
342 // Remove the service from the middle of the list
344 while ( NULL
!= pPreviousService
) {
345 if ( pService
== pPreviousService
->pNext
) {
346 pPreviousService
->pNext
= pService
->pNext
;
349 pPreviousService
= pPreviousService
->pNext
;
354 // Release the socket layer synchronization
356 RESTORE_TPL ( TplPrevious
);
359 // Break the driver connection
361 Status
= gBS
->UninstallMultipleProtocolInterfaces (
363 pSocketBinding
->pTagGuid
,
366 if ( !EFI_ERROR ( Status
)) {
367 DEBUG (( DEBUG_POOL
| DEBUG_INIT
,
368 "Removed: %s TagGuid from 0x%08x\r\n",
369 pSocketBinding
->pName
,
373 DEBUG (( DEBUG_ERROR
| DEBUG_POOL
| DEBUG_INIT
,
374 "ERROR - Failed to removed %s TagGuid from 0x%08x, Status: %r\r\n",
375 pSocketBinding
->pName
,
381 // Free the service structure
383 Status
= gBS
->FreePool ( pService
);
384 if ( !EFI_ERROR ( Status
)) {
385 DEBUG (( DEBUG_POOL
| DEBUG_INIT
,
386 "0x%08x: Free pService, %d bytes\r\n",
388 sizeof ( *pService
)));
391 DEBUG (( DEBUG_POOL
| DEBUG_INIT
,
392 "ERROR - Failed to free pService 0x%08x, Status: %r\r\n",
401 // The controller is no longer in use
403 gBS
->UninstallMultipleProtocolInterfaces (
408 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
409 "Removed: gEfiCallerIdGuid from 0x%08x\r\n",
413 // The driver is disconnected from the network controller
415 Status
= EFI_SUCCESS
;
418 // Display the driver start status
420 DBG_EXIT_STATUS ( Status
);
427 Initialize the service layer
429 @param [in] ImageHandle Handle for the image.
435 IN EFI_HANDLE ImageHandle
441 // Save the image handle
444 ZeroMem ( pLayer
, sizeof ( *pLayer
));
445 pLayer
->Signature
= LAYER_SIGNATURE
;
446 pLayer
->ImageHandle
= ImageHandle
;
449 // Connect the service binding protocol to the image handle
451 pLayer
->pServiceBinding
= &mEfiServiceBinding
;
456 Shutdown the service layer
468 // Undo the work by ServiceLoad
471 pLayer
->ImageHandle
= NULL
;
472 pLayer
->pServiceBinding
= NULL
;