+++ /dev/null
-/** @file\r
- Connect to and disconnect from the various network layers\r
-\r
- Copyright (c) 2011, Intel Corporation. All rights reserved.\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "Socket.h"\r
-\r
-\r
-/**\r
- Connect to the network service bindings\r
-\r
- Walk the network service protocols on the controller handle and\r
- locate any that are not in use. Create ::ESL_SERVICE structures to\r
- manage the network layer interfaces for the socket driver. Tag\r
- each of the network interfaces that are being used. Finally, this\r
- routine calls ESL_SOCKET_BINDING::pfnInitialize to prepare the network\r
- interface for use by the socket layer.\r
-\r
- @param [in] BindingHandle Handle for protocol binding.\r
- @param [in] Controller Handle of device to work with.\r
-\r
- @retval EFI_SUCCESS This driver is added to Controller.\r
- @retval EFI_OUT_OF_RESOURCES No more memory available.\r
- @retval EFI_UNSUPPORTED This driver does not support this device.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-EslServiceConnect (\r
- IN EFI_HANDLE BindingHandle,\r
- IN EFI_HANDLE Controller\r
- )\r
-{\r
- BOOLEAN bInUse;\r
- EFI_STATUS ExitStatus;\r
- UINTN LengthInBytes;\r
- UINT8 * pBuffer;\r
- CONST ESL_SOCKET_BINDING * pEnd;\r
- VOID * pJunk;\r
- ESL_SERVICE ** ppServiceListHead;\r
- ESL_SERVICE * pService;\r
- CONST ESL_SOCKET_BINDING * pSocketBinding;\r
- EFI_SERVICE_BINDING_PROTOCOL * pServiceBinding;\r
- EFI_STATUS Status;\r
- EFI_TPL TplPrevious;\r
-\r
- DBG_ENTER ( );\r
-\r
- //\r
- // Assume the list is empty\r
- //\r
- ExitStatus = EFI_UNSUPPORTED;\r
- bInUse = FALSE;\r
-\r
- //\r
- // Walk the list of network connection points\r
- //\r
- pSocketBinding = &cEslSocketBinding[0];\r
- pEnd = &pSocketBinding[ cEslSocketBindingEntries ];\r
- while ( pEnd > pSocketBinding ) {\r
- //\r
- // Determine if the controller supports the network protocol\r
- //\r
- Status = gBS->OpenProtocol (\r
- Controller,\r
- pSocketBinding->pNetworkBinding,\r
- (VOID**)&pServiceBinding,\r
- BindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if ( !EFI_ERROR ( Status )) {\r
- //\r
- // Determine if the socket layer is already connected\r
- //\r
- Status = gBS->OpenProtocol (\r
- Controller,\r
- (EFI_GUID *)pSocketBinding->pTagGuid,\r
- &pJunk,\r
- BindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if ( EFI_UNSUPPORTED == Status ) {\r
- //\r
- // Allocate a service structure since the tag is not present\r
- //\r
- LengthInBytes = sizeof ( *pService );\r
- Status = gBS->AllocatePool (\r
- EfiRuntimeServicesData,\r
- LengthInBytes,\r
- (VOID **) &pService\r
- );\r
- if ( !EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_POOL | DEBUG_INIT,\r
- "0x%08x: Allocate pService, %d bytes\r\n",\r
- pService,\r
- LengthInBytes ));\r
-\r
- //\r
- // Set the structure signature and service binding\r
- //\r
- ZeroMem ( pService, LengthInBytes );\r
- pService->Signature = SERVICE_SIGNATURE;\r
- pService->pSocketBinding = pSocketBinding;\r
- pService->Controller = Controller;\r
- pService->pServiceBinding = pServiceBinding;\r
-\r
- //\r
- // Mark the controller in use\r
- //\r
- if ( !bInUse ) {\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &Controller,\r
- &gEfiCallerIdGuid,\r
- NULL,\r
- NULL\r
- );\r
- if ( !EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
- "Installed: gEfiCallerIdGuid on 0x%08x\r\n",\r
- Controller ));\r
- bInUse = TRUE;\r
- }\r
- else {\r
- if ( EFI_INVALID_PARAMETER == Status ) {\r
- Status = EFI_SUCCESS;\r
- }\r
- }\r
- }\r
- if ( !EFI_ERROR ( Status )) {\r
- //\r
- // Mark the network service protocol in use\r
- //\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &Controller,\r
- pSocketBinding->pTagGuid,\r
- pService,\r
- NULL\r
- );\r
- if ( !EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
- "Installed: %s TagGuid on 0x%08x\r\n",\r
- pSocketBinding->pName,\r
- Controller ));\r
-\r
- //\r
- // Synchronize with the socket layer\r
- //\r
- RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
-\r
- //\r
- // Connect the service to the list\r
- //\r
- pBuffer = (UINT8 *)&mEslLayer;\r
- pBuffer = &pBuffer[ pSocketBinding->ServiceListOffset ];\r
- ppServiceListHead = (ESL_SERVICE **)pBuffer;\r
- pService->pNext = *ppServiceListHead;\r
- *ppServiceListHead = pService;\r
-\r
- //\r
- // Release the socket layer synchronization\r
- //\r
- RESTORE_TPL ( TplPrevious );\r
-\r
- //\r
- // At least one service was made available\r
- //\r
- ExitStatus = EFI_SUCCESS;\r
- }\r
- else {\r
- DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,\r
- "ERROR - Failed to install %s TagGuid on 0x%08x, Status: %r\r\n",\r
- pSocketBinding->pName,\r
- Controller,\r
- Status ));\r
- }\r
-\r
- if ( EFI_ERROR ( Status )) {\r
- //\r
- // The controller is no longer in use\r
- //\r
- if ( bInUse ) {\r
- gBS->UninstallMultipleProtocolInterfaces (\r
- Controller,\r
- &gEfiCallerIdGuid,\r
- NULL,\r
- NULL );\r
- DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
- "Removed: gEfiCallerIdGuid from 0x%08x\r\n",\r
- Controller ));\r
- }\r
- }\r
- }\r
- else {\r
- DEBUG (( DEBUG_ERROR | DEBUG_INIT,\r
- "ERROR - Failed to install gEfiCallerIdGuid on 0x%08x, Status: %r\r\n",\r
- Controller,\r
- Status ));\r
- }\r
-\r
- //\r
- // Release the service if necessary\r
- //\r
- if ( EFI_ERROR ( Status )) {\r
- gBS->FreePool ( pService );\r
- DEBUG (( DEBUG_POOL | DEBUG_INIT,\r
- "0x%08x: Free pService, %d bytes\r\n",\r
- pService,\r
- sizeof ( *pService )));\r
- pService = NULL;\r
- }\r
- }\r
- else {\r
- DEBUG (( DEBUG_ERROR | DEBUG_INIT,\r
- "ERROR - Failed service allocation, Status: %r\r\n",\r
- Status ));\r
- ExitStatus = EFI_OUT_OF_RESOURCES;\r
- break;\r
- }\r
- }\r
- }\r
- \r
- //\r
- // Set the next network protocol\r
- //\r
- pSocketBinding += 1;\r
- }\r
- \r
- //\r
- // Display the driver start status\r
- //\r
- DBG_EXIT_STATUS ( ExitStatus );\r
- return ExitStatus;\r
-}\r
-\r
-\r
-/**\r
- Shutdown the connections to the network layer by locating the\r
- tags on the network interfaces established by ::EslServiceConnect.\r
- This routine shutdowns any activity on the network interface and\r
- then frees the ::ESL_SERVICE structures.\r
-\r
- @param [in] BindingHandle Handle for protocol binding.\r
- @param [in] Controller Handle of device to stop driver on.\r
-\r
- @retval EFI_SUCCESS This driver is removed Controller.\r
- @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.\r
- @retval other This driver was not removed from this device.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-EslServiceDisconnect (\r
- IN EFI_HANDLE BindingHandle,\r
- IN EFI_HANDLE Controller\r
- )\r
-{\r
- UINT8 * pBuffer;\r
- CONST ESL_SOCKET_BINDING * pEnd;\r
- ESL_PORT * pPort;\r
- ESL_SERVICE * pPreviousService;\r
- ESL_SERVICE * pService;\r
- ESL_SERVICE ** ppServiceListHead;\r
- CONST ESL_SOCKET_BINDING * pSocketBinding;\r
- EFI_STATUS Status;\r
- EFI_TPL TplPrevious;\r
- \r
- DBG_ENTER ( );\r
-\r
- //\r
- // Walk the list of network connection points in reverse order\r
- //\r
- pEnd = &cEslSocketBinding[0];\r
- pSocketBinding = &pEnd[ cEslSocketBindingEntries ];\r
- while ( pEnd < pSocketBinding ) {\r
- //\r
- // Set the next network protocol\r
- //\r
- pSocketBinding -= 1;\r
-\r
- //\r
- // Determine if the driver connected\r
- //\r
- Status = gBS->OpenProtocol (\r
- Controller,\r
- (EFI_GUID *)pSocketBinding->pTagGuid,\r
- (VOID **)&pService,\r
- BindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if ( !EFI_ERROR ( Status )) {\r
-\r
- //\r
- // Synchronize with the socket layer\r
- //\r
- RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
-\r
- //\r
- // Walk the list of ports\r
- //\r
- pPort = pService->pPortList;\r
- while ( NULL != pPort ) {\r
- //\r
- // Remove the port from the port list\r
- //\r
- pPort->pService = NULL;\r
- pService->pPortList = pPort->pLinkService;\r
- \r
- //\r
- // Close the port\r
- //\r
- EslSocketPortCloseStart ( pPort,\r
- TRUE,\r
- DEBUG_POOL | DEBUG_INIT );\r
-\r
- //\r
- // Set the next port\r
- //\r
- pPort = pService->pPortList;\r
- }\r
- \r
- //\r
- // Remove the service from the service list\r
- //\r
- pBuffer = (UINT8 *)&mEslLayer;\r
- pBuffer = &pBuffer[ pService->pSocketBinding->ServiceListOffset ];\r
- ppServiceListHead = (ESL_SERVICE **)pBuffer;\r
- pPreviousService = *ppServiceListHead;\r
- if ( pService == pPreviousService ) {\r
- //\r
- // Remove the service from the beginning of the list\r
- //\r
- *ppServiceListHead = pService->pNext;\r
- }\r
- else {\r
- //\r
- // Remove the service from the middle of the list\r
- //\r
- while ( NULL != pPreviousService ) {\r
- if ( pService == pPreviousService->pNext ) {\r
- pPreviousService->pNext = pService->pNext;\r
- break;\r
- }\r
- pPreviousService = pPreviousService->pNext;\r
- }\r
- }\r
-\r
- //\r
- // Release the socket layer synchronization\r
- //\r
- RESTORE_TPL ( TplPrevious );\r
-\r
- //\r
- // Break the driver connection\r
- //\r
- Status = gBS->UninstallMultipleProtocolInterfaces (\r
- Controller,\r
- pSocketBinding->pTagGuid,\r
- pService,\r
- NULL );\r
- if ( !EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_POOL | DEBUG_INIT,\r
- "Removed: %s TagGuid from 0x%08x\r\n",\r
- pSocketBinding->pName,\r
- Controller ));\r
- }\r
- else {\r
- DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,\r
- "ERROR - Failed to removed %s TagGuid from 0x%08x, Status: %r\r\n",\r
- pSocketBinding->pName,\r
- Controller,\r
- Status ));\r
- }\r
-\r
- //\r
- // Free the service structure\r
- //\r
- Status = gBS->FreePool ( pService );\r
- if ( !EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_POOL | DEBUG_INIT,\r
- "0x%08x: Free pService, %d bytes\r\n",\r
- pService,\r
- sizeof ( *pService )));\r
- }\r
- else {\r
- DEBUG (( DEBUG_POOL | DEBUG_INIT,\r
- "ERROR - Failed to free pService 0x%08x, Status: %r\r\n",\r
- pService,\r
- Status ));\r
- }\r
- pService = NULL;\r
- }\r
- }\r
-\r
- //\r
- // The controller is no longer in use\r
- //\r
- gBS->UninstallMultipleProtocolInterfaces (\r
- Controller,\r
- &gEfiCallerIdGuid,\r
- NULL,\r
- NULL );\r
- DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
- "Removed: gEfiCallerIdGuid from 0x%08x\r\n",\r
- Controller ));\r
-\r
- //\r
- // The driver is disconnected from the network controller\r
- //\r
- Status = EFI_SUCCESS;\r
-\r
- //\r
- // Display the driver start status\r
- //\r
- DBG_EXIT_STATUS ( Status );\r
- return Status;\r
-}\r
-\r
-\r
-\r
-/**\r
-Initialize the service layer\r
-\r
-@param [in] ImageHandle Handle for the image.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-EslServiceLoad (\r
- IN EFI_HANDLE ImageHandle\r
- )\r
-{\r
- ESL_LAYER * pLayer;\r
-\r
- //\r
- // Save the image handle\r
- //\r
- pLayer = &mEslLayer;\r
- ZeroMem ( pLayer, sizeof ( *pLayer ));\r
- pLayer->Signature = LAYER_SIGNATURE;\r
- pLayer->ImageHandle = ImageHandle;\r
-\r
- //\r
- // Connect the service binding protocol to the image handle\r
- //\r
- pLayer->pServiceBinding = &mEfiServiceBinding;\r
-}\r
-\r
-\r
-/**\r
- Shutdown the service layer\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-EslServiceUnload (\r
- VOID\r
- )\r
-{\r
- ESL_LAYER * pLayer;\r
-\r
- //\r
- // Undo the work by ServiceLoad\r
- //\r
- pLayer = &mEslLayer;\r
- pLayer->ImageHandle = NULL;\r
- pLayer->pServiceBinding = NULL;\r
-}\r