summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/downloader.c15
-rw-r--r--src/core/hw.c27
-rw-r--r--src/core/posix_io.c8
-rw-r--r--src/core/xfer.c71
-rw-r--r--src/include/gpxe/xfer.h16
5 files changed, 96 insertions, 41 deletions
diff --git a/src/core/downloader.c b/src/core/downloader.c
index 2f28bc953..15ef962d3 100644
--- a/src/core/downloader.c
+++ b/src/core/downloader.c
@@ -115,19 +115,6 @@ static int downloader_ensure_size ( struct downloader *downloader,
*/
/**
- * Handle start() event received via job control interface
- *
- * @v job Downloader job control interface
- */
-static void downloader_job_start ( struct job_interface *job ) {
- struct downloader *downloader =
- container_of ( job, struct downloader, job );
-
- /* Start data transfer */
- xfer_request_all ( &downloader->xfer );
-}
-
-/**
* Handle kill() event received via job control interface
*
* @v job Downloader job control interface
@@ -142,7 +129,7 @@ static void downloader_job_kill ( struct job_interface *job ) {
/** Downloader job control interface operations */
static struct job_interface_operations downloader_job_operations = {
- .start = downloader_job_start,
+ .start = ignore_job_start,
.done = ignore_job_done,
.kill = downloader_job_kill,
.progress = ignore_job_progress,
diff --git a/src/core/hw.c b/src/core/hw.c
index 77b39ba1a..a3eb85007 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 );
diff --git a/src/core/posix_io.c b/src/core/posix_io.c
index 6cefbf7b9..3b5660e4f 100644
--- a/src/core/posix_io.c
+++ b/src/core/posix_io.c
@@ -191,6 +191,7 @@ static int posix_find_free_fd ( void ) {
if ( ! posix_fd_to_file ( fd ) )
return fd;
}
+ DBG ( "POSIX could not find free file descriptor\n" );
return -ENFILE;
}
@@ -226,13 +227,11 @@ int open ( const char *uri_string ) {
if ( ( rc = xfer_open_uri ( &file->xfer, uri_string ) ) != 0 )
goto err;
- /* Request data */
- if ( ( rc = xfer_request_all ( &file->xfer ) ) != 0 )
- goto err;
-
/* Wait for open to succeed or fail */
while ( list_empty ( &file->data ) ) {
step();
+ if ( file->rc == 0 )
+ break;
if ( file->rc != -EINPROGRESS ) {
rc = file->rc;
goto err;
@@ -241,6 +240,7 @@ int open ( const char *uri_string ) {
/* Add to list of open files. List takes reference ownership. */
list_add ( &file->list, &posix_files );
+ DBG ( "POSIX opened %s as file %d\n", uri_string, fd );
return fd;
err:
diff --git a/src/core/xfer.c b/src/core/xfer.c
index f2783f5bd..54377c705 100644
--- a/src/core/xfer.c
+++ b/src/core/xfer.c
@@ -35,6 +35,8 @@
void xfer_close ( struct xfer_interface *xfer, int rc ) {
struct xfer_interface *dest = xfer_get_dest ( xfer );
+ DBGC ( xfer, "XFER %p->%p close\n", xfer, dest );
+
dest->op->close ( dest, rc );
xfer_unplug ( xfer );
xfer_put ( dest );
@@ -52,7 +54,14 @@ int xfer_vredirect ( struct xfer_interface *xfer, int type, va_list args ) {
struct xfer_interface *dest = xfer_get_dest ( xfer );
int rc;
+ DBGC ( xfer, "XFER %p->%p redirect\n", xfer, dest );
+
rc = dest->op->vredirect ( dest, type, args );
+
+ if ( rc != 0 ) {
+ DBGC ( xfer, "XFER %p<-%p redirect: %s\n", xfer, dest,
+ strerror ( rc ) );
+ }
xfer_put ( dest );
return rc;
}
@@ -89,22 +98,20 @@ int xfer_request ( struct xfer_interface *xfer, off_t offset, int whence,
struct xfer_interface *dest = xfer_get_dest ( xfer );
int rc;
+ DBGC ( xfer, "XFER %p->%p request %s+%ld %zd\n", xfer, dest,
+ whence_text ( whence ), offset, len );
+
rc = dest->op->request ( dest, offset, whence, len );
+
+ if ( rc != 0 ) {
+ DBGC ( xfer, "XFER %p<-%p request: %s\n", xfer, dest,
+ strerror ( rc ) );
+ }
xfer_put ( dest );
return rc;
}
/**
- * Request all data
- *
- * @v xfer Data transfer interface
- * @ret rc Return status code
- */
-int xfer_request_all ( struct xfer_interface *xfer ) {
- return xfer_request ( xfer, 0, SEEK_SET, ~( ( size_t ) 0 ) );
-}
-
-/**
* Seek to position
*
* @v xfer Data transfer interface
@@ -116,12 +123,34 @@ int xfer_seek ( struct xfer_interface *xfer, off_t offset, int whence ) {
struct xfer_interface *dest = xfer_get_dest ( xfer );
int rc;
+ DBGC ( xfer, "XFER %p->%p seek %s+%ld\n", xfer, dest,
+ whence_text ( whence ), offset );
+
rc = dest->op->seek ( dest, offset, whence );
+
+ if ( rc != 0 ) {
+ DBGC ( xfer, "XFER %p<-%p seek: %s\n", xfer, dest,
+ strerror ( rc ) );
+ }
xfer_put ( dest );
return rc;
}
/**
+ * Test to see if interface is ready to accept data
+ *
+ * @v xfer Data transfer interface
+ * @ret rc Return status code
+ *
+ * This test is optional; the data transfer interface may wish that it
+ * does not yet wish to accept data, but cannot prevent attempts to
+ * deliver data to it.
+ */
+int xfer_ready ( struct xfer_interface *xfer ) {
+ return xfer_seek ( xfer, 0, SEEK_CUR );
+}
+
+/**
* Allocate I/O buffer
*
* @v xfer Data transfer interface
@@ -132,7 +161,13 @@ struct io_buffer * xfer_alloc_iob ( struct xfer_interface *xfer, size_t len ) {
struct xfer_interface *dest = xfer_get_dest ( xfer );
struct io_buffer *iobuf;
+ DBGC ( xfer, "XFER %p->%p alloc_iob %zd\n", xfer, dest, len );
+
iobuf = dest->op->alloc_iob ( dest, len );
+
+ if ( ! iobuf ) {
+ DBGC ( xfer, "XFER %p<-%p alloc_iob failed\n", xfer, dest );
+ }
xfer_put ( dest );
return iobuf;
}
@@ -148,7 +183,15 @@ int xfer_deliver_iob ( struct xfer_interface *xfer, struct io_buffer *iobuf ) {
struct xfer_interface *dest = xfer_get_dest ( xfer );
int rc;
+ DBGC ( xfer, "XFER %p->%p deliver_iob %zd\n", xfer, dest,
+ iob_len ( iobuf ) );
+
rc = dest->op->deliver_iob ( dest, iobuf );
+
+ if ( rc != 0 ) {
+ DBGC ( xfer, "XFER %p<-%p deliver_iob: %s\n", xfer, dest,
+ strerror ( rc ) );
+ }
xfer_put ( dest );
return rc;
}
@@ -165,7 +208,15 @@ int xfer_deliver_raw ( struct xfer_interface *xfer,
struct xfer_interface *dest = xfer_get_dest ( xfer );
int rc;
+ DBGC ( xfer, "XFER %p->%p deliver_raw %p+%zd\n", xfer, dest,
+ data, len );
+
rc = dest->op->deliver_raw ( dest, data, len );
+
+ if ( rc != 0 ) {
+ DBGC ( xfer, "XFER %p<-%p deliver_raw: %s\n", xfer, dest,
+ strerror ( rc ) );
+ }
xfer_put ( dest );
return rc;
}
diff --git a/src/include/gpxe/xfer.h b/src/include/gpxe/xfer.h
index 71b69dc51..e6c896c39 100644
--- a/src/include/gpxe/xfer.h
+++ b/src/include/gpxe/xfer.h
@@ -112,6 +112,20 @@ enum seek_whence {
SEEK_CUR,
};
+/**
+ * Describe seek basis
+ *
+ * @v whence Basis for new position
+ */
+static inline __attribute__ (( always_inline )) const char *
+whence_text ( int whence ) {
+ switch ( whence ) {
+ case SEEK_SET: return "SET";
+ case SEEK_CUR: return "CUR";
+ default: return "INVALID";
+ }
+}
+
extern struct xfer_interface null_xfer;
extern struct xfer_interface_operations null_xfer_ops;
@@ -121,8 +135,8 @@ extern int xfer_vredirect ( struct xfer_interface *xfer, int type,
extern int xfer_redirect ( struct xfer_interface *xfer, int type, ... );
extern int xfer_request ( struct xfer_interface *xfer, off_t offset,
int whence, size_t len );
-extern int xfer_request_all ( struct xfer_interface *xfer );
extern int xfer_seek ( struct xfer_interface *xfer, off_t offset, int whence );
+extern int xfer_ready ( struct xfer_interface *xfer );
extern struct io_buffer * xfer_alloc_iob ( struct xfer_interface *xfer,
size_t len );
extern int xfer_deliver_iob ( struct xfer_interface *xfer,