summaryrefslogtreecommitdiffstats
path: root/src/include
diff options
context:
space:
mode:
authorMichael Brown2006-05-19 17:06:51 +0200
committerMichael Brown2006-05-19 17:06:51 +0200
commitd48d0fb1bb53262bf44a03dbe8388529f1566a1c (patch)
tree31081f33dbeb48c42d2e4cf806570853162781d9 /src/include
parentUse typeof(sizeof(...)) to define a size_t. This stops gcc complaining (diff)
downloadipxe-d48d0fb1bb53262bf44a03dbe8388529f1566a1c.tar.gz
ipxe-d48d0fb1bb53262bf44a03dbe8388529f1566a1c.tar.xz
ipxe-d48d0fb1bb53262bf44a03dbe8388529f1566a1c.zip
Add the concept of a "user pointer" (similar to the void __user * in
the kernel), which encapsulates the information needed to refer to an external buffer. Under normal operation, this can just be a void * equivalent, but under -DKEEP_IT_REAL it would be a segoff_t equivalent. Use this concept to avoid the need for bounce buffers in int13.c, which reduces memory usage and opens up the possibility of using multi-sector reads. Extend the block-device API and the SCSI block device implementation to support multi-sector reads. Update iscsi.c to use user buffers. Move the obsolete portions of realmode.h to old_realmode.h. MS-DOS now boots an order of magnitude faster over iSCSI (~10 seconds from power-up to C:> prompt in bochs).
Diffstat (limited to 'src/include')
-rw-r--r--src/include/gpxe/blockdev.h8
-rw-r--r--src/include/gpxe/scsi.h5
-rw-r--r--src/include/gpxe/uaccess.h24
3 files changed, 33 insertions, 4 deletions
diff --git a/src/include/gpxe/blockdev.h b/src/include/gpxe/blockdev.h
index 59f5bf746..467ed1d9d 100644
--- a/src/include/gpxe/blockdev.h
+++ b/src/include/gpxe/blockdev.h
@@ -8,6 +8,8 @@
*
*/
+#include <gpxe/uaccess.h>
+
/** A block device */
struct block_device {
/** Block size */
@@ -19,21 +21,23 @@ struct block_device {
*
* @v blockdev Block device
* @v block Block number
+ * @v count Block count
* @v buffer Data buffer
* @ret rc Return status code
*/
int ( * read ) ( struct block_device *blockdev, uint64_t block,
- void *buffer );
+ unsigned long count, userptr_t buffer );
/**
* Write block
*
* @v blockdev Block device
* @v block Block number
+ * @v count Block count
* @v buffer Data buffer
* @ret rc Return status code
*/
int ( * write ) ( struct block_device *blockdev, uint64_t block,
- const void *buffer );
+ unsigned long count, userptr_t buffer );
};
#endif /* _GPXE_BLOCKDEV_H */
diff --git a/src/include/gpxe/scsi.h b/src/include/gpxe/scsi.h
index dea39e162..d7da1255e 100644
--- a/src/include/gpxe/scsi.h
+++ b/src/include/gpxe/scsi.h
@@ -3,6 +3,7 @@
#include <stdint.h>
#include <gpxe/blockdev.h>
+#include <gpxe/uaccess.h>
/**
* @defgroup scsiops SCSI operation codes
@@ -123,14 +124,14 @@ struct scsi_command {
/** CDB for this command */
union scsi_cdb cdb;
/** Data-out buffer (may be NULL) */
- const void *data_out;
+ userptr_t data_out;
/** Data-out buffer length
*
* Must be zero if @c data_out is NULL
*/
size_t data_out_len;
/** Data-in buffer (may be NULL) */
- void *data_in;
+ userptr_t data_in;
/** Data-in buffer length
*
* Must be zero if @c data_in is NULL
diff --git a/src/include/gpxe/uaccess.h b/src/include/gpxe/uaccess.h
new file mode 100644
index 000000000..38853bfbc
--- /dev/null
+++ b/src/include/gpxe/uaccess.h
@@ -0,0 +1,24 @@
+#ifndef _GPXE_UACCESS_H
+#define _GPXE_UACCESS_H
+
+/**
+ * @file
+ *
+ * Access to external ("user") memory
+ *
+ * gPXE often needs to transfer data between internal and external
+ * buffers. On i386, the external buffers may require access via a
+ * different segment, and the buffer address cannot be encoded into a
+ * simple void * pointer. The @c userptr_t type encapsulates the
+ * information needed to identify an external buffer, and the
+ * copy_to_user() and copy_from_user() functions provide methods for
+ * transferring data between internal and external buffers.
+ *
+ * Note that userptr_t is an opaque type; in particular, performing
+ * arithmetic upon a userptr_t is not allowed.
+ *
+ */
+
+#include <bits/uaccess.h>
+
+#endif /* _GPXE_UACCESS_H */