summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
authorMichael Brown2014-12-11 18:10:01 +0100
committerMichael Brown2014-12-18 15:46:38 +0100
commitc86b22221dd2aa787e2eae49d9d46287b8cf381e (patch)
treeb736bf5ed3abfedf4e13273dd79355303e85382e /src/core
parent[device] Provide a driver-private data field for root devices (diff)
downloadipxe-c86b22221dd2aa787e2eae49d9d46287b8cf381e.tar.gz
ipxe-c86b22221dd2aa787e2eae49d9d46287b8cf381e.tar.xz
ipxe-c86b22221dd2aa787e2eae49d9d46287b8cf381e.zip
[iobuf] Add iob_split() to split an I/O buffer into portions
RNDIS devices may provide multiple packets encapsulated into a single message. Provide an API to allow the RNDIS driver to split an I/O buffer into smaller portions. The current implementation will always copy the underlying data, rather than splitting the buffer in situ. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/core')
-rw-r--r--src/core/iobuf.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/core/iobuf.c b/src/core/iobuf.c
index afc91d150..6dae0c1dd 100644
--- a/src/core/iobuf.c
+++ b/src/core/iobuf.c
@@ -200,3 +200,33 @@ struct io_buffer * iob_concatenate ( struct list_head *list ) {
return concatenated;
}
+
+/**
+ * Split I/O buffer
+ *
+ * @v iobuf I/O buffer
+ * @v len Length to split into a new I/O buffer
+ * @ret split New I/O buffer, or NULL on allocation failure
+ *
+ * Split the first @c len bytes of the existing I/O buffer into a
+ * separate I/O buffer. The resulting buffers are likely to have no
+ * headroom or tailroom.
+ *
+ * If this call fails, then the original buffer will be unmodified.
+ */
+struct io_buffer * iob_split ( struct io_buffer *iobuf, size_t len ) {
+ struct io_buffer *split;
+
+ /* Sanity checks */
+ assert ( len <= iob_len ( iobuf ) );
+
+ /* Allocate new I/O buffer */
+ split = alloc_iob ( len );
+ if ( ! split )
+ return NULL;
+
+ /* Copy in data */
+ memcpy ( iob_put ( split, len ), iobuf->data, len );
+ iob_pull ( iobuf, len );
+ return split;
+}