diff options
Diffstat (limited to 'qemu/roms/seabios/src/hw/blockcmd.c')
-rw-r--r-- | qemu/roms/seabios/src/hw/blockcmd.c | 139 |
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; |