diff options
author | Michael Brown <mcb30@ipxe.org> | 2015-07-20 12:15:21 +0100 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2015-07-22 21:17:47 +0100 |
commit | 07b0d4fa30d021322efa8a423295a0677325ec8d (patch) | |
tree | 92ae1c8e37930a89835b77c488067b91bb0c52e2 /src/core/xferbuf.c | |
parent | cbbd6b761ed315ab6df82f1434657ef76bb3e676 (diff) | |
download | ipxe-07b0d4fa30d021322efa8a423295a0677325ec8d.tar.gz |
[xferbuf] Add xfer_buffer() to provide direct access to underlying buffer
Allow data transfer buffer users to provide direct access to their
underlying data transfer buffer.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/core/xferbuf.c')
-rw-r--r-- | src/core/xferbuf.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/src/core/xferbuf.c b/src/core/xferbuf.c index 7f9780b3a..afc72ae76 100644 --- a/src/core/xferbuf.c +++ b/src/core/xferbuf.c @@ -283,3 +283,42 @@ struct xfer_buffer_operations xferbuf_umalloc_operations = { .write = xferbuf_umalloc_write, .read = xferbuf_umalloc_read, }; + +/** + * Get underlying data transfer buffer + * + * @v interface Data transfer interface + * @ret xferbuf Data transfer buffer, or NULL on error + * + * This call will check that the xfer_buffer() handler belongs to the + * destination interface which also provides xfer_deliver() for this + * interface. + * + * This is done to prevent accidental accesses to a data transfer + * buffer which may be located behind a non-transparent datapath via a + * series of pass-through interfaces. + */ +struct xfer_buffer * xfer_buffer ( struct interface *intf ) { + struct interface *dest; + xfer_buffer_TYPE ( void * ) *op = + intf_get_dest_op ( intf, xfer_buffer, &dest ); + void *object = intf_object ( dest ); + struct interface *xfer_deliver_dest; + struct xfer_buffer *xferbuf; + + /* Check that this operation is provided by the same interface + * which handles xfer_deliver(). + */ + intf_get_dest_op ( intf, xfer_deliver, &xfer_deliver_dest ); + + if ( op && ( dest == xfer_deliver_dest ) ) { + xferbuf = op ( object ); + } else { + /* Default is to not have a data transfer buffer */ + xferbuf = NULL; + } + + intf_put ( xfer_deliver_dest ); + intf_put ( dest ); + return xferbuf; +} |