Added deliver-as-iobuf/deliver-as-raw concepts.
authorMichael Brown <mcb30@etherboot.org>
Fri, 27 Apr 2007 00:02:23 +0000 (00:02 +0000)
committerMichael Brown <mcb30@etherboot.org>
Fri, 27 Apr 2007 00:02:23 +0000 (00:02 +0000)
src/core/xfer.c
src/include/gpxe/xfer.h

index d08b3b8..bf56d06 100644 (file)
@@ -16,6 +16,7 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <string.h>
 #include <errno.h>
 #include <gpxe/xfer.h>
 
@@ -39,23 +40,75 @@ int deliver ( struct xfer_interface *xfer, struct io_buffer *iobuf ) {
 }
 
 /**
- * Null deliver datagram
+ * Deliver datagram as raw data
  *
  * @v xfer             Data-transfer interface
  * @v src              Source interface
  * @v iobuf            Datagram I/O buffer
  * @ret rc             Return status code
+ *
+ * This function is intended to be used as the deliver() method for
+ * data transfer interfaces that prefer to handle raw data.
  */
-static int null_deliver ( struct xfer_interface *xfer __unused,
-                         struct xfer_interface *src __unused,
-                         struct io_buffer *iobuf ) {
+int deliver_as_raw ( struct xfer_interface *xfer,
+                    struct xfer_interface *src,
+                    struct io_buffer *iobuf ) {
+       int rc;
+
+       rc = xfer->op->deliver_raw ( xfer, src, iobuf->data,
+                                    iob_len ( iobuf ) );
        free_iob ( iobuf );
+       return rc;
+}
+
+/**
+ * Deliver datagram as I/O buffer
+ *
+ * @v xfer             Data-transfer interface
+ * @v src              Source interface
+ * @v data             Data buffer
+ * @v len              Length of data buffer
+ * @ret rc             Return status code
+ *
+ * This function is intended to be used as the deliver_raw() method
+ * for data transfer interfaces that prefer to handle I/O buffers.
+ */
+int deliver_as_iobuf ( struct xfer_interface *xfer,
+                      struct xfer_interface *src,
+                      const void *data, size_t len ) {
+       struct io_buffer *iobuf;
+
+#warning "Do we need interface-specific I/O buffer allocation?"
+       iobuf = alloc_iob ( len );
+       if ( ! iobuf )
+               return -ENOMEM;
+
+       memcpy ( iob_put ( iobuf, len ), data, len );
+       return xfer->op->deliver ( xfer, src, iobuf );
+}
+
+/**
+ * Null deliver datagram as raw data
+ *
+ * @v xfer             Data-transfer interface
+ * @v src              Source 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,
+                             struct xfer_interface *src,
+                             const void *data __unused, size_t len ) {
+       DBGC ( src, "XFER %p->%p %zd bytes delivered %s\n", src, xfer, len,
+              ( ( xfer == &null_xfer ) ?
+                "before connection" : "after termination" ) );
        return -EPIPE;
 }
 
 /** Null data transfer interface operations */
 struct xfer_interface_operations null_xfer_ops = {
-       .deliver = null_deliver,
+       .deliver        = deliver_as_raw,
+       .deliver_raw    = null_deliver_raw,
 };
 
 /**
index 0e577e9..7a10b86 100644 (file)
@@ -18,13 +18,32 @@ struct xfer_interface_operations {
        /** Deliver datagram
         *
         * @v xfer              Data-transfer interface
-        * @v src               Source  interface
+        * @v src               Source interface
         * @v iobuf             Datagram I/O buffer
         * @ret rc              Return status code
+        *
+        * A data transfer interface that wishes to support only raw
+        * data delivery should set this method to
+        * deliver_as_raw().
         */
        int ( * deliver ) ( struct xfer_interface *xfer,
                            struct xfer_interface *src,
                            struct io_buffer *iobuf );
+       /** Deliver datagram as raw data
+        *
+        * @v xfer              Data-transfer interface
+        * @v src               Source interface
+        * @v data              Data buffer
+        * @v len               Length of data buffer
+        * @ret rc              Return status code
+        *
+        * A data transfer interface that wishes to support only I/O
+        * buffer delivery should set this method to
+        * deliver_as_iobuf().
+        */
+       int ( * deliver_raw ) ( struct xfer_interface *xfer,
+                               struct xfer_interface *src,
+                               const void *data, size_t len );
 };
 
 /** A data transfer interface */
@@ -38,6 +57,19 @@ struct xfer_interface {
 extern struct xfer_interface null_xfer;
 extern struct xfer_interface_operations null_xfer_ops;
 
+extern int deliver_as_raw ( struct xfer_interface *xfer,
+                           struct xfer_interface *src,
+                           struct io_buffer *iobuf );
+extern int deliver_as_iobuf ( struct xfer_interface *xfer,
+                             struct xfer_interface *src,
+                             const void *data, size_t len );
+
+/**
+ * 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 );