aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2014-12-11 17:10:01 +0000
committerMichael Brown <mcb30@ipxe.org>2014-12-18 14:46:38 +0000
commitc86b22221dd2aa787e2eae49d9d46287b8cf381e (patch)
treeb736bf5ed3abfedf4e13273dd79355303e85382e /src
parentd83fb45b66a9aa0a10efd2181fba42817ee1785d (diff)
downloadipxe-c86b22221dd2aa787e2eae49d9d46287b8cf381e.zip
ipxe-c86b22221dd2aa787e2eae49d9d46287b8cf381e.tar.gz
ipxe-c86b22221dd2aa787e2eae49d9d46287b8cf381e.tar.bz2
[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')
-rw-r--r--src/core/iobuf.c30
-rw-r--r--src/include/ipxe/iobuf.h1
2 files changed, 31 insertions, 0 deletions
diff --git a/src/core/iobuf.c b/src/core/iobuf.c
index afc91d1..6dae0c1 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;
+}
diff --git a/src/include/ipxe/iobuf.h b/src/include/ipxe/iobuf.h
index b2b0cb4..d7c10ab 100644
--- a/src/include/ipxe/iobuf.h
+++ b/src/include/ipxe/iobuf.h
@@ -217,5 +217,6 @@ extern void free_iob ( struct io_buffer *iobuf );
extern void iob_pad ( struct io_buffer *iobuf, size_t min_len );
extern int iob_ensure_headroom ( struct io_buffer *iobuf, size_t len );
extern struct io_buffer * iob_concatenate ( struct list_head *list );
+extern struct io_buffer * iob_split ( struct io_buffer *iobuf, size_t len );
#endif /* _IPXE_IOBUF_H */