summaryrefslogtreecommitdiffstats
path: root/src/core/hw.c
diff options
context:
space:
mode:
authorMichael Brown2007-05-26 17:04:36 +0200
committerMichael Brown2007-05-26 17:04:36 +0200
commit10d0a1f8c759309ad0aa8f73c87ae7b45cbb5fe6 (patch)
tree626d6b2493ebf72ef02ae7bae5f7bc77de8d7092 /src/core/hw.c
parentModify process semantics; rescheduling is now automatic. (diff)
downloadipxe-10d0a1f8c759309ad0aa8f73c87ae7b45cbb5fe6.tar.gz
ipxe-10d0a1f8c759309ad0aa8f73c87ae7b45cbb5fe6.tar.xz
ipxe-10d0a1f8c759309ad0aa8f73c87ae7b45cbb5fe6.zip
Modify data-xfer semantics: it is no longer necessary to call one of
request(), seek() or deliver_xxx() in order to start the data flow. Autonomous generators must be genuinely autonomous (having their own process), or otherwise arrange to be called. TCP does this by starting the retry timer immediately. Add some debugging statements.
Diffstat (limited to 'src/core/hw.c')
-rw-r--r--src/core/hw.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/src/core/hw.c b/src/core/hw.c
index 77b39ba1..a3eb8500 100644
--- a/src/core/hw.c
+++ b/src/core/hw.c
@@ -3,6 +3,7 @@
#include <string.h>
#include <errno.h>
#include <gpxe/refcnt.h>
+#include <gpxe/process.h>
#include <gpxe/xfer.h>
#include <gpxe/open.h>
@@ -15,6 +16,7 @@
struct hw {
struct refcnt refcnt;
struct xfer_interface xfer;
+ struct process process;
};
static const char hw_msg[] = "Hello world!\n";
@@ -22,6 +24,7 @@ static const char hw_msg[] = "Hello world!\n";
static void hw_finished ( struct hw *hw, int rc ) {
xfer_nullify ( &hw->xfer );
xfer_close ( &hw->xfer, rc );
+ process_del ( &hw->process );
}
static void hw_xfer_close ( struct xfer_interface *xfer, int rc ) {
@@ -30,26 +33,25 @@ static void hw_xfer_close ( struct xfer_interface *xfer, int rc ) {
hw_finished ( hw, rc );
}
-static int hw_xfer_request ( struct xfer_interface *xfer,
- off_t start __unused, int whence __unused,
- size_t len __unused ) {
- struct hw *hw = container_of ( xfer, struct hw, xfer );
- int rc;
-
- rc = xfer_deliver_raw ( xfer, hw_msg, sizeof ( hw_msg ) );
- hw_finished ( hw, rc );
- return 0;
-}
-
static struct xfer_interface_operations hw_xfer_operations = {
.close = hw_xfer_close,
.vredirect = ignore_xfer_vredirect,
- .request = hw_xfer_request,
+ .request = ignore_xfer_request,
.seek = ignore_xfer_seek,
.deliver_iob = xfer_deliver_as_raw,
.deliver_raw = ignore_xfer_deliver_raw,
};
+static void hw_step ( struct process *process ) {
+ struct hw *hw = container_of ( process, struct hw, process );
+ int rc;
+
+ if ( xfer_ready ( &hw->xfer ) == 0 ) {
+ rc = xfer_deliver_raw ( &hw->xfer, hw_msg, sizeof ( hw_msg ) );
+ hw_finished ( hw, rc );
+ }
+}
+
static int hw_open ( struct xfer_interface *xfer, struct uri *uri __unused ) {
struct hw *hw;
@@ -59,6 +61,7 @@ static int hw_open ( struct xfer_interface *xfer, struct uri *uri __unused ) {
return -ENOMEM;
memset ( hw, 0, sizeof ( *hw ) );
xfer_init ( &hw->xfer, &hw_xfer_operations, &hw->refcnt );
+ process_init ( &hw->process, hw_step, &hw->refcnt );
/* Attach parent interface, mortalise self, and return */
xfer_plug_plug ( &hw->xfer, xfer );