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
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
\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
<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
*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