6 * Data transfer interfaces
10 FILE_LICENCE ( GPL2_OR_LATER
);
14 #include <gpxe/interface.h>
15 #include <gpxe/iobuf.h>
17 struct xfer_interface
;
20 /** Data transfer interface operations */
21 struct xfer_interface_operations
{
24 * @v xfer Data transfer interface
25 * @v rc Reason for close
27 void ( * close
) ( struct xfer_interface
*xfer
, int rc
);
28 /** Redirect to new location
30 * @v xfer Data transfer interface
31 * @v type New location type
32 * @v args Remaining arguments depend upon location type
33 * @ret rc Return status code
35 int ( * vredirect
) ( struct xfer_interface
*xfer
, int type
,
37 /** Check flow control window
39 * @v xfer Data transfer interface
40 * @ret len Length of window
42 * Flow control is regarded as advisory but not mandatory.
43 * Users who have control over their own rate of data
44 * generation should perform a flow control check before
45 * generating new data. Users who have no control (such as
46 * NIC drivers or filter layers) are not obliged to check.
48 * Data transfer interfaces must be prepared to accept
49 * datagrams even if they are advertising a window of zero
52 size_t ( * window
) ( struct xfer_interface
*xfer
);
53 /** Allocate I/O buffer
55 * @v xfer Data transfer interface
56 * @v len I/O buffer payload length
57 * @ret iobuf I/O buffer
59 struct io_buffer
* ( * alloc_iob
) ( struct xfer_interface
*xfer
,
61 /** Deliver datagram as I/O buffer with metadata
63 * @v xfer Data transfer interface
64 * @v iobuf Datagram I/O buffer
65 * @v meta Data transfer metadata
66 * @ret rc Return status code
68 * A data transfer interface that wishes to support only raw
69 * data delivery should set this method to
70 * xfer_deliver_as_raw().
72 int ( * deliver_iob
) ( struct xfer_interface
*xfer
,
73 struct io_buffer
*iobuf
,
74 struct xfer_metadata
*meta
);
75 /** Deliver datagram as raw data
77 * @v xfer Data transfer interface
79 * @v len Length of data buffer
80 * @ret rc Return status code
82 * A data transfer interface that wishes to support only I/O
83 * buffer delivery should set this method to
84 * xfer_deliver_as_iob().
86 int ( * deliver_raw
) ( struct xfer_interface
*xfer
,
87 const void *data
, size_t len
);
90 /** A data transfer interface */
91 struct xfer_interface
{
92 /** Generic object communication interface */
93 struct interface intf
;
94 /** Operations for received messages */
95 struct xfer_interface_operations
*op
;
98 /** Basis positions for seek() events */
104 /** Data transfer metadata */
105 struct xfer_metadata
{
106 /** Position of data within stream */
108 /** Basis for data position
110 * Must be one of @c SEEK_CUR or @c SEEK_SET.
113 /** Source socket address, or NULL */
114 struct sockaddr
*src
;
115 /** Destination socket address, or NULL */
116 struct sockaddr
*dest
;
117 /** Network device, or NULL */
118 struct net_device
*netdev
;
122 * Describe seek basis
124 * @v whence Basis for new position
126 static inline __attribute__ (( always_inline
)) const char *
127 whence_text ( int whence
) {
129 case SEEK_CUR
: return "CUR";
130 case SEEK_SET
: return "SET";
131 default: return "INVALID";
135 extern struct xfer_interface null_xfer
;
136 extern struct xfer_interface_operations null_xfer_ops
;
138 extern void xfer_close ( struct xfer_interface
*xfer
, int rc
);
139 extern int xfer_vredirect ( struct xfer_interface
*xfer
, int type
,
141 extern int xfer_redirect ( struct xfer_interface
*xfer
, int type
, ... );
142 extern size_t xfer_window ( struct xfer_interface
*xfer
);
143 extern struct io_buffer
* xfer_alloc_iob ( struct xfer_interface
*xfer
,
145 extern int xfer_deliver_iob ( struct xfer_interface
*xfer
,
146 struct io_buffer
*iobuf
);
147 extern int xfer_deliver_iob_meta ( struct xfer_interface
*xfer
,
148 struct io_buffer
*iobuf
,
149 struct xfer_metadata
*meta
);
150 extern int xfer_deliver_raw ( struct xfer_interface
*xfer
,
151 const void *data
, size_t len
);
152 extern int xfer_vprintf ( struct xfer_interface
*xfer
,
153 const char *format
, va_list args
);
154 extern int __attribute__ (( format ( printf
, 2, 3 ) ))
155 xfer_printf ( struct xfer_interface
*xfer
, const char *format
, ... );
156 extern int xfer_seek ( struct xfer_interface
*xfer
, off_t offset
, int whence
);
158 extern void ignore_xfer_close ( struct xfer_interface
*xfer
, int rc
);
159 extern int ignore_xfer_vredirect ( struct xfer_interface
*xfer
,
160 int type
, va_list args
);
161 extern size_t unlimited_xfer_window ( struct xfer_interface
*xfer
);
162 extern size_t no_xfer_window ( struct xfer_interface
*xfer
);
163 extern struct io_buffer
* default_xfer_alloc_iob ( struct xfer_interface
*xfer
,
165 extern int xfer_deliver_as_raw ( struct xfer_interface
*xfer
,
166 struct io_buffer
*iobuf
,
167 struct xfer_metadata
*meta
);
168 extern int xfer_deliver_as_iob ( struct xfer_interface
*xfer
,
169 const void *data
, size_t len
);
170 extern int ignore_xfer_deliver_raw ( struct xfer_interface
*xfer
,
171 const void *data __unused
, size_t len
);
174 * Initialise a data transfer interface
176 * @v xfer Data transfer interface
177 * @v op Data transfer interface operations
178 * @v refcnt Containing object reference counter, or NULL
180 static inline void xfer_init ( struct xfer_interface
*xfer
,
181 struct xfer_interface_operations
*op
,
182 struct refcnt
*refcnt
) {
183 xfer
->intf
.dest
= &null_xfer
.intf
;
184 xfer
->intf
.refcnt
= refcnt
;
189 * Initialise a static data transfer interface
191 * @v operations Data transfer interface operations
193 #define XFER_INIT( operations ) { \
195 .dest = &null_xfer.intf, \
202 * Get data transfer interface from generic object communication interface
204 * @v intf Generic object communication interface
205 * @ret xfer Data transfer interface
207 static inline __attribute__ (( always_inline
)) struct xfer_interface
*
208 intf_to_xfer ( struct interface
*intf
) {
209 return container_of ( intf
, struct xfer_interface
, intf
);
213 * Get reference to destination data transfer interface
215 * @v xfer Data transfer interface
216 * @ret dest Destination interface
218 static inline __attribute__ (( always_inline
)) struct xfer_interface
*
219 xfer_get_dest ( struct xfer_interface
*xfer
) {
220 return intf_to_xfer ( intf_get ( xfer
->intf
.dest
) );
224 * Drop reference to data transfer interface
226 * @v xfer Data transfer interface
228 static inline __attribute__ (( always_inline
)) void
229 xfer_put ( struct xfer_interface
*xfer
) {
230 intf_put ( &xfer
->intf
);
234 * Plug a data transfer interface into a new destination interface
236 * @v xfer Data transfer interface
237 * @v dest New destination interface
239 static inline __attribute__ (( always_inline
)) void
240 xfer_plug ( struct xfer_interface
*xfer
, struct xfer_interface
*dest
) {
241 plug ( &xfer
->intf
, &dest
->intf
);
245 * Plug two data transfer interfaces together
247 * @v a Data transfer interface A
248 * @v b Data transfer interface B
250 static inline __attribute__ (( always_inline
)) void
251 xfer_plug_plug ( struct xfer_interface
*a
, struct xfer_interface
*b
) {
252 plug_plug ( &a
->intf
, &b
->intf
);
256 * Unplug a data transfer interface
258 * @v xfer Data transfer interface
260 static inline __attribute__ (( always_inline
)) void
261 xfer_unplug ( struct xfer_interface
*xfer
) {
262 plug ( &xfer
->intf
, &null_xfer
.intf
);
266 * Stop using a data transfer interface
268 * @v xfer Data transfer interface
270 * After calling this method, no further messages will be received via
273 static inline void xfer_nullify ( struct xfer_interface
*xfer
) {
274 xfer
->op
= &null_xfer_ops
;
277 #endif /* _GPXE_XFER_H */