aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown <mcb30@etherboot.org>2005-05-24 17:00:55 +0000
committerMichael Brown <mcb30@etherboot.org>2005-05-24 17:00:55 +0000
commit572483cc59fc9ca929d373d2395dabf53d17b103 (patch)
tree940870bc7579de665d1750a79eaf9b864bb0998a
parent257944286523cf9c7a325aee097551a9153ada41 (diff)
downloadipxe-572483cc59fc9ca929d373d2395dabf53d17b103.tar.gz
Separate out the documentation of the PXE API from the documentation of
the Etherboot implementation (i.e. don't do what Intel did).
-rw-r--r--src/include/pxe_api.h22
-rw-r--r--src/interface/pxe/pxe_udp.c128
2 files changed, 92 insertions, 58 deletions
diff --git a/src/include/pxe_api.h b/src/include/pxe_api.h
index 60d5b30a..da19afb4 100644
--- a/src/include/pxe_api.h
+++ b/src/include/pxe_api.h
@@ -1631,4 +1631,26 @@ extern PXENV_EXIT_t undi_loader ( struct s_UNDI_LOADER *undi_loader );
/** @} */ /* pxe */
+/** @page pxe_notes Etherboot PXE implementation notes
+
+@section pxe_x86_modes x86 processor mode restrictions
+
+On the x86 platform, different PXE API calls have different
+restrictions on the processor modes (real or protected) that can be
+used. See the individual API call descriptions for the restrictions
+that apply to any particular call.
+
+@subsection pxe_x86_pmode16 Real mode, or protected-mode with 16-bit stack
+
+The PXE specification states that the API function can be called in
+protected mode only if the s_PXE::StatusCallout field is set to a
+non-zero value, and that the API function cannot be called with a
+32-bit stack segment.
+
+Etherboot does not enforce either of these restrictions; they seem (as
+with so much of the PXE specification) to be artifacts of the Intel
+implementation.
+
+*/
+
#endif /* PXE_API_H */
diff --git a/src/interface/pxe/pxe_udp.c b/src/interface/pxe/pxe_udp.c
index f46971ea..ace1e30b 100644
--- a/src/interface/pxe/pxe_udp.c
+++ b/src/interface/pxe/pxe_udp.c
@@ -43,23 +43,20 @@
* pxenv_udp_read(). (If s_PXENV_UDP_OPEN::src_ip is 0.0.0.0, the
* local station's IP address will remain unchanged.)
*
- * You can have multiple UDP connections open simultaneously (and
- * even open concurrently with TFTP connections), provided that
+ * You can only have one open UDP connection at a time. You cannot
+ * have a UDP connection open at the same time as a TFTP connection.
+ * (This is not strictly true for Etherboot; see the relevant @ref
+ * pxe_note_udp "implementation note" for more details.)
*
- * - they all have the same local IP address, and
+ * On x86, you must set the s_PXE::StatusCallout field to a nonzero
+ * value before calling this function in protected mode. You cannot
+ * call this function with a 32-bit stack segment. (See the relevant
+ * @ref pxe_x86_pmode16 "implementation note" for more details.)
*
- * - you take the multiple connections into account when calling
- * pxenv_udp_read().
- *
- * On x86, you can call pxenv_udp_open() in real mode, 16-bit
- * protected mode with a 16-bit stack segment, 16-bit protected mode
- * with a 32-bit stack segment, or V86 mode. The pxe::StatusCallout
- * field may be zero even in protected mode.
- *
- * @note The PXE specification states that you have only one UDP
- * connection open at a time, and that you cannot have a UDP
- * connection open simultaneously with a TFTP connection. Etherboot
- * does not enforce this unnecessary restriction.
+ * @note The PXE specification does not make it clear whether the IP
+ * address supplied in s_PXENV_UDP_OPEN::src_ip should be used only
+ * for this UDP connection, or retained for all future communication.
+ * The latter seems more consistent with typical PXE stack behaviour.
*
*/
PXENV_EXIT_t pxenv_udp_open ( struct s_PXENV_UDP_OPEN *udp_open ) {
@@ -85,21 +82,19 @@ PXENV_EXIT_t pxenv_udp_open ( struct s_PXENV_UDP_OPEN *udp_open ) {
* @ret s_PXENV_UDP_CLOSE::Status PXE status code
* @err None -
*
- * Closes a UDP "connection" opened with pxenv_udp_open(). Since UDP
- * is a connectionless protocol, this is a no-op.
- *
- * You can call pxenv_udp_close() even if there is another active UDP
- * or TFTP connection, since it has no effect on anything.
+ * Closes a UDP "connection" opened with pxenv_udp_open().
*
- * You can call pxenv_udp_close() in real mode, 16-bit protected mode
- * with a 16-bit stack segment, 16-bit protected mode with a 32-bit
- * stack segment, or V86 mode. The pxe::StatusCallout field may be
- * zero even in protected mode.
+ * You can only have one open UDP connection at a time. You cannot
+ * have a UDP connection open at the same time as a TFTP connection.
+ * You cannot use pxenv_udp_close() to close a TFTP connection; use
+ * pxenv_tftp_close() instead. (This is not strictly true for
+ * Etherboot; see the relevant @ref pxe_note_udp "implementation note"
+ * for more details.)
*
- * @note The PXE specification states that you have only one UDP
- * connection open at a time, and that you cannot have a UDP
- * connection open simultaneously with a TFTP connection. Etherboot
- * does not enforce this unnecessary restriction.
+ * On x86, you must set the s_PXE::StatusCallout field to a nonzero
+ * value before calling this function in protected mode. You cannot
+ * call this function with a 32-bit stack segment. (See the relevant
+ * @ref pxe_x86_pmode16 "implementation note" for more details.)
*
*/
PXENV_EXIT_t pxenv_udp_close ( struct s_PXENV_UDP_CLOSE *udp_close __unused ) {
@@ -119,7 +114,7 @@ PXENV_EXIT_t pxenv_udp_close ( struct s_PXENV_UDP_CLOSE *udp_close __unused ) {
* @v s_PXENV_UDP_WRITE::buffer_size Length of the UDP payload
* @v s_PXENV_UDP_WRITE::buffer Address of the UDP payload
* @ret #PXENV_EXIT_SUCCESS Packet was transmitted successfully
- * @ret #PXENV_EXIT_FAILURE Packet could not be transmitter
+ * @ret #PXENV_EXIT_FAILURE Packet could not be transmitted
* @ret s_PXENV_UDP_WRITE::Status PXE status code
* @err #PXENV_STATUS_UNDI_INVALID_STATE NIC could not be initialised
* @err #PXENV_STATUS_OUT_OF_RESOURCES Packet was too large to transmit
@@ -138,20 +133,15 @@ PXENV_EXIT_t pxenv_udp_close ( struct s_PXENV_UDP_CLOSE *udp_close __unused ) {
*
* If s_PXENV_UDP_WRITE::src_port is 0, port 2069 will be used.
*
- * It is not necessary to call pxenv_udp_open() before using
- * pxenv_udp_write(), unless you want to change the local station's IP
- * address. pxenv_udp_write() can be called even if there is another
- * active UDP or TFTP connection,.
- *
- * You can call pxenv_udp_write() in real mode, 16-bit protected mode
- * with a 16-bit stack segment, 16-bit protected mode with a 32-bit
- * stack segment, or V86 mode. The pxe::StatusCallout field may be
- * zero even in protected mode.
+ * You must have opened a UDP connection with pxenv_udp_open() before
+ * calling pxenv_udp_write(). (This is not strictly true for
+ * Etherboot; see the relevant @ref pxe_note_udp "implementation note"
+ * for more details.)
*
- * @note The PXE specification states that you have only one UDP
- * connection open at a time, and that you cannot have a UDP
- * connection open simultaneously with a TFTP connection. Etherboot
- * does not enforce this unnecessary restriction.
+ * On x86, you must set the s_PXE::StatusCallout field to a nonzero
+ * value before calling this function in protected mode. You cannot
+ * call this function with a 32-bit stack segment. (See the relevant
+ * @ref pxe_x86_pmode16 "implementation note" for more details.)
*
* @bug s_PXENV_UDP_WRITE::gw is ignored; the default routing table is
* always used.
@@ -278,26 +268,20 @@ static int await_pxe_udp ( int ival __unused, void *ptr,
* s_PXENV_UDP_READ::Status==PXENV_STATUS_FAILURE.
*
* If s_PXENV_UDP_READ::dest_ip is 0.0.0.0, UDP packets addressed to
- * any IP address will be accepted and may be returned.
+ * any IP address will be accepted and may be returned to the caller.
*
* If s_PXENV_UDP_READ::d_port is 0, UDP packets addressed to any UDP
- * port will be accepted and may be returned.
+ * port will be accepted and may be returned to the caller.
*
- * It is not necessary to call pxenv_udp_open() before using
- * pxenv_udp_read(). pxenv_udp_read() can be called even if there is
- * another active UDP or TFTP connection, but be aware that you might
- * then receive (or cause to be lost) a packet belonging to another
- * connection.
+ * You must have opened a UDP connection with pxenv_udp_open() before
+ * calling pxenv_udp_read(). (This is not strictly true for
+ * Etherboot; see the relevant @ref pxe_note_udp "implementation note"
+ * for more details.)
*
- * You can call pxenv_udp_read() in real mode, 16-bit protected mode
- * with a 16-bit stack segment, 16-bit protected mode with a 32-bit
- * stack segment, or V86 mode. The pxe::StatusCallout field may be
- * zero even in protected mode.
- *
- * @note The PXE specification states that you have only one UDP
- * connection open at a time, and that you cannot have a UDP
- * connection open simultaneously with a TFTP connection. Etherboot
- * does not enforce this unnecessary restriction.
+ * On x86, you must set the s_PXE::StatusCallout field to a nonzero
+ * value before calling this function in protected mode. You cannot
+ * call this function with a 32-bit stack segment. (See the relevant
+ * @ref pxe_x86_pmode16 "implementation note" for more details.)
*
* @note The PXE specification (version 2.1) does not state that we
* should fill in s_PXENV_UDP_READ::dest_ip and
@@ -319,3 +303,31 @@ PXENV_EXIT_t pxenv_udp_read ( struct s_PXENV_UDP_READ *udp_read ) {
udp_read->Status = PXENV_STATUS_SUCCESS;
return PXENV_EXIT_SUCCESS;
}
+
+/** @page pxe_notes PXE implementation notes
+
+@section pxe_note_udp The connectionless nature of UDP
+
+The PXE specification states that it is possible to have only one open
+UDP or TFTP connection at any one time. Etherboot does not
+rigourously enforce this restriction, on the UNIX principle that the
+code should not prevent the user from doing stupid things, because
+that would also prevent the user from doing clever things. Since UDP
+is a connectionless protocol, it is perfectly possible to have
+multiple concurrent UDP "connections" open, provided that you take the
+multiplicity of connections into account when calling
+pxenv_udp_read(). Similarly, there is no technical reason that
+prevents you from calling pxenv_udp_write() in the middle of a TFTP
+download.
+
+Etherboot will therefore never return error codes indicating "a
+connection is already open", such as #PXENV_STATUS_UDP_OPEN. If you
+want to have multiple concurrent connections, go for it (but don't
+expect your perfectly sensible code to work with any other PXE stack).
+
+Since Etherboot treats UDP as the connectionless protocol that it
+really is, pxenv_udp_close() is actually a no-op, and there is no need
+to call pxenv_udp_open() before using pxenv_udp_write() or
+pxenv_udp_read().
+
+*/