summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlpleahy <lpleahy@6f19259b-4bc3-4df7-8a09-765794883524>2011-09-12 22:43:05 +0000
committerlpleahy <lpleahy@6f19259b-4bc3-4df7-8a09-765794883524>2011-09-12 22:43:05 +0000
commitf996231101d8a4b746136f8bf5fe36c87f0556f8 (patch)
tree9ffb4622d9912973f9e43126338c635f89b10cb5
parent243bd22d70f3bbdf67281c871db3f6f4bdf221bc (diff)
downloadedk2-f996231101d8a4b746136f8bf5fe36c87f0556f8.zip
edk2-f996231101d8a4b746136f8bf5fe36c87f0556f8.tar.gz
edk2-f996231101d8a4b746136f8bf5fe36c87f0556f8.tar.bz2
Move the rest of the PortClose state machine into Socket.c as common code.
Signed-off by: Lee Leahy git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/branches/EADK@12328 6f19259b-4bc3-4df7-8a09-765794883524
-rw-r--r--StdLib/EfiSocketLib/Ip4.c308
-rw-r--r--StdLib/EfiSocketLib/Service.c6
-rw-r--r--StdLib/EfiSocketLib/Socket.c427
-rw-r--r--StdLib/EfiSocketLib/Socket.h242
-rw-r--r--StdLib/EfiSocketLib/Tcp4.c366
-rw-r--r--StdLib/EfiSocketLib/Udp4.c307
-rw-r--r--StdLib/Include/Efi/EfiSocketLib.h1
7 files changed, 580 insertions, 1077 deletions
diff --git a/StdLib/EfiSocketLib/Ip4.c b/StdLib/EfiSocketLib/Ip4.c
index 5e3b014..88c8df2 100644
--- a/StdLib/EfiSocketLib/Ip4.c
+++ b/StdLib/EfiSocketLib/Ip4.c
@@ -10,26 +10,6 @@
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
- \section Ip4PortCloseStateMachine IPv4 Port Close State Machine
-
- The port close state machine walks the port through the necessary
- states to stop activity on the port and get it into a state where
- the resources may be released. The state machine consists of the
- following arcs and states:
- <ul>
- <li>Arc: ::EslIp4PortCloseStart - Marks the port as closing and
- initiates the port close operation</li>
- <li>State: PORT_STATE_CLOSE_STARTED</li>
- <li>Arc: ::EslSocketPortCloseTxDone - Waits until all of the transmit
- operations to complete.</li>
- <li>State: PORT_STATE_CLOSE_TX_DONE - RX still active</li>
- <li>Arc: ::EslSocketPortCloseRxDone - Waits until all of the receive
- operation have been cancelled.</li>
- <li>State: PORT_STATE_CLOSE_RX_DONE - RX shutdown</li>
- <li>State: PORT_STATE_CLOSE_DONE - Port never configured</li>
- <li>Arc: ::EslIp4PortClose - Releases the port resources</li>
- </ul>
-
\section Ip4ReceiveEngine IPv4 Receive Engine
@@ -128,7 +108,7 @@ EslIp4Bind (
{
EFI_HANDLE ChildHandle;
CONST struct sockaddr_in * pIp4Address;
- EFI_SERVICE_BINDING_PROTOCOL * pIp4Service;
+ EFI_SERVICE_BINDING_PROTOCOL * pServiceBinding;
ESL_LAYER * pLayer;
ESL_PORT * pPort;
ESL_SERVICE * pService;
@@ -165,10 +145,10 @@ EslIp4Bind (
//
// Create the IP port
//
- pIp4Service = pService->pInterface;
+ pServiceBinding = pService->pServiceBinding;
ChildHandle = NULL;
- Status = pIp4Service->CreateChild ( pIp4Service,
- &ChildHandle );
+ Status = pServiceBinding->CreateChild ( pServiceBinding,
+ &ChildHandle );
if ( !EFI_ERROR ( Status )) {
DEBUG (( DEBUG_BIND | DEBUG_POOL,
"0x%08x: Ip4 port handle created\r\n",
@@ -195,8 +175,8 @@ EslIp4Bind (
// Close the port if necessary
//
if (( EFI_ERROR ( Status )) && ( NULL != ChildHandle )) {
- TempStatus = pIp4Service->DestroyChild ( pIp4Service,
- ChildHandle );
+ TempStatus = pServiceBinding->DestroyChild ( pServiceBinding,
+ ChildHandle );
if ( !EFI_ERROR ( TempStatus )) {
DEBUG (( DEBUG_BIND | DEBUG_POOL,
"0x%08x: Ip4 port handle destroyed\r\n",
@@ -788,9 +768,10 @@ EslIp4PortAllocate (
UINT8 * pBuffer;
EFI_IP4_CONFIG_DATA * pConfig;
ESL_IO_MGMT * pIo;
+ ESL_IP4_CONTEXT * pIp4;
ESL_LAYER * pLayer;
ESL_PORT * pPort;
- ESL_IP4_CONTEXT * pIp4;
+ CONST ESL_SOCKET_BINDING * pSocketBinding;
EFI_STATUS Status;
DBG_ENTER ( );
@@ -829,10 +810,10 @@ EslIp4PortAllocate (
pPort->Signature = PORT_SIGNATURE;
pPort->pService = pService;
pPort->pSocket = pSocket;
- pPort->pfnCloseStart = EslIp4PortCloseStart;
pPort->DebugFlags = DebugFlags;
- pSocket->TxTokenOffset = OFFSET_OF ( EFI_IP4_COMPLETION_TOKEN, Packet.TxData );
pSocket->TxPacketOffset = OFFSET_OF ( ESL_PACKET, Op.Ip4Tx.TxData );
+ pSocket->TxTokenEventOffset = OFFSET_OF ( ESL_IO_MGMT, Token.Ip4Tx.Event );
+ pSocket->TxTokenOffset = OFFSET_OF ( EFI_IP4_COMPLETION_TOKEN, Packet.TxData );
pBuffer = (UINT8 *)&pPort[ 1 ];
pBuffer = &pBuffer[ ESL_STRUCTURE_ALIGNMENT_BYTES ];
pBuffer = (UINT8 *)( ESL_STRUCTURE_ALIGNMENT_MASK & (UINTN)pBuffer );
@@ -876,35 +857,35 @@ EslIp4PortAllocate (
//
// Open the port protocol
//
+ pSocketBinding = pService->pSocketBinding;
Status = gBS->OpenProtocol (
ChildHandle,
- &gEfiIp4ProtocolGuid,
- (VOID **) &pIp4->pProtocol,
+ pSocketBinding->pNetworkProtocolGuid,
+ &pPort->pProtocol.v,
pLayer->ImageHandle,
NULL,
EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL );
if ( EFI_ERROR ( Status )) {
DEBUG (( DEBUG_ERROR | DebugFlags,
"ERROR - Failed to open gEfiIp4ProtocolGuid on controller 0x%08x\r\n",
- pIp4->Handle ));
+ pPort->Handle ));
pSocket->errno = EEXIST;
break;
}
DEBUG (( DebugFlags,
"0x%08x: gEfiIp4ProtocolGuid opened on controller 0x%08x\r\n",
- pIp4->pProtocol,
+ pPort->pProtocol.v,
ChildHandle ));
//
// Save the transmit address
//
- pPort->pProtocol = (VOID *)pIp4->pProtocol;
- pPort->pfnTxStart = (PFN_NET_TX_START)pIp4->pProtocol->Transmit;
+ pPort->pfnTxStart = (PFN_NET_TX_START)pPort->pProtocol.IPv4->Transmit;
//
// Set the port address
//
- pIp4->Handle = ChildHandle;
+ pPort->Handle = ChildHandle;
pConfig = &pPort->Context.Ip4.ModeData.ConfigData;
pConfig->DefaultProtocol = (UINT8)pSocket->Protocol;
if (( 0 == pIpAddress[0])
@@ -979,7 +960,7 @@ EslIp4PortAllocate (
//
// Close the port
//
- EslIp4PortClose ( pPort );
+ EslSocketPortClose ( pPort );
}
//
// Return the operation status
@@ -995,12 +976,8 @@ EslIp4PortAllocate (
This routine releases the resources allocated by
::EslIp4PortAllocate.
- This routine is called by:
- <ul>
- <li>::EslIp4PortAllocate - Port initialization failure</li>
- <li>::EslSocketPortCloseRxDone - Last step of close processing</li>
- </ul>
- See the \ref Ip4PortCloseStateMachine section.
+ This routine is called by ::EslSocketPortClose.
+ See the \ref PortCloseStateMachine section.
@param [in] pPort Address of an ::ESL_PORT structure.
@@ -1014,104 +991,21 @@ EslIp4PortClose (
)
{
UINTN DebugFlags;
- ESL_LAYER * pLayer;
- ESL_PACKET * pPacket;
- ESL_PORT * pPreviousPort;
- ESL_SERVICE * pService;
- ESL_SOCKET * pSocket;
- EFI_SERVICE_BINDING_PROTOCOL * pIp4Service;
ESL_IP4_CONTEXT * pIp4;
EFI_STATUS Status;
DBG_ENTER ( );
//
- // Verify the socket layer synchronization
- //
- VERIFY_TPL ( TPL_SOCKETS );
-
- //
// Assume success
//
Status = EFI_SUCCESS;
- pSocket = pPort->pSocket;
- pSocket->errno = 0;
-
- //
- // Locate the port in the socket list
- //
- pLayer = &mEslLayer;
DebugFlags = pPort->DebugFlags;
- pPreviousPort = pSocket->pPortList;
- if ( pPreviousPort == pPort ) {
- //
- // Remove this port from the head of the socket list
- //
- pSocket->pPortList = pPort->pLinkSocket;
- }
- else {
- //
- // Locate the port in the middle of the socket list
- //
- while (( NULL != pPreviousPort )
- && ( pPreviousPort->pLinkSocket != pPort )) {
- pPreviousPort = pPreviousPort->pLinkSocket;
- }
- if ( NULL != pPreviousPort ) {
- //
- // Remove the port from the middle of the socket list
- //
- pPreviousPort->pLinkSocket = pPort->pLinkSocket;
- }
- }
-
- //
- // Locate the port in the service list
- //
- pService = pPort->pService;
- pPreviousPort = pService->pPortList;
- if ( pPreviousPort == pPort ) {
- //
- // Remove this port from the head of the service list
- //
- pService->pPortList = pPort->pLinkService;
- }
- else {
- //
- // Locate the port in the middle of the service list
- //
- while (( NULL != pPreviousPort )
- && ( pPreviousPort->pLinkService != pPort )) {
- pPreviousPort = pPreviousPort->pLinkService;
- }
- if ( NULL != pPreviousPort ) {
- //
- // Remove the port from the middle of the service list
- //
- pPreviousPort->pLinkService = pPort->pLinkService;
- }
- }
-
- //
- // Empty the receive queue
- //
- ASSERT ( NULL == pSocket->pRxPacketListHead );
- ASSERT ( NULL == pSocket->pRxPacketListTail );
- ASSERT ( 0 == pSocket->RxBytes );
-
- //
- // Empty the receive free queue
- //
- while ( NULL != pSocket->pRxFree ) {
- pPacket = pSocket->pRxFree;
- pSocket->pRxFree = pPacket->pNext;
- EslSocketPacketFree ( pPacket, DEBUG_RX );
- }
+ pIp4 = &pPort->Context.Ip4;
//
// Done with the receive event
//
- pIp4 = &pPort->Context.Ip4;
if ( NULL != pIp4->RxToken.Event ) {
Status = gBS->CloseEvent ( pIp4->RxToken.Event );
if ( !EFI_ERROR ( Status )) {
@@ -1128,86 +1022,6 @@ EslIp4PortClose (
}
//
- // Done with the transmit events
- //
- Status = EslSocketIoFree ( pPort,
- &pPort->pTxFree,
- DebugFlags | DEBUG_POOL,
- "transmit",
- OFFSET_OF ( ESL_IO_MGMT, Token.Ip4Tx.Event ));
-
- //
- // Done with the IP protocol
- //
- pIp4Service = pService->pInterface;
- if ( NULL != pIp4->pProtocol ) {
- Status = gBS->CloseProtocol ( pIp4->Handle,
- &gEfiIp4ProtocolGuid,
- pLayer->ImageHandle,
- NULL );
- if ( !EFI_ERROR ( Status )) {
- DEBUG (( DebugFlags,
- "0x%08x: gEfiIp4ProtocolGuid closed on controller 0x%08x\r\n",
- pIp4->pProtocol,
- pIp4->Handle ));
- }
- else {
- DEBUG (( DEBUG_ERROR | DebugFlags,
- "ERROR - Failed to close gEfiIp4ProtocolGuid opened on controller 0x%08x, Status: %r\r\n",
- pIp4->Handle,
- Status ));
- ASSERT ( EFI_SUCCESS == Status );
- }
- }
-
- //
- // Done with the IP port
- //
- if ( NULL != pIp4->Handle ) {
- Status = pIp4Service->DestroyChild ( pIp4Service,
- pIp4->Handle );
- if ( !EFI_ERROR ( Status )) {
- DEBUG (( DebugFlags | DEBUG_POOL,
- "0x%08x: Ip4 port handle destroyed\r\n",
- pIp4->Handle ));
- }
- else {
- DEBUG (( DEBUG_ERROR | DebugFlags | DEBUG_POOL,
- "ERROR - Failed to destroy the Ip4 port handle, Status: %r\r\n",
- Status ));
- ASSERT ( EFI_SUCCESS == Status );
- }
- }
-
- //
- // Release the port structure
- //
- Status = gBS->FreePool ( pPort );
- if ( !EFI_ERROR ( Status )) {
- DEBUG (( DebugFlags | DEBUG_POOL,
- "0x%08x: Free pPort, %d bytes\r\n",
- pPort,
- sizeof ( *pPort )));
- }
- else {
- DEBUG (( DEBUG_ERROR | DebugFlags | DEBUG_POOL,
- "ERROR - Failed to free pPort: 0x%08x, Status: %r\r\n",
- pPort,
- Status ));
- ASSERT ( EFI_SUCCESS == Status );
- }
-
- //
- // Mark the socket as closed if necessary
- //
- if ( NULL == pSocket->pPortList ) {
- pSocket->State = SOCKET_STATE_CLOSED;
- DEBUG (( DEBUG_CLOSE | DEBUG_INFO,
- "0x%08x: Socket State: SOCKET_STATE_CLOSED\r\n",
- pSocket ));
- }
-
- //
// Return the operation status
//
DBG_EXIT_STATUS ( Status );
@@ -1221,7 +1035,7 @@ EslIp4PortClose (
This routine performs the network specific operations necessary
to free a receive packet.
- This routine is called by ::EslSocketPortCloseTx to free a
+ This routine is called by ::EslSocketPortCloseTxDone to free a
receive packet.
@param [in] pPacket Address of an ::ESL_PACKET structure.
@@ -1247,76 +1061,6 @@ EslIp4PortClosePacketFree (
/**
- Start the close operation on a IP4 port, state 1.
-
- This routine marks the port as closed and initiates the port
- close state machine. The first step is to allow the \ref
- TransmitEngine to run down.
-
- This routine is called by ::EslSocketCloseStart to initiate the socket
- network specific close operation on the socket.
- See the \ref Ip4PortCloseStateMachine section.
-
- @param [in] pPort Address of an ::ESL_PORT structure.
- @param [in] bCloseNow Set TRUE to abort active transfers
- @param [in] DebugFlags Flags for debug messages
-
- @retval EFI_SUCCESS The port is closed, not normally returned
- @retval EFI_NOT_READY The port has started the closing process
- @retval EFI_ALREADY_STARTED Error, the port is in the wrong state,
- most likely the routine was called already.
-
-**/
-EFI_STATUS
-EslIp4PortCloseStart (
- IN ESL_PORT * pPort,
- IN BOOLEAN bCloseNow,
- IN UINTN DebugFlags
- )
-{
- ESL_SOCKET * pSocket;
- EFI_STATUS Status;
-
- DBG_ENTER ( );
-
- //
- // Verify the socket layer synchronization
- //
- VERIFY_TPL ( TPL_SOCKETS );
-
- //
- // Mark the port as closing
- //
- Status = EFI_ALREADY_STARTED;
- pSocket = pPort->pSocket;
- pSocket->errno = EALREADY;
- if ( PORT_STATE_CLOSE_STARTED > pPort->State ) {
-
- //
- // Update the port state
- //
- pPort->State = PORT_STATE_CLOSE_STARTED;
- DEBUG (( DEBUG_CLOSE | DEBUG_INFO,
- "0x%08x: Port Close State: PORT_STATE_CLOSE_STARTED\r\n",
- pPort ));
- pPort->bCloseNow = bCloseNow;
- pPort->DebugFlags = DebugFlags;
-
- //
- // Determine if transmits are complete
- //
- Status = EslSocketPortCloseTxDone ( pPort );
- }
-
- //
- // Return the operation status
- //
- DBG_EXIT_STATUS ( Status );
- return Status;
-}
-
-
-/**
Perform the network specific close operation on the port.
This routine performs a cancel operations on the IPv4 port to
@@ -1348,7 +1092,7 @@ EslIp4PortCloseRxStop (
// Reset the port, cancel the outstanding receive
//
pIp4 = &pPort->Context.Ip4;
- pIp4Protocol = pIp4->pProtocol;
+ pIp4Protocol = pPort->pProtocol.IPv4;
Status = pIp4Protocol->Configure ( pIp4Protocol,
NULL );
if ( !EFI_ERROR ( Status )) {
@@ -1718,7 +1462,7 @@ EslIp4RxCancel (
//
// Attempt to cancel the receive operation
//
- pIp4Protocol = pIp4->pProtocol;
+ pIp4Protocol = pPort->pProtocol.IPv4;
Status = pIp4Protocol->Cancel ( pIp4Protocol,
&pIp4->RxToken );
if ( EFI_NOT_FOUND == Status ) {
@@ -1971,7 +1715,7 @@ EslIp4RxStart (
//
// Start the receive on the packet
//
- pIp4Protocol = pIp4->pProtocol;
+ pIp4Protocol = pPort->pProtocol.IPv4;
Status = pIp4Protocol->Receive ( pIp4Protocol,
&pIp4->RxToken );
if ( !EFI_ERROR ( Status )) {
@@ -2159,7 +1903,7 @@ EslIp4Shutdown (
// Attempt to configure the port
//
pNextPort = pPort->pLinkSocket;
- pIp4Protocol = pIp4->pProtocol;
+ pIp4Protocol = pPort->pProtocol.IPv4;
DEBUG (( DEBUG_TX,
"0x%08x: pPort Configuring for %d.%d.%d.%d --> %d.%d.%d.%d\r\n",
pPort,
diff --git a/StdLib/EfiSocketLib/Service.c b/StdLib/EfiSocketLib/Service.c
index 90ebdf2..21cdce4 100644
--- a/StdLib/EfiSocketLib/Service.c
+++ b/StdLib/EfiSocketLib/Service.c
@@ -43,9 +43,9 @@ EslServiceConnect (
UINTN LengthInBytes;
CONST ESL_SOCKET_BINDING * pEnd;
VOID * pJunk;
- VOID * pInterface;
ESL_SERVICE * pService;
CONST ESL_SOCKET_BINDING * pSocketBinding;
+ EFI_SERVICE_BINDING_PROTOCOL * pServiceBinding;
EFI_STATUS Status;
EFI_TPL TplPrevious;
@@ -69,7 +69,7 @@ EslServiceConnect (
Status = gBS->OpenProtocol (
Controller,
pSocketBinding->pNetworkBinding,
- &pInterface,
+ (VOID**)&pServiceBinding,
BindingHandle,
Controller,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
@@ -109,7 +109,7 @@ EslServiceConnect (
pService->Signature = SERVICE_SIGNATURE;
pService->pSocketBinding = pSocketBinding;
pService->Controller = Controller;
- pService->pInterface = pInterface;
+ pService->pServiceBinding = pServiceBinding;
//
// Mark the controller in use
diff --git a/StdLib/EfiSocketLib/Socket.c b/StdLib/EfiSocketLib/Socket.c
index 66eb336..012fb6c 100644
--- a/StdLib/EfiSocketLib/Socket.c
+++ b/StdLib/EfiSocketLib/Socket.c
@@ -15,6 +15,45 @@
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+ \section PortCloseStateMachine Port Close State Machine
+
+ The port close state machine walks the port through the necessary
+ states to stop activity on the port and get it into a state where
+ the resources may be released. The state machine consists of the
+ following arcs and states:
+ <ul>
+ <li>Arc: ::EslSocketPortCloseStart - Marks the port as closing and
+ initiates the port close operation</li>
+ <li>State: PORT_STATE_CLOSE_STARTED</li>
+ <li>Arc: ::EslSocketPortCloseTxDone - Waits until all of the transmit
+ operations to complete. After all of the transmits are complete,
+ this routine discards any receive buffers using a network specific
+ support routine via ESL_PROTOCOL_API::pfnPortClosePktFree. This
+ routine also calls a network specific helper routine via
+ ESL_PROTOCOL_API::pfnPortCloseRxStop to abort the pending receive
+ operation.
+ </li>
+ <li>State: PORT_STATE_CLOSE_TX_DONE</li>
+ <li>Arc: ::EslSocketPortCloseRxDone - Waits until all of the receive
+ operation have been cancelled.</li>
+ <li>State: PORT_STATE_CLOSE_RX_DONE</li>
+ <li>Arc: ::EslSocketPortCloseComplete - Called by the TCP layer
+ when the port is closed.
+ <li>State: PORT_STATE_CLOSE_DONE</li>
+ <li>Arc: ::EslSocketPortClose - Releases the port resources. Calls
+ a routine via ESL_PROTOCOL_API::pfnPortClose to close the network
+ specific resources:
+ <ul>
+ <li>::EslIp4PortClose</li>
+ <li>::EslTcp4PortClose</li>
+ <li>::EslUp4PortClose</li>
+ </ul>
+ </li>
+ </ul>
+ Note that the state machine takes into account that close and receive
+ completions may happen in either order.
+
+
\section TransmitEngine Transmit Engine
The transmit engine uses the ESL_IO_MGMT structures to manage
multiple transmit buffers. The network specific PortAllocate
@@ -56,6 +95,7 @@
CONST ESL_SOCKET_BINDING cEslSocketBinding[] = {
{ L"Ip4",
&gEfiIp4ServiceBindingProtocolGuid,
+ &gEfiIp4ProtocolGuid,
&mEslIp4ServiceGuid,
EslIp4Initialize,
EslIp4Shutdown,
@@ -63,6 +103,7 @@ CONST ESL_SOCKET_BINDING cEslSocketBinding[] = {
0 },
{ L"Tcp4",
&gEfiTcp4ServiceBindingProtocolGuid,
+ &gEfiTcp4ProtocolGuid,
&mEslTcp4ServiceGuid,
EslTcp4Initialize,
EslTcp4Shutdown,
@@ -70,6 +111,7 @@ CONST ESL_SOCKET_BINDING cEslSocketBinding[] = {
4 },
{ L"Udp4",
&gEfiUdp4ServiceBindingProtocolGuid,
+ &gEfiUdp4ProtocolGuid,
&mEslUdp4ServiceGuid,
EslUdp4Initialize,
EslUdp4Shutdown,
@@ -965,9 +1007,9 @@ EslSocketCloseStart (
// Start closing the ports
//
pNextPort = pPort->pLinkSocket;
- Status = pPort->pfnCloseStart ( pPort,
- bCloseNow,
- DEBUG_CLOSE | DEBUG_LISTEN | DEBUG_CONNECTION );
+ Status = EslSocketPortCloseStart ( pPort,
+ bCloseNow,
+ DEBUG_CLOSE | DEBUG_LISTEN | DEBUG_CONNECTION );
if (( EFI_SUCCESS != Status )
&& ( EFI_NOT_READY != Status )) {
errno = EIO;
@@ -1438,7 +1480,6 @@ EslSocketGetPeerAddress (
@param [in] ppFreeQueue Address of the free queue head
@param [in] DebugFlags Flags for debug messages
@param [in] pEventName Zero terminated string containing the event name
- @param [in] EventOffset Offset of the event in the ::ESL_IO_MGMT structure
@retval EFI_SUCCESS - The structures were properly initialized
@@ -1448,8 +1489,7 @@ EslSocketIoFree (
IN ESL_PORT * pPort,
IN ESL_IO_MGMT ** ppFreeQueue,
IN UINTN DebugFlags,
- IN CHAR8 * pEventName,
- IN UINT32 EventOffset
+ IN CHAR8 * pEventName
)
{
UINT8 * pBuffer;
@@ -1475,7 +1515,7 @@ EslSocketIoFree (
//
pIo = *ppFreeQueue;
pBuffer = (UINT8 *)pIo;
- pBuffer = &pBuffer[ EventOffset ];
+ pBuffer = &pBuffer[ pSocket->TxTokenEventOffset ];
pEvent = (EFI_EVENT *)pBuffer;
Status = gBS->CloseEvent ( *pEvent );
if ( EFI_ERROR ( Status )) {
@@ -2497,6 +2537,282 @@ EslSocketPoll (
/**
+ Close a port.
+
+ This routine releases the resources allocated by the network specific
+ PortAllocate routine.
+
+ This routine is called by:
+ <ul>
+ <li>::EslIp4PortAllocate - Port initialization failure</li>
+ <li>::EslSocketPortCloseRxDone - Last step of close processing</li>
+ <li>::EslTcp4ConnectComplete - Connection failure and reducint the port list to a single port</li>
+ <li>::EslTcp4PortAllocate - Port initialization failure</li>
+ <li>::EslUdp4PortAllocate - Port initialization failure</li>
+ </ul>
+ See the \ref PortCloseStateMachine section.
+
+ @param [in] pPort Address of an ::ESL_PORT structure.
+
+ @retval EFI_SUCCESS The port is closed
+ @retval other Port close error
+
+**/
+EFI_STATUS
+EslSocketPortClose (
+ IN ESL_PORT * pPort
+ )
+{
+ UINTN DebugFlags;
+ ESL_LAYER * pLayer;
+ ESL_PACKET * pPacket;
+ ESL_PORT * pPreviousPort;
+ ESL_SERVICE * pService;
+ EFI_SERVICE_BINDING_PROTOCOL * pServiceBinding;
+ CONST ESL_SOCKET_BINDING * pSocketBinding;
+ ESL_SOCKET * pSocket;
+ ESL_TCP4_CONTEXT * pTcp4;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Verify the socket layer synchronization
+ //
+ VERIFY_TPL ( TPL_SOCKETS );
+
+ //
+ // Locate the port in the socket list
+ //
+ Status = EFI_SUCCESS;
+ pLayer = &mEslLayer;
+ DebugFlags = pPort->DebugFlags;
+ pSocket = pPort->pSocket;
+ pPreviousPort = pSocket->pPortList;
+ if ( pPreviousPort == pPort ) {
+ //
+ // Remove this port from the head of the socket list
+ //
+ pSocket->pPortList = pPort->pLinkSocket;
+ }
+ else {
+ //
+ // Locate the port in the middle of the socket list
+ //
+ while (( NULL != pPreviousPort )
+ && ( pPreviousPort->pLinkSocket != pPort )) {
+ pPreviousPort = pPreviousPort->pLinkSocket;
+ }
+ if ( NULL != pPreviousPort ) {
+ //
+ // Remove the port from the middle of the socket list
+ //
+ pPreviousPort->pLinkSocket = pPort->pLinkSocket;
+ }
+ }
+
+ //
+ // Locate the port in the service list
+ //
+ pService = pPort->pService;
+ pPreviousPort = pService->pPortList;
+ if ( pPreviousPort == pPort ) {
+ //
+ // Remove this port from the head of the service list
+ //
+ pService->pPortList = pPort->pLinkService;
+ }
+ else {
+ //
+ // Locate the port in the middle of the service list
+ //
+ while (( NULL != pPreviousPort )
+ && ( pPreviousPort->pLinkService != pPort )) {
+ pPreviousPort = pPreviousPort->pLinkService;
+ }
+ if ( NULL != pPreviousPort ) {
+ //
+ // Remove the port from the middle of the service list
+ //
+ pPreviousPort->pLinkService = pPort->pLinkService;
+ }
+ }
+
+ //
+ // Empty the urgent receive queue
+ //
+ pTcp4 = &pPort->Context.Tcp4;
+ while ( NULL != pSocket->pRxOobPacketListHead ) {
+ pPacket = pSocket->pRxOobPacketListHead;
+ pSocket->pRxOobPacketListHead = pPacket->pNext;
+ pSocket->RxOobBytes -= pPacket->Op.Tcp4Rx.ValidBytes;
+ EslSocketPacketFree ( pPacket, DEBUG_RX );
+ }
+ pSocket->pRxOobPacketListTail = NULL;
+ ASSERT ( 0 == pSocket->RxOobBytes );
+
+ //
+ // Empty the receive queue
+ //
+ while ( NULL != pSocket->pRxPacketListHead ) {
+ pPacket = pSocket->pRxPacketListHead;
+ pSocket->pRxPacketListHead = pPacket->pNext;
+ pSocket->RxBytes -= pPacket->Op.Tcp4Rx.ValidBytes;
+ EslSocketPacketFree ( pPacket, DEBUG_RX );
+ }
+ pSocket->pRxPacketListTail = NULL;
+ ASSERT ( 0 == pSocket->RxBytes );
+
+ //
+ // Empty the receive free queue
+ //
+ while ( NULL != pSocket->pRxFree ) {
+ pPacket = pSocket->pRxFree;
+ pSocket->pRxFree = pPacket->pNext;
+ EslSocketPacketFree ( pPacket, DEBUG_RX );
+ }
+
+ //
+ // Release the network specific resources
+ //
+ Status = pSocket->pApi->pfnPortClose ( pPort );
+
+ //
+ // Done with the normal transmit events
+ //
+ Status = EslSocketIoFree ( pPort,
+ &pPort->pTxFree,
+ DebugFlags | DEBUG_POOL,
+ "normal transmit" );
+
+ //
+ // Done with the urgent transmit events
+ //
+ Status = EslSocketIoFree ( pPort,
+ &pPort->pTxOobFree,
+ DebugFlags | DEBUG_POOL,
+ "urgent transmit" );
+
+ //
+ // Done with the lower layer network protocol
+ //
+ pSocketBinding = pService->pSocketBinding;
+ if ( NULL != pPort->pProtocol.v ) {
+ Status = gBS->CloseProtocol ( pPort->Handle,
+ pSocketBinding->pNetworkProtocolGuid,
+ pLayer->ImageHandle,
+ NULL );
+ if ( !EFI_ERROR ( Status )) {
+ DEBUG (( DebugFlags,
+ "0x%08x: Network protocol GUID closed on controller 0x%08x\r\n",
+ pPort->pProtocol.v,
+ pPort->Handle ));
+ }
+ else {
+ DEBUG (( DEBUG_ERROR | DebugFlags,
+ "ERROR - Failed to close network protocol GUID on controller 0x%08x, Status: %r\r\n",
+ pPort->Handle,
+ Status ));
+ ASSERT ( EFI_SUCCESS == Status );
+ }
+ }
+
+ //
+ // Done with the network port
+ //
+ pServiceBinding = pService->pServiceBinding;
+ if ( NULL != pPort->Handle ) {
+ Status = pServiceBinding->DestroyChild ( pServiceBinding,
+ pPort->Handle );
+ if ( !EFI_ERROR ( Status )) {
+ DEBUG (( DebugFlags | DEBUG_POOL,
+ "0x%08x: %s port handle destroyed\r\n",
+ pPort->Handle,
+ pSocketBinding->pName ));
+ }
+ else {
+ DEBUG (( DEBUG_ERROR | DebugFlags | DEBUG_POOL,
+ "ERROR - Failed to destroy the %s port handle, Status: %r\r\n",
+ pSocketBinding->pName,
+ Status ));
+ ASSERT ( EFI_SUCCESS == Status );
+ }
+ }
+
+ //
+ // Release the port structure
+ //
+ Status = gBS->FreePool ( pPort );
+ if ( !EFI_ERROR ( Status )) {
+ DEBUG (( DebugFlags | DEBUG_POOL,
+ "0x%08x: Free pPort, %d bytes\r\n",
+ pPort,
+ sizeof ( *pPort )));
+ }
+ else {
+ DEBUG (( DEBUG_ERROR | DebugFlags | DEBUG_POOL,
+ "ERROR - Failed to free pPort: 0x%08x, Status: %r\r\n",
+ pPort,
+ Status ));
+ ASSERT ( EFI_SUCCESS == Status );
+ }
+
+ //
+ // Mark the socket as closed if necessary
+ //
+ if ( NULL == pSocket->pPortList ) {
+ pSocket->State = SOCKET_STATE_CLOSED;
+ DEBUG (( DEBUG_CLOSE | DEBUG_INFO,
+ "0x%08x: Socket State: SOCKET_STATE_CLOSED\r\n",
+ pSocket ));
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
+ Process the port close completion event
+
+ This routine attempts to complete the port close operation.
+
+ This routine is called by the TCP layer upon completion of
+ the close operation.
+ See the \ref PortCloseStateMachine section.
+
+ @param [in] Event The close completion event
+
+ @param [in] pPort Address of an ::ESL_PORT structure.
+
+**/
+VOID
+EslSocketPortCloseComplete (
+ IN EFI_EVENT Event,
+ IN ESL_PORT * pPort
+ )
+{
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Update the port state
+ //
+ pPort->State = PORT_STATE_CLOSE_DONE;
+
+ //
+ // Release the resources once the receive operation completes
+ //
+ Status = EslSocketPortCloseRxDone ( pPort );
+ DBG_EXIT_STATUS ( Status );
+}
+
+
+/**
Port close state 3
This routine determines the state of the receive operations and
@@ -2506,14 +2822,13 @@ EslSocketPoll (
This routine is called by
<ul>
<li>::EslIp4RxComplete</li>
- <li>::EslIp4PortCloseTxDone</li>
- <li>::EslTcp4PortCloseComplete</li>
- <li>::EslTcp4PortCloseTxDone</li>
+ <li>::EslSocketPortCloseComplete</li>
+ <li>::EslSocketPortCloseTxDone</li>
+ <li>::EslTcp4RxComplete/li>
<li>::EslUdp4RxComplete</li>
- <li>::EslUdp4PortCloseTxDone</li>
</ul>
to determine the state of the receive operations.
- See the \ref Tcp4PortCloseStateMachine section.
+ See the \ref PortCloseStateMachine section.
@param [in] pPort Address of an ::ESL_PORT structure.
@@ -2570,7 +2885,7 @@ EslSocketPortCloseRxDone (
// The close operation has completed
// Release the port resources
//
- Status = pSocket->pApi->pfnPortClose ( pPort );
+ Status = EslSocketPortClose ( pPort );
}
else {
//
@@ -2597,22 +2912,86 @@ EslSocketPortCloseRxDone (
/**
+ Start the close operation on a port, state 1.
+
+ This routine marks the port as closed and initiates the \ref
+ PortCloseStateMachine. The first step is to allow the \ref
+ TransmitEngine to run down.
+
+ This routine is called by ::EslSocketCloseStart to initiate the socket
+ network specific close operation on the socket.
+
+ @param [in] pPort Address of an ::ESL_PORT structure.
+ @param [in] bCloseNow Set TRUE to abort active transfers
+ @param [in] DebugFlags Flags for debug messages
+
+ @retval EFI_SUCCESS The port is closed, not normally returned
+ @retval EFI_NOT_READY The port has started the closing process
+ @retval EFI_ALREADY_STARTED Error, the port is in the wrong state,
+ most likely the routine was called already.
+
+**/
+EFI_STATUS
+EslSocketPortCloseStart (
+ IN ESL_PORT * pPort,
+ IN BOOLEAN bCloseNow,
+ IN UINTN DebugFlags
+ )
+{
+ ESL_SOCKET * pSocket;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Verify the socket layer synchronization
+ //
+ VERIFY_TPL ( TPL_SOCKETS );
+
+ //
+ // Mark the port as closing
+ //
+ Status = EFI_ALREADY_STARTED;
+ pSocket = pPort->pSocket;
+ pSocket->errno = EALREADY;
+ if ( PORT_STATE_CLOSE_STARTED > pPort->State ) {
+
+ //
+ // Update the port state
+ //
+ pPort->State = PORT_STATE_CLOSE_STARTED;
+ DEBUG (( DEBUG_CLOSE | DEBUG_INFO,
+ "0x%08x: Port Close State: PORT_STATE_CLOSE_STARTED\r\n",
+ pPort ));
+ pPort->bCloseNow = bCloseNow;
+ pPort->DebugFlags = DebugFlags;
+
+ //
+ // Determine if transmits are complete
+ //
+ Status = EslSocketPortCloseTxDone ( pPort );
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
Port close state 2
This routine determines the state of the transmit engine and
- continues the close operation after the transmission is complete.
+ continue the close operation after the transmission is complete.
The next step is to stop the \ref Tcp4ReceiveEngine.
+ See the \ref PortCloseStateMachine section.
- This routine is called by
- <ul>
- <li>::EslIp4PortCloseStart</li>
- <li>::EslTcp4PortCloseStart</li>
- <li>::EslUdp4PortCloseStart</li>
- </ul>
- to determine if the transmission is complete.
- See the \ref Tcp4PortCloseStateMachine section.
+ This routine is called by ::EslSocketPortCloseStart to determine
+ if the transmission is complete.
- @param [in] pPort Address of an ::ESL_PORT structure.
+ @param [in] pPort Address of an ::ESL_PORT structure.
@retval EFI_SUCCESS The port is closed, not normally returned
@retval EFI_NOT_READY The port is still closing
@@ -3433,7 +3812,7 @@ EslSocketTxStart (
//
// Start the transmit operation
//
- Status = pPort->pfnTxStart ( pPort->pProtocol,
+ Status = pPort->pfnTxStart ( pPort->pProtocol.v,
&pIo->Token );
if ( EFI_ERROR ( Status )) {
if ( EFI_SUCCESS == pSocket->TxError ) {
diff --git a/StdLib/EfiSocketLib/Socket.h b/StdLib/EfiSocketLib/Socket.h
index cb4ea4a..fd7066a 100644
--- a/StdLib/EfiSocketLib/Socket.h
+++ b/StdLib/EfiSocketLib/Socket.h
@@ -190,9 +190,9 @@ typedef struct _ESL_SERVICE {
//
// Service data
//
- CONST ESL_SOCKET_BINDING * pSocketBinding; ///< Name and shutdown routine
- EFI_HANDLE Controller; ///< Controller for the service
- VOID * pInterface; ///< Network layer service binding interface
+ CONST ESL_SOCKET_BINDING * pSocketBinding; ///< Name and shutdown routine
+ EFI_HANDLE Controller; ///< Controller for the service
+ EFI_SERVICE_BINDING_PROTOCOL * pServiceBinding; ///< Network layer service binding interface
//
// Network data
@@ -201,22 +201,6 @@ typedef struct _ESL_SERVICE {
}GCC_ESL_SERVICE;
/**
- Start the close operation on a TCP4 port.
-
- @param [in] pPort Address of the port structure.
- @param [in] bAbort Set TRUE to abort active transfers
- @param [in] DebugFlags Flags for debug messages
-
-**/
-typedef
-EFI_STATUS
-PFN_PORT_CLOSE_START (
- IN ESL_PORT * pPort,
- IN BOOLEAN bAbort,
- IN UINTN DebugFlags
- );
-
-/**
IO management structure
This structure manages a single operation with the network.
@@ -241,8 +225,6 @@ typedef struct {
//
// IP4 context
//
- EFI_HANDLE Handle; ///< IP4 port handle
- EFI_IP4_PROTOCOL * pProtocol; ///< IP4 protocol pointer
EFI_IP4_MODE_DATA ModeData; ///< IP4 mode data, includes configuration data
EFI_IPv4_ADDRESS DestinationAddress; ///< Default destination address
@@ -262,8 +244,6 @@ typedef struct {
//
// TCP4 context
//
- EFI_HANDLE Handle; ///< TCP4 port handle
- EFI_TCP4_PROTOCOL * pProtocol; ///< TCP4 protocol pointer
EFI_TCP4_CONFIG_DATA ConfigData; ///< TCP4 configuration data
EFI_TCP4_OPTION Option; ///< TCP4 port options
@@ -289,8 +269,6 @@ typedef struct {
//
// UDP4 context
//
- EFI_HANDLE Handle; ///< UDP4 port handle
- EFI_UDP4_PROTOCOL * pProtocol; ///< UDP4 protocol pointer
EFI_UDP4_CONFIG_DATA ConfigData; ///< UDP4 configuration data
//
@@ -336,11 +314,11 @@ typedef struct _ESL_PORT {
//
ESL_SERVICE * pService; ///< Service for this port
ESL_SOCKET * pSocket; ///< Socket for this port
- PFN_PORT_CLOSE_START * pfnCloseStart; ///< Routine to start closing the port
//
// Port management
//
+ EFI_HANDLE Handle; ///< Network port handle
PORT_STATE State; ///< State of the port
UINTN DebugFlags; ///< Debug flags used to close the port
BOOLEAN bCloseNow; ///< TRUE = Close the port immediately
@@ -364,7 +342,12 @@ typedef struct _ESL_PORT {
//
// Protocol specific management data
//
- VOID * pProtocol; ///< Copy of the network layer protocol
+ union {
+ VOID * v; ///< VOID pointer
+ EFI_IP4_PROTOCOL * IPv4; ///< IP4 protocol pointer
+ EFI_TCP4_PROTOCOL * TCPv4; ///< TCP4 protocol pointer
+ EFI_UDP4_PROTOCOL * UDPv4; ///< UDP4 protocol pointer
+ } pProtocol; ///< Protocol structure address
union {
ESL_IP4_CONTEXT Ip4; ///< IPv4 management data
ESL_TCP4_CONTEXT Tcp4; ///< TCPv4 management data
@@ -830,8 +813,9 @@ typedef struct _ESL_SOCKET {
//
// Transmit data management
//
- UINTN TxTokenOffset; ///< Offset for data pointer in TX token
UINTN TxPacketOffset; ///< Offset for data pointer in ::ESL_PACKET
+ UINTN TxTokenEventOffset; ///< Offset to the Event in the TX token
+ UINTN TxTokenOffset; ///< Offset for data pointer in TX token
UINT32 MaxTxBuf; ///< Maximum size of the transmit buffer
ESL_PACKET * pTxOobPacketListHead;///< Urgent data list head
ESL_PACKET * pTxOobPacketListTail;///< Urgent data list tail
@@ -935,7 +919,6 @@ EslSocketAllocate (
@param [in] ppFreeQueue Address of the free queue head
@param [in] DebugFlags Flags for debug messages
@param [in] pEventName Zero terminated string containing the event name
- @param [in] EventOffset Offset of the event in the ::ESL_IO_MGMT structure
@retval EFI_SUCCESS - The structures were properly initialized
@@ -945,8 +928,7 @@ EslSocketIoFree (
IN ESL_PORT * pPort,
IN ESL_IO_MGMT ** ppFreeQueue,
IN UINTN DebugFlags,
- IN CHAR8 * pEventName,
- IN UINT32 EventOffset
+ IN CHAR8 * pEventName
);
/**
@@ -1049,6 +1031,53 @@ EslSocketPacketFree (
);
/**
+ Close a port.
+
+ This routine releases the resources allocated by the network specific
+ PortAllocate routine.
+
+ This routine is called by:
+ <ul>
+ <li>::EslIp4PortAllocate - Port initialization failure</li>
+ <li>::EslSocketPortCloseRxDone - Last step of close processing</li>
+ <li>::EslTcp4ConnectComplete - Connection failure and reducint the port list to a single port</li>
+ <li>::EslTcp4PortAllocate - Port initialization failure</li>
+ <li>::EslUdp4PortAllocate - Port initialization failure</li>
+ </ul>
+ See the \ref PortCloseStateMachine section.
+
+ @param [in] pPort Address of an ::ESL_PORT structure.
+
+ @retval EFI_SUCCESS The port is closed
+ @retval other Port close error
+
+**/
+EFI_STATUS
+EslSocketPortClose (
+ IN ESL_PORT * pPort
+ );
+
+/**
+ Process the port close completion event
+
+ This routine attempts to complete the port close operation.
+
+ This routine is called by the TCP layer upon completion of
+ the close operation.
+ See the \ref PortCloseStateMachine section.
+
+ @param [in] Event The close completion event
+
+ @param [in] pPort Address of an ::ESL_PORT structure.
+
+**/
+VOID
+EslSocketPortCloseComplete (
+ IN EFI_EVENT Event,
+ IN ESL_PORT * pPort
+ );
+
+/**
Port close state 3
This routine determines the state of the receive operations and
@@ -1079,22 +1108,44 @@ EslSocketPortCloseRxDone (
);
/**
+ Start the close operation on a port, state 1.
+
+ This routine marks the port as closed and initiates the \ref
+ PortCloseStateMachine. The first step is to allow the \ref
+ TransmitEngine to run down.
+
+ This routine is called by ::EslSocketCloseStart to initiate the socket
+ network specific close operation on the socket.
+
+ @param [in] pPort Address of an ::ESL_PORT structure.
+ @param [in] bCloseNow Set TRUE to abort active transfers
+ @param [in] DebugFlags Flags for debug messages
+
+ @retval EFI_SUCCESS The port is closed, not normally returned
+ @retval EFI_NOT_READY The port has started the closing process
+ @retval EFI_ALREADY_STARTED Error, the port is in the wrong state,
+ most likely the routine was called already.
+
+**/
+EFI_STATUS
+EslSocketPortCloseStart (
+ IN ESL_PORT * pPort,
+ IN BOOLEAN bCloseNow,
+ IN UINTN DebugFlags
+ );
+
+/**
Port close state 2
This routine determines the state of the transmit engine and
- continues the close operation after the transmission is complete.
+ continue the close operation after the transmission is complete.
The next step is to stop the \ref Tcp4ReceiveEngine.
+ See the \ref PortCloseStateMachine section.
- This routine is called by
- <ul>
- <li>::EslIp4PortCloseStart</li>
- <li>::EslTcp4PortCloseStart</li>
- <li>::EslUdp4PortCloseStart</li>
- </ul>
- to determine if the transmission is complete.
- See the \ref Tcp4PortCloseStateMachine section.
+ This routine is called by ::EslSocketPortCloseStart to determine
+ if the transmission is complete.
- @param [in] pPort Address of an ::ESL_PORT structure.
+ @param [in] pPort Address of an ::ESL_PORT structure.
@retval EFI_SUCCESS The port is closed, not normally returned
@retval EFI_NOT_READY The port is still closing
@@ -1422,7 +1473,7 @@ EslIp4PortClose (
This routine performs the network specific operations necessary
to free a receive packet.
- This routine is called by ::EslSocketPortCloseTx to free a
+ This routine is called by ::EslSocketPortCloseTxDone to free a
receive packet.
@param [in] pPacket Address of an ::ESL_PACKET structure.
@@ -1458,34 +1509,6 @@ EslIp4PortCloseRxStop (
);
/**
- Start the close operation on a IP4 port, state 1.
-
- This routine marks the port as closed and initiates the port
- close state machine. The first step is to allow the \ref
- TransmitEngine to run down.
-
- This routine is called by ::EslSocketCloseStart to initiate the socket
- network specific close operation on the socket.
- See the \ref Ip4PortCloseStateMachine section.
-
- @param [in] pPort Address of an ::ESL_PORT structure.
- @param [in] bCloseNow Set TRUE to abort active transfers
- @param [in] DebugFlags Flags for debug messages
-
- @retval EFI_SUCCESS The port is closed, not normally returned
- @retval EFI_NOT_READY The port has started the closing process
- @retval EFI_ALREADY_STARTED Error, the port is in the wrong state,
- most likely the routine was called already.
-
-**/
-EFI_STATUS
-EslIp4PortCloseStart (
- IN ESL_PORT * pPort,
- IN BOOLEAN bCloseNow,
- IN UINTN DebugFlags
- );
-
-/**
Receive data from a network connection.
This routine attempts to return buffered data to the caller. The
@@ -1988,32 +2011,12 @@ EslTcp4PortClose (
);
/**
- Process the port close completion event
-
- This routine attempts to complete the port close operation.
-
- This routine is called by the TCPv4 layer upon completion of
- the close operation.
- See the \ref Tcp4PortCloseStateMachine section.
-
- @param [in] Event The close completion event
-
- @param [in] pPort Address of an ::ESL_PORT structure.
-
-**/
-VOID
-EslTcp4PortCloseComplete (
- IN EFI_EVENT Event,
- IN ESL_PORT * pPort
- );
-
-/**
Free a receive packet
This routine performs the network specific operations necessary
to free a receive packet.
- This routine is called by ::EslSocketPortCloseTx to free a
+ This routine is called by ::EslSocketPortCloseTxDone to free a
receive packet.
@param [in] pPacket Address of an ::ESL_PACKET structure.
@@ -2049,33 +2052,6 @@ EslTcp4PortCloseRxStop (
);
/**
- Start the close operation on a TCP4 port, state 1.
-
- This routine marks the port as closed and initiates the port
- close state machine.
-
- This routine is called by ::EslSocketCloseStart to initiate the socket
- network specific close operation on the socket.
- See the \ref Tcp4PortCloseStateMachine section.
-
- @param [in] pPort Address of an ::ESL_PORT structure.
- @param [in] bCloseNow Set TRUE to abort active transfers
- @param [in] DebugFlags Flags for debug messages
-
- @retval EFI_SUCCESS The port is closed, not normally returned
- @retval EFI_NOT_READY The port has started the closing process
- @retval EFI_ALREADY_STARTED Error, the port is in the wrong state,
- most likely the routine was called already.
-
-**/
-EFI_STATUS
-EslTcp4PortCloseStart (
- IN ESL_PORT * pPort,
- IN BOOLEAN bCloseNow,
- IN UINTN DebugFlags
- );
-
-/**
Receive data from a network connection.
This routine attempts to return buffered data to the caller. The
@@ -2508,7 +2484,7 @@ EslUdp4PortClose (
This routine performs the network specific operations necessary
to free a receive packet.
- This routine is called by ::EslSocketPortCloseTx to free a
+ This routine is called by ::EslSocketPortCloseTxDone to free a
receive packet.
@param [in] pPacket Address of an ::ESL_PACKET structure.
@@ -2544,34 +2520,6 @@ EslUdp4PortCloseRxStop (
);
/**
- Start the close operation on a UDP4 port, state 1.
-
- This routine marks the port as closed and initiates the port
- close state machine. The first step is to allow the \ref
- TransmitEngine to run down.
-
- This routine is called by ::EslSocketCloseStart to initiate the socket
- network specific close operation on the socket.
- See the \ref Udp4PortCloseStateMachine section.
-
- @param [in] pPort Address of an ::ESL_PORT structure.
- @param [in] bCloseNow Set TRUE to abort active transfers
- @param [in] DebugFlags Flags for debug messages
-
- @retval EFI_SUCCESS The port is closed, not normally returned
- @retval EFI_NOT_READY The port has started the closing process
- @retval EFI_ALREADY_STARTED Error, the port is in the wrong state,
- most likely the routine was called already.
-
-**/
-EFI_STATUS
-EslUdp4PortCloseStart (
- IN ESL_PORT * pPort,
- IN BOOLEAN bCloseNow,
- IN UINTN DebugFlags
- );
-
-/**
Receive data from a network connection.
This routine attempts to return buffered data to the caller. The
diff --git a/StdLib/EfiSocketLib/Tcp4.c b/StdLib/EfiSocketLib/Tcp4.c
index 25fd838..23137cf 100644
--- a/StdLib/EfiSocketLib/Tcp4.c
+++ b/StdLib/EfiSocketLib/Tcp4.c
@@ -25,31 +25,6 @@
and get the associated socket.
- \section Tcp4PortCloseStateMachine TCPv4 Port Close State Machine
-
- The port close state machine walks the port through the necessary
- states to stop activity on the port and get it into a state where
- the resources may be released. The state machine consists of the
- following arcs and states:
- <ul>
- <li>Arc: ::EslTcp4PortCloseStart - Marks the port as closing and
- initiates the port close operation</li>
- <li>State: PORT_STATE_CLOSE_STARTED</li>
- <li>Arc: ::EslSocketPortCloseTxDone - Waits until all of the transmit
- operations to complete.</li>
- <li>State: PORT_STATE_CLOSE_TX_DONE</li>
- <li>Arc: ::EslSocketPortCloseRxDone - Waits until all of the receive
- operation have been cancelled.</li>
- <li>State: PORT_STATE_CLOSE_RX_DONE</li>
- <li>Arc: ::EslTcp4PortCloseComplete - Called by the TCPv4 layer
- when the port is closed.
- <li>State: PORT_STATE_CLOSE_DONE</li>
- <li>Arc: ::EslTcp4PortClose - Releases the port resources</li>
- </ul>
- Note that the state machine takes into account that close and receive
- completions may happen in either order.
-
-
\section Tcp4ReceiveEngine TCPv4 Receive Engine
The receive engine is started by calling ::EslTcp4RxStart when the
@@ -236,7 +211,7 @@ EslTcp4Bind (
ESL_PORT * pPort;
ESL_SERVICE * pService;
CONST struct sockaddr_in * pIp4Address;
- EFI_SERVICE_BINDING_PROTOCOL * pTcp4Service;
+ EFI_SERVICE_BINDING_PROTOCOL * pServiceBinding;
EFI_STATUS Status;
EFI_STATUS TempStatus;
@@ -269,10 +244,10 @@ EslTcp4Bind (
//
// Create the TCP port
//
- pTcp4Service = pService->pInterface;
+ pServiceBinding = pService->pServiceBinding;
ChildHandle = NULL;
- Status = pTcp4Service->CreateChild ( pTcp4Service,
- &ChildHandle );
+ Status = pServiceBinding->CreateChild ( pServiceBinding,
+ &ChildHandle );
if ( !EFI_ERROR ( Status )) {
DEBUG (( DEBUG_BIND | DEBUG_POOL,
"0x%08x: Tcp4 port handle created\r\n",
@@ -300,8 +275,8 @@ EslTcp4Bind (
// Close the port if necessary
//
if (( EFI_ERROR ( Status )) && ( NULL != ChildHandle )) {
- TempStatus = pTcp4Service->DestroyChild ( pTcp4Service,
- ChildHandle );
+ TempStatus = pServiceBinding->DestroyChild ( pServiceBinding,
+ ChildHandle );
if ( !EFI_ERROR ( TempStatus )) {
DEBUG (( DEBUG_BIND | DEBUG_POOL,
"0x%08x: Tcp4 port handle destroyed\r\n",
@@ -396,7 +371,7 @@ EslTcp4ConnectAttempt (
pTcp4 = &pPort->Context.Tcp4;
pTcp4->ConfigData.AccessPoint.ActiveFlag = TRUE;
pTcp4->ConfigData.TimeToLive = 255;
- pTcp4Protocol = pTcp4->pProtocol;
+ pTcp4Protocol = pPort->pProtocol.TCPv4;
Status = pTcp4Protocol->Configure ( pTcp4Protocol,
&pTcp4->ConfigData );
if ( EFI_ERROR ( Status )) {
@@ -1125,7 +1100,7 @@ EslTcp4Listen (
//
// Configure the port
//
- pTcp4Protocol = pTcp4->pProtocol;
+ pTcp4Protocol = pPort->pProtocol.TCPv4;
Status = pTcp4Protocol->Configure ( pTcp4Protocol,
&pTcp4->ConfigData );
if ( EFI_ERROR ( Status )) {
@@ -1217,7 +1192,7 @@ EslTcp4Listen (
// Close the port upon error
//
if ( EFI_ERROR ( Status )) {
- EslTcp4PortCloseStart ( pPort, TRUE, DEBUG_LISTEN );
+ EslSocketPortCloseStart ( pPort, TRUE, DEBUG_LISTEN );
}
//
@@ -1342,7 +1317,7 @@ EslTcp4ListenComplete (
//
// Restart the listen operation on the port
//
- pTcp4Protocol = pTcp4->pProtocol;
+ pTcp4Protocol = pPort->pProtocol.TCPv4;
Status = pTcp4Protocol->Accept ( pTcp4Protocol,
&pTcp4->ListenToken );
@@ -1362,7 +1337,7 @@ EslTcp4ListenComplete (
pNewPort->bConfigured = TRUE;
pConfigData = &pTcp4->ConfigData;
pConfigData->ControlOption = &pTcp4->Option;
- pTcp4Protocol = pTcp4->pProtocol;
+ pTcp4Protocol = pNewPort->pProtocol.TCPv4;
Status = pTcp4Protocol->GetModeData ( pTcp4Protocol,
NULL,
pConfigData,
@@ -1439,7 +1414,7 @@ EslTcp4ListenComplete (
//
// Close the listening port
//
- EslTcp4PortCloseStart ( pPort, TRUE, DEBUG_LISTEN );
+ EslSocketPortCloseStart ( pPort, TRUE, DEBUG_LISTEN );
}
}
@@ -1562,10 +1537,10 @@ EslTcp4PortAllocate (
pPort->Signature = PORT_SIGNATURE;
pPort->pService = pService;
pPort->pSocket = pSocket;
- pPort->pfnCloseStart = EslTcp4PortCloseStart;
pPort->DebugFlags = DebugFlags;
- pSocket->TxTokenOffset = OFFSET_OF ( EFI_TCP4_IO_TOKEN, Packet.TxData );
pSocket->TxPacketOffset = OFFSET_OF ( ESL_PACKET, Op.Tcp4Tx.TxData );
+ pSocket->TxTokenEventOffset = OFFSET_OF ( ESL_IO_MGMT, Token.Tcp4Tx.CompletionToken.Event );
+ pSocket->TxTokenOffset = OFFSET_OF ( EFI_TCP4_IO_TOKEN, Packet.TxData );
pBuffer = (UINT8 *)&pPort[ 1 ];
pBuffer = &pBuffer[ ESL_STRUCTURE_ALIGNMENT_BYTES ];
pBuffer = (UINT8 *)( ESL_STRUCTURE_ALIGNMENT_MASK & (UINTN)pBuffer );
@@ -1626,7 +1601,7 @@ EslTcp4PortAllocate (
//
Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL,
TPL_SOCKETS,
- (EFI_EVENT_NOTIFY)EslTcp4PortCloseComplete,
+ (EFI_EVENT_NOTIFY)EslSocketPortCloseComplete,
pPort,
&pTcp4->CloseToken.CompletionToken.Event);
if ( EFI_ERROR ( Status )) {
@@ -1665,32 +1640,31 @@ EslTcp4PortAllocate (
Status = gBS->OpenProtocol (
ChildHandle,
&gEfiTcp4ProtocolGuid,
- (VOID **) &pTcp4->pProtocol,
+ &pPort->pProtocol.v,
pLayer->ImageHandle,
NULL,
EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL );
if ( EFI_ERROR ( Status )) {
DEBUG (( DEBUG_ERROR | DebugFlags,
"ERROR - Failed to open gEfiTcp4ProtocolGuid on controller 0x%08x\r\n",
- pTcp4->Handle ));
+ pPort->Handle ));
pSocket->errno = EEXIST;
break;
}
DEBUG (( DebugFlags,
"0x%08x: gEfiTcp4ProtocolGuid opened on controller 0x%08x\r\n",
- pTcp4->pProtocol,
+ pPort->pProtocol.v,
ChildHandle ));
//
// Save the transmit address
//
- pPort->pProtocol = (VOID *)pTcp4->pProtocol;
- pPort->pfnTxStart = (PFN_NET_TX_START)pTcp4->pProtocol->Transmit;
+ pPort->pfnTxStart = (PFN_NET_TX_START)pPort->pProtocol.TCPv4->Transmit;
//
// Set the port address
//
- pTcp4->Handle = ChildHandle;
+ pPort->Handle = ChildHandle;
pAccessPoint = &pPort->Context.Tcp4.ConfigData.AccessPoint;
pAccessPoint->StationPort = PortNumber;
if (( 0 == pIpAddress[0])
@@ -1760,16 +1734,11 @@ EslTcp4PortAllocate (
/**
Close a TCP4 port.
- This routine releases the resources allocated by
+ This routine releases the network specific resources allocated by
::EslTcp4PortAllocate.
- This routine is called by:
- <ul>
- <li>::EslTcp4ConnectComplete - Connection failure and reducint the port list to a single port</li>
- <li>::EslTcp4PortAllocate - Port initialization failure</li>
- <li>::EslSocketPortCloseRxDone - Last step of close processing</li>
- </ul>
- See the \ref Tcp4PortCloseStateMachine section.
+ This routine is called by ::EslSocketPortClose.
+ See the \ref PortCloseStateMachine section.
@param [in] pPort Address of an ::ESL_PORT structure.
@@ -1783,112 +1752,17 @@ EslTcp4PortClose (
)
{
UINTN DebugFlags;
- ESL_LAYER * pLayer;
- ESL_PACKET * pPacket;
- ESL_PORT * pPreviousPort;
- ESL_SERVICE * pService;
- ESL_SOCKET * pSocket;
- EFI_SERVICE_BINDING_PROTOCOL * pTcp4Service;
ESL_TCP4_CONTEXT * pTcp4;
EFI_STATUS Status;
DBG_ENTER ( );
//
- // Verify the socket layer synchronization
- //
- VERIFY_TPL ( TPL_SOCKETS );
-
- //
// Locate the port in the socket list
//
Status = EFI_SUCCESS;
- pLayer = &mEslLayer;
DebugFlags = pPort->DebugFlags;
- pSocket = pPort->pSocket;
- pPreviousPort = pSocket->pPortList;
- if ( pPreviousPort == pPort ) {
- //
- // Remove this port from the head of the socket list
- //
- pSocket->pPortList = pPort->pLinkSocket;
- }
- else {
- //
- // Locate the port in the middle of the socket list
- //
- while (( NULL != pPreviousPort )
- && ( pPreviousPort->pLinkSocket != pPort )) {
- pPreviousPort = pPreviousPort->pLinkSocket;
- }
- if ( NULL != pPreviousPort ) {
- //
- // Remove the port from the middle of the socket list
- //
- pPreviousPort->pLinkSocket = pPort->pLinkSocket;
- }
- }
-
- //
- // Locate the port in the service list
- //
- pService = pPort->pService;
- pPreviousPort = pService->pPortList;
- if ( pPreviousPort == pPort ) {
- //
- // Remove this port from the head of the service list
- //
- pService->pPortList = pPort->pLinkService;
- }
- else {
- //
- // Locate the port in the middle of the service list
- //
- while (( NULL != pPreviousPort )
- && ( pPreviousPort->pLinkService != pPort )) {
- pPreviousPort = pPreviousPort->pLinkService;
- }
- if ( NULL != pPreviousPort ) {
- //
- // Remove the port from the middle of the service list
- //
- pPreviousPort->pLinkService = pPort->pLinkService;
- }
- }
-
- //
- // Empty the urgent receive queue
- //
pTcp4 = &pPort->Context.Tcp4;
- while ( NULL != pSocket->pRxOobPacketListHead ) {
- pPacket = pSocket->pRxOobPacketListHead;
- pSocket->pRxOobPacketListHead = pPacket->pNext;
- pSocket->RxOobBytes -= pPacket->Op.Tcp4Rx.ValidBytes;
- EslSocketPacketFree ( pPacket, DEBUG_RX );
- }
- pSocket->pRxOobPacketListTail = NULL;
- ASSERT ( 0 == pSocket->RxOobBytes );
-
- //
- // Empty the receive queue
- //
- while ( NULL != pSocket->pRxPacketListHead ) {
- pPacket = pSocket->pRxPacketListHead;
- pSocket->pRxPacketListHead = pPacket->pNext;
- pSocket->RxBytes -= pPacket->Op.Tcp4Rx.ValidBytes;
- EslSocketPacketFree ( pPacket, DEBUG_RX );
- }
- pSocket->pRxPacketListTail = NULL;
- ASSERT ( 0 == pSocket->RxBytes );
-
- //
- // Empty the receive free queue
- //
- while ( NULL != pSocket->pRxFree ) {
- pPacket = pSocket->pRxFree;
- pSocket->pRxFree = pPacket->pNext;
- EslSocketPacketFree ( pPacket, DEBUG_RX );
- }
//
// Done with the connect event
@@ -1963,85 +1837,6 @@ EslTcp4PortClose (
}
//
- // Done with the normal transmit events
- //
- Status = EslSocketIoFree ( pPort,
- &pPort->pTxFree,
- DebugFlags | DEBUG_POOL,
- "normal transmit",
- OFFSET_OF ( ESL_IO_MGMT, Token.Tcp4Tx.CompletionToken.Event ));
-
- //
- // Done with the urgent transmit events
- //
- Status = EslSocketIoFree ( pPort,
- &pPort->pTxOobFree,
- DebugFlags | DEBUG_POOL,
- "urgent transmit",
- OFFSET_OF ( ESL_IO_MGMT, Token.Tcp4Tx.CompletionToken.Event ));
-
- //
- // Done with the TCP protocol
- //
- pTcp4Service = pService->pInterface;
- if ( NULL != pTcp4->pProtocol ) {
- Status = gBS->CloseProtocol ( pTcp4->Handle,
- &gEfiTcp4ProtocolGuid,
- pLayer->ImageHandle,
- NULL );
- if ( !EFI_ERROR ( Status )) {
- DEBUG (( DebugFlags,
- "0x%08x: gEfiTcp4ProtocolGuid closed on controller 0x%08x\r\n",
- pTcp4->pProtocol,
- pTcp4->Handle ));
- }
- else {
- DEBUG (( DEBUG_ERROR | DebugFlags,
- "ERROR - Failed to close gEfiTcp4ProtocolGuid opened on controller 0x%08x, Status: %r\r\n",
- pTcp4->Handle,
- Status ));
- ASSERT ( EFI_SUCCESS == Status );
- }
- }
-
- //
- // Done with the TCP port
- //
- if ( NULL != pTcp4->Handle ) {
- Status = pTcp4Service->DestroyChild ( pTcp4Service,
- pTcp4->Handle );
- if ( !EFI_ERROR ( Status )) {
- DEBUG (( DebugFlags | DEBUG_POOL,
- "0x%08x: Tcp4 port handle destroyed\r\n",
- pTcp4->Handle ));
- }
- else {
- DEBUG (( DEBUG_ERROR | DebugFlags | DEBUG_POOL,
- "ERROR - Failed to destroy the Tcp4 port handle, Status: %r\r\n",
- Status ));
- ASSERT ( EFI_SUCCESS == Status );
- }
- }
-
- //
- // Release the port structure
- //
- Status = gBS->FreePool ( pPort );
- if ( !EFI_ERROR ( Status )) {
- DEBUG (( DebugFlags | DEBUG_POOL,
- "0x%08x: Free pPort, %d bytes\r\n",
- pPort,
- sizeof ( *pPort )));
- }
- else {
- DEBUG (( DEBUG_ERROR | DebugFlags | DEBUG_POOL,
- "ERROR - Failed to free pPort: 0x%08x, Status: %r\r\n",
- pPort,
- Status ));
- ASSERT ( EFI_SUCCESS == Status );
- }
-
- //
// Return the operation status
//
DBG_EXIT_STATUS ( Status );
@@ -2050,49 +1845,12 @@ EslTcp4PortClose (
/**
- Process the port close completion event
-
- This routine attempts to complete the port close operation.
-
- This routine is called by the TCPv4 layer upon completion of
- the close operation.
- See the \ref Tcp4PortCloseStateMachine section.
-
- @param [in] Event The close completion event
-
- @param [in] pPort Address of an ::ESL_PORT structure.
-
-**/
-VOID
-EslTcp4PortCloseComplete (
- IN EFI_EVENT Event,
- IN ESL_PORT * pPort
- )
-{
- EFI_STATUS Status;
-
- DBG_ENTER ( );
-
- //
- // Update the port state
- //
- pPort->State = PORT_STATE_CLOSE_DONE;
-
- //
- // Release the resources once the receive operation completes
- //
- Status = EslSocketPortCloseRxDone ( pPort );
- DBG_EXIT_STATUS ( Status );
-}
-
-
-/**
Free a receive packet
This routine performs the network specific operations necessary
to free a receive packet.
- This routine is called by ::EslSocketPortCloseTx to free a
+ This routine is called by ::EslSocketPortCloseTxDone to free a
receive packet.
@param [in] pPacket Address of an ::ESL_PACKET structure.
@@ -2144,7 +1902,7 @@ EslTcp4PortCloseRxStop (
// Close the configured port
//
pTcp4 = &pPort->Context.Tcp4;
- pTcp4Protocol = pTcp4->pProtocol;
+ pTcp4Protocol = pPort->pProtocol.TCPv4;
pTcp4->CloseToken.AbortOnClose = FALSE;
Status = pTcp4Protocol->Close ( pTcp4Protocol,
&pTcp4->CloseToken );
@@ -2169,76 +1927,6 @@ EslTcp4PortCloseRxStop (
/**
- Start the close operation on a TCP4 port, state 1.
-
- This routine marks the port as closed and initiates the port
- close state machine. The first step is to allow the \ref
- TransmitEngine to run down.
-
- This routine is called by ::EslSocketCloseStart to initiate the socket
- network specific close operation on the socket.
- See the \ref Tcp4PortCloseStateMachine section.
-
- @param [in] pPort Address of an ::ESL_PORT structure.
- @param [in] bCloseNow Set TRUE to abort active transfers
- @param [in] DebugFlags Flags for debug messages
-
- @retval EFI_SUCCESS The port is closed, not normally returned
- @retval EFI_NOT_READY The port has started the closing process
- @retval EFI_ALREADY_STARTED Error, the port is in the wrong state,
- most likely the routine was called already.
-
-**/
-EFI_STATUS
-EslTcp4PortCloseStart (
- IN ESL_PORT * pPort,
- IN BOOLEAN bCloseNow,
- IN UINTN DebugFlags
- )
-{
- ESL_SOCKET * pSocket;
- EFI_STATUS Status;
-
- DBG_ENTER ( );
-
- //
- // Verify the socket layer synchronization
- //
- VERIFY_TPL ( TPL_SOCKETS );
-
- //
- // Mark the port as closing
- //
- Status = EFI_ALREADY_STARTED;
- pSocket = pPort->pSocket;
- pSocket->errno = EALREADY;
- if ( PORT_STATE_CLOSE_STARTED > pPort->State ) {
-
- //
- // Update the port state
- //
- pPort->State = PORT_STATE_CLOSE_STARTED;
- DEBUG (( DEBUG_CLOSE | DEBUG_INFO,
- "0x%08x: Port Close State: PORT_STATE_CLOSE_STARTED\r\n",
- pPort ));
- pPort->bCloseNow = bCloseNow;
- pPort->DebugFlags = DebugFlags;
-
- //
- // Determine if transmits are complete
- //
- Status = EslSocketPortCloseTxDone ( pPort );
- }
-
- //
- // Return the operation status
- //
- DBG_EXIT_STATUS ( Status );
- return Status;
-}
-
-
-/**
Receive data from a network connection.
This routine attempts to return buffered data to the caller. The
@@ -2597,7 +2285,7 @@ EslTcp4RxCancel (
//
// Attempt to cancel the receive operation
//
- pTcp4Protocol = pTcp4->pProtocol;
+ pTcp4Protocol = pPort->pProtocol.TCPv4;
Status = pTcp4Protocol->Cancel ( pTcp4Protocol,
&pTcp4->RxToken.CompletionToken );
if ( EFI_NOT_FOUND == Status ) {
@@ -2855,7 +2543,7 @@ EslTcp4RxStart (
//
// Start the receive on the packet
//
- pTcp4Protocol = pTcp4->pProtocol;
+ pTcp4Protocol = pPort->pProtocol.TCPv4;
Status = pTcp4Protocol->Receive ( pTcp4Protocol,
&pTcp4->RxToken );
if ( !EFI_ERROR ( Status )) {
diff --git a/StdLib/EfiSocketLib/Udp4.c b/StdLib/EfiSocketLib/Udp4.c
index 465fb6d..f8ec06e 100644
--- a/StdLib/EfiSocketLib/Udp4.c
+++ b/StdLib/EfiSocketLib/Udp4.c
@@ -11,27 +11,6 @@
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
- \section Udp4PortCloseStateMachine UDPv4 Port Close State Machine
-
- The port close state machine walks the port through the necessary
- states to stop activity on the port and get it into a state where
- the resources may be released. The state machine consists of the
- following arcs and states:
- <ul>
- <li>Arc: ::EslUdp4PortCloseStart - Marks the port as closing and
- initiates the port close operation</li>
- <li>State: PORT_STATE_CLOSE_STARTED</li>
- <li>Arc: ::EslSocketPortCloseTxDone - Waits until all of the transmit
- operations to complete.</li>
- <li>State: PORT_STATE_CLOSE_TX_DONE - RX still active</li>
- <li>Arc: ::EslSocketPortCloseRxDone - Waits until all of the receive
- operation have been cancelled.</li>
- <li>State: PORT_STATE_CLOSE_RX_DONE - RX shutdown</li>
- <li>State: PORT_STATE_CLOSE_DONE - Port never configured</li>
- <li>Arc: ::EslUdp4PortClose - Releases the port resources</li>
- </ul>
-
-
\section Udp4ReceiveEngine UDPv4 Receive Engine
The receive engine is started by calling ::EslUdp4RxStart when the
@@ -135,7 +114,7 @@ EslUdp4Bind (
ESL_PORT * pPort;
ESL_SERVICE * pService;
CONST struct sockaddr_in * pIp4Address;
- EFI_SERVICE_BINDING_PROTOCOL * pUdp4Service;
+ EFI_SERVICE_BINDING_PROTOCOL * pServiceBinding;
EFI_STATUS Status;
EFI_STATUS TempStatus;
@@ -169,10 +148,10 @@ EslUdp4Bind (
//
// Create the UDP port
//
- pUdp4Service = pService->pInterface;
+ pServiceBinding = pService->pServiceBinding;
ChildHandle = NULL;
- Status = pUdp4Service->CreateChild ( pUdp4Service,
- &ChildHandle );
+ Status = pServiceBinding->CreateChild ( pServiceBinding,
+ &ChildHandle );
if ( !EFI_ERROR ( Status )) {
DEBUG (( DEBUG_BIND | DEBUG_POOL,
"0x%08x: Udp4 port handle created\r\n",
@@ -200,8 +179,8 @@ EslUdp4Bind (
// Close the port if necessary
//
if (( EFI_ERROR ( Status )) && ( NULL != ChildHandle )) {
- TempStatus = pUdp4Service->DestroyChild ( pUdp4Service,
- ChildHandle );
+ TempStatus = pServiceBinding->DestroyChild ( pServiceBinding,
+ ChildHandle );
if ( !EFI_ERROR ( TempStatus )) {
DEBUG (( DEBUG_BIND | DEBUG_POOL,
"0x%08x: Udp4 port handle destroyed\r\n",
@@ -612,6 +591,7 @@ EslUdp4PortAllocate (
ESL_IO_MGMT * pIo;
ESL_LAYER * pLayer;
ESL_PORT * pPort;
+ CONST ESL_SOCKET_BINDING * pSocketBinding;
ESL_UDP4_CONTEXT * pUdp4;
EFI_STATUS Status;
@@ -651,10 +631,10 @@ EslUdp4PortAllocate (
pPort->Signature = PORT_SIGNATURE;
pPort->pService = pService;
pPort->pSocket = pSocket;
- pPort->pfnCloseStart = EslUdp4PortCloseStart;
pPort->DebugFlags = DebugFlags;
- pSocket->TxTokenOffset = OFFSET_OF ( EFI_UDP4_COMPLETION_TOKEN, Packet.TxData );
pSocket->TxPacketOffset = OFFSET_OF ( ESL_PACKET, Op.Udp4Tx.TxData );
+ pSocket->TxTokenEventOffset = OFFSET_OF ( ESL_IO_MGMT, Token.Udp4Tx.Event );
+ pSocket->TxTokenOffset = OFFSET_OF ( EFI_UDP4_COMPLETION_TOKEN, Packet.TxData );
pBuffer = (UINT8 *)&pPort[ 1 ];
pBuffer = &pBuffer[ ESL_STRUCTURE_ALIGNMENT_BYTES ];
pBuffer = (UINT8 *)( ESL_STRUCTURE_ALIGNMENT_MASK & (UINTN)pBuffer );
@@ -698,35 +678,35 @@ EslUdp4PortAllocate (
//
// Open the port protocol
//
+ pSocketBinding = pService->pSocketBinding;
Status = gBS->OpenProtocol (
ChildHandle,
- &gEfiUdp4ProtocolGuid,
- (VOID **) &pUdp4->pProtocol,
+ pSocketBinding->pNetworkProtocolGuid,
+ &pPort->pProtocol.v,
pLayer->ImageHandle,
NULL,
EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL );
if ( EFI_ERROR ( Status )) {
DEBUG (( DEBUG_ERROR | DebugFlags,
"ERROR - Failed to open gEfiUdp4ProtocolGuid on controller 0x%08x\r\n",
- pUdp4->Handle ));
+ pPort->Handle ));
pSocket->errno = EEXIST;
break;
}
DEBUG (( DebugFlags,
"0x%08x: gEfiUdp4ProtocolGuid opened on controller 0x%08x\r\n",
- pUdp4->pProtocol,
+ pPort->pProtocol.v,
ChildHandle ));
//
// Save the transmit address
//
- pPort->pProtocol = (VOID *)pUdp4->pProtocol;
- pPort->pfnTxStart = (PFN_NET_TX_START)pUdp4->pProtocol->Transmit;
+ pPort->pfnTxStart = (PFN_NET_TX_START)pPort->pProtocol.UDPv4->Transmit;
//
// Set the port address
//
- pUdp4->Handle = ChildHandle;
+ pPort->Handle = ChildHandle;
pConfig = &pPort->Context.Udp4.ConfigData;
pConfig->StationPort = PortNumber;
if (( 0 == pIpAddress[0])
@@ -787,7 +767,7 @@ EslUdp4PortAllocate (
//
// Close the port
//
- EslUdp4PortClose ( pPort );
+ EslSocketPortClose ( pPort );
}
//
// Return the operation status
@@ -803,12 +783,8 @@ EslUdp4PortAllocate (
This routine releases the resources allocated by
::EslUdp4PortAllocate.
- This routine is called by:
- <ul>
- <li>::EslUdp4PortAllocate - Port initialization failure</li>
- <li>::EslSocketPortCloseRxDone - Last step of close processing</li>
- </ul>
- See the \ref Udp4PortCloseStateMachine section.
+ This routine is called by ::EslSocketPortClose.
+ See the \ref PortCloseStateMachine section.
@param [in] pPort Address of an ::ESL_PORT structure.
@@ -822,104 +798,21 @@ EslUdp4PortClose (
)
{
UINTN DebugFlags;
- ESL_LAYER * pLayer;
- ESL_PACKET * pPacket;
- ESL_PORT * pPreviousPort;
- ESL_SERVICE * pService;
- ESL_SOCKET * pSocket;
- EFI_SERVICE_BINDING_PROTOCOL * pUdp4Service;
ESL_UDP4_CONTEXT * pUdp4;
EFI_STATUS Status;
DBG_ENTER ( );
//
- // Verify the socket layer synchronization
- //
- VERIFY_TPL ( TPL_SOCKETS );
-
- //
// Assume success
//
Status = EFI_SUCCESS;
- pSocket = pPort->pSocket;
- pSocket->errno = 0;
-
- //
- // Locate the port in the socket list
- //
- pLayer = &mEslLayer;
DebugFlags = pPort->DebugFlags;
- pPreviousPort = pSocket->pPortList;
- if ( pPreviousPort == pPort ) {
- //
- // Remove this port from the head of the socket list
- //
- pSocket->pPortList = pPort->pLinkSocket;
- }
- else {
- //
- // Locate the port in the middle of the socket list
- //
- while (( NULL != pPreviousPort )
- && ( pPreviousPort->pLinkSocket != pPort )) {
- pPreviousPort = pPreviousPort->pLinkSocket;
- }
- if ( NULL != pPreviousPort ) {
- //
- // Remove the port from the middle of the socket list
- //
- pPreviousPort->pLinkSocket = pPort->pLinkSocket;
- }
- }
-
- //
- // Locate the port in the service list
- //
- pService = pPort->pService;
- pPreviousPort = pService->pPortList;
- if ( pPreviousPort == pPort ) {
- //
- // Remove this port from the head of the service list
- //
- pService->pPortList = pPort->pLinkService;
- }
- else {
- //
- // Locate the port in the middle of the service list
- //
- while (( NULL != pPreviousPort )
- && ( pPreviousPort->pLinkService != pPort )) {
- pPreviousPort = pPreviousPort->pLinkService;
- }
- if ( NULL != pPreviousPort ) {
- //
- // Remove the port from the middle of the service list
- //
- pPreviousPort->pLinkService = pPort->pLinkService;
- }
- }
-
- //
- // Empty the receive queue
- //
- ASSERT ( NULL == pSocket->pRxPacketListHead );
- ASSERT ( NULL == pSocket->pRxPacketListTail );
- ASSERT ( 0 == pSocket->RxBytes );
-
- //
- // Empty the receive free queue
- //
- while ( NULL != pSocket->pRxFree ) {
- pPacket = pSocket->pRxFree;
- pSocket->pRxFree = pPacket->pNext;
- EslSocketPacketFree ( pPacket, DEBUG_RX );
- }
+ pUdp4 = &pPort->Context.Udp4;
//
// Done with the receive event
//
- pUdp4 = &pPort->Context.Udp4;
if ( NULL != pUdp4->RxToken.Event ) {
Status = gBS->CloseEvent ( pUdp4->RxToken.Event );
if ( !EFI_ERROR ( Status )) {
@@ -936,86 +829,6 @@ EslUdp4PortClose (
}
//
- // Done with the transmit events
- //
- Status = EslSocketIoFree ( pPort,
- &pPort->pTxFree,
- DebugFlags | DEBUG_POOL,
- "transmit",
- OFFSET_OF ( ESL_IO_MGMT, Token.Udp4Tx.Event ));
-
- //
- // Done with the UDP protocol
- //
- pUdp4Service = pService->pInterface;
- if ( NULL != pUdp4->pProtocol ) {
- Status = gBS->CloseProtocol ( pUdp4->Handle,
- &gEfiUdp4ProtocolGuid,
- pLayer->ImageHandle,
- NULL );
- if ( !EFI_ERROR ( Status )) {
- DEBUG (( DebugFlags,
- "0x%08x: gEfiUdp4ProtocolGuid closed on controller 0x%08x\r\n",
- pUdp4->pProtocol,
- pUdp4->Handle ));
- }
- else {
- DEBUG (( DEBUG_ERROR | DebugFlags,
- "ERROR - Failed to close gEfiUdp4ProtocolGuid opened on controller 0x%08x, Status: %r\r\n",
- pUdp4->Handle,
- Status ));
- ASSERT ( EFI_SUCCESS == Status );
- }
- }
-
- //
- // Done with the UDP port
- //
- if ( NULL != pUdp4->Handle ) {
- Status = pUdp4Service->DestroyChild ( pUdp4Service,
- pUdp4->Handle );
- if ( !EFI_ERROR ( Status )) {
- DEBUG (( DebugFlags | DEBUG_POOL,
- "0x%08x: Udp4 port handle destroyed\r\n",
- pUdp4->Handle ));
- }
- else {
- DEBUG (( DEBUG_ERROR | DebugFlags | DEBUG_POOL,
- "ERROR - Failed to destroy the Udp4 port handle, Status: %r\r\n",
- Status ));
- ASSERT ( EFI_SUCCESS == Status );
- }
- }
-
- //
- // Release the port structure
- //
- Status = gBS->FreePool ( pPort );
- if ( !EFI_ERROR ( Status )) {
- DEBUG (( DebugFlags | DEBUG_POOL,
- "0x%08x: Free pPort, %d bytes\r\n",
- pPort,
- sizeof ( *pPort )));
- }
- else {
- DEBUG (( DEBUG_ERROR | DebugFlags | DEBUG_POOL,
- "ERROR - Failed to free pPort: 0x%08x, Status: %r\r\n",
- pPort,
- Status ));
- ASSERT ( EFI_SUCCESS == Status );
- }
-
- //
- // Mark the socket as closed if necessary
- //
- if ( NULL == pSocket->pPortList ) {
- pSocket->State = SOCKET_STATE_CLOSED;
- DEBUG (( DEBUG_CLOSE | DEBUG_INFO,
- "0x%08x: Socket State: SOCKET_STATE_CLOSED\r\n",
- pSocket ));
- }
-
- //
// Return the operation status
//
DBG_EXIT_STATUS ( Status );
@@ -1029,7 +842,7 @@ EslUdp4PortClose (
This routine performs the network specific operations necessary
to free a receive packet.
- This routine is called by ::EslSocketPortCloseTx to free a
+ This routine is called by ::EslSocketPortCloseTxDone to free a
receive packet.
@param [in] pPacket Address of an ::ESL_PACKET structure.
@@ -1086,7 +899,7 @@ EslUdp4PortCloseRxStop (
// Reset the port, cancel the outstanding receive
//
pUdp4 = &pPort->Context.Udp4;
- pUdp4Protocol = pUdp4->pProtocol;
+ pUdp4Protocol = pPort->pProtocol.UDPv4;
Status = pUdp4Protocol->Configure ( pUdp4Protocol,
NULL );
if ( !EFI_ERROR ( Status )) {
@@ -1110,76 +923,6 @@ EslUdp4PortCloseRxStop (
/**
- Start the close operation on a UDP4 port, state 1.
-
- This routine marks the port as closed and initiates the port
- close state machine. The first step is to allow the \ref
- TransmitEngine to run down.
-
- This routine is called by ::EslSocketCloseStart to initiate the socket
- network specific close operation on the socket.
- See the \ref Udp4PortCloseStateMachine section.
-
- @param [in] pPort Address of an ::ESL_PORT structure.
- @param [in] bCloseNow Set TRUE to abort active transfers
- @param [in] DebugFlags Flags for debug messages
-
- @retval EFI_SUCCESS The port is closed, not normally returned
- @retval EFI_NOT_READY The port has started the closing process
- @retval EFI_ALREADY_STARTED Error, the port is in the wrong state,
- most likely the routine was called already.
-
-**/
-EFI_STATUS
-EslUdp4PortCloseStart (
- IN ESL_PORT * pPort,
- IN BOOLEAN bCloseNow,
- IN UINTN DebugFlags
- )
-{
- ESL_SOCKET * pSocket;
- EFI_STATUS Status;
-
- DBG_ENTER ( );
-
- //
- // Verify the socket layer synchronization
- //
- VERIFY_TPL ( TPL_SOCKETS );
-
- //
- // Mark the port as closing
- //
- Status = EFI_ALREADY_STARTED;
- pSocket = pPort->pSocket;
- pSocket->errno = EALREADY;
- if ( PORT_STATE_CLOSE_STARTED > pPort->State ) {
-
- //
- // Update the port state
- //
- pPort->State = PORT_STATE_CLOSE_STARTED;
- DEBUG (( DEBUG_CLOSE | DEBUG_INFO,
- "0x%08x: Port Close State: PORT_STATE_CLOSE_STARTED\r\n",
- pPort ));
- pPort->bCloseNow = bCloseNow;
- pPort->DebugFlags = DebugFlags;
-
- //
- // Determine if transmits are complete
- //
- Status = EslSocketPortCloseTxDone ( pPort );
- }
-
- //
- // Return the operation status
- //
- DBG_EXIT_STATUS ( Status );
- return Status;
-}
-
-
-/**
Receive data from a network connection.
This routine attempts to return buffered data to the caller. The
@@ -1509,7 +1252,7 @@ EslUdp4RxCancel (
//
// Attempt to cancel the receive operation
//
- pUdp4Protocol = pUdp4->pProtocol;
+ pUdp4Protocol = pPort->pProtocol.UDPv4;
Status = pUdp4Protocol->Cancel ( pUdp4Protocol,
&pUdp4->RxToken );
if ( EFI_NOT_FOUND == Status ) {
@@ -1764,7 +1507,7 @@ EslUdp4RxStart (
//
// Start the receive on the packet
//
- pUdp4Protocol = pUdp4->pProtocol;
+ pUdp4Protocol = pPort->pProtocol.UDPv4;
Status = pUdp4Protocol->Receive ( pUdp4Protocol,
&pUdp4->RxToken );
if ( !EFI_ERROR ( Status )) {
@@ -1942,7 +1685,7 @@ EslUdp4Shutdown (
//
pNextPort = pPort->pLinkSocket;
pUdp4 = &pPort->Context.Udp4;
- pUdp4Protocol = pUdp4->pProtocol;
+ pUdp4Protocol = pPort->pProtocol.UDPv4;
DEBUG (( DEBUG_TX,
"0x%08x: pPort Configuring for %d.%d.%d.%d:%d --> %d.%d.%d.%d:%d\r\n",
pPort,
diff --git a/StdLib/Include/Efi/EfiSocketLib.h b/StdLib/Include/Efi/EfiSocketLib.h
index f8e9e98..4a44693 100644
--- a/StdLib/Include/Efi/EfiSocketLib.h
+++ b/StdLib/Include/Efi/EfiSocketLib.h
@@ -145,6 +145,7 @@ VOID
typedef struct {
CHAR16 * pName; ///< Protocol name
EFI_GUID * pNetworkBinding; ///< Network service binding protocol for socket support
+ EFI_GUID * pNetworkProtocolGuid;///< Network protocol GUID
CONST EFI_GUID * pTagGuid; ///< Tag to mark protocol in use
PFN_SB_INITIALIZE pfnInitialize;///< Routine to initialize the service
PFN_SB_SHUTDOWN pfnShutdown; ///< Routine to shutdown the service