4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/** @file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Implement the socket support for the socket layer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Socket States:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Bound - pSocket->PortList is not NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Listen - AcceptWait event is not NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Copyright (c) 2011, Intel Corporation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync All rights reserved. This program and the accompanying materials
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync are licensed and made available under the terms and conditions of the BSD License
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync which accompanies this distribution. The full text of the license may be found at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync http://opensource.org/licenses/bsd-license.php
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync \section DataStructures Data Structures
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <code><pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +-------------+ +-------------+ +-------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Service Lists | ::ESL_SERVICE |-->| ESL_SERVICE |-->| ESL_SERVICE |--> NULL (pNext)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +-------------+ +-------------+ +-------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ^ | (pPortList) |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pUdp4List ^ | pTcp4List | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | | | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ^ | | | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIp4List | | | | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +---------------+ | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | ::ESL_LAYER | ::mEslLayer | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +---------------+ | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | (pSocketList) | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Socket List V V V
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +-------------+ +-------------+ +-------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | ::ESL_SOCKET |-->| ::ESL_PORT |-->| ESL_PORT |--> NULL (pLinkSocket)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +-------------+ +-------------+ +-------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | | V
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync V V NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +-------------+ +-------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | ESL_SOCKET |-->| ESL_PORT |--> NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +-------------+ +-------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | | | | | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync V | | | | V
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL | | | | NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (pNext) | | | | (pLinkService)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | | | | pRxPacketListHead
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | | | `-----------------------------------------------.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | | | pRxOobPacketListHead |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | | `--------------------------------. |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | | pTxPacketListHead | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | `---------------. | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pTxOobPacketListHead | | | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync V V V V
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +------------+ +------------+ +------------+ +------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | ::ESL_PACKET | | ESL_PACKET | | ESL_PACKET | | ESL_PACKET |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +------------+ +------------+ +------------+ +------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | | | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync V V V V
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +------------+ +------------+ +------------+ +------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | ESL_PACKET | | ESL_PACKET | | ESL_PACKET | | ESL_PACKET |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +------------+ +------------+ +------------+ +------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | | | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync V V V V
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL NULL NULL NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (pNext)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync </pre></code>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ::mEslLayer is the one and only ::ESL_LAYER structure. It connects directly or
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync indirectly to the other data structures. The ESL_LAYER structure has a unique
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync service list for each of the network protocol interfaces.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ::ESL_SERVICE manages the network interfaces for a given transport type (IP4, TCP4, UDP4, etc.)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ::ESL_SOCKET manages the activity for a single socket instance. As such, it contains
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the ::EFI_SOCKET_PROTOCOL structure which the BSD socket library uses as the object
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync reference and the API into the EFI socket library.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ::ESL_PORT manages the connection with a single instance of the lower layer network.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This structure is the socket equivalent of an IP connection or a TCP or UDP port.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ::ESL_PACKET buffers data for transmit and receive. There are four queues connected
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync to the ::ESL_SOCKET that manage the data:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <ul>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>ESL_SOCKET::pRxPacketListHead - Normal (low) priority receive data</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>ESL_SOCKET::pRxOobPacketListHead - High (out-of-band or urgent) priority receive data</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>ESL_SOCKET::pTxPacketListHead - Normal (low) priority transmit data</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>ESL_SOCKET::pTxOobPacketListHead - High (out-of-band or urgent) priority transmit data</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync </ul>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The selection of the transmit queue is controlled by the MSG_OOB flag on the transmit
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync request as well as the socket option SO_OOBINLINE. The receive queue is selected by
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the URGENT data flag for TCP and the setting of the socket option SO_OOBINLINE.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Data structure synchronization is done by raising TPL to TPL_SOCKET. Modifying
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync critical elements within the data structures must be done at this TPL. TPL is then
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync restored to the previous level. Note that the code verifies that all callbacks are
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync entering at TPL_SOCKETS for proper data structure synchronization.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync \section PortCloseStateMachine Port Close State Machine
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The port close state machine walks the port through the necessary
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync states to stop activity on the port and get it into a state where
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the resources may be released. The state machine consists of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync following arcs and states:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <code><pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +--------------------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | Open |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +--------------------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | ::EslSocketPortCloseStart
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync V
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +--------------------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | PORT_STATE_CLOSE_STARTED |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +--------------------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | ::EslSocketPortCloseTxDone
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync V
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +--------------------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | PORT_STATE_CLOSE_TX_DONE |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +--------------------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | ::EslSocketPortCloseComplete
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync V
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +--------------------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | PORT_STATE_CLOSE_DONE |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +--------------------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | ::EslSocketPortCloseRxDone
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync V
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +--------------------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | PORT_STATE_CLOSE_RX_DONE |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +--------------------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | ::EslSocketPortClose
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync V
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +--------------------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | Closed |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +--------------------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync </pre></code>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <ul>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>Arc: ::EslSocketPortCloseStart - Marks the port as closing and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync initiates the port close operation</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>State: PORT_STATE_CLOSE_STARTED</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>Arc: ::EslSocketPortCloseTxDone - Waits until all of the transmit
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync operations to complete. After all of the transmits are complete,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync this routine initiates the network specific close operation by calling
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync through ESL_PROTOCOL_API::pfnPortCloseOp. One such routine is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ::EslTcp4PortCloseOp.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync </li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>State: PORT_STATE_CLOSE_TX_DONE</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>Arc: ::EslSocketPortCloseComplete - Called when the close operation is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync complete. After the transition to PORT_STATE_CLOSE_DONE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync this routine calls ::EslSocketRxCancel to abort the pending receive operations.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync </li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>State: PORT_STATE_CLOSE_DONE</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>Arc: ::EslSocketPortCloseRxDone - Waits until all of the receive
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync operation have been cancelled. After the transition to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PORT_STATE_CLOSE_RX_DONE, this routine calls ::EslSocketPortClose.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync </li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>State: PORT_STATE_CLOSE_RX_DONE</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>Arc: ::EslSocketPortClose - This routine discards any receive buffers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync using a network specific support routine via ESL_PROTOCOL_API::pfnPacketFree.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine then releases the port resources allocated by ::EslSocketPortAllocate
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync and calls the network specific port close routine (e.g. ::EslTcp4PortClose)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync via ESL_PROTOCOL_API::pfnPortClose to release any network specific resources.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync </li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync </ul>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync \section ReceiveEngine Receive Engine
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The receive path accepts data from the network and queues (buffers) it for the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync application. Flow control is applied once a maximum amount of buffering is reached
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync and is released when the buffer usage drops below that limit. Eventually the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync application requests data from the socket which removes entries from the queue and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync returns the data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The receive engine is the state machine which reads data from the network and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fills the queue with received packets. The receive engine uses two data structures
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync to manage the network receive opeations and the buffers.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync At a high level, the ::ESL_IO_MGMT structures are managing the tokens and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync events for the interface to the UEFI network stack. The ::ESL_PACKET
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync structures are managing the receive data buffers. The receive engine
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync connects these two structures in the network specific receive completion
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync routines.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<code><pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +------------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | ::ESL_PORT |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +------------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | ::ESL_IO_MGMT |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +------------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | ESL_IO_MGMT |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +------------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync . .
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync . ESL_IO_MGMT .
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync . .
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +------------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</pre></code>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The ::ESL_IO_MGMT structures are allocated as part of the ::ESL_PORT structure in
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ::EslSocketPortAllocate. The ESL_IO_MGMT structures are separated and placed on
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the free list by calling ::EslSocketIoInit. The ESL_IO_MGMT structure contains
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the network layer specific receive completion token and event. The receive engine
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync is eventually shutdown by ::EslSocketPortCloseTxDone and the resources in these
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync structures are released in ::EslSocketPortClose by a call to ::EslSocketIoFree.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<code><pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->pRxActive
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync V
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +-------------+ +-------------+ +-------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Active | ESL_IO_MGMT |-->| ESL_IO_MGMT |-->| ESL_IO_MGMT |--> NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +-------------+ +-------------+ +-------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +-------------+ +-------------+ +-------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Free | ESL_IO_MGMT |-->| ESL_IO_MGMT |-->| ESL_IO_MGMT |--> NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +-------------+ +-------------+ +-------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ^
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->pRxFree
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</pre></code>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The receive engine is started by calling ::EslSocketRxStart. Flow control pauses
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the receive engine by stopping the calls to EslSocketRxStart when the amount of
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync receive data waiting for the application meets or exceeds MAX_RX_DATA. After
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the application reads enough data that the amount of buffering drops below this
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync limit, the calls to EslSockeRxStart continue which releases the flow control.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Receive flow control is applied when the port is created, since no receive
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync operation are pending to the low layer network driver. The flow control gets
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync released when the low layer network port is configured or the first receive
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync operation is posted. Flow control remains in the released state until the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync maximum buffer space is consumed. During this time, ::EslSocketRxComplete
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync calls ::EslSocketRxStart. Flow control is applied in EslSocketRxComplete
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync by skipping the call to EslSocketRxStart. Flow control is eventually
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync released in ::EslSocketReceive when the buffer space drops below the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync maximum amount causing EslSocketReceive to call EslSocketRxStart.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<code><pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +------------+ +------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync High .----->| ESL_PACKET |-->| ESL_PACKET |--> NULL (pNext)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Priority | +------------+ +------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | pRxOobPacketListHead
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | ::ESL_SOCKET |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | pRxPacketListHead
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Low |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Priority | +------------+ +------------+ +------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync `----->| ::ESL_PACKET |-->| ESL_PACKET |-->| ESL_PACKET |--> NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +------------+ +------------+ +------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</pre></code>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ::EslSocketRxStart connects an ::ESL_PACKET structure to the ::ESL_IO_MGMT structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync and then calls the network layer to start the receive operation. Upon
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync receive completion, ::EslSocketRxComplete breaks the connection between these
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync structrues and places the ESL_IO_MGMT structure onto the ESL_PORT::pRxFree list to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync make token and event available for another receive operation. EslSocketRxComplete
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync then queues the ESL_PACKET structure (data packet) to either the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SOCKET::pRxOobPacketListTail or ESL_SOCKET::pRxPacketListTail depending on
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync whether urgent or normal data was received. Finally ::EslSocketRxComplete attempts
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync to start another receive operation.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<code><pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Setup for IP4 and UDP4
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +--------------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | ESL_IO_MGMT |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | +---------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | | Token |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | | RxData --> NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +----+---------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync V
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +--------------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | ESL_PACKET |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | +---------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | | pRxData --> NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +----+---------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Completion for IP4 and UDP4
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +--------------------+ +----------------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | ESL_IO_MGMT | | Data Buffer |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | | | (Driver owned) |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | +---------------+ +----------------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | | Token | ^
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | | Rx Event | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | | | +----------------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | | RxData --> | EFI_IP4_RECEIVE_DATA |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +----+---------------+ | (Driver owned) |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | +----------------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync V ^
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +--------------------+ .
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | ESL_PACKET | .
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | | .
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | +---------------+ .
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | | pRxData --> NULL .......
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +----+---------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Setup and completion for TCP4
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +--------------------+ +--------------------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | ESL_IO_MGMT |-->| ESL_PACKET |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | | | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | +---------------+ +----------------------+ |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | | Token | | EFI_IP4_RECEIVE_DATA | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | | RxData --> | | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | | | +----------------------+---+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | | Event | | Data Buffer |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +----+---------------+ | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +--------------------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</pre></code>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync To minimize the number of buffer copies, the data is not copied until the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync application makes a receive call. At this point socket performs a single copy
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync in the receive path to move the data from the buffer filled by the network layer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync into the application's buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The IP4 and UDP4 drivers go one step further to reduce buffer copies. They
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync allow the socket layer to hold on to the actual receive buffer until the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync application has performed a receive operation or closes the socket. Both
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync of theses operations return the buffer to the lower layer network driver
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync by calling ESL_PROTOCOL_API::pfnPacketFree.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync When a socket application wants to receive data it indirectly calls
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ::EslSocketReceive to remove data from one of the receive data queues. This routine
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync removes the next available packet from ESL_SOCKET::pRxOobPacketListHead or
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SOCKET::pRxPacketListHead and copies the data from the packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync into the application's buffer. For SOCK_STREAM sockets, if the packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync contains more data then the ESL_PACKET structures remains at the head of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync receive queue for the next application receive
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync operation. For SOCK_DGRAM, SOCK_RAW and SOCK_SEQ_PACKET sockets, the ::ESL_PACKET
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync structure is removed from the head of the receive queue and any remaining data is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync discarded as the packet is placed on the free queue.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync During socket layer shutdown, ::EslSocketShutdown calls ::EslSocketRxCancel to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync cancel any pending receive operations. EslSocketRxCancel calls the network specific
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync cancel routine using ESL_PORT::pfnRxCancel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync \section TransmitEngine Transmit Engine
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Application calls to ::EslSocketTransmit cause data to be copied into a buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The buffer exists as an extension to an ESL_PACKET structure and the structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync is placed at the end of the transmit queue.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<code><pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ppQueueHead: pSocket->pRxPacketListHead or pSocket->pRxOobPacketListHead
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync V
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +------------+ +------------+ +------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Data | ESL_PACKET |-->| ESL_PACKET |-->| ESL_PACKET |--> NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +------------+ +------------+ +------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ^
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ppQueueTail: pSocket->pRxPacketListTail or pSocket->pRxOobPacketListTail
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</pre></code>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync There are actually two transmit queues the normal or low priority queue which is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the default and the urgent or high priority queue which is addressed by specifying
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the MSG_OOB flag during the transmit request. Associated with each queue is a
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync transmit engine which is responsible for sending the data in that queue.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The transmit engine is the state machine which removes entries from the head
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync of the transmit queue and causes the data to be sent over the network.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<code><pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +--------------------+ +--------------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | ESL_IO_MGMT | | ESL_PACKET |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | | | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | +---------------+ +----------------+ |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | | Token | | Buffer Length | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | | TxData --> | Buffer Address | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | | | +----------------+---+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | | Event | | Data Buffer |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +----+---------------+ | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +--------------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</pre></code>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync At a high level, the transmit engine uses a couple of data structures
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync to manage the data flow. The ::ESL_IO_MGMT structures manage the tokens and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync events for the interface to the UEFI network stack. The ::ESL_PACKET
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync structures manage the data buffers that get sent. The transmit
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync engine connects these two structures prior to transmission and disconnects
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync them upon completion.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<code><pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->pTxActive or pTxOobActive
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync V
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +-------------+ +-------------+ +-------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Active | ESL_IO_MGMT |-->| ESL_IO_MGMT |-->| ESL_IO_MGMT |--> NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +-------------+ +-------------+ +-------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +-------------+ +-------------+ +-------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Free | ESL_IO_MGMT |-->| ESL_IO_MGMT |-->| ESL_IO_MGMT |--> NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync +-------------+ +-------------+ +-------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ^
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->pTxFree or pTxOobFree
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</pre></code>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The transmit engine manages multiple transmit operations using the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync active and free lists shown above. ::EslSocketPortAllocate allocates the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ::ESL_IO_MGMT structures as an extension to the ::ESL_PORT structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine places the ESL_IO_MGMT structures on the free list by calling
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ::EslSocketIoInit. During their lifetime, the ESL_IO_MGMT structures
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync will move from the free list to the active list and back again. The
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync active list contains the packets that are actively being processed by
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the UEFI network stack. Eventually the ESL_IO_MGMT structures will be
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync removed from the free list and be deallocated by the EslSocketPortClose
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync routine.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The network specific code calls the ::EslSocketTxStart routine
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync to hand a packet to the network stack. EslSocketTxStart connects
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the transmit packet (::ESL_PACKET) to an ::ESL_IO_MGMT structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync and then queues the result to one of the active lists:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_PORT::pTxActive or ESL_PORT::pTxOobActive. The routine then
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync hands the packet to the network stack.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Upon completion, the network specific TxComplete routine calls
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ::EslSocketTxComplete to disconnect the transmit packet from the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_IO_MGMT structure and frees the ::ESL_PACKET structure by calling
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ::EslSocketPacketFree. The routine places the ::ESL_IO_MGMT structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync into the free list either ESL_PORT::pTxFree or ESL_PORT::pTxOobFree.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EslSocketTxComplete then starts the next transmit operation while
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the socket is active or calls the ::EslSocketPortCloseTxDone routine
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync when the socket is shutting down.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include "Socket.h"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Socket driver connection points
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync List the network stack connection points for the socket driver.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCONST ESL_SOCKET_BINDING cEslSocketBinding[] = {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { L"Ip4",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiIp4ServiceBindingProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiIp4ProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &mEslIp4ServiceGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OFFSET_OF ( ESL_LAYER, pIp4List ),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 4, // RX buffers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 4, // TX buffers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0 }, // TX Oob buffers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { L"Tcp4",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiTcp4ServiceBindingProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiTcp4ProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &mEslTcp4ServiceGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OFFSET_OF ( ESL_LAYER, pTcp4List ),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 4, // RX buffers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 4, // TX buffers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 4 }, // TX Oob buffers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { L"Udp4",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiUdp4ServiceBindingProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiUdp4ProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &mEslUdp4ServiceGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OFFSET_OF ( ESL_LAYER, pUdp4List ),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 4, // RX buffers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 4, // TX buffers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0 } // TX Oob buffers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync};
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCONST UINTN cEslSocketBindingEntries = DIM ( cEslSocketBinding );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync APIs to support the various socket types for the v4 network stack.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCONST ESL_PROTOCOL_API * cEslAfInetApi[] = {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL, // 0
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &cEslTcp4Api, // SOCK_STREAM
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &cEslUdp4Api, // SOCK_DGRAM
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &cEslIp4Api, // SOCK_RAW
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL, // SOCK_RDM
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &cEslTcp4Api // SOCK_SEQPACKET
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync};
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Number of entries in the v4 API array ::cEslAfInetApi.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCONST int cEslAfInetApiSize = DIM ( cEslAfInetApi );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync APIs to support the various socket types for the v6 network stack.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCONST ESL_PROTOCOL_API * cEslAfInet6Api[] = {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL, // 0
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL, // SOCK_STREAM
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL, // SOCK_DGRAM
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL, // SOCK_RAW
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL, // SOCK_RDM
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL // SOCK_SEQPACKET
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync};
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Number of entries in the v6 API array ::cEslAfInet6Api.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCONST int cEslAfInet6ApiSize = DIM ( cEslAfInet6Api );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Global management structure for the socket layer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncESL_LAYER mEslLayer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Initialize an endpoint for network communication.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine initializes the communication endpoint.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The ::socket routine calls this routine indirectly to create
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the communication endpoint.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pSocketProtocol Address of the socket protocol structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] domain Select the family of protocols for the client or server
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync application. See the ::socket documentation for values.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] type Specifies how to make the network connection.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync See the ::socket documentation for values.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] protocol Specifies the lower layer protocol to use.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync See the ::socket documentation for values.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [out] pErrno Address to receive the errno value upon completion.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS - Socket successfully created
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER - Invalid domain value, errno = EAFNOSUPPORT
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER - Invalid type value, errno = EINVAL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER - Invalid protocol value, errno = EINVAL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync **/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocket (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_SOCKET_PROTOCOL * pSocketProtocol,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN int domain,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN int type,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN int protocol,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN int * pErrno
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CONST ESL_PROTOCOL_API * pApi;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CONST ESL_PROTOCOL_API ** ppApiArray;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CONST ESL_PROTOCOL_API ** ppApiArrayEnd;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int ApiArraySize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SOCKET * pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int errno;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Locate the socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the default domain if necessary
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( AF_UNSPEC == domain ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync domain = AF_INET;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Assume success
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errno = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Use break instead of goto
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for ( ; ; ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the domain value
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( AF_INET != domain )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && ( AF_LOCAL != domain )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR | DEBUG_SOCKET,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Invalid domain value\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errno = EAFNOSUPPORT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine the protocol APIs
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ppApiArray = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ApiArraySize = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( AF_INET == domain )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync || ( AF_LOCAL == domain )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ppApiArray = &cEslAfInetApi[0];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ApiArraySize = cEslAfInetApiSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ppApiArray = &cEslAfInet6Api[0];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ApiArraySize = cEslAfInet6ApiSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the default type if necessary
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( 0 == type ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync type = SOCK_STREAM;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the type value
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( type >= ApiArraySize )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync || ( NULL == ppApiArray )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync || ( NULL == ppApiArray[ type ])) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR | DEBUG_SOCKET,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Invalid type value\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The socket type is not supported
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errno = EPROTOTYPE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the default protocol if necessary
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pApi = ppApiArray[ type ];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( 0 == protocol ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync protocol = pApi->DefaultProtocol;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the protocol value
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( pApi->DefaultProtocol != protocol )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && ( SOCK_RAW != type )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Assume that the driver supports this protocol
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ppApiArray = &cEslAfInetApi[0];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ppApiArrayEnd = &ppApiArray [ cEslAfInetApiSize ];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ( ppApiArrayEnd > ppApiArray ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pApi = *ppApiArray;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( protocol == pApi->DefaultProtocol ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ppApiArray += 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( ppApiArrayEnd <= ppApiArray ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify against the IPv6 table
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ppApiArray = &cEslAfInet6Api[0];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ppApiArrayEnd = &ppApiArray [ cEslAfInet6ApiSize ];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ( ppApiArrayEnd > ppApiArray ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pApi = *ppApiArray;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( protocol == pApi->DefaultProtocol ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ppApiArray += 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( ppApiArrayEnd <= ppApiArray ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR | DEBUG_SOCKET,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - The protocol is not supported!\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errno = EPROTONOSUPPORT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The driver does not support this protocol
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR | DEBUG_SOCKET,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - The protocol does not support this socket type!\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errno = EPROTONOSUPPORT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errno = EPROTOTYPE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Save the socket attributes
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->pApi = pApi;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->Domain = domain;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->Type = type;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->Protocol = protocol;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Done
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pErrno ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pErrno = errno;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Accept a network connection.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine calls the network specific layer to remove the next
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync connection from the FIFO.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The ::accept calls this routine to poll for a network
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync connection to the socket. When a connection is available
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync this routine returns the ::EFI_SOCKET_PROTOCOL structure address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync associated with the new socket and the remote network address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if requested.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pSockAddr Address of a buffer to receive the remote
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync network address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in, out] pSockAddrLength Length in bytes of the address buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync On output specifies the length of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync remote network address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [out] ppSocketProtocol Address of a buffer to receive the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ::EFI_SOCKET_PROTOCOL instance
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync associated with the new socket.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [out] pErrno Address to receive the errno value upon completion.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS New connection successfully created
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_READY No connection is available
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync **/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketAccept (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_SOCKET_PROTOCOL * pSocketProtocol,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN struct sockaddr * pSockAddr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT socklen_t * pSockAddrLength,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_SOCKET_PROTOCOL ** ppSocketProtocol,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN int * pErrno
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SOCKET * pNewSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SOCKET * pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TPL TplPrevious;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Assume success
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pNewSocket = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pSocketProtocol ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the API
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pSocket->pApi->pfnAccept ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = ENOTSUP;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the sockaddr
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( NULL != pSockAddr )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && ( NULL == pSockAddrLength )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ACCEPT,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - pSockAddr is NULL!\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EFAULT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Synchronize with the socket layer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RAISE_TPL ( TplPrevious, TPL_SOCKETS );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify that the socket is in the listen state
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( SOCKET_STATE_LISTENING != pSocket->State ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ACCEPT,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Socket is not listening!\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pSocket->pApi->pfnAccept ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Socket does not support listen
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EOPNOTSUPP;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Socket supports listen, but not in listen state
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EINVAL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_NOT_STARTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine if a socket is available
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( 0 == pSocket->FifoDepth ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // No connections available
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine if any ports are available
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pSocket->pPortList ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // No ports available
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_DEVICE_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EINVAL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update the socket state
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->State = SOCKET_STATE_NO_PORTS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Ports are available
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // No connection requests at this time
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_NOT_READY;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EAGAIN;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Attempt to accept the connection and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // get the remote network address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pNewSocket = pSocket->pFifoHead;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ( NULL != pNewSocket );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = pSocket->pApi->pfnAccept ( pNewSocket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSockAddr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSockAddrLength );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Remove the new socket from the list
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->pFifoHead = pNewSocket->pNextConnection;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pSocket->pFifoHead ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->pFifoTail = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Account for this socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->FifoDepth -= 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update the new socket's state
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pNewSocket->State = SOCKET_STATE_CONNECTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pNewSocket->bConfigured = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ACCEPT,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Socket connected\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pNewSocket ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Release the socket layer synchronization
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RESTORE_TPL ( TplPrevious );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the new socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( NULL != ppSocketProtocol )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && ( NULL != pNewSocket )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ppSocketProtocol = &pNewSocket->SocketProtocol;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pErrno ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pSocket ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pErrno = pSocket->errno;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pErrno = ENOTSOCK;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Allocate and initialize a ESL_SOCKET structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This support function allocates an ::ESL_SOCKET structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync and installs a protocol on ChildHandle. If pChildHandle is a
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pointer to NULL, then a new handle is created and returned in
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pChildHandle. If pChildHandle is not a pointer to NULL, then
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the protocol installs on the existing pChildHandle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in, out] pChildHandle Pointer to the handle of the child to create.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If it is NULL, then a new handle is created.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If it is a pointer to an existing UEFI handle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync then the protocol is added to the existing UEFI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync handle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] DebugFlags Flags for debug messages
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in, out] ppSocket The buffer to receive an ::ESL_SOCKET structure address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The protocol was added to ChildHandle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the child
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval other The child handle was not created
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketAllocate (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT EFI_HANDLE * pChildHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN DebugFlags,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT ESL_SOCKET ** ppSocket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN LengthInBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_LAYER * pLayer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SOCKET * pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TPL TplPrevious;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create a socket structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes = sizeof ( *pSocket );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = (ESL_SOCKET *) AllocateZeroPool ( LengthInBytes );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pSocket ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DebugFlags | DEBUG_POOL | DEBUG_INIT,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Allocate pSocket, %d bytes\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Initialize the socket protocol
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->Signature = SOCKET_SIGNATURE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->SocketProtocol.pfnAccept = EslSocketAccept;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->SocketProtocol.pfnBind = EslSocketBind;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->SocketProtocol.pfnClosePoll = EslSocketClosePoll;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->SocketProtocol.pfnCloseStart = EslSocketCloseStart;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->SocketProtocol.pfnConnect = EslSocketConnect;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->SocketProtocol.pfnGetLocal = EslSocketGetLocalAddress;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->SocketProtocol.pfnGetPeer = EslSocketGetPeerAddress;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->SocketProtocol.pfnListen = EslSocketListen;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->SocketProtocol.pfnOptionGet = EslSocketOptionGet;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->SocketProtocol.pfnOptionSet = EslSocketOptionSet;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->SocketProtocol.pfnPoll = EslSocketPoll;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->SocketProtocol.pfnReceive = EslSocketReceive;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->SocketProtocol.pfnShutdown = EslSocketShutdown;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->SocketProtocol.pfnSocket = EslSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->SocketProtocol.pfnTransmit = EslSocketTransmit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->MaxRxBuf = MAX_RX_DATA;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->MaxTxBuf = MAX_TX_DATA;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Install the socket protocol on the specified handle
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->InstallMultipleProtocolInterfaces (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pChildHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiSocketProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &pSocket->SocketProtocol,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DebugFlags | DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "Installed: gEfiSocketProtocolGuid on 0x%08x\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pChildHandle ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->SocketProtocol.SocketHandle = *pChildHandle;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Synchronize with the socket layer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RAISE_TPL ( TplPrevious, TPL_SOCKETS );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Add this socket to the list
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pLayer = &mEslLayer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->pNext = pLayer->pSocketList;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pLayer->pSocketList = pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Release the socket layer synchronization
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RESTORE_TPL ( TplPrevious );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the socket structure address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ppSocket = pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR | DebugFlags | DEBUG_POOL | DEBUG_INIT,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Failed to install gEfiSocketProtocolGuid on 0x%08x, Status: %r\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pChildHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Release the socket if necessary
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->FreePool ( pSocket );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DebugFlags | DEBUG_POOL | DEBUG_INIT,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Free pSocket, %d bytes\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof ( *pSocket )));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Bind a name to a socket.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine calls the network specific layer to save the network
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync address of the local connection point.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The ::bind routine calls this routine to connect a name
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (network address and port) to a socket on the local machine.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pSockAddr Address of a sockaddr structure that contains the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync connection point on the local machine. An IPv4 address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync of INADDR_ANY specifies that the connection is made to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync all of the network stacks on the platform. Specifying a
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync specific IPv4 address restricts the connection to the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync network stack supporting that address. Specifying zero
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for the port causes the network layer to assign a port
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync number from the dynamic range. Specifying a specific
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync port number causes the network layer to use that port.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] SockAddrLength Specifies the length in bytes of the sockaddr structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [out] pErrno Address to receive the errno value upon completion.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS - Socket successfully created
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync **/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketBind (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_SOCKET_PROTOCOL * pSocketProtocol,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN CONST struct sockaddr * pSockAddr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN socklen_t SockAddrLength,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT int * pErrno
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_HANDLE ChildHandle;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 * pBuffer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_PORT * pPort;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SERVICE ** ppServiceListHead;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SOCKET * pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SERVICE * pService;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SERVICE_BINDING_PROTOCOL * pServiceBinding;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TPL TplPrevious;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Assume success
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pSocketProtocol ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the structure pointer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pSockAddr ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_BIND,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - pSockAddr is NULL!\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EFAULT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the local address length
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if ( SockAddrLength < pSocket->pApi->MinimumAddressLength ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_BIND,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Invalid bind name length: %d\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockAddrLength ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EINVAL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the shutdown state
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if ( pSocket->bRxDisable || pSocket->bTxDisable ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_BIND,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Shutdown has been called on socket 0x%08x\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EINVAL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the socket state
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if ( SOCKET_STATE_NOT_CONFIGURED != pSocket->State ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_BIND,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - The socket 0x%08x is already configured!\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EINVAL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_ALREADY_STARTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Synchronize with the socket layer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RAISE_TPL ( TplPrevious, TPL_SOCKETS );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Assume no ports are available
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EADDRNOTAVAIL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Walk the list of services
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pBuffer = (UINT8 *)&mEslLayer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pBuffer = &pBuffer[ pSocket->pApi->ServiceListOffset ];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ppServiceListHead = (ESL_SERVICE **)pBuffer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pService = *ppServiceListHead;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ( NULL != pService ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create the port
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pServiceBinding = pService->pServiceBinding;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ChildHandle = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = pServiceBinding->CreateChild ( pServiceBinding,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &ChildHandle );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_BIND | DEBUG_POOL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: %s port handle created\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ChildHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pService->pSocketBinding->pName ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Open the port
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EslSocketPortAllocate ( pSocket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pService,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ChildHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSockAddr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TRUE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG_BIND,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &pPort );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_BIND | DEBUG_POOL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Failed to open %s port handle, Status: %r\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pService->pSocketBinding->pName,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the next service
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pService = pService->pNext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify that at least one network connection was found
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pSocket->pPortList ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( EADDRNOTAVAIL == pSocket->errno ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_BIND | DEBUG_POOL | DEBUG_INIT,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Socket address is not available!\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( EADDRINUSE == pSocket->errno ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_BIND | DEBUG_POOL | DEBUG_INIT,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Socket address is in use!\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Mark this socket as bound if successful
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->State = SOCKET_STATE_BOUND;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Release the socket layer synchronization
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RESTORE_TPL ( TplPrevious );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pErrno ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pSocket ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pErrno = pSocket->errno;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pErrno = ENOTSOCK;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Test the bind configuration.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pPort Address of the ::ESL_PORT structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] ErrnoValue errno value if test fails
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The connection was successfully established.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others The connection attempt failed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync **/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketBindTest (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESL_PORT * pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN int ErrnoValue
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 * pBuffer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VOID * pConfigData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Locate the configuration data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pBuffer = (UINT8 *)pPort;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pBuffer = &pBuffer [ pPort->pSocket->pApi->ConfigDataOffset ];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pConfigData = (VOID *)pBuffer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Attempt to use this configuration
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = pPort->pfnConfigure ( pPort->pProtocol.v, pConfigData );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_WARN | DEBUG_BIND,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "WARNING - Port 0x%08x failed configuration, Status: %r\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->pSocket->errno = ErrnoValue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Reset the port
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = pPort->pfnConfigure ( pPort->pProtocol.v, NULL );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR | DEBUG_BIND,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Port 0x%08x failed configuration reset, Status: %r\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ( EFI_SUCCESS == Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Determine if the socket is closed
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine checks the state of the socket to determine if
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the network specific layer has completed the close operation.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The ::close routine polls this routine to determine when the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync close operation is complete. The close operation needs to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync reverse the operations of the ::EslSocketAllocate routine.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [out] pErrno Address to receive the errno value upon completion.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Socket successfully closed
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_READY Close still in progress
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ALREADY Close operation already in progress
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Other Failed to close the socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketClosePoll (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_SOCKET_PROTOCOL * pSocketProtocol,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN int * pErrno
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int errno;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_LAYER * pLayer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SOCKET * pNextSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SOCKET * pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TPL TplPrevious;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Assume success
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errno = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Synchronize with the socket layer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RAISE_TPL ( TplPrevious, TPL_SOCKETS );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Locate the socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pLayer = &mEslLayer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pNextSocket = pLayer->pSocketList;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ( NULL != pNextSocket ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( pNextSocket == pSocket ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine if the socket is in the closing state
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( SOCKET_STATE_CLOSED == pSocket->State ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Walk the list of ports
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pSocket->pPortList ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // All the ports are closed
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Close the WaitAccept event if necessary
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pSocket->WaitAccept ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->CloseEvent ( pSocket->WaitAccept );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_SOCKET | DEBUG_CLOSE | DEBUG_POOL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Closed WaitAccept event\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->WaitAccept ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the transmit status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = pSocket->TxError;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EIO;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR | DEBUG_SOCKET | DEBUG_CLOSE | DEBUG_POOL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Failed to close the WaitAccept event, Status: %r\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ( EFI_SUCCESS == Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // At least one port is still open
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_NOT_READY;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errno = EAGAIN;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // SocketCloseStart was not called
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_NOT_STARTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errno = EPERM;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the next socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pNextSocket = pNextSocket->pNext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Handle the error case where the socket was already closed
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pSocket ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Socket not found
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_NOT_FOUND;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errno = ENOTSOCK;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Release the socket layer synchronization
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RESTORE_TPL ( TplPrevious );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pErrno ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pErrno = errno;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Start the close operation on the socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine calls the network specific layer to initiate the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync close state machine. This routine then calls the network
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync specific layer to determine if the close state machine has gone
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync to completion. The result from this poll is returned to the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync caller.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The ::close routine calls this routine to start the close
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync operation which reverses the operations of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ::EslSocketAllocate routine. The close routine then polls
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the ::EslSocketClosePoll routine to determine when the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync socket is closed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] bCloseNow Boolean to control close behavior
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [out] pErrno Address to receive the errno value upon completion.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Socket successfully closed
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_READY Close still in progress
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ALREADY Close operation already in progress
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Other Failed to close the socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketCloseStart (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_SOCKET_PROTOCOL * pSocketProtocol,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN BOOLEAN bCloseNow,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN int * pErrno
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int errno;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_PORT * pNextPort;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_PORT * pPort;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SOCKET * pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TPL TplPrevious;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Assume success
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errno = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Synchronize with the socket layer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RAISE_TPL ( TplPrevious, TPL_SOCKETS );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine if the socket is already closed
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( SOCKET_STATE_CLOSED > pSocket->State ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update the socket state
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->State = SOCKET_STATE_CLOSED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Walk the list of ports
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort = pSocket->pPortList;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ( NULL != pPort ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Start closing the ports
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pNextPort = pPort->pLinkSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EslSocketPortCloseStart ( pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bCloseNow,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG_CLOSE | DEBUG_LISTEN | DEBUG_CONNECTION );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( EFI_SUCCESS != Status )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && ( EFI_NOT_READY != Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errno = EIO;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the next port
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort = pNextPort;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Attempt to finish closing the socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pPort ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EslSocketClosePoll ( pSocketProtocol, &errno );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_NOT_READY;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errno = EAGAIN;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Release the socket layer synchronization
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RESTORE_TPL ( TplPrevious );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pErrno ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pErrno = errno;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Connect to a remote system via the network.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine calls the network specific layer to establish
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the remote system address and establish the connection to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the remote system.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The ::connect routine calls this routine to establish a
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync connection with the specified remote system. This routine
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync is designed to be polled by the connect routine for completion
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync of the network connection.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pSockAddr Network address of the remote system.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] SockAddrLength Length in bytes of the network address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [out] pErrno Address to receive the errno value upon completion.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The connection was successfully established.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_READY The connection is in progress, call this routine again.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others The connection attempt failed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync **/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketConnect (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_SOCKET_PROTOCOL * pSocketProtocol,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN const struct sockaddr * pSockAddr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN socklen_t SockAddrLength,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN int * pErrno
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync struct sockaddr_in6 LocalAddress;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_PORT * pPort;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SOCKET * pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TPL TplPrevious;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_CONNECT, "Entering SocketConnect\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Assume success
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pSocketProtocol ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the name length
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( SockAddrLength < ( sizeof ( struct sockaddr ) - sizeof ( pSockAddr->sa_data ))) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_CONNECT,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Invalid bind name length: %d\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockAddrLength ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EINVAL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Assume success
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Synchronize with the socket layer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RAISE_TPL ( TplPrevious, TPL_SOCKETS );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the socket state
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch ( pSocket->State ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Wrong socket state
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EIO;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_DEVICE_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case SOCKET_STATE_NOT_CONFIGURED:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case SOCKET_STATE_BOUND:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the address length
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( SockAddrLength >= pSocket->pApi->MinimumAddressLength ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the API
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pSocket->pApi->pfnRemoteAddrSet ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Already connected
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = ENOTSUP;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine if BIND was already called
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pSocket->pPortList ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Allow any local port
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem ( &LocalAddress, sizeof ( LocalAddress ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalAddress.sin6_len = (uint8_t)pSocket->pApi->MinimumAddressLength;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalAddress.sin6_family = pSocket->pApi->AddressFamily;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EslSocketBind ( &pSocket->SocketProtocol,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (struct sockaddr *)&LocalAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalAddress.sin6_len,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &pSocket->errno );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pSocket->pPortList ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Walk the list of ports
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort = pSocket->pPortList;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ( NULL != pPort ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the remote address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = pSocket->pApi->pfnRemoteAddrSet ( pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSockAddr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockAddrLength );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the next port
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort = pPort->pLinkSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the API
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( !EFI_ERROR ( Status ))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && ( NULL != pSocket->pApi->pfnConnectStart )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Initiate the connection with the remote system
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = pSocket->pApi->pfnConnectStart ( pSocket );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the next state if connecting
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( EFI_NOT_READY == Status ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->State = SOCKET_STATE_CONNECTING;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_CONNECT,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Invalid address length: %d\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockAddrLength ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EINVAL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case SOCKET_STATE_CONNECTING:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Poll for connection completion
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pSocket->pApi->pfnConnectPoll ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Already connected
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EISCONN;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_ALREADY_STARTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = pSocket->pApi->pfnConnectPoll ( pSocket );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the next state if connected
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( EFI_NOT_READY != Status ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->State = SOCKET_STATE_CONNECTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->State = SOCKET_STATE_BOUND;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case SOCKET_STATE_CONNECTED:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Already connected
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EISCONN;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_ALREADY_STARTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Release the socket layer synchronization
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RESTORE_TPL ( TplPrevious );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pErrno ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pSocket ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pErrno = pSocket->errno;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Bad socket protocol
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR | DEBUG_CONNECT,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - pSocketProtocol invalid!\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pErrno = ENOTSOCK;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_CONNECT, "Exiting SocketConnect, Status: %r\r\n", Status ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Copy a fragmented buffer into a destination buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This support routine copies a fragmented buffer to the caller specified buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine is called by ::EslIp4Receive and ::EslUdp4Receive.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] FragmentCount Number of fragments in the table
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pFragmentTable Address of an EFI_IP4_FRAGMENT_DATA structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] BufferLength Length of the the buffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pBuffer Address of a buffer to receive the data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pDataLength Number of received data bytes in the buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return Returns the address of the next free byte in the buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINT8 *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketCopyFragmentedBuffer (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT32 FragmentCount,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IP4_FRAGMENT_DATA * pFragmentTable,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN size_t BufferLength,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 * pBuffer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT size_t * pDataLength
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync size_t BytesToCopy;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 Fragment;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 * pBufferEnd;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 * pData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the IP and UDP structures are identical
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ( OFFSET_OF ( EFI_IP4_FRAGMENT_DATA, FragmentLength )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync == OFFSET_OF ( EFI_UDP4_FRAGMENT_DATA, FragmentLength ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ( OFFSET_OF ( EFI_IP4_FRAGMENT_DATA, FragmentBuffer )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync == OFFSET_OF ( EFI_UDP4_FRAGMENT_DATA, FragmentBuffer ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Copy the received data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Fragment = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pBufferEnd = &pBuffer [ BufferLength ];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (( pBufferEnd > pBuffer ) && ( FragmentCount > Fragment )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine the amount of received data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pData = pFragmentTable[Fragment].FragmentBuffer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BytesToCopy = pFragmentTable[Fragment].FragmentLength;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (((size_t)( pBufferEnd - pBuffer )) < BytesToCopy ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BytesToCopy = pBufferEnd - pBuffer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Move the data into the buffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_RX,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x --> 0x%08x: Copy data 0x%08x bytes\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pData,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pBuffer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BytesToCopy ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem ( pBuffer, pData, BytesToCopy );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pBuffer += BytesToCopy;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Fragment += 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the data length and the buffer address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pDataLength = BufferLength - ( pBufferEnd - pBuffer );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_HEX ( pBuffer );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return pBuffer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Get the local address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine calls the network specific layer to get the network
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync address of the local host connection point.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The ::getsockname routine calls this routine to obtain the network
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync address associated with the local host connection point.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [out] pAddress Network address to receive the local system address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in,out] pAddressLength Length of the local network address structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [out] pErrno Address to receive the errno value upon completion.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS - Local address successfully returned
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync **/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketGetLocalAddress (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_SOCKET_PROTOCOL * pSocketProtocol,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT struct sockaddr * pAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT socklen_t * pAddressLength,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN int * pErrno
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync socklen_t LengthInBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_PORT * pPort;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SOCKET * pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TPL TplPrevious;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Assume success
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pSocketProtocol ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the socket state
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EslSocketIsConfigured ( pSocket );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the address buffer and length address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( NULL != pAddress ) && ( NULL != pAddressLength )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the socket state
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( SOCKET_STATE_CONNECTED == pSocket->State ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the API
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pSocket->pApi->pfnLocalAddrGet ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = ENOTSUP;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Synchronize with the socket layer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RAISE_TPL ( TplPrevious, TPL_SOCKETS );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify that there is just a single connection
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort = pSocket->pPortList;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( NULL != pPort ) && ( NULL == pPort->pLinkSocket )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the address length
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes = pSocket->pApi->AddressLength;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( LengthInBytes <= *pAddressLength )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && ( 255 >= LengthInBytes )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the local address and address length
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem ( pAddress, LengthInBytes );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pAddress->sa_len = (uint8_t)LengthInBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pAddressLength = pAddress->sa_len;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->pApi->pfnLocalAddrGet ( pPort, pAddress );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EINVAL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = ENOTCONN;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_NOT_STARTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Release the socket layer synchronization
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RESTORE_TPL ( TplPrevious );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = ENOTCONN;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_NOT_STARTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EINVAL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pErrno ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pSocket ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pErrno = pSocket->errno;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pErrno = ENOTSOCK;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Get the peer address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine calls the network specific layer to get the remote
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync system connection point.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The ::getpeername routine calls this routine to obtain the network
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync address of the remote connection point.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [out] pAddress Network address to receive the remote system address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in,out] pAddressLength Length of the remote network address structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [out] pErrno Address to receive the errno value upon completion.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS - Remote address successfully returned
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync **/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketGetPeerAddress (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_SOCKET_PROTOCOL * pSocketProtocol,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT struct sockaddr * pAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT socklen_t * pAddressLength,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN int * pErrno
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync socklen_t LengthInBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_PORT * pPort;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SOCKET * pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TPL TplPrevious;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Assume success
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pSocketProtocol ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the socket state
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EslSocketIsConfigured ( pSocket );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the API
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pSocket->pApi->pfnRemoteAddrGet ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = ENOTSUP;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the address buffer and length address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( NULL != pAddress ) && ( NULL != pAddressLength )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the socket state
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( SOCKET_STATE_CONNECTED == pSocket->State ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Synchronize with the socket layer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RAISE_TPL ( TplPrevious, TPL_SOCKETS );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify that there is just a single connection
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort = pSocket->pPortList;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( NULL != pPort ) && ( NULL == pPort->pLinkSocket )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the address length
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes = pSocket->pApi->AddressLength;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( LengthInBytes <= *pAddressLength ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the local address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem ( pAddress, LengthInBytes );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pAddress->sa_len = (uint8_t)LengthInBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pAddressLength = pAddress->sa_len;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->pApi->pfnRemoteAddrGet ( pPort, pAddress );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EINVAL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = ENOTCONN;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_NOT_STARTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Release the socket layer synchronization
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RESTORE_TPL ( TplPrevious );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = ENOTCONN;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_NOT_STARTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EINVAL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pErrno ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pSocket ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pErrno = pSocket->errno;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pErrno = ENOTSOCK;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Free the ESL_IO_MGMT event and structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This support routine walks the free list to close the event in
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the ESL_IO_MGMT structure and remove the structure from the free
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync See the \ref TransmitEngine section.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pPort Address of an ::ESL_PORT structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] ppFreeQueue Address of the free queue head
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] DebugFlags Flags for debug messages
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pEventName Zero terminated string containing the event name
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS - The structures were properly initialized
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketIoFree (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESL_PORT * pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESL_IO_MGMT ** ppFreeQueue,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN DebugFlags,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN CHAR8 * pEventName
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 * pBuffer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_EVENT * pEvent;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_IO_MGMT * pIo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SOCKET * pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Assume success
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Walk the list of IO structures
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = pPort->pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ( *ppFreeQueue ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Free the event for this structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo = *ppFreeQueue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pBuffer = (UINT8 *)pIo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pBuffer = &pBuffer[ pSocket->TxTokenEventOffset ];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pEvent = (EFI_EVENT *)pBuffer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->CloseEvent ( *pEvent );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR | DebugFlags,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Failed to close the %a event, Status: %r\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pEventName,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = ENOMEM;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DebugFlags,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Closed %a event 0x%08x\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pEventName,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pEvent ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Remove this structure from the queue
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ppFreeQueue = pIo->pNext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Initialize the ESL_IO_MGMT structures
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This support routine initializes the ESL_IO_MGMT structure and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync places them on to a free list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine is called by ::EslSocketPortAllocate routines to prepare
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the transmit engines. See the \ref TransmitEngine section.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pPort Address of an ::ESL_PORT structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in, out] ppIo Address containing the first structure address. Upon
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return this buffer contains the next structure address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] TokenCount Number of structures to initialize
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] ppFreeQueue Address of the free queue head
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] DebugFlags Flags for debug messages
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pEventName Zero terminated string containing the event name
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pfnCompletion Completion routine address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS - The structures were properly initialized
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketIoInit (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESL_PORT * pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESL_IO_MGMT ** ppIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN TokenCount,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESL_IO_MGMT ** ppFreeQueue,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN DebugFlags,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN CHAR8 * pEventName,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN PFN_API_IO_COMPLETE pfnCompletion
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_IO_MGMT * pEnd;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_EVENT * pEvent;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_IO_MGMT * pIo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SOCKET * pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Assume success
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Walk the list of IO structures
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = pPort->pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo = *ppIo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pEnd = &pIo [ TokenCount ];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ( pEnd > pIo ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Initialize the IO structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo->pPort = pPort;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo->pPacket = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Allocate the event for this structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pEvent = (EFI_EVENT *)&(((UINT8 *)pIo)[ pSocket->TxTokenEventOffset ]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TPL_SOCKETS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (EFI_EVENT_NOTIFY)pfnCompletion,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pEvent );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR | DebugFlags,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Failed to create the %a event, Status: %r\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pEventName,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = ENOMEM;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DebugFlags,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Created %a event 0x%08x\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pEventName,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pEvent ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Add this structure to the queue
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo->pNext = *ppFreeQueue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ppFreeQueue = pIo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the next structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo += 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Save the next structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ppIo = pIo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Determine if the socket is configured
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This support routine is called to determine if the socket if the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync configuration call was made to the network layer. The following
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync routines call this routine to verify that they may be successful
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync in their operations:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <ul>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>::EslSocketGetLocalAddress</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>::EslSocketGetPeerAddress</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>::EslSocketPoll</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>::EslSocketReceive</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>::EslSocketTransmit</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync </ul>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pSocket Address of an ::ESL_SOCKET structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS - The socket is configured
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketIsConfigured (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESL_SOCKET * pSocket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TPL TplPrevious;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Assume success
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the socket state
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !pSocket->bConfigured ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the API
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pSocket->pApi->pfnIsConfigured ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = ENOTSUP;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Synchronize with the socket layer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RAISE_TPL ( TplPrevious, TPL_SOCKETS );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine if the socket is configured
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = pSocket->pApi->pfnIsConfigured ( pSocket );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Release the socket layer synchronization
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RESTORE_TPL ( TplPrevious );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set errno if a failure occurs
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EADDRNOTAVAIL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the configuration status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Establish the known port to listen for network connections.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine calls into the network protocol layer to establish
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync a handler that is called upon connection completion. The handler
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync is responsible for inserting the connection into the FIFO.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The ::listen routine indirectly calls this routine to place the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync socket into a state that enables connection attempts. Connections
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync are placed in a FIFO that is serviced by the application. The
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync application calls the ::accept (::EslSocketAccept) routine to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync remove the next connection from the FIFO and get the associated
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync socket and address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] Backlog Backlog specifies the maximum FIFO depth for
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the connections waiting for the application
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync to call accept. Connection attempts received
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while the queue is full are refused.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [out] pErrno Address to receive the errno value upon completion.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS - Socket successfully created
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Other - Failed to enable the socket for listen
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketListen (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_SOCKET_PROTOCOL * pSocketProtocol,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN INT32 Backlog,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT int * pErrno
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SOCKET * pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS TempStatus;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TPL TplPrevious;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Assume success
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pSocketProtocol ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the API
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pSocket->pApi->pfnListen ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = ENOTSUP;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Assume success
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify that the bind operation was successful
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( SOCKET_STATE_BOUND == pSocket->State ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Synchronize with the socket layer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RAISE_TPL ( TplPrevious, TPL_SOCKETS );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create the event for SocketAccept completion
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->CreateEvent ( 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TplPrevious,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &pSocket->WaitAccept );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_POOL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Created WaitAccept event\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->WaitAccept ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the maximum FIFO depth
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( 0 >= Backlog ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Backlog = MAX_PENDING_CONNECTIONS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( SOMAXCONN < Backlog ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Backlog = SOMAXCONN;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->MaxFifoDepth = Backlog;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Initiate the connection attempt listen
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = pSocket->pApi->pfnListen ( pSocket );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Place the socket in the listen state if successful
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->State = SOCKET_STATE_LISTENING;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->bListenCalled = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Not waiting for SocketAccept to complete
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TempStatus = gBS->CloseEvent ( pSocket->WaitAccept );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( TempStatus )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_POOL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Closed WaitAccept event\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->WaitAccept ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->WaitAccept = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR | DEBUG_POOL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Failed to close WaitAccept event, Status: %r\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TempStatus ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ( EFI_SUCCESS == TempStatus );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR | DEBUG_LISTEN,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Failed to create the WaitAccept event, Status: %r\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = ENOMEM;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Release the socket layer synchronization
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RESTORE_TPL ( TplPrevious );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR | DEBUG_LISTEN,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Bind operation must be performed first!\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = ( SOCKET_STATE_NOT_CONFIGURED == pSocket->State ) ? EDESTADDRREQ
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync : EINVAL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_NO_MAPPING;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pErrno ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pSocket ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pErrno = pSocket->errno;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pErrno = ENOTSOCK;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Get the socket options
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine handles the socket level options and passes the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync others to the network specific layer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The ::getsockopt routine calls this routine to retrieve the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync socket options one at a time by name.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] level Option protocol level
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] OptionName Name of the option
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [out] pOptionValue Buffer to receive the option value
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in,out] pOptionLength Length of the buffer in bytes,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync upon return length of the option value in bytes
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [out] pErrno Address to receive the errno value upon completion.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS - Socket data successfully received
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync **/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketOptionGet (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_SOCKET_PROTOCOL * pSocketProtocol,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN int level,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN int OptionName,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT void * __restrict pOptionValue,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT socklen_t * __restrict pOptionLength,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN int * pErrno
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int errno;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync socklen_t LengthInBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync socklen_t MaxBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CONST UINT8 * pOptionData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SOCKET * pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Assume failure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errno = EINVAL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pSocketProtocol ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_OPTION, "ERROR - pSocketProtocol is NULL!\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if ( NULL == pOptionValue ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_OPTION, "ERROR - No option buffer specified\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if ( NULL == pOptionLength ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_OPTION, "ERROR - Option length not specified!\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MaxBytes = *pOptionLength;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pOptionData = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch ( level ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // See if the protocol will handle the option
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pSocket->pApi->pfnOptionGet ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( pSocket->pApi->DefaultProtocol == level ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = pSocket->pApi->pfnOptionGet ( pSocket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OptionName,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (CONST void ** __restrict)&pOptionData,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &LengthInBytes );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errno = pSocket->errno;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Protocol not supported
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_OPTION,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - The socket does not support this protocol!\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Protocol level not supported
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_OPTION,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - %a does not support any options!\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->pApi->pName ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errno = ENOPROTOOPT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case SOL_SOCKET:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch ( OptionName ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Socket option not supported
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_INFO | DEBUG_OPTION, "ERROR - Invalid socket option!\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errno = EINVAL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case SO_ACCEPTCONN:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the listen flag
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pOptionData = (CONST UINT8 *)&pSocket->bListenCalled;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes = sizeof ( pSocket->bListenCalled );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case SO_DEBUG:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the debug flags
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pOptionData = (CONST UINT8 *)&pSocket->bOobInLine;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes = sizeof ( pSocket->bOobInLine );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case SO_OOBINLINE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the out-of-band inline flag
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pOptionData = (CONST UINT8 *)&pSocket->bOobInLine;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes = sizeof ( pSocket->bOobInLine );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case SO_RCVTIMEO:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the receive timeout
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pOptionData = (CONST UINT8 *)&pSocket->RxTimeout;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes = sizeof ( pSocket->RxTimeout );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case SO_RCVBUF:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the maximum receive buffer size
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pOptionData = (CONST UINT8 *)&pSocket->MaxRxBuf;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes = sizeof ( pSocket->MaxRxBuf );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case SO_SNDBUF:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the maximum transmit buffer size
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pOptionData = (CONST UINT8 *)&pSocket->MaxTxBuf;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes = sizeof ( pSocket->MaxTxBuf );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case SO_TYPE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the socket type
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pOptionData = (CONST UINT8 *)&pSocket->Type;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes = sizeof ( pSocket->Type );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the option length
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pOptionLength = LengthInBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine if the option is present
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( 0 != LengthInBytes ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Silently truncate the value length
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( LengthInBytes > MaxBytes ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_OPTION,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "INFO - Truncating option from %d to %d bytes\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MaxBytes ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes = MaxBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the value
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem ( pOptionValue, pOptionData, LengthInBytes );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Zero fill any remaining space
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( LengthInBytes < MaxBytes ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem ( &((UINT8 *)pOptionValue)[LengthInBytes], MaxBytes - LengthInBytes );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errno = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pErrno ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pErrno = errno;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Set the socket options
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine handles the socket level options and passes the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync others to the network specific layer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The ::setsockopt routine calls this routine to adjust the socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync options one at a time by name.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] level Option protocol level
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] OptionName Name of the option
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pOptionValue Buffer containing the option value
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] OptionLength Length of the buffer in bytes
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [out] pErrno Address to receive the errno value upon completion.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS - Option successfully set
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync **/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketOptionSet (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_SOCKET_PROTOCOL * pSocketProtocol,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN int level,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN int OptionName,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN CONST void * pOptionValue,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN socklen_t OptionLength,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN int * pErrno
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN bTrueFalse;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int errno;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync socklen_t LengthInBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 * pOptionData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SOCKET * pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Assume failure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errno = EINVAL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pSocketProtocol ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_OPTION, "ERROR - pSocketProtocol is NULL!\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if ( NULL == pOptionValue ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_OPTION, "ERROR - No option buffer specified\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( pSocket->bRxDisable || pSocket->bTxDisable ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_OPTION, "ERROR - Socket has been shutdown!\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pOptionData = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch ( level ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // See if the protocol will handle the option
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pSocket->pApi->pfnOptionSet ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( pSocket->pApi->DefaultProtocol == level ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = pSocket->pApi->pfnOptionSet ( pSocket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OptionName,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pOptionValue,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OptionLength );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errno = pSocket->errno;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Protocol not supported
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_OPTION,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - The socket does not support this protocol!\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Protocol level not supported
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_OPTION,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - %a does not support any options!\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->pApi->pName ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errno = ENOPROTOOPT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case SOL_SOCKET:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch ( OptionName ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Option not supported
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_OPTION,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Sockets does not support this option!\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errno = EINVAL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case SO_DEBUG:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the debug flags
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pOptionData = (UINT8 *)&pSocket->bOobInLine;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes = sizeof ( pSocket->bOobInLine );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case SO_OOBINLINE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pOptionData = (UINT8 *)&pSocket->bOobInLine;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes = sizeof ( pSocket->bOobInLine );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the option length
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( sizeof ( UINT32 ) == OptionLength ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Restrict the input to TRUE or FALSE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bTrueFalse = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( 0 == *(UINT32 *)pOptionValue ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bTrueFalse = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pOptionValue = &bTrueFalse;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Force an invalid option length error
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OptionLength = LengthInBytes - 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case SO_RCVTIMEO:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the receive timeout
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pOptionData = (UINT8 *)&pSocket->RxTimeout;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes = sizeof ( pSocket->RxTimeout );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case SO_RCVBUF:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the maximum receive buffer size
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pOptionData = (UINT8 *)&pSocket->MaxRxBuf;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes = sizeof ( pSocket->MaxRxBuf );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case SO_SNDBUF:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Send buffer size
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the maximum transmit buffer size
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pOptionData = (UINT8 *)&pSocket->MaxTxBuf;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes = sizeof ( pSocket->MaxTxBuf );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine if an option was found
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( 0 != LengthInBytes ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the option length
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( LengthInBytes <= OptionLength ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the option value
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem ( pOptionData, pOptionValue, LengthInBytes );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errno = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_OPTION,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Buffer to small, %d bytes < %d bytes!\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OptionLength,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pErrno ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pErrno = errno;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Allocate a packet for a receive or transmit operation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This support routine is called by ::EslSocketRxStart and the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync network specific TxBuffer routines to get buffer space for the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync next operation.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] ppPacket Address to receive the ::ESL_PACKET structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] LengthInBytes Length of the packet structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] ZeroBytes Length of packet to zero
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] DebugFlags Flags for debug messages
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS - The packet was allocated successfully
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync **/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketPacketAllocate (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESL_PACKET ** ppPacket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN size_t LengthInBytes,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN size_t ZeroBytes,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN DebugFlags
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_PACKET * pPacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Allocate a packet structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes += sizeof ( *pPacket )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - sizeof ( pPacket->Op );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->AllocatePool ( EfiRuntimeServicesData,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (VOID **)&pPacket );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DebugFlags | DEBUG_POOL | DEBUG_INIT,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Allocate pPacket, %d bytes\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( 0 != ZeroBytes ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem ( &pPacket->Op, ZeroBytes );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket->PacketSize = LengthInBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DebugFlags | DEBUG_POOL | DEBUG_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Packet allocation failed for %d bytes, Status: %r\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ppPacket = pPacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Free a packet used for receive or transmit operation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This support routine is called by the network specific Close
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync and TxComplete routines and during error cases in RxComplete
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync and TxBuffer. Note that the network layers typically place
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync receive packets on the ESL_SOCKET::pRxFree list for reuse.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pPacket Address of an ::ESL_PACKET structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] DebugFlags Flags for debug messages
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS - The packet was allocated successfully
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync **/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketPacketFree (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESL_PACKET * pPacket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN DebugFlags
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN LengthInBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Allocate a packet structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes = pPacket->PacketSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->FreePool ( pPacket );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DebugFlags | DEBUG_POOL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Free pPacket, %d bytes\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DebugFlags | DEBUG_POOL | DEBUG_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Failed to free packet 0x%08x, Status: %r\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Poll a socket for pending activity.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine builds a detected event mask which is returned to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the caller in the buffer provided.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The ::poll routine calls this routine to determine if the socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync needs to be serviced as a result of connection, error, receive or
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync transmit activity.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] Events Events of interest for this socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pEvents Address to receive the detected events
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [out] pErrno Address to receive the errno value upon completion.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS - Socket successfully polled
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER - When pEvents is NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync **/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketPoll (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_SOCKET_PROTOCOL * pSocketProtocol,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN short Events,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN short * pEvents,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN int * pErrno
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync short DetectedEvents;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SOCKET * pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync short ValidEvents;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_POLL, "Entering SocketPoll\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Assume success
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DetectedEvents = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the socket state
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EslSocketIsConfigured ( pSocket );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check for invalid events
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ValidEvents = POLLIN
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | POLLPRI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | POLLOUT | POLLWRNORM
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | POLLERR
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | POLLHUP
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | POLLNVAL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | POLLRDNORM
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | POLLRDBAND
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | POLLWRBAND ;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( 0 != ( Events & ( ~ValidEvents ))) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DetectedEvents |= POLLNVAL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_INFO | DEBUG_POLL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Invalid event mask, Valid Events: 0x%04x, Invalid Events: 0x%04x\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Events & ValidEvents,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Events & ( ~ValidEvents )));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check for pending connections
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( 0 != pSocket->FifoDepth ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // A connection is waiting for an accept call
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // See posix connect documentation at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // http://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.htm
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DetectedEvents |= POLLIN | POLLRDNORM;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( pSocket->bConnected ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // A connection is present
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // See posix connect documentation at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // http://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.htm
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DetectedEvents |= POLLOUT | POLLWRNORM;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The following bits are set based upon the POSIX poll documentation at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // http://pubs.opengroup.org/onlinepubs/9699919799/functions/poll.html
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check for urgent receive data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( 0 < pSocket->RxOobBytes ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DetectedEvents |= POLLRDBAND | POLLPRI | POLLIN;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check for normal receive data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( 0 < pSocket->RxBytes )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync || ( EFI_SUCCESS != pSocket->RxError )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DetectedEvents |= POLLRDNORM | POLLIN;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Handle the receive errors
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( EFI_SUCCESS != pSocket->RxError )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && ( 0 == ( DetectedEvents & POLLIN ))) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DetectedEvents |= POLLERR | POLLIN | POLLRDNORM | POLLRDBAND;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check for urgent transmit data buffer space
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( MAX_TX_DATA > pSocket->TxOobBytes )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync || ( EFI_SUCCESS != pSocket->TxError )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DetectedEvents |= POLLWRBAND;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check for normal transmit data buffer space
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( MAX_TX_DATA > pSocket->TxBytes )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync || ( EFI_SUCCESS != pSocket->TxError )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DetectedEvents |= POLLWRNORM;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Handle the transmit error
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( EFI_ERROR ( pSocket->TxError )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DetectedEvents |= POLLERR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the detected events
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pEvents = DetectedEvents & ( Events
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | POLLERR
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | POLLHUP
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync | POLLNVAL );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_POLL, "Exiting SocketPoll, Status: %r\r\n", Status ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Allocate and initialize a ESL_PORT structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine initializes an ::ESL_PORT structure for use by
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the socket. This routine calls a routine via
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_PROTOCOL_API::pfnPortAllocate to initialize the network
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync specific resources. The resources are released later by the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync \ref PortCloseStateMachine.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This support routine is called by:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <ul>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>::EslSocketBind</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>::EslTcp4ListenComplete</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync </ul>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync to connect the socket with the underlying network adapter
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync to the socket.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pSocket Address of an ::ESL_SOCKET structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pService Address of an ::ESL_SERVICE structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] ChildHandle Network protocol child handle
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pSockAddr Address of a sockaddr structure that contains the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync connection point on the local machine. An IPv4 address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync of INADDR_ANY specifies that the connection is made to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync all of the network stacks on the platform. Specifying a
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync specific IPv4 address restricts the connection to the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync network stack supporting that address. Specifying zero
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for the port causes the network layer to assign a port
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync number from the dynamic range. Specifying a specific
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync port number causes the network layer to use that port.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] bBindTest TRUE if EslSocketBindTest should be called
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] DebugFlags Flags for debug messages
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [out] ppPort Buffer to receive new ::ESL_PORT structure address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS - Socket successfully created
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync **/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketPortAllocate (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESL_SOCKET * pSocket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESL_SERVICE * pService,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE ChildHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN CONST struct sockaddr * pSockAddr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN BOOLEAN bBindTest,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN DebugFlags,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT ESL_PORT ** ppPort
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN LengthInBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 * pBuffer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_IO_MGMT * pIo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_LAYER * pLayer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_PORT * pPort;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SERVICE_BINDING_PROTOCOL * pServiceBinding;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CONST ESL_SOCKET_BINDING * pSocketBinding;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS TempStatus;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the socket layer synchronization
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VERIFY_TPL ( TPL_SOCKETS );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Use for/break instead of goto
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocketBinding = pService->pSocketBinding;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for ( ; ; ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Allocate a port structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pLayer = &mEslLayer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes = sizeof ( *pPort )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync + ESL_STRUCTURE_ALIGNMENT_BYTES
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync + (( pSocketBinding->RxIo
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync + pSocketBinding->TxIoNormal
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync + pSocketBinding->TxIoUrgent )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * sizeof ( ESL_IO_MGMT ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort = (ESL_PORT *) AllocateZeroPool ( LengthInBytes );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pPort ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = ENOMEM;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DebugFlags | DEBUG_POOL | DEBUG_INIT,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Allocate pPort, %d bytes\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Initialize the port
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->DebugFlags = DebugFlags;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->Handle = ChildHandle;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->pService = pService;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->pServiceBinding = pService->pServiceBinding;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->pSocket = pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->pSocketBinding = pService->pSocketBinding;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->Signature = PORT_SIGNATURE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Open the port protocol
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->OpenProtocol ( pPort->Handle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocketBinding->pNetworkProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &pPort->pProtocol.v,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pLayer->ImageHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR | DebugFlags,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Failed to open network protocol GUID on controller 0x%08x\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->Handle ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EEXIST;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DebugFlags,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Network protocol GUID opened on controller 0x%08x\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->pProtocol.v,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->Handle ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Initialize the port specific resources
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = pSocket->pApi->pfnPortAllocate ( pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DebugFlags );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the local address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = pSocket->pApi->pfnLocalAddrSet ( pPort, pSockAddr, bBindTest );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Test the address/port configuration
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( bBindTest ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EslSocketBindTest ( pPort, pSocket->pApi->BindTestErrno );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Initialize the receive structures
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pBuffer = (UINT8 *)&pPort[ 1 ];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pBuffer = &pBuffer[ ESL_STRUCTURE_ALIGNMENT_BYTES ];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pBuffer = (UINT8 *)( ESL_STRUCTURE_ALIGNMENT_MASK & (UINTN)pBuffer );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo = (ESL_IO_MGMT *)pBuffer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( 0 != pSocketBinding->RxIo )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && ( NULL != pSocket->pApi->pfnRxComplete )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EslSocketIoInit ( pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &pIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocketBinding->RxIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &pPort->pRxFree,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DebugFlags | DEBUG_POOL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "receive",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->pApi->pfnRxComplete );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Initialize the urgent transmit structures
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( 0 != pSocketBinding->TxIoUrgent )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && ( NULL != pSocket->pApi->pfnTxOobComplete )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EslSocketIoInit ( pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &pIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocketBinding->TxIoUrgent,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &pPort->pTxOobFree,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DebugFlags | DEBUG_POOL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "urgent transmit",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->pApi->pfnTxOobComplete );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Initialize the normal transmit structures
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( 0 != pSocketBinding->TxIoNormal )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && ( NULL != pSocket->pApi->pfnTxComplete )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EslSocketIoInit ( pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &pIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocketBinding->TxIoNormal,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &pPort->pTxFree,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DebugFlags | DEBUG_POOL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "normal transmit",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->pApi->pfnTxComplete );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Add this port to the socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->pLinkSocket = pSocket->pPortList;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->pPortList = pPort;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DebugFlags,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Socket adding port: 0x%08x\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Add this port to the service
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->pLinkService = pService->pPortList;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pService->pPortList = pPort;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the port
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ppPort = pPort;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Clean up after the error if necessary
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pPort ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Close the port
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EslSocketPortClose ( pPort );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Close the port if necessary
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pServiceBinding = pService->pServiceBinding;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TempStatus = pServiceBinding->DestroyChild ( pServiceBinding,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ChildHandle );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( TempStatus )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_BIND | DEBUG_POOL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: %s port handle destroyed\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ChildHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocketBinding->pName ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR | DEBUG_BIND | DEBUG_POOL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Failed to destroy the %s port handle 0x%08x, Status: %r\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocketBinding->pName,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ChildHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TempStatus ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ( EFI_SUCCESS == TempStatus );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Close a port.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine releases the resources allocated by ::EslSocketPortAllocate.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine calls ESL_PROTOCOL_API::pfnPortClose to release the network
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync specific resources.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine is called by:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <ul>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>::EslSocketPortAllocate - Port initialization failure</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>::EslSocketPortCloseRxDone - Last step of close processing</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>::EslTcp4ConnectComplete - Connection failure and reducing the port list to a single port</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync </ul>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync See the \ref PortCloseStateMachine section.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pPort Address of an ::ESL_PORT structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The port is closed
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval other Port close error
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketPortClose (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESL_PORT * pPort
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN DebugFlags;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_LAYER * pLayer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_PACKET * pPacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_PORT * pPreviousPort;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SERVICE * pService;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SERVICE_BINDING_PROTOCOL * pServiceBinding;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CONST ESL_SOCKET_BINDING * pSocketBinding;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SOCKET * pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the socket layer synchronization
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VERIFY_TPL ( TPL_SOCKETS );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Locate the port in the socket list
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pLayer = &mEslLayer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DebugFlags = pPort->DebugFlags;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = pPort->pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPreviousPort = pSocket->pPortList;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( pPreviousPort == pPort ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Remove this port from the head of the socket list
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->pPortList = pPort->pLinkSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Locate the port in the middle of the socket list
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (( NULL != pPreviousPort )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && ( pPreviousPort->pLinkSocket != pPort )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPreviousPort = pPreviousPort->pLinkSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pPreviousPort ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Remove the port from the middle of the socket list
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPreviousPort->pLinkSocket = pPort->pLinkSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Locate the port in the service list
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Note that the port may not be in the service list
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // if the service has been shutdown.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pService = pPort->pService;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pService ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPreviousPort = pService->pPortList;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( pPreviousPort == pPort ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Remove this port from the head of the service list
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pService->pPortList = pPort->pLinkService;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Locate the port in the middle of the service list
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (( NULL != pPreviousPort )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && ( pPreviousPort->pLinkService != pPort )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPreviousPort = pPreviousPort->pLinkService;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pPreviousPort ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Remove the port from the middle of the service list
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPreviousPort->pLinkService = pPort->pLinkService;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Empty the urgent receive queue
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ( NULL != pSocket->pRxOobPacketListHead ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket = pSocket->pRxOobPacketListHead;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->pRxOobPacketListHead = pPacket->pNext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->pApi->pfnPacketFree ( pPacket, &pSocket->RxOobBytes );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EslSocketPacketFree ( pPacket, DEBUG_RX );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->pRxOobPacketListTail = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ( 0 == pSocket->RxOobBytes );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Empty the receive queue
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ( NULL != pSocket->pRxPacketListHead ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket = pSocket->pRxPacketListHead;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->pRxPacketListHead = pPacket->pNext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->pApi->pfnPacketFree ( pPacket, &pSocket->RxBytes );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EslSocketPacketFree ( pPacket, DEBUG_RX );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->pRxPacketListTail = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ( 0 == pSocket->RxBytes );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Empty the receive free queue
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ( NULL != pSocket->pRxFree ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket = pSocket->pRxFree;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->pRxFree = pPacket->pNext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EslSocketPacketFree ( pPacket, DEBUG_RX );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Release the network specific resources
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pSocket->pApi->pfnPortClose ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = pSocket->pApi->pfnPortClose ( pPort );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Done with the normal transmit events
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EslSocketIoFree ( pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &pPort->pTxFree,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DebugFlags | DEBUG_POOL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "normal transmit" );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Done with the urgent transmit events
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EslSocketIoFree ( pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &pPort->pTxOobFree,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DebugFlags | DEBUG_POOL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "urgent transmit" );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Done with the receive events
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EslSocketIoFree ( pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &pPort->pRxFree,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DebugFlags | DEBUG_POOL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "receive" );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Done with the lower layer network protocol
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocketBinding = pPort->pSocketBinding;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pPort->pProtocol.v ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->CloseProtocol ( pPort->Handle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocketBinding->pNetworkProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pLayer->ImageHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DebugFlags,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Network protocol GUID closed on controller 0x%08x\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->pProtocol.v,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->Handle ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR | DebugFlags,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Failed to close network protocol GUID on controller 0x%08x, Status: %r\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->Handle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ( EFI_SUCCESS == Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Done with the network port
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pServiceBinding = pPort->pServiceBinding;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pPort->Handle ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = pServiceBinding->DestroyChild ( pServiceBinding,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->Handle );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DebugFlags | DEBUG_POOL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: %s port handle destroyed\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->Handle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocketBinding->pName ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR | DebugFlags | DEBUG_POOL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Failed to destroy the %s port handle, Status: %r\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocketBinding->pName,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ( EFI_SUCCESS == Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Release the port structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->FreePool ( pPort );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DebugFlags | DEBUG_POOL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Free pPort, %d bytes\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof ( *pPort )));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR | DebugFlags | DEBUG_POOL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Failed to free pPort: 0x%08x, Status: %r\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ( EFI_SUCCESS == Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Mark the socket as closed if necessary
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pSocket->pPortList ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->State = SOCKET_STATE_CLOSED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_CLOSE | DEBUG_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Socket State: SOCKET_STATE_CLOSED\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Port close state 3
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine attempts to complete the port close operation.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine is called by the TCP layer upon completion of
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the close operation and by ::EslSocketPortCloseTxDone.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync See the \ref PortCloseStateMachine section.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] Event The close completion event
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pPort Address of an ::ESL_PORT structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketPortCloseComplete (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_EVENT Event,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESL_PORT * pPort
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_IO_MGMT * pIo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VERIFY_AT_TPL ( TPL_SOCKETS );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update the port state
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->State = PORT_STATE_CLOSE_DONE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_CLOSE | DEBUG_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Port Close State: PORT_STATE_CLOSE_DONE\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Shutdown the receive operation on the port
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pPort->pfnRxCancel ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo = pPort->pRxActive;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ( NULL != pIo ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EslSocketRxCancel ( pPort, pIo );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo = pIo->pNext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine if the receive operation is pending
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EslSocketPortCloseRxDone ( pPort );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Port close state 4
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine determines the state of the receive operations and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continues the close operation after the pending receive operations
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync are cancelled.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine is called by
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <ul>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>::EslSocketPortCloseComplete</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>::EslSocketPortCloseTxDone</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>::EslSocketRxComplete</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync </ul>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync to determine the state of the receive operations.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync See the \ref PortCloseStateMachine section.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pPort Address of an ::ESL_PORT structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The port is closed
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_READY The port is still closing
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ALREADY_STARTED Error, the port is in the wrong state,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync most likely the routine was called already.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketPortCloseRxDone (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESL_PORT * pPort
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the socket layer synchronization
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VERIFY_TPL ( TPL_SOCKETS );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify that the port is closing
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_ALREADY_STARTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( PORT_STATE_CLOSE_DONE == pPort->State ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine if the receive operation is pending
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_NOT_READY;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pPort->pRxActive ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The receive operation is complete
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update the port state
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->State = PORT_STATE_CLOSE_RX_DONE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_CLOSE | DEBUG_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Port Close State: PORT_STATE_CLOSE_RX_DONE\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Complete the port close operation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EslSocketPortClose ( pPort );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG_CODE_BEGIN ();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_IO_MGMT * pIo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Display the outstanding receive operations
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_CLOSE | DEBUG_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Port Close: Receive still pending!\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo = pPort->pRxActive;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ( NULL != pIo ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_CLOSE | DEBUG_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Packet pending on network adapter\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo->pPacket ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo = pIo->pNext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG_CODE_END ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Start the close operation on a port, state 1.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine marks the port as closed and initiates the \ref
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PortCloseStateMachine. The first step is to allow the \ref
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TransmitEngine to run down.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine is called by ::EslSocketCloseStart to initiate the socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync network specific close operation on the socket.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pPort Address of an ::ESL_PORT structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] bCloseNow Set TRUE to abort active transfers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] DebugFlags Flags for debug messages
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The port is closed, not normally returned
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_READY The port has started the closing process
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ALREADY_STARTED Error, the port is in the wrong state,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync most likely the routine was called already.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketPortCloseStart (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESL_PORT * pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN BOOLEAN bCloseNow,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN DebugFlags
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SOCKET * pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the socket layer synchronization
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VERIFY_TPL ( TPL_SOCKETS );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Mark the port as closing
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_ALREADY_STARTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = pPort->pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EALREADY;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( PORT_STATE_CLOSE_STARTED > pPort->State ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update the port state
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->State = PORT_STATE_CLOSE_STARTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_CLOSE | DEBUG_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Port Close State: PORT_STATE_CLOSE_STARTED\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->bCloseNow = bCloseNow;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->DebugFlags = DebugFlags;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine if transmits are complete
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EslSocketPortCloseTxDone ( pPort );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Port close state 2
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine determines the state of the transmit engine and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue the close operation after the transmission is complete.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The next step is to stop the \ref ReceiveEngine.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync See the \ref PortCloseStateMachine section.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine is called by ::EslSocketPortCloseStart to determine
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if the transmission is complete.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pPort Address of an ::ESL_PORT structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The port is closed, not normally returned
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_READY The port is still closing
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ALREADY_STARTED Error, the port is in the wrong state,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync most likely the routine was called already.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketPortCloseTxDone (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESL_PORT * pPort
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_IO_MGMT * pIo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SOCKET * pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the socket layer synchronization
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VERIFY_TPL ( TPL_SOCKETS );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // All transmissions are complete or must be stopped
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Mark the port as TX complete
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_ALREADY_STARTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( PORT_STATE_CLOSE_STARTED == pPort->State ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify that the transmissions are complete
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = pPort->pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( pPort->bCloseNow
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync || ( EFI_SUCCESS != pSocket->TxError )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync || (( NULL == pPort->pTxActive )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && ( NULL == pPort->pTxOobActive ))) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update the port state
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->State = PORT_STATE_CLOSE_TX_DONE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_CLOSE | DEBUG_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Port Close State: PORT_STATE_CLOSE_TX_DONE\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Close the port
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Skip the close operation if the port is not configured
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = pPort->pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( pPort->bConfigured )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && ( NULL != pSocket->pApi->pfnPortCloseOp )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Start the close operation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = pSocket->pApi->pfnPortCloseOp ( pPort );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_CLOSE | DEBUG_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Port Close: Close operation still pending!\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ( EFI_SUCCESS == Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The receive operation is complete
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update the port state
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EslSocketPortCloseComplete ( NULL, pPort );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Transmissions are still active, exit
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_NOT_READY;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EAGAIN;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG_CODE_BEGIN ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_PACKET * pPacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_CLOSE | DEBUG_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Port Close: Transmits are still pending!\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Display the pending urgent transmit packets
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket = pSocket->pTxOobPacketListHead;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ( NULL != pPacket ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_CLOSE | DEBUG_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Packet pending on urgent TX list, %d bytes\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket->PacketSize ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket = pPacket->pNext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo = pPort->pTxOobActive;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ( NULL != pIo ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket = pIo->pPacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_CLOSE | DEBUG_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Packet active %d bytes, pIo: 0x%08x\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket->PacketSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo = pIo->pNext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Display the pending normal transmit packets
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket = pSocket->pTxPacketListHead;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ( NULL != pPacket ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_CLOSE | DEBUG_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Packet pending on normal TX list, %d bytes\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket->PacketSize ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket = pPacket->pNext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo = pPort->pTxActive;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ( NULL != pIo ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket = pIo->pPacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_CLOSE | DEBUG_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Packet active %d bytes, pIo: 0x%08x\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket->PacketSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo = pIo->pNext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG_CODE_END ();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Receive data from a network connection.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine calls the network specific routine to remove the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync next portion of data from the receive queue and return it to the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync caller.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The ::recvfrom routine calls this routine to determine if any data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync is received from the remote system. Note that the other routines
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ::recv and ::read are layered on top of ::recvfrom.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] Flags Message control flags
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] BufferLength Length of the the buffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pBuffer Address of a buffer to receive the data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pDataLength Number of received data bytes in the buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [out] pAddress Network address to receive the remote system address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in,out] pAddressLength Length of the remote network address structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [out] pErrno Address to receive the errno value upon completion.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS - Socket data successfully received
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync **/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketReceive (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_SOCKET_PROTOCOL * pSocketProtocol,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN INT32 Flags,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN size_t BufferLength,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 * pBuffer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT size_t * pDataLength,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT struct sockaddr * pAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT socklen_t * pAddressLength,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN int * pErrno
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync union {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync struct sockaddr_in v4;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync struct sockaddr_in6 v6;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } Addr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync socklen_t AddressLength;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN bConsumePacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN bUrgentQueue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync size_t DataLength;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_PACKET * pNextPacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_PACKET * pPacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_PORT * pPort;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_PACKET ** ppQueueHead;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_PACKET ** ppQueueTail;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync struct sockaddr * pRemoteAddress;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync size_t * pRxDataBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SOCKET * pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync size_t SkipBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TPL TplPrevious;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Assume success
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pSocketProtocol ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the return address parameters
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( NULL == pAddress ) || ( NULL != pAddressLength )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the transmit error if necessary
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( EFI_SUCCESS != pSocket->TxError ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EIO;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = pSocket->TxError;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->TxError = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the socket state
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EslSocketIsConfigured ( pSocket );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the buffer length
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( NULL == pDataLength )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync || ( NULL == pBuffer )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pDataLength ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_RX,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - pDataLength is NULL!\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_RX,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - pBuffer is NULL!\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EFAULT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the API
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pSocket->pApi->pfnReceive ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = ENOTSUP;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Zero the receive address if being returned
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pRemoteAddress = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pAddress ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pRemoteAddress = (struct sockaddr *)&Addr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem ( pRemoteAddress, sizeof ( Addr ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pRemoteAddress->sa_family = pSocket->pApi->AddressFamily;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pRemoteAddress->sa_len = (UINT8)pSocket->pApi->AddressLength;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Synchronize with the socket layer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RAISE_TPL ( TplPrevious, TPL_SOCKETS );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Assume failure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = ENOTCONN;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify that the socket is connected
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( SOCKET_STATE_CONNECTED == pSocket->State ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Locate the port
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort = pSocket->pPortList;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pPort ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine the queue head
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bUrgentQueue = (BOOLEAN)( 0 != ( Flags & MSG_OOB ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( bUrgentQueue ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ppQueueHead = &pSocket->pRxOobPacketListHead;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ppQueueTail = &pSocket->pRxOobPacketListTail;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pRxDataBytes = &pSocket->RxOobBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ppQueueHead = &pSocket->pRxPacketListHead;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ppQueueTail = &pSocket->pRxPacketListTail;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pRxDataBytes = &pSocket->RxBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine if there is any data on the queue
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pDataLength = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket = *ppQueueHead;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pPacket ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Copy the received data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync do {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Attempt to receive a packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SkipBytes = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bConsumePacket = (BOOLEAN)( 0 == ( Flags & MSG_PEEK ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pBuffer = pSocket->pApi->pfnReceive ( pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &bConsumePacket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BufferLength,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pBuffer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &DataLength,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (struct sockaddr *)&Addr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &SkipBytes );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pDataLength += DataLength;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BufferLength -= DataLength;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine if the data is being read
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pNextPacket = pPacket->pNext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( bConsumePacket ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // All done with this packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Account for any discarded data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->pApi->pfnPacketFree ( pPacket, pRxDataBytes );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( 0 != SkipBytes ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_RX,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Port, packet read, skipping over 0x%08x bytes\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SkipBytes ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Remove this packet from the queue
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ppQueueHead = pPacket->pNext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == *ppQueueHead ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ppQueueTail = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Move the packet to the free queue
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket->pNext = pSocket->pRxFree;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->pRxFree = pPacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_RX,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Port freeing packet 0x%08x\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Restart the receive operation if necessary
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( NULL != pPort->pRxFree )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && ( MAX_RX_DATA > pSocket->RxBytes )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EslSocketRxStart ( pPort );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get the next packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket = pNextPacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } while (( SOCK_STREAM == pSocket->Type )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && ( NULL != pPacket )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && ( 0 < BufferLength ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Successful operation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The queue is empty
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine if it is time to return the receive error
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( EFI_ERROR ( pSocket->RxError )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && ( NULL == pSocket->pRxPacketListHead )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && ( NULL == pSocket->pRxOobPacketListHead )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = pSocket->RxError;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->RxError = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch ( Status ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EIO;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case EFI_CONNECTION_FIN:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Continue to return zero bytes received when the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // peer has successfully closed the connection
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->RxError = EFI_CONNECTION_FIN;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pDataLength = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case EFI_CONNECTION_REFUSED:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = ECONNREFUSED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case EFI_CONNECTION_RESET:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = ECONNRESET;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case EFI_HOST_UNREACHABLE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EHOSTUNREACH;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case EFI_NETWORK_UNREACHABLE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = ENETUNREACH;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case EFI_PORT_UNREACHABLE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EPROTONOSUPPORT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case EFI_PROTOCOL_UNREACHABLE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = ENOPROTOOPT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_NOT_READY;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EAGAIN;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Release the socket layer synchronization
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RESTORE_TPL ( TplPrevious );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( !EFI_ERROR ( Status )) && ( NULL != pAddress )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the remote address if requested, truncate if necessary
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AddressLength = pRemoteAddress->sa_len;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( AddressLength > *pAddressLength ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AddressLength = *pAddressLength;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_RX,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "Returning the remote address, 0x%016x bytes --> 0x%16x\r\n", *pAddressLength, pAddress ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem ( pAddress, *pAddressLength );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem ( pAddress, &Addr, AddressLength );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update the address length
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pAddressLength = pRemoteAddress->sa_len;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Bad return address pointer and length
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EINVAL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pErrno ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pSocket ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pErrno = pSocket->errno;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pErrno = ENOTSOCK;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Cancel the receive operations
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine cancels a pending receive operation.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync See the \ref ReceiveEngine section.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine is called by ::EslSocketShutdown when the socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync layer is being shutdown.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pPort Address of an ::ESL_PORT structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pIo Address of an ::ESL_IO_MGMT structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync **/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketRxCancel (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESL_PORT * pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESL_IO_MGMT * pIo
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Cancel the outstanding receive
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = pPort->pfnRxCancel ( pPort->pProtocol.v,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &pIo->Token );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( pPort->DebugFlags | DEBUG_CLOSE | DEBUG_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Packet receive aborted on port: 0x%08x\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo->pPacket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( pPort->DebugFlags | DEBUG_CLOSE | DEBUG_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Packet receive pending on Port 0x%08x, Status: %r\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo->pPacket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Process the receive completion
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine queues the data in FIFO order in either the urgent
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync or normal data queues depending upon the type of data received.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync See the \ref ReceiveEngine section.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine is called when some data is received by:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <ul>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>::EslIp4RxComplete</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>::EslTcp4RxComplete</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>::EslUdp4RxComplete</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync </ul>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pIo Address of an ::ESL_IO_MGMT structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] Status Receive status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] LengthInBytes Length of the receive data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] bUrgent TRUE if urgent data is received and FALSE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for normal data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketRxComplete (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESL_IO_MGMT * pIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_STATUS Status,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN LengthInBytes,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN BOOLEAN bUrgent
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN bUrgentQueue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_IO_MGMT * pIoNext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_PACKET * pPacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_PORT * pPort;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_PACKET * pPrevious;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_PACKET ** ppQueueHead;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_PACKET ** ppQueueTail;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync size_t * pRxBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SOCKET * pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VERIFY_AT_TPL ( TPL_SOCKETS );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Locate the active receive packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket = pIo->pPacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort = pIo->pPort;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = pPort->pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // pPort->pRxActive
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // V
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // +-------------+ +-------------+ +-------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Active | ESL_IO_MGMT |-->| ESL_IO_MGMT |-->| ESL_IO_MGMT |--> NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // +-------------+ +-------------+ +-------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // +-------------+ +-------------+ +-------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Free | ESL_IO_MGMT |-->| ESL_IO_MGMT |-->| ESL_IO_MGMT |--> NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // +-------------+ +-------------+ +-------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // ^
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // pPort->pRxFree
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Remove the IO structure from the active list
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The following code searches for the entry in the list and does not
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // assume that the receive operations complete in the order they were
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // issued to the UEFI network layer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIoNext = pPort->pRxActive;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (( NULL != pIoNext ) && ( pIoNext != pIo ) && ( pIoNext->pNext != pIo ))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIoNext = pIoNext->pNext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ( NULL != pIoNext );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( pIoNext == pIo ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->pRxActive = pIo->pNext; // Beginning of list
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIoNext->pNext = pIo->pNext; // Middle of list
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Free the IO structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo->pNext = pPort->pRxFree;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->pRxFree = pIo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // pRxOobPacketListHead pRxOobPacketListTail
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // V V
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // +------------+ +------------+ +------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Urgent Data | ESL_PACKET |-->| ESL_PACKET |-->| ESL_PACKET |--> NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // +------------+ +------------+ +------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // +------------+ +------------+ +------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Normal Data | ESL_PACKET |-->| ESL_PACKET |-->| ESL_PACKET |--> NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // +------------+ +------------+ +------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // ^ ^
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // pRxPacketListHead pRxPacketListTail
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine the queue to use
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bUrgentQueue = (BOOLEAN)( bUrgent
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && pSocket->pApi->bOobSupported
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && ( !pSocket->bOobInLine ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( bUrgentQueue ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ppQueueHead = &pSocket->pRxOobPacketListHead;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ppQueueTail = &pSocket->pRxOobPacketListTail;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pRxBytes = &pSocket->RxOobBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ppQueueHead = &pSocket->pRxPacketListHead;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ppQueueTail = &pSocket->pRxPacketListTail;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pRxBytes = &pSocket->RxBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine if this receive was successful
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( !EFI_ERROR ( Status ))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && ( PORT_STATE_CLOSE_STARTED > pPort->State )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && ( !pSocket->bRxDisable )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Account for the received data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pRxBytes += LengthInBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Log the received data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_RX | DEBUG_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Packet queued on %s queue of port 0x%08x with 0x%08x bytes of %s data\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bUrgentQueue ? L"urgent" : L"normal",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bUrgent ? L"urgent" : L"normal" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Add the packet to the list tail.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket->pNext = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPrevious = *ppQueueTail;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pPrevious ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ppQueueHead = pPacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPrevious->pNext = pPacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ppQueueTail = pPacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Attempt to restart this receive operation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( pSocket->MaxRxBuf > pSocket->RxBytes ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EslSocketRxStart ( pPort );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_RX,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Port RX suspended, 0x%08x bytes queued\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->RxBytes ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_RX | DEBUG_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Receive error on port 0x%08x, packet 0x%08x, Status:%r\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Account for the receive bytes and release the driver's buffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pRxBytes += LengthInBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->pApi->pfnPacketFree ( pPacket, pRxBytes );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Receive error, free the packet save the error
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EslSocketPacketFree ( pPacket, DEBUG_RX );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( pSocket->RxError )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->RxError = Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update the port state
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( PORT_STATE_CLOSE_STARTED <= pPort->State ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( PORT_STATE_CLOSE_DONE == pPort->State ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EslSocketPortCloseRxDone ( pPort );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_RX | DEBUG_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Port state: PORT_STATE_RX_ERROR, Status: %r\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->State = PORT_STATE_RX_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Start a receive operation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine posts a receive buffer to the network adapter.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync See the \ref ReceiveEngine section.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This support routine is called by:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <ul>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>::EslIp4Receive to restart the receive engine to release flow control.</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>::EslIp4RxComplete to continue the operation of the receive engine if flow control is not being applied.</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>::EslIp4SocketIsConfigured to start the recevie engine for the new socket.</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>::EslTcp4ListenComplete to start the recevie engine for the new socket.</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>::EslTcp4Receive to restart the receive engine to release flow control.</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>::EslTcp4RxComplete to continue the operation of the receive engine if flow control is not being applied.</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>::EslUdp4Receive to restart the receive engine to release flow control.</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>::EslUdp4RxComplete to continue the operation of the receive engine if flow control is not being applied.</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>::EslUdp4SocketIsConfigured to start the recevie engine for the new socket.</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync </ul>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pPort Address of an ::ESL_PORT structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync **/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketRxStart (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESL_PORT * pPort
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 * pBuffer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_IO_MGMT * pIo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_PACKET * pPacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SOCKET * pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine if a receive is already pending
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = pPort->pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( pPort->pSocket->RxError )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( NULL != pPort->pRxFree )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && ( !pSocket->bRxDisable )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && ( PORT_STATE_CLOSE_STARTED > pPort->State )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Start all of the pending receive operations
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ( NULL != pPort->pRxFree ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine if there are any free packets
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket = pSocket->pRxFree;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pPacket ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Remove this packet from the free list
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->pRxFree = pPacket->pNext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_RX,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Port removed packet 0x%08x from free list\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Allocate a packet structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EslSocketPacketAllocate ( &pPacket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->pApi->RxPacketBytes,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->pApi->RxZeroBytes,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG_RX );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR | DEBUG_RX,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Port failed to allocate RX packet, Status: %r\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Connect the IO and packet structures
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo = pPort->pRxFree;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo->pPacket = pPacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Eliminate the need for IP4 and UDP4 specific routines by
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // clearing the RX data pointer here.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // No driver buffer for this packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // +--------------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // | ESL_IO_MGMT |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // | +---------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // | | Token |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // | | RxData --> NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // +----+---------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pBuffer = (UINT8 *)pIo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pBuffer = &pBuffer[ pSocket->pApi->RxBufferOffset ];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *(VOID **)pBuffer = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Network specific receive packet initialization
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pSocket->pApi->pfnRxStart ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->pApi->pfnRxStart ( pPort, pIo );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Start the receive on the packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = pPort->pfnRxStart ( pPort->pProtocol.v, &pIo->Token );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_RX | DEBUG_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Packet receive pending on port 0x%08x\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Allocate the receive control structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->pRxFree = pIo->pNext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Mark this receive as pending
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo->pNext = pPort->pRxActive;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->pRxActive = pIo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_RX | DEBUG_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Failed to post a receive on port 0x%08x, Status: %r\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( pSocket->RxError )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Save the error status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->RxError = Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Free the packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo->pPacket = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket->pNext = pSocket->pRxFree;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->pRxFree = pPacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pPort->pRxFree ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_RX | DEBUG_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Port, no available ESL_IO_MGMT structures\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( pSocket->bRxDisable ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_RX | DEBUG_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Port, receive disabled!\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( PORT_STATE_CLOSE_STARTED <= pPort->State ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_RX | DEBUG_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Port, is closing!\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR | DEBUG_RX,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Previous receive error, Status: %r\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort->pSocket->RxError ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Shutdown the socket receive and transmit operations
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine sets a flag to stop future transmissions and calls
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the network specific layer to cancel the pending receive operation.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The ::shutdown routine calls this routine to stop receive and transmit
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync operations on the socket.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] How Which operations to stop
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [out] pErrno Address to receive the errno value upon completion.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS - Socket operations successfully shutdown
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync **/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketShutdown (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_SOCKET_PROTOCOL * pSocketProtocol,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN int How,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN int * pErrno
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_IO_MGMT * pIo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_PORT * pPort;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SOCKET * pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TPL TplPrevious;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Assume success
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pSocketProtocol ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify that the socket is connected
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( pSocket->bConnected ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the How value
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( SHUT_RD <= How ) && ( SHUT_RDWR >= How )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Synchronize with the socket layer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RAISE_TPL ( TplPrevious, TPL_SOCKETS );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Disable the receiver if requested
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( SHUT_RD == How ) || ( SHUT_RDWR == How )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->bRxDisable = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Disable the transmitter if requested
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( SHUT_WR == How ) || ( SHUT_RDWR == How )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->bTxDisable = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Cancel the pending receive operations
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( pSocket->bRxDisable ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Walk the list of ports
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort = pSocket->pPortList;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ( NULL != pPort ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Walk the list of active receive operations
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo = pPort->pRxActive;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ( NULL != pIo ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EslSocketRxCancel ( pPort, pIo );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the next port
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort = pPort->pLinkSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Release the socket layer synchronization
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RESTORE_TPL ( TplPrevious );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Invalid How value
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EINVAL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The socket is not connected
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = ENOTCONN;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_NOT_STARTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pErrno ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pSocket ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pErrno = pSocket->errno;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pErrno = ENOTSOCK;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Send data using a network connection.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine calls the network specific layer to queue the data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for transmission. Eventually the buffer will reach the head of
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the queue and will get transmitted over the network by the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync \ref TransmitEngine. For datagram
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sockets (SOCK_DGRAM and SOCK_RAW) there is no guarantee that
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the data reaches the application running on the remote system.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The ::sendto routine calls this routine to send data to the remote
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync system. Note that ::send and ::write are layered on top of ::sendto.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] Flags Message control flags
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] BufferLength Length of the the buffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pBuffer Address of a buffer containing the data to send
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pDataLength Address to receive the number of data bytes sent
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pAddress Network address of the remote system address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] AddressLength Length of the remote network address structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [out] pErrno Address to receive the errno value upon completion.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS - Socket data successfully queued for transmit
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync **/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketTransmit (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_SOCKET_PROTOCOL * pSocketProtocol,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN int Flags,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN size_t BufferLength,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN CONST UINT8 * pBuffer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT size_t * pDataLength,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN const struct sockaddr * pAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN socklen_t AddressLength,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN int * pErrno
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SOCKET * pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TPL TplPrevious;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Assume success
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pSocketProtocol ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the transmit error if necessary
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( EFI_SUCCESS != pSocket->TxError ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EIO;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = pSocket->TxError;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->TxError = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the socket state
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EslSocketIsConfigured ( pSocket );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify that transmit is still allowed
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !pSocket->bTxDisable ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the buffer length
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( NULL == pDataLength )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && ( 0 > pDataLength )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && ( NULL == pBuffer )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pDataLength ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_RX,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - pDataLength is NULL!\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if ( NULL == pBuffer ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_RX,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - pBuffer is NULL!\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_RX,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Data length < 0!\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EFAULT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the remote network address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( NULL != pAddress )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && ( AddressLength < pAddress->sa_len )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_TX,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Invalid sin_len field in address\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EFAULT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the API
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pSocket->pApi->pfnTransmit ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = ENOTSUP;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Synchronize with the socket layer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RAISE_TPL ( TplPrevious, TPL_SOCKETS );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Attempt to buffer the packet for transmission
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = pSocket->pApi->pfnTransmit ( pSocket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Flags,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BufferLength,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pBuffer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pDataLength,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AddressLength );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Release the socket layer synchronization
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RESTORE_TPL ( TplPrevious );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The transmitter was shutdown
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->errno = EPIPE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_NOT_STARTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pErrno ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pSocket ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pErrno = pSocket->errno;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pErrno = ENOTSOCK;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Complete the transmit operation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This support routine handles the transmit completion processing for
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the various network layers. It frees the ::ESL_IO_MGMT structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync and and frees packet resources by calling ::EslSocketPacketFree.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Transmit errors are logged in ESL_SOCKET::TxError.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync See the \ref TransmitEngine section.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine is called by:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <ul>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>::EslIp4TxComplete</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>::EslTcp4TxComplete</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>::EslTcp4TxOobComplete</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li>::EslUdp4TxComplete</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync </ul>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pIo Address of an ::ESL_IO_MGMT structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] LengthInBytes Length of the data in bytes
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] Status Transmit operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pQueueType Zero terminated string describing queue type
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] ppQueueHead Transmit queue head address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] ppQueueTail Transmit queue tail address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] ppActive Active transmit queue address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] ppFree Free transmit queue address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync **/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketTxComplete (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESL_IO_MGMT * pIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT32 LengthInBytes,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_STATUS Status,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN CONST CHAR8 * pQueueType,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESL_PACKET ** ppQueueHead,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESL_PACKET ** ppQueueTail,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESL_IO_MGMT ** ppActive,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESL_IO_MGMT ** ppFree
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_PACKET * pCurrentPacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_IO_MGMT * pIoNext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_PACKET * pNextPacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_PACKET * pPacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_PORT * pPort;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SOCKET * pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VERIFY_AT_TPL ( TPL_SOCKETS );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Locate the active transmit packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket = pIo->pPacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPort = pIo->pPort;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = pPort->pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // No more packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo->pPacket = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Remove the IO structure from the active list
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIoNext = *ppActive;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (( NULL != pIoNext ) && ( pIoNext != pIo ) && ( pIoNext->pNext != pIo ))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIoNext = pIoNext->pNext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ( NULL != pIoNext );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( pIoNext == pIo ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ppActive = pIo->pNext; // Beginning of list
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIoNext->pNext = pIo->pNext; // Middle of list
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Free the IO structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo->pNext = *ppFree;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ppFree = pIo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Display the results
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_TX | DEBUG_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: pIo Released\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Save any transmit error
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( pSocket->TxError )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->TxError = Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_TX | DEBUG_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Transmit failure for %apacket 0x%08x, Status: %r\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pQueueType,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Empty the normal transmit list
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pCurrentPacket = pPacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pNextPacket = *ppQueueHead;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ( NULL != pNextPacket ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket = pNextPacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pNextPacket = pPacket->pNext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EslSocketPacketFree ( pPacket, DEBUG_TX );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ppQueueHead = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ppQueueTail = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket = pCurrentPacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_TX | DEBUG_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: %apacket transmitted %d bytes successfully\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pQueueType,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the transmit engine is still running
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !pPort->bCloseNow ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Start the next packet transmission
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EslSocketTxStart ( pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ppQueueHead,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ppQueueTail,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ppActive,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ppFree );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Release this packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EslSocketPacketFree ( pPacket, DEBUG_TX );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Finish the close operation if necessary
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( PORT_STATE_CLOSE_STARTED <= pPort->State ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Indicate that the transmit is complete
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EslSocketPortCloseTxDone ( pPort );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Transmit data using a network connection.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This support routine starts a transmit operation on the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync underlying network layer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The network specific code calls this routine to start a
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync transmit operation. See the \ref TransmitEngine section.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pPort Address of an ::ESL_PORT structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] ppQueueHead Transmit queue head address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] ppQueueTail Transmit queue tail address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] ppActive Active transmit queue address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] ppFree Free transmit queue address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync **/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEslSocketTxStart (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESL_PORT * pPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESL_PACKET ** ppQueueHead,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESL_PACKET ** ppQueueTail,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESL_IO_MGMT ** ppActive,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESL_IO_MGMT ** ppFree
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 * pBuffer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_IO_MGMT * pIo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_PACKET * pNextPacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_PACKET * pPacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VOID ** ppTokenData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ESL_SOCKET * pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Assume success
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get the packet from the queue head
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket = *ppQueueHead;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo = *ppFree;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( NULL != pPacket ) && ( NULL != pIo )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket = pPort->pSocket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // *ppQueueHead: pSocket->pRxPacketListHead or pSocket->pRxOobPacketListHead
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // V
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // +------------+ +------------+ +------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Data | ESL_PACKET |-->| ESL_PACKET |-->| ESL_PACKET |--> NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // +------------+ +------------+ +------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // ^
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // *ppQueueTail: pSocket->pRxPacketListTail or pSocket->pRxOobPacketListTail
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Remove the packet from the queue
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pNextPacket = pPacket->pNext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ppQueueHead = pNextPacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pNextPacket ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ppQueueTail = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket->pNext = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Eliminate the need for IP4 and UDP4 specific routines by
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // connecting the token with the TX data control structure here.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // +--------------------+ +--------------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // | ESL_IO_MGMT | | ESL_PACKET |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // | | | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // | +---------------+ +----------------+ |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // | | Token | | Buffer Length | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // | | TxData --> | Buffer Address | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // | | | +----------------+---+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // | | Event | | Data Buffer |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // +----+---------------+ | |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // +--------------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Compute the address of the TxData pointer in the token
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pBuffer = (UINT8 *)&pIo->Token;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pBuffer = &pBuffer[ pSocket->TxTokenOffset ];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ppTokenData = (VOID **)pBuffer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Compute the address of the TX data control structure in the packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // * EFI_IP4_TRANSMIT_DATA
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // * EFI_TCP4_TRANSMIT_DATA
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // * EFI_UDP4_TRANSMIT_DATA
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pBuffer = (UINT8 *)pPacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pBuffer = &pBuffer[ pSocket->TxPacketOffset ];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Connect the token to the transmit data control structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ppTokenData = (VOID **)pBuffer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Display the results
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_TX | DEBUG_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: pIo allocated for pPacket: 0x%08x\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPacket ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Start the transmit operation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = pPort->pfnTxStart ( pPort->pProtocol.v,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &pIo->Token );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Connect the structures
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo->pPacket = pPacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // +-------------+ +-------------+ +-------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Free | ESL_IO_MGMT |-->| ESL_IO_MGMT |-->| ESL_IO_MGMT |--> NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // +-------------+ +-------------+ +-------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // ^
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // *ppFree: pPort->pTxFree or pTxOobFree
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Remove the IO structure from the queue
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ppFree = pIo->pNext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // *ppActive: pPort->pTxActive or pTxOobActive
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // V
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // +-------------+ +-------------+ +-------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Active | ESL_IO_MGMT |-->| ESL_IO_MGMT |-->| ESL_IO_MGMT |--> NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // +-------------+ +-------------+ +-------------+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Mark this packet as active
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo->pPacket = pPacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pIo->pNext = *ppActive;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ppActive = pIo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( EFI_SUCCESS == pSocket->TxError ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pSocket->TxError = Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Discard the transmit buffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EslSocketPacketFree ( pPacket, DEBUG_TX );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}