summaryrefslogtreecommitdiffstats
path: root/src/core/xferbuf.c
diff options
context:
space:
mode:
authorMichael Brown2015-07-20 13:15:21 +0200
committerMichael Brown2015-07-22 22:17:47 +0200
commit07b0d4fa30d021322efa8a423295a0677325ec8d (patch)
tree92ae1c8e37930a89835b77c488067b91bb0c52e2 /src/core/xferbuf.c
parent[xferbuf] Generalise to handle umalloc()-based buffers (diff)
downloadipxe-07b0d4fa30d021322efa8a423295a0677325ec8d.tar.gz
ipxe-07b0d4fa30d021322efa8a423295a0677325ec8d.tar.xz
ipxe-07b0d4fa30d021322efa8a423295a0677325ec8d.zip
[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.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/src/core/xferbuf.c b/src/core/xferbuf.c
index 7f9780b3..afc72ae7 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;
+}