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 EFI_OUT_OF_RESOURCES No more memory available.
33 @retval EFI_UNSUPPORTED This driver does not support this device.
39 IN EFI_HANDLE BindingHandle
,
40 IN EFI_HANDLE Controller
44 EFI_STATUS ExitStatus
;
47 CONST ESL_SOCKET_BINDING
* pEnd
;
49 ESL_SERVICE
** ppServiceListHead
;
50 ESL_SERVICE
* pService
;
51 CONST ESL_SOCKET_BINDING
* pSocketBinding
;
52 EFI_SERVICE_BINDING_PROTOCOL
* pServiceBinding
;
59 // Assume the list is empty
61 ExitStatus
= EFI_UNSUPPORTED
;
65 // Walk the list of network connection points
67 pSocketBinding
= &cEslSocketBinding
[0];
68 pEnd
= &pSocketBinding
[ cEslSocketBindingEntries
];
69 while ( pEnd
> pSocketBinding
) {
71 // Determine if the controller supports the network protocol
73 Status
= gBS
->OpenProtocol (
75 pSocketBinding
->pNetworkBinding
,
76 (VOID
**)&pServiceBinding
,
79 EFI_OPEN_PROTOCOL_GET_PROTOCOL
81 if ( !EFI_ERROR ( Status
)) {
83 // Determine if the socket layer is already connected
85 Status
= gBS
->OpenProtocol (
87 (EFI_GUID
*)pSocketBinding
->pTagGuid
,
91 EFI_OPEN_PROTOCOL_GET_PROTOCOL
93 if ( EFI_UNSUPPORTED
== Status
) {
95 // Allocate a service structure since the tag is not present
97 LengthInBytes
= sizeof ( *pService
);
98 Status
= gBS
->AllocatePool (
99 EfiRuntimeServicesData
,
103 if ( !EFI_ERROR ( Status
)) {
104 DEBUG (( DEBUG_POOL
| DEBUG_INIT
,
105 "0x%08x: Allocate pService, %d bytes\r\n",
110 // Set the structure signature and service binding
112 ZeroMem ( pService
, LengthInBytes
);
113 pService
->Signature
= SERVICE_SIGNATURE
;
114 pService
->pSocketBinding
= pSocketBinding
;
115 pService
->Controller
= Controller
;
116 pService
->pServiceBinding
= pServiceBinding
;
119 // Mark the controller in use
122 Status
= gBS
->InstallMultipleProtocolInterfaces (
128 if ( !EFI_ERROR ( Status
)) {
129 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
130 "Installed: gEfiCallerIdGuid on 0x%08x\r\n",
135 if ( EFI_INVALID_PARAMETER
== Status
) {
136 Status
= EFI_SUCCESS
;
140 if ( !EFI_ERROR ( Status
)) {
142 // Mark the network service protocol in use
144 Status
= gBS
->InstallMultipleProtocolInterfaces (
146 pSocketBinding
->pTagGuid
,
150 if ( !EFI_ERROR ( Status
)) {
151 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
152 "Installed: %s TagGuid on 0x%08x\r\n",
153 pSocketBinding
->pName
,
157 // Synchronize with the socket layer
159 RAISE_TPL ( TplPrevious
, TPL_SOCKETS
);
162 // Connect the service to the list
164 pBuffer
= (UINT8
*)&mEslLayer
;
165 pBuffer
= &pBuffer
[ pSocketBinding
->ServiceListOffset
];
166 ppServiceListHead
= (ESL_SERVICE
**)pBuffer
;
167 pService
->pNext
= *ppServiceListHead
;
168 *ppServiceListHead
= pService
;
171 // Release the socket layer synchronization
173 RESTORE_TPL ( TplPrevious
);
176 // At least one service was made available
178 ExitStatus
= EFI_SUCCESS
;
181 DEBUG (( DEBUG_ERROR
| DEBUG_POOL
| DEBUG_INIT
,
182 "ERROR - Failed to install %s TagGuid on 0x%08x, Status: %r\r\n",
183 pSocketBinding
->pName
,
188 if ( EFI_ERROR ( Status
)) {
190 // The controller is no longer in use
193 gBS
->UninstallMultipleProtocolInterfaces (
198 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
199 "Removed: gEfiCallerIdGuid from 0x%08x\r\n",
205 DEBUG (( DEBUG_ERROR
| DEBUG_INIT
,
206 "ERROR - Failed to install gEfiCallerIdGuid on 0x%08x, Status: %r\r\n",
212 // Release the service if necessary
214 if ( EFI_ERROR ( Status
)) {
215 gBS
->FreePool ( pService
);
216 DEBUG (( DEBUG_POOL
| DEBUG_INIT
,
217 "0x%08x: Free pService, %d bytes\r\n",
219 sizeof ( *pService
)));
224 DEBUG (( DEBUG_ERROR
| DEBUG_INIT
,
225 "ERROR - Failed service allocation, Status: %r\r\n",
227 ExitStatus
= EFI_OUT_OF_RESOURCES
;
234 // Set the next network protocol
240 // Display the driver start status
242 DBG_EXIT_STATUS ( ExitStatus
);
248 Shutdown the connections to the network layer by locating the
249 tags on the network interfaces established by ::EslServiceConnect.
250 This routine shutdowns any activity on the network interface and
251 then frees the ::ESL_SERVICE structures.
253 @param [in] BindingHandle Handle for protocol binding.
254 @param [in] Controller Handle of device to stop driver on.
256 @retval EFI_SUCCESS This driver is removed Controller.
257 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
258 @retval other This driver was not removed from this device.
263 EslServiceDisconnect (
264 IN EFI_HANDLE BindingHandle
,
265 IN EFI_HANDLE Controller
269 CONST ESL_SOCKET_BINDING
* pEnd
;
271 ESL_SERVICE
* pPreviousService
;
272 ESL_SERVICE
* pService
;
273 ESL_SERVICE
** ppServiceListHead
;
274 CONST ESL_SOCKET_BINDING
* pSocketBinding
;
281 // Walk the list of network connection points in reverse order
283 pEnd
= &cEslSocketBinding
[0];
284 pSocketBinding
= &pEnd
[ cEslSocketBindingEntries
];
285 while ( pEnd
< pSocketBinding
) {
287 // Set the next network protocol
292 // Determine if the driver connected
294 Status
= gBS
->OpenProtocol (
296 (EFI_GUID
*)pSocketBinding
->pTagGuid
,
300 EFI_OPEN_PROTOCOL_GET_PROTOCOL
302 if ( !EFI_ERROR ( Status
)) {
305 // Synchronize with the socket layer
307 RAISE_TPL ( TplPrevious
, TPL_SOCKETS
);
310 // Walk the list of ports
312 pPort
= pService
->pPortList
;
313 while ( NULL
!= pPort
) {
315 // Remove the port from the port list
317 pPort
->pService
= NULL
;
318 pService
->pPortList
= pPort
->pLinkService
;
323 EslSocketPortCloseStart ( pPort
,
325 DEBUG_POOL
| DEBUG_INIT
);
330 pPort
= pService
->pPortList
;
334 // Remove the service from the service list
336 pBuffer
= (UINT8
*)&mEslLayer
;
337 pBuffer
= &pBuffer
[ pService
->pSocketBinding
->ServiceListOffset
];
338 ppServiceListHead
= (ESL_SERVICE
**)pBuffer
;
339 pPreviousService
= *ppServiceListHead
;
340 if ( pService
== pPreviousService
) {
342 // Remove the service from the beginning of the list
344 *ppServiceListHead
= pService
->pNext
;
348 // Remove the service from the middle of the list
350 while ( NULL
!= pPreviousService
) {
351 if ( pService
== pPreviousService
->pNext
) {
352 pPreviousService
->pNext
= pService
->pNext
;
355 pPreviousService
= pPreviousService
->pNext
;
360 // Release the socket layer synchronization
362 RESTORE_TPL ( TplPrevious
);
365 // Break the driver connection
367 Status
= gBS
->UninstallMultipleProtocolInterfaces (
369 pSocketBinding
->pTagGuid
,
372 if ( !EFI_ERROR ( Status
)) {
373 DEBUG (( DEBUG_POOL
| DEBUG_INIT
,
374 "Removed: %s TagGuid from 0x%08x\r\n",
375 pSocketBinding
->pName
,
379 DEBUG (( DEBUG_ERROR
| DEBUG_POOL
| DEBUG_INIT
,
380 "ERROR - Failed to removed %s TagGuid from 0x%08x, Status: %r\r\n",
381 pSocketBinding
->pName
,
387 // Free the service structure
389 Status
= gBS
->FreePool ( pService
);
390 if ( !EFI_ERROR ( Status
)) {
391 DEBUG (( DEBUG_POOL
| DEBUG_INIT
,
392 "0x%08x: Free pService, %d bytes\r\n",
394 sizeof ( *pService
)));
397 DEBUG (( DEBUG_POOL
| DEBUG_INIT
,
398 "ERROR - Failed to free pService 0x%08x, Status: %r\r\n",
407 // The controller is no longer in use
409 gBS
->UninstallMultipleProtocolInterfaces (
414 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
415 "Removed: gEfiCallerIdGuid from 0x%08x\r\n",
419 // The driver is disconnected from the network controller
421 Status
= EFI_SUCCESS
;
424 // Display the driver start status
426 DBG_EXIT_STATUS ( Status
);
433 Initialize the service layer
435 @param [in] ImageHandle Handle for the image.
441 IN EFI_HANDLE ImageHandle
447 // Save the image handle
450 ZeroMem ( pLayer
, sizeof ( *pLayer
));
451 pLayer
->Signature
= LAYER_SIGNATURE
;
452 pLayer
->ImageHandle
= ImageHandle
;
455 // Connect the service binding protocol to the image handle
457 pLayer
->pServiceBinding
= &mEfiServiceBinding
;
462 Shutdown the service layer
474 // Undo the work by ServiceLoad
477 pLayer
->ImageHandle
= NULL
;
478 pLayer
->pServiceBinding
= NULL
;