Add per-file error identifiers
[people/holger/gpxe.git] / src / include / gpxe / iobuf.h
1 #ifndef _GPXE_IOBUF_H
2 #define _GPXE_IOBUF_H
3
4 /** @file
5  *
6  * I/O buffers
7  *
8  */
9
10 #include <stdint.h>
11 #include <assert.h>
12 #include <gpxe/list.h>
13
14 /**
15  * I/O buffer alignment
16  *
17  * I/O buffers allocated via alloc_iob() are guaranteed to be
18  * physically aligned to this boundary.  Some cards cannot DMA across
19  * a 4kB boundary.  With a standard Ethernet MTU, aligning to a 2kB
20  * boundary is sufficient to guarantee no 4kB boundary crossings.  For
21  * a jumbo Ethernet MTU, a packet may be larger than 4kB anyway.
22  */
23 #define IOB_ALIGN 2048
24
25 /**
26  * Minimum I/O buffer length
27  *
28  * alloc_iob() will round up the allocated length to this size if
29  * necessary.  This is used on behalf of hardware that is not capable
30  * of auto-padding.
31  */
32 #define IOB_ZLEN 64
33
34 /**
35  * A persistent I/O buffer
36  *
37  * This data structure encapsulates a long-lived I/O buffer.  The
38  * buffer may be passed between multiple owners, queued for possible
39  * retransmission, etc.
40  */
41 struct io_buffer {
42         /** List of which this buffer is a member
43          *
44          * The list must belong to the current owner of the buffer.
45          * Different owners may maintain different lists (e.g. a
46          * retransmission list for TCP).
47          */
48         struct list_head list;
49
50         /** Start of the buffer */
51         void *head;
52         /** Start of data */
53         void *data;
54         /** End of data */
55         void *tail;
56         /** End of the buffer */
57         void *end;
58 };
59
60 /**
61  * Reserve space at start of I/O buffer
62  *
63  * @v iobuf     I/O buffer
64  * @v len       Length to reserve
65  * @ret data    Pointer to new start of buffer
66  */
67 static inline void * iob_reserve ( struct io_buffer *iobuf, size_t len ) {
68         iobuf->data += len;
69         iobuf->tail += len;
70         assert ( iobuf->tail <= iobuf->end );
71         return iobuf->data;
72 }
73
74 /**
75  * Add data to start of I/O buffer
76  *
77  * @v iobuf     I/O buffer
78  * @v len       Length to add
79  * @ret data    Pointer to new start of buffer
80  */
81 static inline void * iob_push ( struct io_buffer *iobuf, size_t len ) {
82         iobuf->data -= len;
83         assert ( iobuf->data >= iobuf->head );
84         return iobuf->data;
85 }
86
87 /**
88  * Remove data from start of I/O buffer
89  *
90  * @v iobuf     I/O buffer
91  * @v len       Length to remove
92  * @ret data    Pointer to new start of buffer
93  */
94 static inline void * iob_pull ( struct io_buffer *iobuf, size_t len ) {
95         iobuf->data += len;
96         assert ( iobuf->data <= iobuf->tail );
97         return iobuf->data;
98 }
99
100 /**
101  * Add data to end of I/O buffer
102  *
103  * @v iobuf     I/O buffer
104  * @v len       Length to add
105  * @ret data    Pointer to newly added space
106  */
107 static inline void * iob_put ( struct io_buffer *iobuf, size_t len ) {
108         void *old_tail = iobuf->tail;
109         iobuf->tail += len;
110         assert ( iobuf->tail <= iobuf->end );
111         return old_tail;
112 }
113
114 /**
115  * Remove data from end of I/O buffer
116  *
117  * @v iobuf     I/O buffer
118  * @v len       Length to remove
119  */
120 static inline void iob_unput ( struct io_buffer *iobuf, size_t len ) {
121         iobuf->tail -= len;
122         assert ( iobuf->tail >= iobuf->data );
123 }
124
125 /**
126  * Empty an I/O buffer
127  *
128  * @v iobuf     I/O buffer
129  */
130 static inline void iob_empty ( struct io_buffer *iobuf ) {
131         iobuf->tail = iobuf->data;
132 }
133
134 /**
135  * Calculate length of data in an I/O buffer
136  *
137  * @v iobuf     I/O buffer
138  * @ret len     Length of data in buffer
139  */
140 static inline size_t iob_len ( struct io_buffer *iobuf ) {
141         return ( iobuf->tail - iobuf->data );
142 }
143
144 /**
145  * Calculate available space at start of an I/O buffer
146  *
147  * @v iobuf     I/O buffer
148  * @ret len     Length of data available at start of buffer
149  */
150 static inline size_t iob_headroom ( struct io_buffer *iobuf ) {
151         return ( iobuf->data - iobuf->head );
152 }
153
154 /**
155  * Calculate available space at end of an I/O buffer
156  *
157  * @v iobuf     I/O buffer
158  * @ret len     Length of data available at end of buffer
159  */
160 static inline size_t iob_tailroom ( struct io_buffer *iobuf ) {
161         return ( iobuf->end - iobuf->tail );
162 }
163
164 extern struct io_buffer * alloc_iob ( size_t len );
165 extern void free_iob ( struct io_buffer *iobuf );
166 extern void iob_pad ( struct io_buffer *iobuf, size_t min_len );
167 extern int iob_ensure_headroom ( struct io_buffer *iobuf, size_t len );
168
169 #endif /* _GPXE_IOBUF_H */