* Bound - pSocket->PortList is not NULL\r
* Listen - AcceptWait event is not NULL\r
\r
- Copyright (c) 2011, Intel Corporation\r
- All rights reserved. This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
+ Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials are licensed and made available under\r
+ the terms and conditions of the BSD License that accompanies this distribution.\r
+ The full text of the license may be found at\r
http://opensource.org/licenses/bsd-license.php\r
\r
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
\r
<code><pre>\r
\r
- +-------------+ +-------------+ +-------------+ \r
+ +---------------+ +-------------+ +-------------+\r
Service Lists | ::ESL_SERVICE |-->| ESL_SERVICE |-->| ESL_SERVICE |--> NULL (pNext)\r
- +-------------+ +-------------+ +-------------+ \r
+ +---------------+ +-------------+ +-------------+\r
^ | (pPortList) |\r
pUdp4List ^ | pTcp4List | |\r
| | | |\r
^ | | | |\r
pIp4List | | | | |\r
+---------------+ | |\r
- | ::ESL_LAYER | ::mEslLayer | |\r
+ | ::ESL_LAYER | ::mEslLayer | |\r
+---------------+ | |\r
| (pSocketList) | |\r
Socket List V V V\r
- +-------------+ +-------------+ +-------------+ \r
- | ::ESL_SOCKET |-->| ::ESL_PORT |-->| ESL_PORT |--> NULL (pLinkSocket)\r
- +-------------+ +-------------+ +-------------+ \r
+ +---------------+ +-------------+ +-------------+\r
+ | ::ESL_SOCKET |-->| ::ESL_PORT |-->| ESL_PORT |--> NULL (pLinkSocket)\r
+ +---------------+ +-------------+ +-------------+\r
| | |\r
| | V\r
V V NULL\r
- +-------------+ +-------------+ \r
+ +-------------+ +-------------+\r
| ESL_SOCKET |-->| ESL_PORT |--> NULL\r
+-------------+ +-------------+\r
| | | | | |\r
| `---------------. | |\r
pTxOobPacketListHead | | | |\r
V V V V\r
- +------------+ +------------+ +------------+ +------------+\r
+ +--------------+ +------------+ +------------+ +------------+\r
| ::ESL_PACKET | | ESL_PACKET | | ESL_PACKET | | ESL_PACKET |\r
- +------------+ +------------+ +------------+ +------------+\r
+ +--------------+ +------------+ +------------+ +------------+\r
| | | |\r
V V V V\r
+------------+ +------------+ +------------+ +------------+\r
::EslTcp4PortCloseOp.\r
</li>\r
<li>State: PORT_STATE_CLOSE_TX_DONE</li>\r
- <li>Arc: ::EslSocketPortCloseComplete - Called when the close operation is \r
+ <li>Arc: ::EslSocketPortCloseComplete - Called when the close operation is\r
complete. After the transition to PORT_STATE_CLOSE_DONE,\r
this routine calls ::EslSocketRxCancel to abort the pending receive operations.\r
</li>\r
pPort->pRxActive\r
|\r
V\r
- +-------------+ +-------------+ +-------------+ \r
+ +-------------+ +-------------+ +-------------+\r
Active | ESL_IO_MGMT |-->| ESL_IO_MGMT |-->| ESL_IO_MGMT |--> NULL\r
- +-------------+ +-------------+ +-------------+ \r
+ +-------------+ +-------------+ +-------------+\r
\r
- +-------------+ +-------------+ +-------------+ \r
+ +-------------+ +-------------+ +-------------+\r
Free | ESL_IO_MGMT |-->| ESL_IO_MGMT |-->| ESL_IO_MGMT |--> NULL\r
- +-------------+ +-------------+ +-------------+ \r
+ +-------------+ +-------------+ +-------------+\r
^\r
|\r
pPort->pRxFree\r
\r
<code><pre>\r
\r
- +------------+ +------------+ \r
+ +------------+ +------------+\r
High .----->| ESL_PACKET |-->| ESL_PACKET |--> NULL (pNext)\r
Priority | +------------+ +------------+\r
|\r
+------------+\r
| pRxPacketListHead\r
Low |\r
- Priority | +------------+ +------------+ +------------+ \r
+ Priority | +------------+ +------------+ +------------+\r
`----->| ::ESL_PACKET |-->| ESL_PACKET |-->| ESL_PACKET |--> NULL\r
- +------------+ +------------+ +------------+ \r
+ +------------+ +------------+ +------------+\r
\r
</pre></code>\r
\r
::EslSocketRxStart connects an ::ESL_PACKET structure to the ::ESL_IO_MGMT structure\r
- and then calls the network layer to start the receive operation. Upon \r
+ and then calls the network layer to start the receive operation. Upon\r
receive completion, ::EslSocketRxComplete breaks the connection between these\r
structrues and places the ESL_IO_MGMT structure onto the ESL_PORT::pRxFree list to\r
make token and event available for another receive operation. EslSocketRxComplete\r
*ppQueueHead: pSocket->pRxPacketListHead or pSocket->pRxOobPacketListHead\r
|\r
V\r
- +------------+ +------------+ +------------+ \r
+ +------------+ +------------+ +------------+\r
Data | ESL_PACKET |-->| ESL_PACKET |-->| ESL_PACKET |--> NULL\r
- +------------+ +------------+ +------------+ \r
+ +------------+ +------------+ +------------+\r
^\r
|\r
*ppQueueTail: pSocket->pRxPacketListTail or pSocket->pRxOobPacketListTail\r
pPort->pTxActive or pTxOobActive\r
|\r
V\r
- +-------------+ +-------------+ +-------------+ \r
+ +-------------+ +-------------+ +-------------+\r
Active | ESL_IO_MGMT |-->| ESL_IO_MGMT |-->| ESL_IO_MGMT |--> NULL\r
- +-------------+ +-------------+ +-------------+ \r
+ +-------------+ +-------------+ +-------------+\r
\r
- +-------------+ +-------------+ +-------------+ \r
+ +-------------+ +-------------+ +-------------+\r
Free | ESL_IO_MGMT |-->| ESL_IO_MGMT |-->| ESL_IO_MGMT |--> NULL\r
- +-------------+ +-------------+ +-------------+ \r
+ +-------------+ +-------------+ +-------------+\r
^\r
|\r
pPort->pTxFree or pTxOobFree\r
\r
/**\r
Allocate and initialize a ESL_SOCKET structure.\r
- \r
+\r
This support function allocates an ::ESL_SOCKET structure\r
and installs a protocol on ChildHandle. If pChildHandle is a\r
pointer to NULL, then a new handle is created and returned in\r
\r
@param [in, out] pChildHandle Pointer to the handle of the child to create.\r
If it is NULL, then a new handle is created.\r
- If it is a pointer to an existing UEFI handle, \r
+ If it is a pointer to an existing UEFI handle,\r
then the protocol is added to the existing UEFI\r
handle.\r
@param [in] DebugFlags Flags for debug messages\r
@retval EFI_OUT_OF_RESOURCES There are not enough resources available to create\r
the child\r
@retval other The child handle was not created\r
- \r
+\r
**/\r
EFI_STATUS\r
EFIAPI\r
pConfigData = (VOID *)pBuffer;\r
\r
//\r
- // Attempt to use this configuration\r
+ // Validate that the port is connected\r
//\r
- Status = pPort->pfnConfigure ( pPort->pProtocol.v, pConfigData );\r
+ Status = pPort->pSocket->pApi->pfnVerifyLocalIpAddress ( pPort, pBuffer );\r
if ( EFI_ERROR ( Status )) {\r
DEBUG (( DEBUG_WARN | DEBUG_BIND,\r
- "WARNING - Port 0x%08x failed configuration, Status: %r\r\n",\r
+ "WARNING - Port 0x%08x invalid IP address: %r\r\n",\r
pPort,\r
Status ));\r
pPort->pSocket->errno = ErrnoValue;\r
}\r
else {\r
//\r
- // Reset the port\r
+ // Attempt to use this configuration\r
//\r
- Status = pPort->pfnConfigure ( pPort->pProtocol.v, NULL );\r
+ Status = pPort->pfnConfigure ( pPort->pProtocol.v, pConfigData );\r
if ( EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_ERROR | DEBUG_BIND,\r
- "ERROR - Port 0x%08x failed configuration reset, Status: %r\r\n",\r
+ DEBUG (( DEBUG_WARN | DEBUG_BIND,\r
+ "WARNING - Port 0x%08x failed configuration, Status: %r\r\n",\r
pPort,\r
Status ));\r
- ASSERT ( EFI_SUCCESS == Status );\r
+ pPort->pSocket->errno = ErrnoValue;\r
+ }\r
+ else {\r
+ //\r
+ // Reset the port\r
+ //\r
+ Status = pPort->pfnConfigure ( pPort->pProtocol.v, NULL );\r
+ if ( EFI_ERROR ( Status )) {\r
+ DEBUG (( DEBUG_ERROR | DEBUG_BIND,\r
+ "ERROR - Port 0x%08x failed configuration reset, Status: %r\r\n",\r
+ pPort,\r
+ Status ));\r
+ ASSERT ( EFI_SUCCESS == Status );\r
+ }\r
}\r
}\r
\r
connection with the specified remote system. This routine\r
is designed to be polled by the connect routine for completion\r
of the network connection.\r
- \r
+\r
@param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL structure.\r
\r
@param [in] pSockAddr Network address of the remote system.\r
- \r
+\r
@param [in] SockAddrLength Length in bytes of the network address.\r
- \r
+\r
@param [out] pErrno Address to receive the errno value upon completion.\r
- \r
+\r
@retval EFI_SUCCESS The connection was successfully established.\r
@retval EFI_NOT_READY The connection is in progress, call this routine again.\r
@retval Others The connection attempt failed.\r
ESL_SOCKET * pSocket;\r
EFI_STATUS Status;\r
EFI_TPL TplPrevious;\r
- \r
+\r
DEBUG (( DEBUG_CONNECT, "Entering SocketConnect\r\n" ));\r
\r
//\r
break;\r
\r
case SOCKET_STATE_CONNECTING:\r
+ //\r
+ // Poll the network adapter\r
+ //\r
+ EslSocketRxPoll ( pSocket );\r
+\r
//\r
// Poll for connection completion\r
//\r
// Set the next state if connected\r
//\r
if ( EFI_NOT_READY != Status ) {\r
- if ( !EFI_ERROR ( Status )) {\r
- pSocket->State = SOCKET_STATE_CONNECTED;\r
-\r
- //\r
- // Start the receive operations\r
- //\r
- EslSocketRxStart ( pSocket->pPortList );\r
- }\r
- else {\r
+ if ( EFI_ERROR ( Status )) {\r
pSocket->State = SOCKET_STATE_BOUND;\r
}\r
}\r
\r
case SOCKET_STATE_CONNECTED:\r
//\r
- // Already connected\r
+ // Connected\r
//\r
- pSocket->errno = EISCONN;\r
- Status = EFI_ALREADY_STARTED;\r
+ Status = EFI_SUCCESS;\r
break;\r
}\r
\r
}\r
\r
\r
+/**\r
+ Free the socket.\r
+\r
+ This routine frees the socket structure and handle resources.\r
+\r
+ The ::close routine calls EslServiceFreeProtocol which then calls\r
+ this routine to free the socket context structure and close the\r
+ handle.\r
+\r
+ @param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL structure.\r
+\r
+ @param [out] pErrno Address to receive the errno value upon completion.\r
+\r
+ @retval EFI_SUCCESS The socket resources were returned successfully.\r
+\r
+ **/\r
+EFI_STATUS\r
+EslSocketFree (\r
+ IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+ IN int * pErrno\r
+ )\r
+{\r
+ EFI_HANDLE ChildHandle;\r
+ int errno;\r
+ ESL_LAYER * pLayer;\r
+ ESL_SOCKET * pSocket;\r
+ ESL_SOCKET * pSocketPrevious;\r
+ EFI_STATUS Status;\r
+ EFI_TPL TplPrevious;\r
+\r
+ DBG_ENTER ( );\r
+\r
+ //\r
+ // Assume failure\r
+ //\r
+ errno = EIO;\r
+ pSocket = NULL;\r
+ Status = EFI_INVALID_PARAMETER;\r
+\r
+ //\r
+ // Validate the socket\r
+ //\r
+ pLayer = &mEslLayer;\r
+ if ( NULL != pSocketProtocol ) {\r
+ pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );\r
+\r
+ //\r
+ // Synchronize with the socket layer\r
+ //\r
+ RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
+\r
+ //\r
+ // Walk the socket list\r
+ //\r
+ pSocketPrevious = pLayer->pSocketList;\r
+ if ( NULL != pSocketPrevious ) {\r
+ if ( pSocket == pSocketPrevious ) {\r
+ //\r
+ // Remove the socket from the head of the list\r
+ //\r
+ pLayer->pSocketList = pSocket->pNext;\r
+ }\r
+ else {\r
+ //\r
+ // Find the socket in the middle of the list\r
+ //\r
+ while (( NULL != pSocketPrevious )\r
+ && ( pSocket != pSocketPrevious->pNext )) {\r
+ //\r
+ // Set the next socket\r
+ //\r
+ pSocketPrevious = pSocketPrevious->pNext;\r
+ }\r
+ if ( NULL != pSocketPrevious ) {\r
+ //\r
+ // Remove the socket from the middle of the list\r
+ //\r
+ pSocketPrevious = pSocket->pNext;\r
+ }\r
+ }\r
+ }\r
+ else {\r
+ DEBUG (( DEBUG_ERROR | DEBUG_POOL,\r
+ "ERROR - Socket list is empty!\r\n" ));\r
+ }\r
+\r
+ //\r
+ // Release the socket layer synchronization\r
+ //\r
+ RESTORE_TPL ( TplPrevious );\r
+\r
+ //\r
+ // Determine if the socket was found\r
+ //\r
+ if ( NULL != pSocketPrevious ) {\r
+ pSocket->pNext = NULL;\r
+\r
+ //\r
+ // Remove the socket protocol\r
+ //\r
+ ChildHandle = pSocket->SocketProtocol.SocketHandle;\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ ChildHandle,\r
+ &gEfiSocketProtocolGuid,\r
+ &pSocket->SocketProtocol,\r
+ NULL );\r
+ if ( !EFI_ERROR ( Status )) {\r
+ DEBUG (( DEBUG_POOL | DEBUG_INFO,\r
+ "Removed: gEfiSocketProtocolGuid from 0x%08x\r\n",\r
+ ChildHandle ));\r
+\r
+ //\r
+ // Free the socket structure\r
+ //\r
+ Status = gBS->FreePool ( pSocket );\r
+ if ( !EFI_ERROR ( Status )) {\r
+ DEBUG (( DEBUG_POOL,\r
+ "0x%08x: Free pSocket, %d bytes\r\n",\r
+ pSocket,\r
+ sizeof ( *pSocket )));\r
+ errno = 0;\r
+ }\r
+ else {\r
+ DEBUG (( DEBUG_ERROR | DEBUG_POOL,\r
+ "ERROR - Failed to free pSocket 0x%08x, Status: %r\r\n",\r
+ pSocket,\r
+ Status ));\r
+ }\r
+ }\r
+ else {\r
+ DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INFO,\r
+ "ERROR - Failed to remove gEfiSocketProtocolGuid from 0x%08x, Status: %r\r\n",\r
+ ChildHandle,\r
+ Status ));\r
+ }\r
+ }\r
+ else {\r
+ DEBUG (( DEBUG_ERROR | DEBUG_INFO,\r
+ "ERROR - The socket was not in the socket list!\r\n" ));\r
+ Status = EFI_NOT_FOUND;\r
+ }\r
+ }\r
+ else {\r
+ DEBUG (( DEBUG_ERROR,\r
+ "ERROR - Invalid parameter pSocketProtocol is NULL\r\n" ));\r
+ }\r
+\r
+ //\r
+ // Return the errno value if possible\r
+ //\r
+ if ( NULL != pErrno ) {\r
+ *pErrno = errno;\r
+ }\r
+\r
+ //\r
+ // Return the operation status\r
+ //\r
+ DBG_EXIT_STATUS ( Status );\r
+ return Status;\r
+}\r
+\r
+\r
/**\r
Get the local address.\r
\r
address associated with the local host connection point.\r
\r
@param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL structure.\r
- \r
+\r
@param [out] pAddress Network address to receive the local system address\r
\r
@param [in,out] pAddressLength Length of the local network address structure\r
ESL_SOCKET * pSocket;\r
EFI_STATUS Status;\r
EFI_TPL TplPrevious;\r
- \r
+\r
DBG_ENTER ( );\r
- \r
+\r
//\r
// Assume success\r
//\r
Status = EFI_SUCCESS;\r
- \r
+\r
//\r
// Validate the socket\r
//\r
// Verify the address length\r
//\r
LengthInBytes = pSocket->pApi->AddressLength;\r
- if (( LengthInBytes <= *pAddressLength ) \r
+ if (( LengthInBytes <= *pAddressLength )\r
&& ( 255 >= LengthInBytes )) {\r
//\r
// Return the local address and address length\r
pSocket->errno = ENOTCONN;\r
Status = EFI_NOT_STARTED;\r
}\r
- \r
+\r
//\r
// Release the socket layer synchronization\r
//\r
pSocket->errno = EADDRNOTAVAIL;\r
}\r
}\r
- \r
+\r
//\r
// Return the operation status\r
//\r
address of the remote connection point.\r
\r
@param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL structure.\r
- \r
+\r
@param [out] pAddress Network address to receive the remote system address\r
\r
@param [in,out] pAddressLength Length of the remote network address structure\r
ESL_SOCKET * pSocket;\r
EFI_STATUS Status;\r
EFI_TPL TplPrevious;\r
- \r
+\r
DBG_ENTER ( );\r
- \r
+\r
//\r
// Assume success\r
//\r
Status = EFI_SUCCESS;\r
- \r
+\r
//\r
// Validate the socket\r
//\r
pOptionData = (CONST UINT8 *)&pSocket->RxTimeout;\r
LengthInBytes = sizeof ( pSocket->RxTimeout );\r
break;\r
- \r
+\r
case SO_RCVBUF:\r
//\r
// Return the maximum receive buffer size\r
pOptionData = (UINT8 *)&pSocket->bReUseAddr;\r
LengthInBytes = sizeof ( pSocket->bReUseAddr );\r
break;\r
- \r
+\r
case SO_SNDBUF:\r
//\r
// Return the maximum transmit buffer size\r
UINT8 * pOptionData;\r
ESL_SOCKET * pSocket;\r
EFI_STATUS Status;\r
- \r
+\r
DBG_ENTER ( );\r
- \r
+\r
//\r
// Assume failure\r
//\r
errno = ENOPROTOOPT;\r
Status = EFI_INVALID_PARAMETER;\r
break;\r
- \r
+\r
case SOL_SOCKET:\r
switch ( OptionName ) {\r
default:\r
DBG_ENTER ( );\r
\r
//\r
- // Allocate a packet structure\r
+ // Free a packet structure\r
//\r
LengthInBytes = pPacket->PacketSize;\r
Status = gBS->FreePool ( pPacket );\r
// Synchronize with the socket layer\r
//\r
RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
- \r
+\r
//\r
// Increase the network performance by extending the\r
// polling (idle) loop down into the LAN driver\r
//\r
EslSocketRxPoll ( pSocket );\r
- \r
+\r
//\r
// Release the socket layer synchronization\r
//\r
<li>::EslTcp4ConnectComplete - Connection failure and reducing the port list to a single port</li>\r
</ul>\r
See the \ref PortCloseStateMachine section.\r
- \r
+\r
@param [in] pPort Address of an ::ESL_PORT structure.\r
\r
@retval EFI_SUCCESS The port is closed\r
CONST ESL_SOCKET_BINDING * pSocketBinding;\r
ESL_SOCKET * pSocket;\r
EFI_STATUS Status;\r
- \r
+\r
DBG_ENTER ( );\r
\r
//\r
::recv and ::read are layered on top of ::recvfrom.\r
\r
@param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL structure.\r
- \r
+\r
@param [in] Flags Message control flags\r
- \r
+\r
@param [in] BufferLength Length of the the buffer\r
- \r
+\r
@param [in] pBuffer Address of a buffer to receive the data.\r
- \r
+\r
@param [in] pDataLength Number of received data bytes in the buffer.\r
\r
@param [out] pAddress Network address to receive the remote system address\r
pRemoteAddress->sa_family = pSocket->pApi->AddressFamily;\r
pRemoteAddress->sa_len = (UINT8)pSocket->pApi->AddressLength;\r
}\r
- \r
+\r
//\r
// Synchronize with the socket layer\r
//\r
}\r
}\r
\r
- \r
+\r
}\r
else {\r
//\r
// pPort->pRxActive\r
// |\r
// V\r
- // +-------------+ +-------------+ +-------------+ \r
+ // +-------------+ +-------------+ +-------------+\r
// Active | ESL_IO_MGMT |-->| ESL_IO_MGMT |-->| ESL_IO_MGMT |--> NULL\r
- // +-------------+ +-------------+ +-------------+ \r
+ // +-------------+ +-------------+ +-------------+\r
//\r
- // +-------------+ +-------------+ +-------------+ \r
+ // +-------------+ +-------------+ +-------------+\r
// Free | ESL_IO_MGMT |-->| ESL_IO_MGMT |-->| ESL_IO_MGMT |--> NULL\r
- // +-------------+ +-------------+ +-------------+ \r
+ // +-------------+ +-------------+ +-------------+\r
// ^\r
// |\r
// pPort->pRxFree\r
// pRxOobPacketListHead pRxOobPacketListTail\r
// | |\r
// V V\r
- // +------------+ +------------+ +------------+ \r
+ // +------------+ +------------+ +------------+\r
// Urgent Data | ESL_PACKET |-->| ESL_PACKET |-->| ESL_PACKET |--> NULL\r
- // +------------+ +------------+ +------------+ \r
+ // +------------+ +------------+ +------------+\r
//\r
- // +------------+ +------------+ +------------+ \r
+ // +------------+ +------------+ +------------+\r
// Normal Data | ESL_PACKET |-->| ESL_PACKET |-->| ESL_PACKET |--> NULL\r
- // +------------+ +------------+ +------------+ \r
+ // +------------+ +------------+ +------------+\r
// ^ ^\r
// | |\r
// pRxPacketListHead pRxPacketListTail\r
<ul>\r
<li>::EslIp4Receive to restart the receive engine to release flow control.</li>\r
<li>::EslIp4RxComplete to continue the operation of the receive engine if flow control is not being applied.</li>\r
- <li>::EslIp4SocketIsConfigured to start the recevie engine for the new socket.</li>\r
+ <li>::EslIp4SocketIsConfigured to start the receive engine for the new socket.</li>\r
<li>::EslTcp4ListenComplete to start the recevie engine for the new socket.</li>\r
<li>::EslTcp4Receive to restart the receive engine to release flow control.</li>\r
<li>::EslTcp4RxComplete to continue the operation of the receive engine if flow control is not being applied.</li>\r
// Allocate the receive control structure\r
//\r
pPort->pRxFree = pIo->pNext;\r
- \r
+\r
//\r
// Mark this receive as pending\r
//\r
pIo->pNext = pPort->pRxActive;\r
pPort->pRxActive = pIo;\r
- \r
+\r
}\r
else {\r
DEBUG (( DEBUG_RX | DEBUG_INFO,\r
operations on the socket.\r
\r
@param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL structure.\r
- \r
+\r
@param [in] How Which operations to stop\r
- \r
+\r
@param [out] pErrno Address to receive the errno value upon completion.\r
\r
@retval EFI_SUCCESS - Socket operations successfully shutdown\r
ESL_SOCKET * pSocket;\r
EFI_STATUS Status;\r
EFI_TPL TplPrevious;\r
- \r
+\r
DBG_ENTER ( );\r
- \r
+\r
//\r
// Assume success\r
//\r
system. Note that ::send and ::write are layered on top of ::sendto.\r
\r
@param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL structure.\r
- \r
+\r
@param [in] Flags Message control flags\r
- \r
+\r
@param [in] BufferLength Length of the the buffer\r
- \r
+\r
@param [in] pBuffer Address of a buffer containing the data to send\r
- \r
+\r
@param [in] pDataLength Address to receive the number of data bytes sent\r
\r
@param [in] pAddress Network address of the remote system address\r
// *ppQueueHead: pSocket->pRxPacketListHead or pSocket->pRxOobPacketListHead\r
// |\r
// V\r
- // +------------+ +------------+ +------------+ \r
+ // +------------+ +------------+ +------------+\r
// Data | ESL_PACKET |-->| ESL_PACKET |-->| ESL_PACKET |--> NULL\r
- // +------------+ +------------+ +------------+ \r
+ // +------------+ +------------+ +------------+\r
// ^\r
// |\r
// *ppQueueTail: pSocket->pRxPacketListTail or pSocket->pRxOobPacketListTail\r
pIo->pPacket = pPacket;\r
\r
//\r
- // +-------------+ +-------------+ +-------------+ \r
+ // +-------------+ +-------------+ +-------------+\r
// Free | ESL_IO_MGMT |-->| ESL_IO_MGMT |-->| ESL_IO_MGMT |--> NULL\r
- // +-------------+ +-------------+ +-------------+ \r
+ // +-------------+ +-------------+ +-------------+\r
// ^\r
// |\r
// *ppFree: pPort->pTxFree or pTxOobFree\r
// Remove the IO structure from the queue\r
//\r
*ppFree = pIo->pNext;\r
- \r
+\r
//\r
// *ppActive: pPort->pTxActive or pTxOobActive\r
// |\r
// V\r
- // +-------------+ +-------------+ +-------------+ \r
+ // +-------------+ +-------------+ +-------------+\r
// Active | ESL_IO_MGMT |-->| ESL_IO_MGMT |-->| ESL_IO_MGMT |--> NULL\r
- // +-------------+ +-------------+ +-------------+ \r
+ // +-------------+ +-------------+ +-------------+\r
//\r
//\r
// Mark this packet as active\r
*ppActive = pIo;\r
}\r
else {\r
+ //\r
+ // Display the transmit error\r
+ //\r
+ DEBUG (( DEBUG_TX | DEBUG_INFO,\r
+ "0x%08x, 0x%08x: pIo, pPacket transmit failure: %r\r\n",\r
+ pIo,\r
+ pPacket,\r
+ Status ));\r
if ( EFI_SUCCESS == pSocket->TxError ) {\r
pSocket->TxError = Status;\r
}\r
\r
+ //\r
+ // Free the IO structure\r
+ //\r
+ pIo->pNext = *ppFree;\r
+ *ppFree = pIo;\r
+\r
//\r
// Discard the transmit buffer\r
//\r