71b69dc51f0d1e527d7680204b85efee922a8fbe
[people/dverkamp/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 extern struct xfer_interface null_xfer;
116 extern struct xfer_interface_operations null_xfer_ops;
117
118 extern void xfer_close ( struct xfer_interface *xfer, int rc );
119 extern int xfer_vredirect ( struct xfer_interface *xfer, int type,
120                             va_list args );
121 extern int xfer_redirect ( struct xfer_interface *xfer, int type, ... );
122 extern int xfer_request ( struct xfer_interface *xfer, off_t offset,
123                           int whence, size_t len );
124 extern int xfer_request_all ( struct xfer_interface *xfer );
125 extern int xfer_seek ( struct xfer_interface *xfer, off_t offset, int whence );
126 extern struct io_buffer * xfer_alloc_iob ( struct xfer_interface *xfer,
127                                            size_t len );
128 extern int xfer_deliver_iob ( struct xfer_interface *xfer,
129                               struct io_buffer *iobuf );
130 extern int xfer_deliver_raw ( struct xfer_interface *xfer,
131                               const void *data, size_t len );
132
133 extern void ignore_xfer_close ( struct xfer_interface *xfer, int rc );
134 extern int ignore_xfer_vredirect ( struct xfer_interface *xfer,
135                                    int type, va_list args );
136 extern int ignore_xfer_request ( struct xfer_interface *xfer, off_t offset,
137                                  int whence, size_t len );
138 extern int ignore_xfer_seek ( struct xfer_interface *xfer, off_t offset,
139                               int whence );
140 extern struct io_buffer * default_xfer_alloc_iob ( struct xfer_interface *xfer,
141                                                    size_t len );
142 extern int xfer_deliver_as_raw ( struct xfer_interface *xfer,
143                                  struct io_buffer *iobuf );
144 extern int xfer_deliver_as_iob ( struct xfer_interface *xfer,
145                                  const void *data, size_t len );
146 extern int ignore_xfer_deliver_raw ( struct xfer_interface *xfer,
147                                      const void *data __unused, size_t len );
148
149 /**
150  * Initialise a data transfer interface
151  *
152  * @v xfer              Data transfer interface
153  * @v op                Data transfer interface operations
154  * @v refcnt            Containing object reference counter, or NULL
155  */
156 static inline void xfer_init ( struct xfer_interface *xfer,
157                                struct xfer_interface_operations *op,
158                                struct refcnt *refcnt ) {
159         xfer->intf.dest = &null_xfer.intf;
160         xfer->intf.refcnt = refcnt;
161         xfer->op = op;
162 }
163
164 /**
165  * Get data transfer interface from generic object communication interface
166  *
167  * @v intf              Generic object communication interface
168  * @ret xfer            Data transfer interface
169  */
170 static inline __attribute__ (( always_inline )) struct xfer_interface *
171 intf_to_xfer ( struct interface *intf ) {
172         return container_of ( intf, struct xfer_interface, intf );
173 }
174
175 /**
176  * Get reference to destination data transfer interface
177  *
178  * @v xfer              Data transfer interface
179  * @ret dest            Destination interface
180  */
181 static inline __attribute__ (( always_inline )) struct xfer_interface *
182 xfer_get_dest ( struct xfer_interface *xfer ) {
183         return intf_to_xfer ( intf_get ( xfer->intf.dest ) );
184 }
185
186 /**
187  * Drop reference to data transfer interface
188  *
189  * @v xfer              Data transfer interface
190  */
191 static inline __attribute__ (( always_inline )) void
192 xfer_put ( struct xfer_interface *xfer ) {
193         intf_put ( &xfer->intf );
194 }
195
196 /**
197  * Plug a data transfer interface into a new destination interface
198  *
199  * @v xfer              Data transfer interface
200  * @v dest              New destination interface
201  */
202 static inline __attribute__ (( always_inline )) void
203 xfer_plug ( struct xfer_interface *xfer, struct xfer_interface *dest ) {
204         plug ( &xfer->intf, &dest->intf );
205 }
206
207 /**
208  * Plug two data transfer interfaces together
209  *
210  * @v a                 Data transfer interface A
211  * @v b                 Data transfer interface B
212  */
213 static inline __attribute__ (( always_inline )) void
214 xfer_plug_plug ( struct xfer_interface *a, struct xfer_interface *b ) {
215         plug_plug ( &a->intf, &b->intf );
216 }
217
218 /**
219  * Unplug a data transfer interface
220  *
221  * @v xfer              Data transfer interface
222  */
223 static inline __attribute__ (( always_inline )) void
224 xfer_unplug ( struct xfer_interface *xfer ) {
225         plug ( &xfer->intf, &null_xfer.intf );
226 }
227
228 /**
229  * Stop using a data transfer interface
230  *
231  * @v xfer              Data transfer interface
232  *
233  * After calling this method, no further messages will be received via
234  * the interface.
235  */
236 static inline void xfer_nullify ( struct xfer_interface *xfer ) {
237         xfer->op = &null_xfer_ops;
238 };
239
240 #endif /* _GPXE_XFER_H */