IN int * pErrno\r
)\r
{\r
- EFI_SERVICE_BINDING_PROTOCOL * pServiceBinding;\r
EFI_STATUS Status;\r
\r
//\r
}\r
if ( !EFI_ERROR ( Status )) {\r
//\r
- // Locate the socket protocol\r
+ // Release the socket resources\r
//\r
- Status = gBS->LocateProtocol ( &gEfiSocketServiceBindingProtocolGuid,\r
- NULL,\r
- (VOID **) &pServiceBinding );\r
- if ( !EFI_ERROR ( Status )) {\r
- //\r
- // Release the handle\r
- //\r
- Status = pServiceBinding->DestroyChild ( pServiceBinding,\r
- pSocketProtocol->SocketHandle );\r
- }\r
- if ( EFI_ERROR ( Status )) {\r
- *pErrno = EIO;\r
- }\r
+ *pErrno = EslServiceFreeProtocol ( pSocketProtocol );\r
}\r
else {\r
DEBUG (( DEBUG_ERROR,\r
)\r
{\r
ESL_LAYER * pLayer;\r
- ESL_SOCKET * pSocket;\r
- ESL_SOCKET * pSocketPrevious;\r
EFI_SOCKET_PROTOCOL * pSocketProtocol;\r
EFI_STATUS Status;\r
- EFI_TPL TplPrevious;\r
\r
DBG_ENTER ( );\r
\r
EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
);\r
if ( !EFI_ERROR ( Status )) {\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
+ // Free the socket resources\r
//\r
- if ( NULL != pSocketPrevious ) {\r
- pSocket->pNext = NULL;\r
-\r
- //\r
- // Remove the socket protocol\r
- //\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
- }\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
+ Status = EslSocketFree ( pSocketProtocol, NULL );\r
}\r
else {\r
DEBUG (( DEBUG_ERROR,\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
OUT size_t * pDataLength\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
/**\r
Free the ESL_IO_MGMT event and structure\r
\r
};\r
\r
\r
+/**\r
+ Free the socket resources\r
+\r
+ This releases the socket resources allocated by calling\r
+ EslServiceGetProtocol.\r
+\r
+ This routine is called from the ::close routine in BsdSocketLib\r
+ to release the socket resources.\r
+\r
+ @param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL\r
+ structure\r
+\r
+ @return Value for ::errno, zero (0) indicates success.\r
+\r
+ **/\r
+int\r
+EslServiceFreeProtocol (\r
+ IN EFI_SOCKET_PROTOCOL * pSocketProtocol\r
+ )\r
+{\r
+ int RetVal;\r
+\r
+ //\r
+ // Release the socket resources\r
+ //\r
+ EslSocketFree ( pSocketProtocol, &RetVal );\r
+\r
+ //\r
+ // Return the operation status\r
+ //\r
+ return RetVal;\r
+}\r
+\r
+\r
/**\r
Connect to the EFI socket library\r
\r
socklen_t * address_len\r
);\r
\r
+/**\r
+ Free the socket resources\r
+\r
+ This releases the socket resources allocated by calling\r
+ EslServiceGetProtocol.\r
+\r
+ This routine is called from the ::close routine in BsdSocketLib\r
+ to release the socket resources.\r
+\r
+ @param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL\r
+ structure\r
+\r
+ @return Value for ::errno, zero (0) indicates success.\r
+\r
+ **/\r
+int\r
+EslServiceFreeProtocol (\r
+ IN EFI_SOCKET_PROTOCOL * pSocketProtocol\r
+ );\r
+\r
/**\r
Connect to the EFI socket library\r
\r
#include <Protocol/ServiceBinding.h>\r
\r
\r
+/**\r
+ Free the socket resources\r
+\r
+ This releases the socket resources allocated by calling\r
+ EslServiceGetProtocol.\r
+\r
+ This routine is called from the ::close routine in BsdSocketLib\r
+ to release the socket resources.\r
+\r
+ @param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL\r
+ structure\r
+\r
+ @return Value for ::errno, zero (0) indicates success.\r
+\r
+ **/\r
+int\r
+EslServiceFreeProtocol (\r
+ IN EFI_SOCKET_PROTOCOL * pSocketProtocol\r
+ )\r
+{\r
+ EFI_SERVICE_BINDING_PROTOCOL * pServiceBinding;\r
+ int RetVal;\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Assume success\r
+ //\r
+ RetVal = 0;\r
+\r
+ //\r
+ // Locate the socket protocol\r
+ //\r
+ Status = gBS->LocateProtocol ( &gEfiSocketServiceBindingProtocolGuid,\r
+ NULL,\r
+ (VOID **) &pServiceBinding );\r
+ if ( !EFI_ERROR ( Status )) {\r
+ //\r
+ // Release the handle\r
+ //\r
+ Status = pServiceBinding->DestroyChild ( pServiceBinding,\r
+ pSocketProtocol->SocketHandle );\r
+ }\r
+ if ( EFI_ERROR ( Status )) {\r
+ RetVal = EIO;\r
+ }\r
+\r
+ //\r
+ // Return the operation status\r
+ //\r
+ return RetVal;\r
+}\r
+\r
+\r
/**\r
Connect to the EFI socket library\r
\r