diff --git a/src/core/open.c b/src/core/open.c index ffcb4e29..fa9c8581 100644 --- a/src/core/open.c +++ b/src/core/open.c @@ -45,7 +45,7 @@ static struct socket_opener socket_openers_end[0] /** * Open URI * - * @v xfer Data-transfer interface + * @v xfer Data transfer interface * @v uri_string URI string (e.g. "http://etherboot.org/kernel") * @ret rc Return status code */ @@ -74,7 +74,7 @@ int open_uri ( struct xfer_interface *xfer, const char *uri_string ) { /** * Open socket * - * @v xfer Data-transfer interface + * @v xfer Data transfer interface * @v domain Communication domain (e.g. PF_INET) * @v type Communication semantics (e.g. SOCK_STREAM) */ @@ -101,7 +101,7 @@ int open_socket ( struct xfer_interface *xfer, /** * Open location * - * @v xfer Data-transfer interface + * @v xfer Data transfer interface * @v type Location type * @v args Remaining arguments depend upon location type * @ret rc Return status code @@ -128,7 +128,7 @@ int vopen ( struct xfer_interface *xfer, int type, va_list args ) { /** * Open location * - * @v xfer Data-transfer interface + * @v xfer Data transfer interface * @v type Location type * @v ... Remaining arguments depend upon location type * @ret rc Return status code diff --git a/src/core/xfer.c b/src/core/xfer.c index c3993799..d3480816 100644 --- a/src/core/xfer.c +++ b/src/core/xfer.c @@ -26,10 +26,36 @@ * */ +/** + * Close data transfer interface + * + * @v xfer Data transfer interface + * @v rc Reason for close + */ +void close ( struct xfer_interface *xfer, int rc ) { + struct xfer_interface *dest = xfer_dest ( xfer ); + + dest->op->close ( dest, rc ); + xfer_unplug ( xfer ); +} + +/** + * Seek to position + * + * @v xfer Data transfer interface + * @v pos New position + * @ret rc Return status code + */ +int seek ( struct xfer_interface *xfer, size_t pos ) { + struct xfer_interface *dest = xfer_dest ( xfer ); + + return dest->op->seek ( dest, pos ); +} + /** * Send redirection event * - * @v xfer Data-transfer interface + * @v xfer Data transfer interface * @v type New location type * @v args Remaining arguments depend upon location type * @ret rc Return status code @@ -43,7 +69,7 @@ int vredirect ( struct xfer_interface *xfer, int type, va_list args ) { /** * Send redirection event * - * @v xfer Data-transfer interface + * @v xfer Data transfer interface * @v type New location type * @v ... Remaining arguments depend upon location type * @ret rc Return status code @@ -61,7 +87,7 @@ int redirect ( struct xfer_interface *xfer, int type, ... ) { /** * Deliver datagram * - * @v xfer Data-transfer interface + * @v xfer Data transfer interface * @v iobuf Datagram I/O buffer * @ret rc Return status code */ @@ -74,7 +100,7 @@ int deliver ( struct xfer_interface *xfer, struct io_buffer *iobuf ) { /** * Deliver datagram as raw data * - * @v xfer Data-transfer interface + * @v xfer Data transfer interface * @v iobuf Datagram I/O buffer * @ret rc Return status code */ @@ -93,10 +119,44 @@ int deliver_raw ( struct xfer_interface *xfer, const void *data, size_t len ) { * */ +/** + * Ignore close() + * + * @v xfer Data transfer interface + * @v rc Reason for close + */ +void ignore_close ( struct xfer_interface *xfer __unused, int rc __unused ) { + /* Nothing to do */ +} + +/** + * Ignore vredirect() + * + * @v xfer Data transfer interface + * @v type New location type + * @v args Remaining arguments depend upon location type + * @ret rc Return status code + */ +int ignore_vredirect ( struct xfer_interface *xfer __unused, + int type __unused, va_list args __unused ) { + return 0; +} + +/** + * Ignore seek() + * + * @v xfer Data transfer interface + * @v pos New position + * @ret rc Return status code + */ +int ignore_seek ( struct xfer_interface *xfer __unused, size_t pos __unused ) { + return 0; +} + /** * Deliver datagram as raw data * - * @v xfer Data-transfer interface + * @v xfer Data transfer interface * @v iobuf Datagram I/O buffer * @ret rc Return status code * @@ -115,7 +175,7 @@ int deliver_as_raw ( struct xfer_interface *xfer, /** * Deliver datagram as I/O buffer * - * @v xfer Data-transfer interface + * @v xfer Data transfer interface * @v data Data buffer * @v len Length of data buffer * @ret rc Return status code @@ -135,32 +195,29 @@ int deliver_as_iobuf ( struct xfer_interface *xfer, return xfer->op->deliver ( xfer, iobuf ); } -/**************************************************************************** - * - * Null data transfer interface - * - */ - /** - * Null deliver datagram as raw data + * Ignore datagram as raw data * - * @v xfer Data-transfer interface + * @v xfer Data transfer interface * @v data Data buffer * @v len Length of data buffer * @ret rc Return status code */ -static int null_deliver_raw ( struct xfer_interface *xfer, - const void *data __unused, size_t len ) { +int ignore_deliver_raw ( struct xfer_interface *xfer, + const void *data __unused, size_t len ) { DBGC ( xfer, "XFER %p %zd bytes delivered %s\n", xfer, len, ( ( xfer == &null_xfer ) ? "before connection" : "after termination" ) ); - return -EPIPE; + return 0; } /** Null data transfer interface operations */ struct xfer_interface_operations null_xfer_ops = { + .close = ignore_close, + .vredirect = ignore_vredirect, + .seek = ignore_seek, .deliver = deliver_as_raw, - .deliver_raw = null_deliver_raw, + .deliver_raw = ignore_deliver_raw, }; /** diff --git a/src/include/gpxe/open.h b/src/include/gpxe/open.h index 8839dc28..ad86d095 100644 --- a/src/include/gpxe/open.h +++ b/src/include/gpxe/open.h @@ -41,7 +41,7 @@ struct uri_opener { const char *scheme; /** Open URI * - * @v xfer Data-transfer interface + * @v xfer Data transfer interface * @v uri URI * @ret rc Return status code * @@ -62,7 +62,7 @@ struct socket_opener { int type; /** Open socket * - * @v xfer Data-transfer interface + * @v xfer Data transfer interface * @v sa Socket address * @ret rc Return status code */ diff --git a/src/include/gpxe/xfer.h b/src/include/gpxe/xfer.h index 0b8bf4ce..dfbde89d 100644 --- a/src/include/gpxe/xfer.h +++ b/src/include/gpxe/xfer.h @@ -32,22 +32,29 @@ struct xfer_interface_operations { /** Close interface * - * @v xfer Data-transfer interface + * @v xfer Data transfer interface * @v rc Reason for close */ void ( * close ) ( struct xfer_interface *xfer, int rc ); /** Redirect to new location * - * @v xfer Data-transfer interface + * @v xfer Data transfer interface * @v type New location type * @v args Remaining arguments depend upon location type * @ret rc Return status code */ int ( * vredirect ) ( struct xfer_interface *xfer, int type, va_list args ); + /** Seek to position + * + * @v xfer Data transfer interface + * @v pos New position + * @ret rc Return status code + */ + int ( * seek ) ( struct xfer_interface *xfer, size_t pos ); /** Deliver datagram * - * @v xfer Data-transfer interface + * @v xfer Data transfer interface * @v iobuf Datagram I/O buffer * @ret rc Return status code * @@ -59,7 +66,7 @@ struct xfer_interface_operations { struct io_buffer *iobuf ); /** Deliver datagram as raw data * - * @v xfer Data-transfer interface + * @v xfer Data transfer interface * @v data Data buffer * @v len Length of data buffer * @ret rc Return status code @@ -83,32 +90,67 @@ struct xfer_interface { extern struct xfer_interface null_xfer; extern struct xfer_interface_operations null_xfer_ops; +extern void close ( struct xfer_interface *xfer, int rc ); +extern int seek ( struct xfer_interface *xfer, size_t pos ); extern int vredirect ( struct xfer_interface *xfer, int type, va_list args ); extern int redirect ( struct xfer_interface *xfer, int type, ... ); extern int deliver ( struct xfer_interface *xfer, struct io_buffer *iobuf ); extern int deliver_raw ( struct xfer_interface *xfer, const void *data, size_t len ); +extern void ignore_close ( struct xfer_interface *xfer, int rc ); +extern int ignore_vredirect ( struct xfer_interface *xfer, + int type, va_list args ); +extern int ignore_seek ( struct xfer_interface *xfer, size_t pos ); extern int deliver_as_raw ( struct xfer_interface *xfer, struct io_buffer *iobuf ); extern int deliver_as_iobuf ( struct xfer_interface *xfer, const void *data, size_t len ); +extern int ignore_deliver_raw ( struct xfer_interface *xfer, + const void *data __unused, size_t len ); /** - * Get destination data-transfer interface + * Initialise a data transfer interface * - * @v xfer Data-transfer interface + * @v xfer Data transfer interface + * @v op Data transfer interface operations + * @v refcnt Data transfer interface reference counting method + */ +static inline void xfer_init ( struct xfer_interface *xfer, + struct xfer_interface_operations *op, + void ( * refcnt ) ( struct interface *intf, + int delta ) ) { + xfer->intf.dest = &null_xfer.intf; + xfer->intf.refcnt = refcnt; + xfer->op = op; +} + +/** + * Get data transfer interface from generic object communication interface + * + * @v intf Generic object communication interface + * @ret xfer Data transfer interface + */ +static inline struct xfer_interface * +intf_to_xfer ( struct interface *intf ) { + return container_of ( intf, struct xfer_interface, intf ); +} + +/** + * Get destination data transfer interface + * + * @v xfer Data transfer interface * @ret dest Destination interface */ static inline struct xfer_interface * xfer_dest ( struct xfer_interface *xfer ) { - return container_of ( xfer->intf.dest, struct xfer_interface, intf ); + return intf_to_xfer ( xfer->intf.dest ); } /** - * Plug a data-transfer interface into a new destination interface + * Plug a data transfer interface into a new destination interface * - * @v xfer Data-transfer interface + * @v xfer Data transfer interface * @v dest New destination interface */ static inline void xfer_plug ( struct xfer_interface *xfer, @@ -117,23 +159,23 @@ static inline void xfer_plug ( struct xfer_interface *xfer, } /** - * Unplug a data-transfer interface + * Unplug a data transfer interface * - * @v xfer Data-transfer interface + * @v xfer Data transfer interface */ static inline void xfer_unplug ( struct xfer_interface *xfer ) { plug ( &xfer->intf, &null_xfer.intf ); } /** - * Terminate a data-transfer interface + * Stop using a data transfer interface * - * @v xfer Data-transfer interface + * @v xfer Data transfer interface * * After calling this method, no further messages will be received via * the interface. */ -static inline void xfer_terminate ( struct xfer_interface *xfer ) { +static inline void xfer_nullify ( struct xfer_interface *xfer ) { xfer->op = &null_xfer_ops; };