mirror of https://github.com/acidanthera/audk.git
352 lines
9.8 KiB
C
352 lines
9.8 KiB
C
/** @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
|