| /** @file | |
| Implement the entry and unload for the socket driver. | |
| Copyright (c) 2011, Intel Corporation | |
| All rights reserved. This program and the accompanying materials | |
| are licensed and made available under the terms and conditions of the BSD License | |
| which accompanies this distribution. The full text of the license may be found at | |
| http://opensource.org/licenses/bsd-license.php | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
| **/ | |
| #include "Socket.h" | |
| /** | |
| The following GUID values are only used by the SocketDxe driver. An | |
| alternative set of values exists in EfiSocketLib\UseEfiSocketLib.c | |
| which an application uses when it links against EfiSocketLib. These | |
| two sets of values allow the SocketDxe driver to coexist with socket | |
| applications. | |
| Tag GUID - IPv4 in use by SocketDxe | |
| **/ | |
| CONST EFI_GUID mEslIp4ServiceGuid = { | |
| 0x4e3a82e6, 0xe43f, 0x460a, { 0x86, 0x6e, 0x9b, 0x5a, 0xab, 0x80, 0x44, 0x48 } | |
| }; | |
| /** | |
| Tag GUID - IPv6 in use by SocketDxe | |
| **/ | |
| CONST EFI_GUID mEslIp6ServiceGuid = { | |
| 0x2fc3b2d3, 0x6eba, 0x42b0, { 0xa4, 0xa7, 0x14, 0xc7, 0xa8, 0x4b, 0x5d, 0x22 } | |
| }; | |
| /** | |
| Tag GUID - TCPv4 in use by SocketDxe | |
| **/ | |
| CONST EFI_GUID mEslTcp4ServiceGuid = { | |
| 0x4dcaab0a, 0x1990, 0x4352, { 0x8d, 0x2f, 0x2d, 0x8f, 0x13, 0x55, 0x98, 0xa5 } | |
| }; | |
| /** | |
| Tag GUID - TCPv6 in use by SocketDxe | |
| **/ | |
| CONST EFI_GUID mEslTcp6ServiceGuid = { | |
| 0xdd455a69, 0xec75, 0x456c, { 0x84, 0xd2, 0x95, 0xca, 0xe7, 0xd3, 0xc6, 0xd3 } | |
| }; | |
| /** | |
| Tag GUID - UDPv4 in use by SocketDxe | |
| **/ | |
| CONST EFI_GUID mEslUdp4ServiceGuid = { | |
| 0x43a110ce, 0x9ccd, 0x402b, { 0x8c, 0x29, 0x4a, 0x6d, 0x8a, 0xf7, 0x79, 0x90 } | |
| }; | |
| /** | |
| Tag GUID - UDPv6 in use by SocketDxe | |
| **/ | |
| CONST EFI_GUID mEslUdp6ServiceGuid = { | |
| 0x32ff59cd, 0xc33, 0x48d0, { 0xa2, 0x44, 0x4b, 0xb8, 0x11, 0x33, 0x64, 0x3 } | |
| }; | |
| /** | |
| Socket driver unload routine. | |
| @param [in] ImageHandle Handle for the image. | |
| @retval EFI_SUCCESS Image may be unloaded | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| DriverUnload ( | |
| IN EFI_HANDLE ImageHandle | |
| ) | |
| { | |
| UINTN BufferSize; | |
| UINTN Index; | |
| UINTN Max; | |
| EFI_HANDLE * pHandle; | |
| EFI_STATUS Status; | |
| // | |
| // Determine which devices are using this driver | |
| // | |
| BufferSize = 0; | |
| pHandle = NULL; | |
| Status = gBS->LocateHandle ( | |
| ByProtocol, | |
| &gEfiCallerIdGuid, | |
| NULL, | |
| &BufferSize, | |
| NULL ); | |
| if ( EFI_BUFFER_TOO_SMALL == Status ) { | |
| for ( ; ; ) { | |
| // | |
| // One or more block IO devices are present | |
| // | |
| Status = gBS->AllocatePool ( | |
| EfiRuntimeServicesData, | |
| BufferSize, | |
| (VOID **) &pHandle | |
| ); | |
| if ( EFI_ERROR ( Status )) { | |
| DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT | DEBUG_INFO, | |
| "Insufficient memory, failed handle buffer allocation\r\n" )); | |
| break; | |
| } | |
| // | |
| // Locate the block IO devices | |
| // | |
| Status = gBS->LocateHandle ( | |
| ByProtocol, | |
| &gEfiCallerIdGuid, | |
| NULL, | |
| &BufferSize, | |
| pHandle ); | |
| if ( EFI_ERROR ( Status )) { | |
| // | |
| // Error getting handles | |
| // | |
| DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_INFO, | |
| "Failure getting Telnet handles\r\n" )); | |
| break; | |
| } | |
| // | |
| // Remove any use of the driver | |
| // | |
| Max = BufferSize / sizeof ( pHandle[ 0 ]); | |
| for ( Index = 0; Max > Index; Index++ ) { | |
| Status = DriverStop ( &mDriverBinding, | |
| pHandle[ Index ], | |
| 0, | |
| NULL ); | |
| if ( EFI_ERROR ( Status )) { | |
| DEBUG (( DEBUG_WARN | DEBUG_INIT | DEBUG_INFO, | |
| "WARNING - Failed to shutdown the driver on handle %08x\r\n", pHandle[ Index ])); | |
| break; | |
| } | |
| } | |
| break; | |
| } | |
| } | |
| else { | |
| if ( EFI_NOT_FOUND == Status ) { | |
| // | |
| // No devices were found | |
| // | |
| Status = EFI_SUCCESS; | |
| } | |
| } | |
| // | |
| // Free the handle array | |
| // | |
| if ( NULL != pHandle ) { | |
| gBS->FreePool ( pHandle ); | |
| } | |
| // | |
| // Done with the socket layer | |
| // | |
| if ( !EFI_ERROR ( Status )) { | |
| Status = EslDxeUninstall ( ImageHandle ); | |
| if ( !EFI_ERROR ( Status )) { | |
| // | |
| // Remove the protocols installed by the EntryPoint routine. | |
| // | |
| Status = gBS->UninstallMultipleProtocolInterfaces ( | |
| ImageHandle, | |
| &gEfiDriverBindingProtocolGuid, | |
| &mDriverBinding, | |
| &gEfiComponentNameProtocolGuid, | |
| &mComponentName, | |
| &gEfiComponentName2ProtocolGuid, | |
| &mComponentName2, | |
| NULL | |
| ); | |
| if ( !EFI_ERROR ( Status )) { | |
| DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO, | |
| "Removed: gEfiComponentName2ProtocolGuid from 0x%08x\r\n", | |
| ImageHandle )); | |
| DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO, | |
| "Removed: gEfiComponentNameProtocolGuid from 0x%08x\r\n", | |
| ImageHandle )); | |
| DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO, | |
| "Removed: gEfiDriverBindingProtocolGuid from 0x%08x\r\n", | |
| ImageHandle )); | |
| } | |
| else { | |
| DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT, | |
| "ERROR - Failed to remove gEfiDriverBindingProtocolGuid from 0x%08x, Status: %r\r\n", | |
| ImageHandle, | |
| Status )); | |
| } | |
| } | |
| } | |
| // | |
| // Disconnect the network services | |
| // | |
| if ( !EFI_ERROR ( Status )) { | |
| EslServiceUnload ( ); | |
| } | |
| // | |
| // Return the unload status | |
| // | |
| return Status; | |
| } | |
| /** | |
| Socket driver entry point. | |
| @param [in] ImageHandle Handle for the image. | |
| @param [in] pSystemTable Address of the system table. | |
| @retval EFI_SUCCESS Image successfully loaded. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| EntryPoint ( | |
| IN EFI_HANDLE ImageHandle, | |
| IN EFI_SYSTEM_TABLE * pSystemTable | |
| ) | |
| { | |
| EFI_LOADED_IMAGE_PROTOCOL * pLoadedImage; | |
| EFI_STATUS Status; | |
| DBG_ENTER ( ); | |
| // | |
| // Display the image handle | |
| // | |
| DEBUG (( DEBUG_INFO, | |
| "ImageHandle: 0x%08x\r\n", | |
| ImageHandle )); | |
| // | |
| // Enable unload support | |
| // | |
| Status = gBS->HandleProtocol ( | |
| gImageHandle, | |
| &gEfiLoadedImageProtocolGuid, | |
| (VOID **)&pLoadedImage | |
| ); | |
| if (!EFI_ERROR (Status)) { | |
| pLoadedImage->Unload = DriverUnload; | |
| // | |
| // Add the driver to the list of drivers | |
| // | |
| Status = EfiLibInstallDriverBindingComponentName2 ( | |
| ImageHandle, | |
| pSystemTable, | |
| &mDriverBinding, | |
| ImageHandle, | |
| &mComponentName, | |
| &mComponentName2 | |
| ); | |
| if ( !EFI_ERROR ( Status )) { | |
| DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO, | |
| "Installed: gEfiDriverBindingProtocolGuid on 0x%08x\r\n", | |
| ImageHandle )); | |
| DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO, | |
| "Installed: gEfiComponentNameProtocolGuid on 0x%08x\r\n", | |
| ImageHandle )); | |
| DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO, | |
| "Installed: gEfiComponentName2ProtocolGuid on 0x%08x\r\n", | |
| ImageHandle )); | |
| // | |
| // Initialize the service layer | |
| // | |
| EslServiceLoad ( ImageHandle ); | |
| // | |
| // Make the socket serivces available to other drivers | |
| // and applications | |
| // | |
| Status = EslDxeInstall ( &ImageHandle ); | |
| if ( EFI_ERROR ( Status )) { | |
| // | |
| // Disconnect from the network | |
| // | |
| EslServiceUnload ( ); | |
| // | |
| // Remove the driver bindings | |
| // | |
| gBS->UninstallMultipleProtocolInterfaces ( | |
| ImageHandle, | |
| &gEfiDriverBindingProtocolGuid, | |
| &mDriverBinding, | |
| &gEfiComponentNameProtocolGuid, | |
| &mComponentName, | |
| &gEfiComponentName2ProtocolGuid, | |
| &mComponentName2, | |
| NULL | |
| ); | |
| DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO, | |
| "Removed: gEfiComponentName2ProtocolGuid from 0x%08x\r\n", | |
| ImageHandle )); | |
| DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO, | |
| "Removed: gEfiComponentNameProtocolGuid from 0x%08x\r\n", | |
| ImageHandle )); | |
| DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO, | |
| "Removed: gEfiDriverBindingProtocolGuid from 0x%08x\r\n", | |
| ImageHandle )); | |
| } | |
| } | |
| else { | |
| DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT, | |
| "ERROR - EfiLibInstallDriverBindingComponentName2 failed, Status: %r\r\n", | |
| Status )); | |
| } | |
| } | |
| DBG_EXIT_STATUS ( Status ); | |
| return Status; | |
| } | |
| /** | |
| Socket layer's service binding protocol delcaration. | |
| **/ | |
| CONST EFI_SERVICE_BINDING_PROTOCOL mEfiServiceBinding = { | |
| EslDxeCreateChild, | |
| EslDxeDestroyChild | |
| }; | |
| /** | |
| The following entries disable the constructor and destructor | |
| for the SocketDxe driver. Note that socket applications linking | |
| against EfiSocketLib use different redirection. | |
| **/ | |
| PFN_ESL_xSTRUCTOR mpfnEslConstructor = NULL; ///< No EfiSocketLib constructor needed for SocketDxe | |
| PFN_ESL_xSTRUCTOR mpfnEslDestructor = NULL; ///< No EfiSocketLib destructor needed for SocketDxe |