Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / include / ipxe / iobuf.h
1 #ifndef _IPXE_IOBUF_H
2 #define _IPXE_IOBUF_H
3
4 /** @file
5  *
6  * I/O buffers
7  *
8  */
9
10 FILE_LICENCE ( GPL2_OR_LATER );
11
12 #include <stdint.h>
13 #include <assert.h>
14 #include <ipxe/list.h>
15
16 /**
17  * Minimum I/O buffer length
18  *
19  * alloc_iob() will round up the allocated length to this size if
20  * necessary.  This is used on behalf of hardware that is not capable
21  * of auto-padding.
22  */
23 #define IOB_ZLEN 64
24
25 /**
26  * A persistent I/O buffer
27  *
28  * This data structure encapsulates a long-lived I/O buffer.  The
29  * buffer may be passed between multiple owners, queued for possible
30  * retransmission, etc.
31  */
32 struct io_buffer {
33         /** List of which this buffer is a member
34          *
35          * The list must belong to the current owner of the buffer.
36          * Different owners may maintain different lists (e.g. a
37          * retransmission list for TCP).
38          */
39         struct list_head list;
40
41         /** Start of the buffer */
42         void *head;
43         /** Start of data */
44         void *data;
45         /** End of data */
46         void *tail;
47         /** End of the buffer */
48         void *end;
49 };
50
51 /**
52  * Reserve space at start of I/O buffer
53  *
54  * @v iobuf     I/O buffer
55  * @v len       Length to reserve
56  * @ret data    Pointer to new start of buffer
57  */
58 static inline void * iob_reserve ( struct io_buffer *iobuf, size_t len ) {
59         iobuf->data += len;
60         iobuf->tail += len;
61         return iobuf->data;
62 }
63 #define iob_reserve( iobuf, len ) ( {                   \
64         void *__result;                                 \
65         __result = iob_reserve ( (iobuf), (len) );      \
66         assert ( (iobuf)->tail <= (iobuf)->end );       \
67         __result; } )
68
69 /**
70  * Add data to start of I/O buffer
71  *
72  * @v iobuf     I/O buffer
73  * @v len       Length to add
74  * @ret data    Pointer to new start of buffer
75  */
76 static inline void * iob_push ( struct io_buffer *iobuf, size_t len ) {
77         iobuf->data -= len;
78         return iobuf->data;
79 }
80 #define iob_push( iobuf, len ) ( {                      \
81         void *__result;                                 \
82         __result = iob_push ( (iobuf), (len) );         \
83         assert ( (iobuf)->data >= (iobuf)->head );      \
84         __result; } )
85
86 /**
87  * Remove data from start of I/O buffer
88  *
89  * @v iobuf     I/O buffer
90  * @v len       Length to remove
91  * @ret data    Pointer to new start of buffer
92  */
93 static inline void * iob_pull ( struct io_buffer *iobuf, size_t len ) {
94         iobuf->data += len;
95         assert ( iobuf->data <= iobuf->tail );
96         return iobuf->data;
97 }
98 #define iob_pull( iobuf, len ) ( {                      \
99         void *__result;                                 \
100         __result = iob_pull ( (iobuf), (len) );         \
101         assert ( (iobuf)->data <= (iobuf)->tail );      \
102         __result; } )
103
104 /**
105  * Add data to end of I/O buffer
106  *
107  * @v iobuf     I/O buffer
108  * @v len       Length to add
109  * @ret data    Pointer to newly added space
110  */
111 static inline void * iob_put ( struct io_buffer *iobuf, size_t len ) {
112         void *old_tail = iobuf->tail;
113         iobuf->tail += len;
114         return old_tail;
115 }
116 #define iob_put( iobuf, len ) ( {                       \
117         void *__result;                                 \
118         __result = iob_put ( (iobuf), (len) );          \
119         assert ( (iobuf)->tail <= (iobuf)->end );       \
120         __result; } )
121
122 /**
123  * Remove data from end of I/O buffer
124  *
125  * @v iobuf     I/O buffer
126  * @v len       Length to remove
127  */
128 static inline void iob_unput ( struct io_buffer *iobuf, size_t len ) {
129         iobuf->tail -= len;
130 }
131 #define iob_unput( iobuf, len ) do {                    \
132         iob_unput ( (iobuf), (len) );                   \
133         assert ( (iobuf)->tail >= (iobuf)->data );      \
134         } while ( 0 )
135
136 /**
137  * Empty an I/O buffer
138  *
139  * @v iobuf     I/O buffer
140  */
141 static inline void iob_empty ( struct io_buffer *iobuf ) {
142         iobuf->tail = iobuf->data;
143 }
144
145 /**
146  * Calculate length of data in an I/O buffer
147  *
148  * @v iobuf     I/O buffer
149  * @ret len     Length of data in buffer
150  */
151 static inline size_t iob_len ( struct io_buffer *iobuf ) {
152         return ( iobuf->tail - iobuf->data );
153 }
154
155 /**
156  * Calculate available space at start of an I/O buffer
157  *
158  * @v iobuf     I/O buffer
159  * @ret len     Length of data available at start of buffer
160  */
161 static inline size_t iob_headroom ( struct io_buffer *iobuf ) {
162         return ( iobuf->data - iobuf->head );
163 }
164
165 /**
166  * Calculate available space at end of an I/O buffer
167  *
168  * @v iobuf     I/O buffer
169  * @ret len     Length of data available at end of buffer
170  */
171 static inline size_t iob_tailroom ( struct io_buffer *iobuf ) {
172         return ( iobuf->end - iobuf->tail );
173 }
174
175 /**
176  * Create a temporary I/O buffer
177  *
178  * @v iobuf     I/O buffer
179  * @v data      Data buffer
180  * @v len       Length of data
181  * @v max_len   Length of buffer
182  *
183  * It is sometimes useful to use the iob_xxx() methods on temporary
184  * data buffers.
185  */
186 static inline void iob_populate ( struct io_buffer *iobuf,
187                                   void *data, size_t len, size_t max_len ) {
188         iobuf->head = iobuf->data = data;
189         iobuf->tail = ( data + len );
190         iobuf->end = ( data + max_len );
191 }
192
193 /**
194  * Disown an I/O buffer
195  *
196  * @v iobuf     I/O buffer
197  *
198  * There are many functions that take ownership of the I/O buffer they
199  * are passed as a parameter.  The caller should not retain a pointer
200  * to the I/O buffer.  Use iob_disown() to automatically nullify the
201  * caller's pointer, e.g.:
202  *
203  *     xfer_deliver_iob ( xfer, iob_disown ( iobuf ) );
204  *
205  * This will ensure that iobuf is set to NULL for any code after the
206  * call to xfer_deliver_iob().
207  */
208 #define iob_disown( iobuf ) ( {                         \
209         struct io_buffer *__iobuf = (iobuf);            \
210         (iobuf) = NULL;                                 \
211         __iobuf; } )
212
213 extern struct io_buffer * __malloc alloc_iob_raw ( size_t len, size_t align,
214                                                    size_t offset );
215 extern struct io_buffer * __malloc alloc_iob ( size_t len );
216 extern void free_iob ( struct io_buffer *iobuf );
217 extern void iob_pad ( struct io_buffer *iobuf, size_t min_len );
218 extern int iob_ensure_headroom ( struct io_buffer *iobuf, size_t len );
219 extern struct io_buffer * iob_concatenate ( struct list_head *list );
220
221 #endif /* _IPXE_IOBUF_H */