mirror_edk2/StdLib/UseSocketDxe/UseSocketDxe.c
Michael D Kinney 0a2530ea7f StdLib: Replace BSD License with BSD+Patent License
https://bugzilla.tianocore.org/show_bug.cgi?id=1373

Replace BSD 2-Clause License with BSD+Patent License.  This change is
based on the following emails:

  https://lists.01.org/pipermail/edk2-devel/2019-February/036260.html
  https://lists.01.org/pipermail/edk2-devel/2018-October/030385.html

RFCs with detailed process for the license change:

  V3: https://lists.01.org/pipermail/edk2-devel/2019-March/038116.html
  V2: https://lists.01.org/pipermail/edk2-devel/2019-March/037669.html
  V1: https://lists.01.org/pipermail/edk2-devel/2019-March/037500.html

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Jaben Carsey <jaben.carsey@intel.com>
2019-04-09 10:58:33 -07:00

222 lines
5.4 KiB
C

/** @file
Implement the connection to the socket driver
Copyright (c) 2011, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Uefi.h>
#include <Library/DebugLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Protocol/EfiSocket.h>
#include <Protocol/ServiceBinding.h>
/**
Free the socket resources
This releases the socket resources allocated by calling
EslServiceGetProtocol.
This routine is called from the ::close routine in BsdSocketLib
to release the socket resources.
@param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL
structure
@return Value for ::errno, zero (0) indicates success.
**/
int
EslServiceFreeProtocol (
IN EFI_SOCKET_PROTOCOL * pSocketProtocol
)
{
EFI_SERVICE_BINDING_PROTOCOL * pServiceBinding;
int RetVal;
EFI_STATUS Status;
//
// Assume success
//
RetVal = 0;
//
// Locate the socket protocol
//
Status = gBS->LocateProtocol ( &gEfiSocketServiceBindingProtocolGuid,
NULL,
(VOID **) &pServiceBinding );
if ( !EFI_ERROR ( Status )) {
//
// Release the handle
//
Status = pServiceBinding->DestroyChild ( pServiceBinding,
pSocketProtocol->SocketHandle );
}
if ( EFI_ERROR ( Status )) {
RetVal = EIO;
}
//
// Return the operation status
//
return RetVal;
}
/**
Connect to the EFI socket library
This routine establishes a connection to the socket driver
and returns the API (::EFI_SOCKET_PROTOCOL address) to the
socket file system layer in BsdSocketLib. This routine looks for
the gEfiSocketServiceBindingProtocolGuid to locate the socket
driver. This routine then creates a child handle and locates
the gEfiSocketProtocolGuid protocol on that handle to get the
::EFI_SOCKET_PROTOCOL structure address.
This routine is called from the ::socket routine in BsdSocketLib
to create the data structure and initialize the API for a socket.
Note that this implementation is only used by socket applications
that link directly to UseSocketDxe.
@param [in] ppSocketProtocol Address to receive the ::EFI_SOCKET_PROTOCOL
structure address
@return Value for ::errno, zero (0) indicates success.
**/
int
EslServiceGetProtocol (
IN EFI_SOCKET_PROTOCOL ** ppSocketProtocol
)
{
EFI_SERVICE_BINDING_PROTOCOL * pServiceBinding;
int RetVal;
EFI_HANDLE SocketHandle;
EFI_STATUS Status;
//
// Locate the socket protocol
//
Status = gBS->LocateProtocol ( &gEfiSocketServiceBindingProtocolGuid,
NULL,
(VOID **)&pServiceBinding );
if ( !EFI_ERROR ( Status )) {
//
// Create a new socket
//
SocketHandle = NULL;
Status = pServiceBinding->CreateChild ( pServiceBinding,
&SocketHandle );
if ( !EFI_ERROR ( Status )) {
//
// Get the socket protocol
//
Status = gBS->OpenProtocol ( SocketHandle,
&gEfiSocketProtocolGuid,
(VOID **)ppSocketProtocol,
NULL,
NULL,
EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL );
if ( !EFI_ERROR ( Status )) {
//
// Success!
//
RetVal = 0;
}
else {
DEBUG (( DEBUG_ERROR,
"ERROR - No socket protocol on 0x%08x, Status: %r\r\n",
SocketHandle,
Status ));
RetVal = ENODEV;
}
}
else {
//
// Translate the error
//
DEBUG (( DEBUG_ERROR,
"ERROR - CreateChild failed, Status: %r\r\n",
Status ));
switch ( Status ) {
case EFI_SUCCESS:
RetVal = 0;
break;
case EFI_ACCESS_DENIED:
case EFI_WRITE_PROTECTED:
RetVal = EACCES;
break;
case EFI_NO_RESPONSE:
RetVal = EHOSTUNREACH;
break;
case EFI_BAD_BUFFER_SIZE:
case EFI_BUFFER_TOO_SMALL:
case EFI_INVALID_PARAMETER:
RetVal = EINVAL;
break;
case EFI_DEVICE_ERROR:
case EFI_MEDIA_CHANGED:
case EFI_NO_MEDIA:
case EFI_VOLUME_CORRUPTED:
RetVal = EIO;
break;
case EFI_NOT_FOUND:
RetVal = ENOENT;
break;
default:
case EFI_OUT_OF_RESOURCES:
RetVal = ENOMEM;
break;
case EFI_VOLUME_FULL:
RetVal = ENOSPC;
break;
case EFI_UNSUPPORTED:
RetVal = ENOSYS;
break;
case EFI_NO_MAPPING:
RetVal = ENXIO;
break;
case EFI_LOAD_ERROR:
RetVal = ESRCH;
break;
case EFI_TIMEOUT:
RetVal = ETIMEDOUT;
break;
case EFI_NOT_READY:
RetVal = EWOULDBLOCK;
break;
}
}
}
else {
DEBUG (( DEBUG_ERROR,
"ERROR - Socket driver not loaded, Status: %r\r\n",
Status ));
RetVal = ENODEV;
}
//
// Return the operation status
//
return RetVal;
}