summaryrefslogtreecommitdiffstats
path: root/qemu/roms/seabios/src/hw/blockcmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/seabios/src/hw/blockcmd.c')
-rw-r--r--qemu/roms/seabios/src/hw/blockcmd.c139
1 files changed, 44 insertions, 95 deletions
diff --git a/qemu/roms/seabios/src/hw/blockcmd.c b/qemu/roms/seabios/src/hw/blockcmd.c
index 78c0e65f4..0725b46db 100644
--- a/qemu/roms/seabios/src/hw/blockcmd.c
+++ b/qemu/roms/seabios/src/hw/blockcmd.c
@@ -5,67 +5,14 @@
//
// This file may be distributed under the terms of the GNU LGPLv3 license.
-#include "ahci.h" // atapi_cmd_data
-#include "ata.h" // atapi_cmd_data
#include "biosvar.h" // GET_GLOBALFLAT
#include "block.h" // struct disk_op_s
#include "blockcmd.h" // struct cdb_request_sense
#include "byteorder.h" // be32_to_cpu
-#include "esp-scsi.h" // esp_scsi_cmd_data
-#include "lsi-scsi.h" // lsi_scsi_cmd_data
-#include "megasas.h" // megasas_cmd_data
-#include "pvscsi.h" // pvscsi_cmd_data
#include "output.h" // dprintf
#include "std/disk.h" // DISK_RET_EPARAM
#include "string.h" // memset
-#include "usb-msc.h" // usb_cmd_data
-#include "usb-uas.h" // usb_cmd_data
#include "util.h" // timer_calc
-#include "virtio-scsi.h" // virtio_scsi_cmd_data
-
-// Route command to low-level handler.
-static int
-cdb_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize)
-{
- u8 type = GET_GLOBALFLAT(op->drive_gf->type);
- switch (type) {
- case DTYPE_ATA_ATAPI:
- return atapi_cmd_data(op, cdbcmd, blocksize);
- case DTYPE_USB:
- return usb_cmd_data(op, cdbcmd, blocksize);
- case DTYPE_UAS:
- return uas_cmd_data(op, cdbcmd, blocksize);
- case DTYPE_VIRTIO_SCSI:
- return virtio_scsi_cmd_data(op, cdbcmd, blocksize);
- case DTYPE_LSI_SCSI:
- return lsi_scsi_cmd_data(op, cdbcmd, blocksize);
- case DTYPE_ESP_SCSI:
- return esp_scsi_cmd_data(op, cdbcmd, blocksize);
- case DTYPE_MEGASAS:
- return megasas_cmd_data(op, cdbcmd, blocksize);
- case DTYPE_USB_32:
- if (!MODESEGMENT)
- return usb_cmd_data(op, cdbcmd, blocksize);
- case DTYPE_UAS_32:
- if (!MODESEGMENT)
- return uas_cmd_data(op, cdbcmd, blocksize);
- case DTYPE_PVSCSI:
- if (!MODESEGMENT)
- return pvscsi_cmd_data(op, cdbcmd, blocksize);
- case DTYPE_AHCI_ATAPI:
- if (!MODESEGMENT)
- return ahci_cmd_data(op, cdbcmd, blocksize);
- default:
- return DISK_RET_EPARAM;
- }
-}
-
-// Determine if the command is a request to pull data from the device
-int
-cdb_is_read(u8 *cdbcmd, u16 blocksize)
-{
- return blocksize && cdbcmd[0] != CDB_CMD_WRITE_10;
-}
/****************************************************************
@@ -79,9 +26,12 @@ cdb_get_inquiry(struct disk_op_s *op, struct cdbres_inquiry *data)
memset(&cmd, 0, sizeof(cmd));
cmd.command = CDB_CMD_INQUIRY;
cmd.length = sizeof(*data);
+ op->command = CMD_SCSI;
op->count = 1;
op->buf_fl = data;
- return cdb_cmd_data(op, &cmd, sizeof(*data));
+ op->cdbcmd = &cmd;
+ op->blocksize = sizeof(*data);
+ return process_op(op);
}
// Request SENSE
@@ -92,9 +42,12 @@ cdb_get_sense(struct disk_op_s *op, struct cdbres_request_sense *data)
memset(&cmd, 0, sizeof(cmd));
cmd.command = CDB_CMD_REQUEST_SENSE;
cmd.length = sizeof(*data);
+ op->command = CMD_SCSI;
op->count = 1;
op->buf_fl = data;
- return cdb_cmd_data(op, &cmd, sizeof(*data));
+ op->cdbcmd = &cmd;
+ op->blocksize = sizeof(*data);
+ return process_op(op);
}
// Test unit ready
@@ -104,9 +57,12 @@ cdb_test_unit_ready(struct disk_op_s *op)
struct cdb_request_sense cmd;
memset(&cmd, 0, sizeof(cmd));
cmd.command = CDB_CMD_TEST_UNIT_READY;
+ op->command = CMD_SCSI;
op->count = 0;
op->buf_fl = NULL;
- return cdb_cmd_data(op, &cmd, 0);
+ op->cdbcmd = &cmd;
+ op->blocksize = 0;
+ return process_op(op);
}
// Request capacity
@@ -116,9 +72,12 @@ cdb_read_capacity(struct disk_op_s *op, struct cdbres_read_capacity *data)
struct cdb_read_capacity cmd;
memset(&cmd, 0, sizeof(cmd));
cmd.command = CDB_CMD_READ_CAPACITY;
+ op->command = CMD_SCSI;
op->count = 1;
op->buf_fl = data;
- return cdb_cmd_data(op, &cmd, sizeof(*data));
+ op->cdbcmd = &cmd;
+ op->blocksize = sizeof(*data);
+ return process_op(op);
}
// Mode sense, geometry page.
@@ -131,33 +90,12 @@ cdb_mode_sense_geom(struct disk_op_s *op, struct cdbres_mode_sense_geom *data)
cmd.flags = 8; /* DBD */
cmd.page = MODE_PAGE_HD_GEOMETRY;
cmd.count = cpu_to_be16(sizeof(*data));
+ op->command = CMD_SCSI;
op->count = 1;
op->buf_fl = data;
- return cdb_cmd_data(op, &cmd, sizeof(*data));
-}
-
-// Read sectors.
-static int
-cdb_read(struct disk_op_s *op)
-{
- struct cdb_rwdata_10 cmd;
- memset(&cmd, 0, sizeof(cmd));
- cmd.command = CDB_CMD_READ_10;
- cmd.lba = cpu_to_be32(op->lba);
- cmd.count = cpu_to_be16(op->count);
- return cdb_cmd_data(op, &cmd, GET_GLOBALFLAT(op->drive_gf->blksize));
-}
-
-// Write sectors.
-static int
-cdb_write(struct disk_op_s *op)
-{
- struct cdb_rwdata_10 cmd;
- memset(&cmd, 0, sizeof(cmd));
- cmd.command = CDB_CMD_WRITE_10;
- cmd.lba = cpu_to_be32(op->lba);
- cmd.count = cpu_to_be16(op->count);
- return cdb_cmd_data(op, &cmd, GET_GLOBALFLAT(op->drive_gf->blksize));
+ op->cdbcmd = &cmd;
+ op->blocksize = sizeof(*data);
+ return process_op(op);
}
@@ -165,25 +103,36 @@ cdb_write(struct disk_op_s *op)
* Main SCSI commands
****************************************************************/
-int VISIBLE32FLAT
-scsi_process_op(struct disk_op_s *op)
+// Create a scsi command request from a disk_op_s request
+int
+scsi_fill_cmd(struct disk_op_s *op, void *cdbcmd, int maxcdb)
{
switch (op->command) {
case CMD_READ:
- return cdb_read(op);
- case CMD_WRITE:
- return cdb_write(op);
- case CMD_FORMAT:
- case CMD_RESET:
- case CMD_ISREADY:
- case CMD_VERIFY:
- case CMD_SEEK:
- return DISK_RET_SUCCESS;
+ case CMD_WRITE: ;
+ struct cdb_rwdata_10 *cmd = cdbcmd;
+ memset(cmd, 0, maxcdb);
+ cmd->command = (op->command == CMD_READ ? CDB_CMD_READ_10
+ : CDB_CMD_WRITE_10);
+ cmd->lba = cpu_to_be32(op->lba);
+ cmd->count = cpu_to_be16(op->count);
+ return GET_GLOBALFLAT(op->drive_gf->blksize);
+ case CMD_SCSI:
+ memcpy(cdbcmd, op->cdbcmd, maxcdb);
+ return op->blocksize;
default:
- return DISK_RET_EPARAM;
+ return -1;
}
}
+// Determine if the command is a request to pull data from the device
+int
+scsi_is_read(struct disk_op_s *op)
+{
+ return op->command == CMD_READ || (op->command == CMD_SCSI && op->blocksize);
+}
+
+// Check if a SCSI device is ready to receive commands
int
scsi_is_ready(struct disk_op_s *op)
{
@@ -219,7 +168,7 @@ scsi_is_ready(struct disk_op_s *op)
if (sense.asc == 0x04 && sense.ascq == 0x01 && !in_progress) {
/* IN PROGRESS OF BECOMING READY */
- printf("Waiting for device to detect medium... ");
+ dprintf(1, "Waiting for device to detect medium... ");
/* Allow 30 seconds more */
end = timer_calc(30000);
in_progress = 1;