Renamed _calloc() to zalloc(), ready to be used as a standalone function.
[people/pcmattman/gpxe.git] / src / include / gpxe / xfer.h
1 #ifndef _GPXE_XFER_H
2 #define _GPXE_XFER_H
3
4 /** @file
5  *
6  * Data transfer interfaces
7  *
8  */
9
10 #include <stddef.h>
11 #include <stdarg.h>
12 #include <gpxe/interface.h>
13 #include <gpxe/iobuf.h>
14
15 struct xfer_interface;
16
17 /** Data transfer interface operations */
18 struct xfer_interface_operations {
19         /** Close interface
20          *
21          * @v xfer              Data transfer interface
22          * @v rc                Reason for close
23          */
24         void ( * close ) ( struct xfer_interface *xfer, int rc );
25         /** Redirect to new location
26          *
27          * @v xfer              Data transfer interface
28          * @v type              New location type
29          * @v args              Remaining arguments depend upon location type
30          * @ret rc              Return status code
31          */
32         int ( * vredirect ) ( struct xfer_interface *xfer, int type,
33                               va_list args );
34         /** Request data
35          *
36          * @v xfer              Data transfer interface
37          * @v offset            Offset to new position
38          * @v whence            Basis for new position
39          * @v len               Length of requested data
40          * @ret rc              Return status code
41          */
42         int ( * request ) ( struct xfer_interface *xfer, off_t offset,
43                             int whence, size_t len );
44         /** Seek to position
45          *
46          * @v xfer              Data transfer interface
47          * @v offset            Offset to new position
48          * @v whence            Basis for new position
49          * @ret rc              Return status code
50          *
51          * @c whence must be one of @c SEEK_SET or @c SEEK_CUR.  A
52          * successful return indicates that the interface is ready to
53          * immediately accept datagrams; return -EAGAIN if this is not
54          * the case.
55          */
56         int ( * seek ) ( struct xfer_interface *xfer, off_t offset,
57                          int whence );
58         /** Allocate I/O buffer
59          *
60          * @v xfer              Data transfer interface
61          * @v len               I/O buffer payload length
62          * @ret iobuf           I/O buffer
63          */
64         struct io_buffer * ( * alloc_iob ) ( struct xfer_interface *xfer,
65                                              size_t len );
66         /** Deliver datagram as I/O buffer
67          *
68          * @v xfer              Data transfer interface
69          * @v iobuf             Datagram I/O buffer
70          * @ret rc              Return status code
71          *
72          * A data transfer interface that wishes to support only raw
73          * data delivery should set this method to
74          * xfer_deliver_as_raw().
75          *
76          * Interfaces may not temporarily refuse to accept data by
77          * returning -EAGAIN; such a response may be treated as a
78          * fatal error.
79          */
80         int ( * deliver_iob ) ( struct xfer_interface *xfer,
81                                 struct io_buffer *iobuf );
82         /** Deliver datagram as raw data
83          *
84          * @v xfer              Data transfer interface
85          * @v data              Data buffer
86          * @v len               Length of data buffer
87          * @ret rc              Return status code
88          *
89          * A data transfer interface that wishes to support only I/O
90          * buffer delivery should set this method to
91          * xfer_deliver_as_iob().
92          *
93          * Interfaces may not temporarily refuse to accept data by
94          * returning -EAGAIN; such a response may be treated as a
95          * fatal error.
96          */
97         int ( * deliver_raw ) ( struct xfer_interface *xfer,
98                                 const void *data, size_t len );
99 };
100
101 /** A data transfer interface */
102 struct xfer_interface {
103         /** Generic object communication interface */
104         struct interface intf;
105         /** Operations for received messages */
106         struct xfer_interface_operations *op;
107 };
108
109 /** Basis positions for seek() events */
110 enum seek_whence {
111         SEEK_SET = 0,
112         SEEK_CUR,
113 };
114
115 /**
116  * Describe seek basis
117  *
118  * @v whence            Basis for new position
119  */
120 static inline __attribute__ (( always_inline )) const char *
121 whence_text ( int whence ) {
122         switch ( whence ) {
123         case SEEK_SET:  return "SET";
124         case SEEK_CUR:  return "CUR";
125         default:        return "INVALID";
126         }
127 }
128
129 extern struct xfer_interface null_xfer;
130 extern struct xfer_interface_operations null_xfer_ops;
131
132 extern void xfer_close ( struct xfer_interface *xfer, int rc );
133 extern int xfer_vredirect ( struct xfer_interface *xfer, int type,
134                             va_list args );
135 extern int xfer_redirect ( struct xfer_interface *xfer, int type, ... );
136 extern int xfer_request ( struct xfer_interface *xfer, off_t offset,
137                           int whence, size_t len );
138 extern int xfer_seek ( struct xfer_interface *xfer, off_t offset, int whence );
139 extern int xfer_ready ( struct xfer_interface *xfer );
140 extern struct io_buffer * xfer_alloc_iob ( struct xfer_interface *xfer,
141                                            size_t len );
142 extern int xfer_deliver_iob ( struct xfer_interface *xfer,
143                               struct io_buffer *iobuf );
144 extern int xfer_deliver_raw ( struct xfer_interface *xfer,
145                               const void *data, size_t len );
146 extern int xfer_vprintf ( struct xfer_interface *xfer,
147                           const char *format, va_list args );
148 extern int xfer_printf ( struct xfer_interface *xfer,
149                          const char *format, ... );
150
151 extern void ignore_xfer_close ( struct xfer_interface *xfer, int rc );
152 extern int ignore_xfer_vredirect ( struct xfer_interface *xfer,
153                                    int type, va_list args );
154 extern int ignore_xfer_request ( struct xfer_interface *xfer, off_t offset,
155                                  int whence, size_t len );
156 extern int ignore_xfer_seek ( struct xfer_interface *xfer, off_t offset,
157                               int whence );
158 extern struct io_buffer * default_xfer_alloc_iob ( struct xfer_interface *xfer,
159                                                    size_t len );
160 extern int xfer_deliver_as_raw ( struct xfer_interface *xfer,
161                                  struct io_buffer *iobuf );
162 extern int xfer_deliver_as_iob ( struct xfer_interface *xfer,
163                                  const void *data, size_t len );
164 extern int ignore_xfer_deliver_raw ( struct xfer_interface *xfer,
165                                      const void *data __unused, size_t len );
166
167 /**
168  * Initialise a data transfer interface
169  *
170  * @v xfer              Data transfer interface
171  * @v op                Data transfer interface operations
172  * @v refcnt            Containing object reference counter, or NULL
173  */
174 static inline void xfer_init ( struct xfer_interface *xfer,
175                                struct xfer_interface_operations *op,
176                                struct refcnt *refcnt ) {
177         xfer->intf.dest = &null_xfer.intf;
178         xfer->intf.refcnt = refcnt;
179         xfer->op = op;
180 }
181
182 /**
183  * Get data transfer interface from generic object communication interface
184  *
185  * @v intf              Generic object communication interface
186  * @ret xfer            Data transfer interface
187  */
188 static inline __attribute__ (( always_inline )) struct xfer_interface *
189 intf_to_xfer ( struct interface *intf ) {
190         return container_of ( intf, struct xfer_interface, intf );
191 }
192
193 /**
194  * Get reference to destination data transfer interface
195  *
196  * @v xfer              Data transfer interface
197  * @ret dest            Destination interface
198  */
199 static inline __attribute__ (( always_inline )) struct xfer_interface *
200 xfer_get_dest ( struct xfer_interface *xfer ) {
201         return intf_to_xfer ( intf_get ( xfer->intf.dest ) );
202 }
203
204 /**
205  * Drop reference to data transfer interface
206  *
207  * @v xfer              Data transfer interface
208  */
209 static inline __attribute__ (( always_inline )) void
210 xfer_put ( struct xfer_interface *xfer ) {
211         intf_put ( &xfer->intf );
212 }
213
214 /**
215  * Plug a data transfer interface into a new destination interface
216  *
217  * @v xfer              Data transfer interface
218  * @v dest              New destination interface
219  */
220 static inline __attribute__ (( always_inline )) void
221 xfer_plug ( struct xfer_interface *xfer, struct xfer_interface *dest ) {
222         plug ( &xfer->intf, &dest->intf );
223 }
224
225 /**
226  * Plug two data transfer interfaces together
227  *
228  * @v a                 Data transfer interface A
229  * @v b                 Data transfer interface B
230  */
231 static inline __attribute__ (( always_inline )) void
232 xfer_plug_plug ( struct xfer_interface *a, struct xfer_interface *b ) {
233         plug_plug ( &a->intf, &b->intf );
234 }
235
236 /**
237  * Unplug a data transfer interface
238  *
239  * @v xfer              Data transfer interface
240  */
241 static inline __attribute__ (( always_inline )) void
242 xfer_unplug ( struct xfer_interface *xfer ) {
243         plug ( &xfer->intf, &null_xfer.intf );
244 }
245
246 /**
247  * Stop using a data transfer interface
248  *
249  * @v xfer              Data transfer interface
250  *
251  * After calling this method, no further messages will be received via
252  * the interface.
253  */
254 static inline void xfer_nullify ( struct xfer_interface *xfer ) {
255         xfer->op = &null_xfer_ops;
256 };
257
258 #endif /* _GPXE_XFER_H */