summaryrefslogtreecommitdiff
path: root/StdLib/EfiSocketLib/Service.c
diff options
context:
space:
mode:
authordarylm503 <darylm503@6f19259b-4bc3-4df7-8a09-765794883524>2011-07-30 00:30:44 +0000
committerdarylm503 <darylm503@6f19259b-4bc3-4df7-8a09-765794883524>2011-07-30 00:30:44 +0000
commitd7ce700605e1af0e455e31ec11f19ff21d26b525 (patch)
tree243b582ac3350e8c6ce6ca96fff13805318fd65c /StdLib/EfiSocketLib/Service.c
parentf766dd76fde231ecd4f2e9faf99293e90902cebb (diff)
downloadedk2-platforms-d7ce700605e1af0e455e31ec11f19ff21d26b525.tar.xz
Add Socket Libraries.
Add Posix functions for porting compatibility. Fix compliance issues with ISO/IEC 9899:199409 New Functions: setenv(), fparseln(), GetFileNameFromPath(), rename(), realpath(), setprogname(), getprogname(), strlcat(), strlcpy(), strsep(), setitimer(), getitimer(), timegm(), getopt(), basename(), mkstemp(), ffs(), vsnprintf(), snprintf(), getpass(), usleep(), select(), writev(), strcasecmp(), getcwd(), chdir(), tcgetpgrp(), getpgrp(), gettimeofday(), bcopy(), git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12061 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'StdLib/EfiSocketLib/Service.c')
-rw-r--r--StdLib/EfiSocketLib/Service.c529
1 files changed, 529 insertions, 0 deletions
diff --git a/StdLib/EfiSocketLib/Service.c b/StdLib/EfiSocketLib/Service.c
new file mode 100644
index 0000000000..49c8884612
--- /dev/null
+++ b/StdLib/EfiSocketLib/Service.c
@@ -0,0 +1,529 @@
+/** @file
+ Connect to and disconnect from the various network layers
+
+ 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"
+
+EFI_TCP4_PROTOCOL * mpEfiTcpClose4 [ 1024 ];
+
+
+/**
+ Connect to the network service bindings
+
+ Walk the network service protocols on the controller handle and
+ locate any that are not in use. Create service structures to
+ manage the service binding for the socket driver.
+
+ @param [in] BindingHandle Handle for protocol binding.
+ @param [in] Controller Handle of device to work with.
+
+ @retval EFI_SUCCESS This driver is added to Controller.
+ @retval other This driver does not support this device.
+
+**/
+EFI_STATUS
+EFIAPI
+EslServiceConnect (
+ IN EFI_HANDLE BindingHandle,
+ IN EFI_HANDLE Controller
+ )
+{
+ BOOLEAN bInUse;
+ UINTN LengthInBytes;
+ CONST DT_SOCKET_BINDING * pEnd;
+ VOID * pJunk;
+ VOID * pInterface;
+ DT_SERVICE * pService;
+ CONST DT_SOCKET_BINDING * pSocketBinding;
+ EFI_STATUS Status;
+ EFI_TPL TplPrevious;
+
+ DBG_ENTER ( );
+
+ //
+ // Assume the list is empty
+ //
+ Status = EFI_UNSUPPORTED;
+ bInUse = FALSE;
+
+ //
+ // Walk the list of network connection points
+ //
+ pSocketBinding = &cEslSocketBinding[0];
+ pEnd = &pSocketBinding[ cEslSocketBindingEntries ];
+ while ( pEnd > pSocketBinding ) {
+ //
+ // Determine if the controller supports the network protocol
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ pSocketBinding->pNetworkBinding,
+ &pInterface,
+ BindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if ( !EFI_ERROR ( Status )) {
+ //
+ // Determine if the socket layer is already connected
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ (EFI_GUID *)pSocketBinding->pTagGuid,
+ &pJunk,
+ BindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if ( EFI_UNSUPPORTED == Status ) {
+ //
+ // Allocate a service structure since the tag is not present
+ //
+ LengthInBytes = sizeof ( *pService );
+ Status = gBS->AllocatePool (
+ EfiRuntimeServicesData,
+ LengthInBytes,
+ (VOID **) &pService
+ );
+ if ( !EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_POOL | DEBUG_INIT,
+ "0x%08x: Allocate pService, %d bytes\r\n",
+ pService,
+ LengthInBytes ));
+
+ //
+ // Set the structure signature and service binding
+ //
+ ZeroMem ( pService, LengthInBytes );
+ pService->Signature = SERVICE_SIGNATURE;
+ pService->pSocketBinding = pSocketBinding;
+ pService->Controller = Controller;
+ pService->pInterface = pInterface;
+
+ //
+ // Mark the controller in use
+ //
+ if ( !bInUse ) {
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Controller,
+ &gEfiCallerIdGuid,
+ NULL,
+ NULL
+ );
+ if ( !EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
+ "Installed: gEfiCallerIdGuid on 0x%08x\r\n",
+ Controller ));
+ bInUse = TRUE;
+ }
+ else {
+ if ( EFI_INVALID_PARAMETER == Status ) {
+ Status = EFI_SUCCESS;
+ }
+ }
+ }
+ if ( !EFI_ERROR ( Status )) {
+ //
+ // Mark the network service protocol in use
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Controller,
+ pSocketBinding->pTagGuid,
+ pService,
+ NULL
+ );
+ if ( !EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
+ "Installed: %s TagGuid on 0x%08x\r\n",
+ pSocketBinding->pName,
+ Controller ));
+
+ //
+ // Synchronize with the socket layer
+ //
+ RAISE_TPL ( TplPrevious, TPL_SOCKETS );
+
+ //
+ // Initialize the service
+ //
+ Status = pSocketBinding->pfnInitialize ( pService );
+
+ //
+ // Release the socket layer synchronization
+ //
+ RESTORE_TPL ( TplPrevious );
+
+ //
+ // Determine if the initialization was successful
+ //
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,
+ "ERROR - Failed to initialize service %s on 0x%08x, Status: %r\r\n",
+ pSocketBinding->pName,
+ Controller,
+ Status ));
+
+ //
+ // Free the network service binding if necessary
+ //
+ gBS->UninstallMultipleProtocolInterfaces (
+ Controller,
+ pSocketBinding->pTagGuid,
+ pService,
+ NULL );
+ DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
+ "Removed: %s TagGuid from 0x%08x\r\n",
+ pSocketBinding->pName,
+ Controller ));
+ }
+ }
+ else {
+ DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,
+ "ERROR - Failed to install %s TagGuid on 0x%08x, Status: %r\r\n",
+ pSocketBinding->pName,
+ Controller,
+ Status ));
+ }
+
+ if ( EFI_ERROR ( Status )) {
+ //
+ // The controller is no longer in use
+ //
+ if ( bInUse ) {
+ gBS->UninstallMultipleProtocolInterfaces (
+ Controller,
+ &gEfiCallerIdGuid,
+ NULL,
+ NULL );
+ DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
+ "Removed: gEfiCallerIdGuid from 0x%08x\r\n",
+ Controller ));
+ }
+ }
+ }
+ else {
+ DEBUG (( DEBUG_ERROR | DEBUG_INIT,
+ "ERROR - Failed to install gEfiCallerIdGuid on 0x%08x, Status: %r\r\n",
+ Controller,
+ Status ));
+ }
+
+ //
+ // Release the service if necessary
+ //
+ if ( EFI_ERROR ( Status )) {
+ gBS->FreePool ( pService );
+ DEBUG (( DEBUG_POOL | DEBUG_INIT,
+ "0x%08x: Free pService, %d bytes\r\n",
+ pService,
+ sizeof ( *pService )));
+ pService = NULL;
+ }
+ }
+ else {
+ DEBUG (( DEBUG_ERROR | DEBUG_INIT,
+ "ERROR - Failed service allocation, Status: %r\r\n",
+ Status ));
+ }
+ }
+ }
+
+ //
+ // Set the next network protocol
+ //
+ pSocketBinding += 1;
+ }
+
+ //
+ // Display the driver start status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
+ Shutdown the network connections to this controller by removing
+ NetworkInterfaceIdentifier protocol and closing the DevicePath
+ and PciIo protocols on Controller.
+
+ @param [in] BindingHandle Handle for protocol binding.
+ @param [in] Controller Handle of device to stop driver on.
+
+ @retval EFI_SUCCESS This driver is removed Controller.
+ @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
+ @retval other This driver was not removed from this device.
+
+**/
+EFI_STATUS
+EFIAPI
+EslServiceDisconnect (
+ IN EFI_HANDLE BindingHandle,
+ IN EFI_HANDLE Controller
+ )
+{
+ CONST DT_SOCKET_BINDING * pEnd;
+ DT_SERVICE * pService;
+ CONST DT_SOCKET_BINDING * pSocketBinding;
+ EFI_STATUS Status;
+ EFI_TPL TplPrevious;
+
+ DBG_ENTER ( );
+
+ //
+ // Walk the list of network connection points in reverse order
+ //
+ pEnd = &cEslSocketBinding[0];
+ pSocketBinding = &pEnd[ cEslSocketBindingEntries ];
+ while ( pEnd < pSocketBinding ) {
+ //
+ // Set the next network protocol
+ //
+ pSocketBinding -= 1;
+
+ //
+ // Determine if the driver connected
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ (EFI_GUID *)pSocketBinding->pTagGuid,
+ (VOID **)&pService,
+ BindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if ( !EFI_ERROR ( Status )) {
+
+ //
+ // Synchronize with the socket layer
+ //
+ RAISE_TPL ( TplPrevious, TPL_SOCKETS );
+
+ //
+ // Shutdown the service
+ //
+ pSocketBinding->pfnShutdown ( pService );
+
+ //
+ // Release the socket layer synchronization
+ //
+ RESTORE_TPL ( TplPrevious );
+
+ //
+ // Break the driver connection
+ //
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ Controller,
+ pSocketBinding->pTagGuid,
+ pService,
+ NULL );
+ if ( !EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_POOL | DEBUG_INIT,
+ "Removed: %s TagGuid from 0x%08x\r\n",
+ pSocketBinding->pName,
+ Controller ));
+ }
+ else {
+ DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,
+ "ERROR - Failed to removed %s TagGuid from 0x%08x, Status: %r\r\n",
+ pSocketBinding->pName,
+ Controller,
+ Status ));
+ }
+
+ //
+ // Free the service structure
+ //
+ Status = gBS->FreePool ( pService );
+ if ( !EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_POOL | DEBUG_INIT,
+ "0x%08x: Free pService, %d bytes\r\n",
+ pService,
+ sizeof ( *pService )));
+ }
+ else {
+ DEBUG (( DEBUG_POOL | DEBUG_INIT,
+ "ERROR - Failed to free pService 0x%08x, Status: %r\r\n",
+ pService,
+ Status ));
+ }
+ pService = NULL;
+ }
+ }
+
+ //
+ // The controller is no longer in use
+ //
+ gBS->UninstallMultipleProtocolInterfaces (
+ Controller,
+ &gEfiCallerIdGuid,
+ NULL,
+ NULL );
+ DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
+ "Removed: gEfiCallerIdGuid from 0x%08x\r\n",
+ Controller ));
+
+ //
+ // The driver is disconnected from the network controller
+ //
+ Status = EFI_SUCCESS;
+
+ //
+ // Display the driver start status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+
+/**
+Install the socket service
+
+@param [in] pImageHandle Address of the image handle
+
+@retval EFI_SUCCESS Service installed successfully
+**/
+EFI_STATUS
+EFIAPI
+EslServiceInstall (
+ IN EFI_HANDLE * pImageHandle
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Install the socket service binding protocol
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ pImageHandle,
+ &gEfiSocketServiceBindingProtocolGuid,
+ &mEslLayer.ServiceBinding,
+ NULL
+ );
+ if ( !EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
+ "Installed: gEfiSocketServiceBindingProtocolGuid on 0x%08x\r\n",
+ *pImageHandle ));
+ }
+ else {
+ DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,
+ "ERROR - InstallMultipleProtocolInterfaces failed, Status: %r\r\n",
+ Status ));
+ }
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+Initialize the service layer
+
+@param [in] ImageHandle Handle for the image.
+
+**/
+VOID
+EFIAPI
+EslServiceLoad (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ DT_LAYER * pLayer;
+
+ //
+ // Save the image handle
+ //
+ pLayer = &mEslLayer;
+ pLayer->Signature = LAYER_SIGNATURE;
+ pLayer->ImageHandle = ImageHandle;
+
+ //
+ // Initialize the TCP4 close
+ //
+ pLayer->TcpCloseMax4 = DIM ( mpEfiTcpClose4 );
+ pLayer->ppTcpClose4 = mpEfiTcpClose4;
+
+ //
+ // Connect the service binding protocol to the image handle
+ //
+ pLayer->ServiceBinding.CreateChild = EslSocketCreateChild;
+ pLayer->ServiceBinding.DestroyChild = EslSocketDestroyChild;
+}
+
+
+/**
+Uninstall the socket service
+
+@param [in] ImageHandle Handle for the image.
+
+@retval EFI_SUCCESS Service installed successfully
+**/
+EFI_STATUS
+EFIAPI
+EslServiceUninstall (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Install the socket service binding protocol
+ //
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ ImageHandle,
+ &gEfiSocketServiceBindingProtocolGuid,
+ &mEslLayer.ServiceBinding,
+ NULL
+ );
+ if ( !EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_POOL | DEBUG_INIT,
+ "Removed: gEfiSocketServiceBindingProtocolGuid from 0x%08x\r\n",
+ ImageHandle ));
+ }
+ else {
+ DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,
+ "ERROR - Failed to remove gEfiSocketServiceBindingProtocolGuid from 0x%08x, Status: %r\r\n",
+ ImageHandle,
+ Status ));
+ }
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Shutdown the service layer
+
+**/
+VOID
+EFIAPI
+EslServiceUnload (
+ VOID
+ )
+{
+ DT_LAYER * pLayer;
+
+ //
+ // Undo the work by ServiceLoad
+ //
+ pLayer = &mEslLayer;
+ pLayer->ImageHandle = NULL;
+ pLayer->ServiceBinding.CreateChild = NULL;
+ pLayer->ServiceBinding.DestroyChild = NULL;
+}