From d48d0fb1bb53262bf44a03dbe8388529f1566a1c Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Fri, 19 May 2006 15:06:51 +0000 Subject: 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). --- src/drivers/block/scsi.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src/drivers/block') diff --git a/src/drivers/block/scsi.c b/src/drivers/block/scsi.c index 7ddc4a11e..1a1d70d8f 100644 --- a/src/drivers/block/scsi.c +++ b/src/drivers/block/scsi.c @@ -50,11 +50,12 @@ static int scsi_command ( struct scsi_device *scsi, * * @v blockdev Block device * @v block LBA block number + * @v count Block count * @v buffer Data buffer * @ret rc Return status code */ static int scsi_read ( struct block_device *blockdev, uint64_t block, - void *buffer ) { + unsigned long count, userptr_t buffer ) { struct scsi_device *scsi = block_to_scsi ( blockdev ); struct scsi_command command; struct scsi_cdb_read_16 *cdb = &command.cdb.read16; @@ -63,9 +64,9 @@ static int scsi_read ( struct block_device *blockdev, uint64_t block, memset ( &command, 0, sizeof ( command ) ); cdb->opcode = SCSI_OPCODE_READ_16; cdb->lba = cpu_to_be64 ( block ); - cdb->len = cpu_to_be32 ( 1 ); /* always a single block */ + cdb->len = cpu_to_be32 ( count ); command.data_in = buffer; - command.data_in_len = blockdev->blksize; + command.data_in_len = ( count * blockdev->blksize ); return scsi_command ( scsi, &command ); } @@ -74,11 +75,12 @@ static int scsi_read ( struct block_device *blockdev, uint64_t block, * * @v blockdev Block device * @v block LBA block number + * @v count Block count * @v buffer Data buffer * @ret rc Return status code */ static int scsi_write ( struct block_device *blockdev, uint64_t block, - const void *buffer ) { + unsigned long count, userptr_t buffer ) { struct scsi_device *scsi = block_to_scsi ( blockdev ); struct scsi_command command; struct scsi_cdb_write_16 *cdb = &command.cdb.write16; @@ -87,9 +89,9 @@ static int scsi_write ( struct block_device *blockdev, uint64_t block, memset ( &command, 0, sizeof ( command ) ); cdb->opcode = SCSI_OPCODE_WRITE_16; cdb->lba = cpu_to_be64 ( block ); - cdb->len = cpu_to_be32 ( 1 ); /* always a single block */ + cdb->len = cpu_to_be32 ( count ); command.data_out = buffer; - command.data_out_len = blockdev->blksize; + command.data_out_len = ( count * blockdev->blksize ); return scsi_command ( scsi, &command ); } @@ -111,7 +113,7 @@ static int scsi_read_capacity ( struct block_device *blockdev ) { cdb->opcode = SCSI_OPCODE_SERVICE_ACTION_IN; cdb->service_action = SCSI_SERVICE_ACTION_READ_CAPACITY_16; cdb->len = cpu_to_be32 ( sizeof ( capacity ) ); - command.data_in = &capacity; + command.data_in = virt_to_user ( &capacity ); command.data_in_len = sizeof ( capacity ); if ( ( rc = scsi_command ( scsi, &command ) ) != 0 ) -- cgit v1.2.3-55-g7522