diff options
author | Michael Brown <mcb30@ipxe.org> | 2010-04-19 20:16:01 +0100 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2010-04-19 23:43:39 +0100 |
commit | 8406115834d38bb743e01f35bfd36e835532415e (patch) | |
tree | ee1e3106e2cdc645d911ba5643f8414b21fc4c3e /src/include/ipxe/iobuf.h | |
parent | 2a36703af228bd10d50a31daec96072fe3a992a3 (diff) | |
download | ipxe-8406115834d38bb743e01f35bfd36e835532415e.tar.gz |
[build] Rename gPXE to iPXE
Access to the gpxe.org and etherboot.org domains and associated
resources has been revoked by the registrant of the domain. Work
around this problem by renaming project from gPXE to iPXE, and
updating URLs to match.
Also update README, LOG and COPYRIGHTS to remove obsolete information.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/include/ipxe/iobuf.h')
-rw-r--r-- | src/include/ipxe/iobuf.h | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/src/include/ipxe/iobuf.h b/src/include/ipxe/iobuf.h new file mode 100644 index 000000000..82c8b8896 --- /dev/null +++ b/src/include/ipxe/iobuf.h @@ -0,0 +1,229 @@ +#ifndef _IPXE_IOBUF_H +#define _IPXE_IOBUF_H + +/** @file + * + * I/O buffers + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <stdint.h> +#include <assert.h> +#include <ipxe/list.h> + +/** + * I/O buffer alignment + * + * I/O buffers allocated via alloc_iob() are guaranteed to be + * physically aligned to this boundary. Some cards cannot DMA across + * a 4kB boundary. With a standard Ethernet MTU, aligning to a 2kB + * boundary is sufficient to guarantee no 4kB boundary crossings. For + * a jumbo Ethernet MTU, a packet may be larger than 4kB anyway. + */ +#define IOB_ALIGN 2048 + +/** + * Minimum I/O buffer length + * + * alloc_iob() will round up the allocated length to this size if + * necessary. This is used on behalf of hardware that is not capable + * of auto-padding. + */ +#define IOB_ZLEN 64 + +/** + * A persistent I/O buffer + * + * This data structure encapsulates a long-lived I/O buffer. The + * buffer may be passed between multiple owners, queued for possible + * retransmission, etc. + */ +struct io_buffer { + /** List of which this buffer is a member + * + * The list must belong to the current owner of the buffer. + * Different owners may maintain different lists (e.g. a + * retransmission list for TCP). + */ + struct list_head list; + + /** Start of the buffer */ + void *head; + /** Start of data */ + void *data; + /** End of data */ + void *tail; + /** End of the buffer */ + void *end; +}; + +/** + * Reserve space at start of I/O buffer + * + * @v iobuf I/O buffer + * @v len Length to reserve + * @ret data Pointer to new start of buffer + */ +static inline void * iob_reserve ( struct io_buffer *iobuf, size_t len ) { + iobuf->data += len; + iobuf->tail += len; + return iobuf->data; +} +#define iob_reserve( iobuf, len ) ( { \ + void *__result; \ + __result = iob_reserve ( (iobuf), (len) ); \ + assert ( (iobuf)->tail <= (iobuf)->end ); \ + __result; } ) + +/** + * Add data to start of I/O buffer + * + * @v iobuf I/O buffer + * @v len Length to add + * @ret data Pointer to new start of buffer + */ +static inline void * iob_push ( struct io_buffer *iobuf, size_t len ) { + iobuf->data -= len; + return iobuf->data; +} +#define iob_push( iobuf, len ) ( { \ + void *__result; \ + __result = iob_push ( (iobuf), (len) ); \ + assert ( (iobuf)->data >= (iobuf)->head ); \ + __result; } ) + +/** + * Remove data from start of I/O buffer + * + * @v iobuf I/O buffer + * @v len Length to remove + * @ret data Pointer to new start of buffer + */ +static inline void * iob_pull ( struct io_buffer *iobuf, size_t len ) { + iobuf->data += len; + assert ( iobuf->data <= iobuf->tail ); + return iobuf->data; +} +#define iob_pull( iobuf, len ) ( { \ + void *__result; \ + __result = iob_pull ( (iobuf), (len) ); \ + assert ( (iobuf)->data <= (iobuf)->tail ); \ + __result; } ) + +/** + * Add data to end of I/O buffer + * + * @v iobuf I/O buffer + * @v len Length to add + * @ret data Pointer to newly added space + */ +static inline void * iob_put ( struct io_buffer *iobuf, size_t len ) { + void *old_tail = iobuf->tail; + iobuf->tail += len; + return old_tail; +} +#define iob_put( iobuf, len ) ( { \ + void *__result; \ + __result = iob_put ( (iobuf), (len) ); \ + assert ( (iobuf)->tail <= (iobuf)->end ); \ + __result; } ) + +/** + * Remove data from end of I/O buffer + * + * @v iobuf I/O buffer + * @v len Length to remove + */ +static inline void iob_unput ( struct io_buffer *iobuf, size_t len ) { + iobuf->tail -= len; +} +#define iob_unput( iobuf, len ) do { \ + iob_unput ( (iobuf), (len) ); \ + assert ( (iobuf)->tail >= (iobuf)->data ); \ + } while ( 0 ) + +/** + * Empty an I/O buffer + * + * @v iobuf I/O buffer + */ +static inline void iob_empty ( struct io_buffer *iobuf ) { + iobuf->tail = iobuf->data; +} + +/** + * Calculate length of data in an I/O buffer + * + * @v iobuf I/O buffer + * @ret len Length of data in buffer + */ +static inline size_t iob_len ( struct io_buffer *iobuf ) { + return ( iobuf->tail - iobuf->data ); +} + +/** + * Calculate available space at start of an I/O buffer + * + * @v iobuf I/O buffer + * @ret len Length of data available at start of buffer + */ +static inline size_t iob_headroom ( struct io_buffer *iobuf ) { + return ( iobuf->data - iobuf->head ); +} + +/** + * Calculate available space at end of an I/O buffer + * + * @v iobuf I/O buffer + * @ret len Length of data available at end of buffer + */ +static inline size_t iob_tailroom ( struct io_buffer *iobuf ) { + return ( iobuf->end - iobuf->tail ); +} + +/** + * Create a temporary I/O buffer + * + * @v iobuf I/O buffer + * @v data Data buffer + * @v len Length of data + * @v max_len Length of buffer + * + * It is sometimes useful to use the iob_xxx() methods on temporary + * data buffers. + */ +static inline void iob_populate ( struct io_buffer *iobuf, + void *data, size_t len, size_t max_len ) { + iobuf->head = iobuf->data = data; + iobuf->tail = ( data + len ); + iobuf->end = ( data + max_len ); +} + +/** + * Disown an I/O buffer + * + * @v iobuf I/O buffer + * + * There are many functions that take ownership of the I/O buffer they + * are passed as a parameter. The caller should not retain a pointer + * to the I/O buffer. Use iob_disown() to automatically nullify the + * caller's pointer, e.g.: + * + * xfer_deliver_iob ( xfer, iob_disown ( iobuf ) ); + * + * This will ensure that iobuf is set to NULL for any code after the + * call to xfer_deliver_iob(). + */ +#define iob_disown( iobuf ) ( { \ + struct io_buffer *__iobuf = (iobuf); \ + (iobuf) = NULL; \ + __iobuf; } ) + +extern struct io_buffer * __malloc alloc_iob ( size_t len ); +extern void free_iob ( struct io_buffer *iobuf ); +extern void iob_pad ( struct io_buffer *iobuf, size_t min_len ); +extern int iob_ensure_headroom ( struct io_buffer *iobuf, size_t len ); + +#endif /* _IPXE_IOBUF_H */ |