diff options
Diffstat (limited to 'debian/grub-extras/disabled/gpxe/src/include/gpxe/iobuf.h')
-rw-r--r-- | debian/grub-extras/disabled/gpxe/src/include/gpxe/iobuf.h | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/debian/grub-extras/disabled/gpxe/src/include/gpxe/iobuf.h b/debian/grub-extras/disabled/gpxe/src/include/gpxe/iobuf.h new file mode 100644 index 0000000..8f05f9e --- /dev/null +++ b/debian/grub-extras/disabled/gpxe/src/include/gpxe/iobuf.h @@ -0,0 +1,229 @@ +#ifndef _GPXE_IOBUF_H +#define _GPXE_IOBUF_H + +/** @file + * + * I/O buffers + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <stdint.h> +#include <assert.h> +#include <gpxe/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 /* _GPXE_IOBUF_H */ |