diff options
| author | Michael Brown | 2006-05-19 17:06:51 +0200 |
|---|---|---|
| committer | Michael Brown | 2006-05-19 17:06:51 +0200 |
| commit | d48d0fb1bb53262bf44a03dbe8388529f1566a1c (patch) | |
| tree | 31081f33dbeb48c42d2e4cf806570853162781d9 /src/include | |
| parent | Use typeof(sizeof(...)) to define a size_t. This stops gcc complaining (diff) | |
| download | ipxe-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.h | 8 | ||||
| -rw-r--r-- | src/include/gpxe/scsi.h | 5 | ||||
| -rw-r--r-- | src/include/gpxe/uaccess.h | 24 |
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 */ |
