Move common "cdb" request functions to a new file. --- Makefile | 2 +- src/ata.c | 22 +++---------------- src/blockcmd.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/blockcmd.h | 5 ++++ src/cdrom.c | 59 ++++++++++------------------------------------------- 5 files changed, 83 insertions(+), 67 deletions(-) create mode 100644 src/blockcmd.c
diff --git a/Makefile b/Makefile index 17d4e1f..e087818 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ OUT=out/ # Source files SRCBOTH=misc.c pmm.c stacks.c output.c util.c block.c floppy.c ata.c mouse.c \ kbd.c pci.c serial.c clock.c pic.c cdrom.c ps2port.c smp.c resume.c \ - pnpbios.c pirtable.c vgahooks.c ramdisk.c pcibios.c \ + pnpbios.c pirtable.c vgahooks.c ramdisk.c pcibios.c blockcmd.c \ usb.c usb-uhci.c usb-ohci.c usb-hid.c usb-hub.c paravirt.c SRC16=$(SRCBOTH) system.c disk.c apm.c font.c SRC32FLAT=$(SRCBOTH) post.c shadow.c memmap.c coreboot.c boot.c \ diff --git a/src/ata.c b/src/ata.c index f935e1f..3c57f9f 100644 --- a/src/ata.c +++ b/src/ata.c @@ -653,32 +653,18 @@ atapi_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize) fail: // Enable interrupts outb(ATA_CB_DC_HD15, iobase2+ATA_CB_DC); - return ret; -} - -// Read sectors from the cdrom. -int -cdrom_read(struct disk_op_s *op) -{ - struct cdb_rwdata_10 cmd; - memset(&cmd, 0, sizeof(cmd)); - cmd.command = CDB_CMD_READ_10; - cmd.lba = htonl(op->lba); - cmd.count = htons(op->count); - return atapi_cmd_data(op, &cmd, CDROM_SECTOR_SIZE); + if (ret) + return DISK_RET_EBADTRACK; + return DISK_RET_SUCCESS; }
// 16bit command demuxer for ATAPI cdroms. int process_atapi_op(struct disk_op_s *op) { - int ret; switch (op->command) { case CMD_READ: - ret = cdrom_read(op); - if (ret) - return DISK_RET_EBADTRACK; - return DISK_RET_SUCCESS; + return cdb_read(op); case CMD_FORMAT: case CMD_WRITE: return DISK_RET_EWRITEPROTECT; diff --git a/src/blockcmd.c b/src/blockcmd.c new file mode 100644 index 0000000..5efbdce --- /dev/null +++ b/src/blockcmd.c @@ -0,0 +1,62 @@ +// Support for several common scsi like command data block requests +// +// Copyright (C) 2010 Kevin O'Connor kevin@koconnor.net +// Copyright (C) 2002 MandrakeSoft S.A. +// +// This file may be distributed under the terms of the GNU LGPLv3 license. + +#include "biosvar.h" // GET_GLOBAL +#include "util.h" // htonl +#include "disk.h" // struct disk_op_s +#include "blockcmd.h" // struct cdb_request_sense +#include "ata.h" // atapi_cmd_data + +static int +cdb_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize) +{ + u8 type = GET_GLOBAL(op->drive_g->type); + switch (type) { + case DTYPE_ATAPI: + return atapi_cmd_data(op, cdbcmd, blocksize); + default: + op->count = 0; + return DISK_RET_EPARAM; + } +} + +// Request SENSE +int +cdb_get_sense(struct disk_op_s *op, struct cdbres_request_sense *data) +{ + struct cdb_request_sense cmd; + memset(&cmd, 0, sizeof(cmd)); + cmd.command = CDB_CMD_REQUEST_SENSE; + cmd.length = sizeof(*data); + op->count = 1; + op->buf_fl = data; + return cdb_cmd_data(op, &cmd, sizeof(*data)); +} + +// Request capacity +int +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->count = 1; + op->buf_fl = data; + return cdb_cmd_data(op, &cmd, sizeof(*data)); +} + +// Read sectors. +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 = htonl(op->lba); + cmd.count = htons(op->count); + return cdb_cmd_data(op, &cmd, CDROM_SECTOR_SIZE); +} diff --git a/src/blockcmd.h b/src/blockcmd.h index 28a4889..d645ebe 100644 --- a/src/blockcmd.h +++ b/src/blockcmd.h @@ -55,4 +55,9 @@ struct cdbres_request_sense { u32 reserved_0e; } PACKED;
+// blockcmd.c +int cdb_get_sense(struct disk_op_s *op, struct cdbres_request_sense *data); +int cdb_read_capacity(struct disk_op_s *op, struct cdbres_read_capacity *data); +int cdb_read(struct disk_op_s *op); + #endif // blockcmd.h diff --git a/src/cdrom.c b/src/cdrom.c index 06adefa..4e14a5c 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -182,45 +182,6 @@ cdemu_134b(struct bregs *regs) * CD booting ****************************************************************/
-// Request SENSE -static int -atapi_get_sense(struct disk_op_s *op, u8 *asc, u8 *ascq) -{ - struct cdb_request_sense cmd; - struct cdbres_request_sense data; - memset(&cmd, 0, sizeof(cmd)); - cmd.command = CDB_CMD_REQUEST_SENSE; - cmd.length = sizeof(data); - op->count = 1; - op->buf_fl = &data; - int ret = atapi_cmd_data(op, &cmd, sizeof(data)); - if (ret) - return ret; - - *asc = data.asc; - *ascq = data.ascq; - return 0; -} - -// Request capacity -static int -atapi_read_capacity(struct disk_op_s *op, u32 *blksize, u32 *sectors) -{ - struct cdb_read_capacity cmd; - struct cdbres_read_capacity data; - memset(&cmd, 0, sizeof(cmd)); - cmd.command = CDB_CMD_READ_CAPACITY; - op->count = 1; - op->buf_fl = &data; - int ret = atapi_cmd_data(op, &cmd, sizeof(data)); - if (ret) - return ret; - - *blksize = ntohl(data.blksize); - *sectors = ntohl(data.sectors); - return 0; -} - static int atapi_is_ready(struct disk_op_s *op) { @@ -229,7 +190,7 @@ atapi_is_ready(struct disk_op_s *op) /* Retry READ CAPACITY for 5 seconds unless MEDIUM NOT PRESENT is * reported by the device. If the device reports "IN PROGRESS", * 30 seconds is added. */ - u32 blksize, sectors; + struct cdbres_read_capacity info; int in_progress = 0; u64 end = calc_future_tsc(5000); for (;;) { @@ -238,24 +199,24 @@ atapi_is_ready(struct disk_op_s *op) return -1; }
- int ret = atapi_read_capacity(op, &blksize, §ors); + int ret = cdb_read_capacity(op, &info); if (!ret) // Success break;
- u8 asc, ascq; - ret = atapi_get_sense(op, &asc, &ascq); + struct cdbres_request_sense sense; + ret = cdb_get_sense(op, &sense); if (ret) // Error - retry. continue;
// Sense succeeded. - if (asc == 0x3a) { /* MEDIUM NOT PRESENT */ + if (sense.asc == 0x3a) { /* MEDIUM NOT PRESENT */ dprintf(1, "Device reports MEDIUM NOT PRESENT\n"); return -1; }
- if (asc == 0x04 && ascq == 0x01 && !in_progress) { + if (sense.asc == 0x04 && sense.ascq == 0x01 && !in_progress) { /* IN PROGRESS OF BECOMING READY */ printf("Waiting for device to detect medium... "); /* Allow 30 seconds more */ @@ -264,6 +225,7 @@ atapi_is_ready(struct disk_op_s *op) } }
+ u32 blksize = ntohl(info.blksize), sectors = ntohl(info.sectors); if (blksize != GET_GLOBAL(op->drive_g->blksize)) { printf("Unsupported sector size %u\n", blksize); return -1; @@ -292,7 +254,7 @@ cdrom_boot(int cdid) dop.lba = 0x11; dop.count = 1; dop.buf_fl = MAKE_FLATPTR(GET_SEG(SS), buffer); - ret = cdrom_read(&dop); + ret = cdb_read(&dop); if (ret) return 3;
@@ -307,7 +269,8 @@ cdrom_boot(int cdid)
// And we read the Boot Catalog dop.lba = lba; - ret = cdrom_read(&dop); + dop.count = 1; + ret = cdb_read(&dop); if (ret) return 7;
@@ -347,7 +310,7 @@ cdrom_boot(int cdid) dop.lba = lba; dop.count = DIV_ROUND_UP(nbsectors, 4); dop.buf_fl = MAKE_FLATPTR(boot_segment, 0); - ret = cdrom_read(&dop); + ret = cdb_read(&dop); if (ret) return 12;