From b155c50e96cf76af7857f5834ef1d7891fc0041d Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Tue, 29 Oct 2024 13:57:21 -0300 Subject: [PATCH] zip/mo: Report image read/write errors --- src/disk/mo.c | 45 +++++++++++++++++++++++++++++++++++++-------- src/disk/zip.c | 45 +++++++++++++++++++++++++++++++++++++-------- 2 files changed, 74 insertions(+), 16 deletions(-) diff --git a/src/disk/mo.c b/src/disk/mo.c index ed1ab2472..5f757c8af 100644 --- a/src/disk/mo.c +++ b/src/disk/mo.c @@ -874,6 +874,24 @@ mo_write_protected(mo_t *dev) mo_cmd_error(dev); } +static void +mo_write_error(mo_t *dev) +{ + mo_sense_key = SENSE_MEDIUM_ERROR; + mo_asc = ASC_WRITE_ERROR; + mo_ascq = 0; + mo_cmd_error(dev); +} + +static void +mo_read_error(mo_t *dev) +{ + mo_sense_key = SENSE_MEDIUM_ERROR; + mo_asc = ASC_UNRECOVERED_READ_ERROR; + mo_ascq = 0; + mo_cmd_error(dev); +} + static void mo_invalid_lun(mo_t *dev) { @@ -928,7 +946,7 @@ mo_blocks(mo_t *dev, int32_t *len, UNUSED(int first_batch), int out) if (!dev->sector_len) { mo_command_complete(dev); - return -1; + return 0; } mo_log("%sing %i blocks starting from %i...\n", out ? "Writ" : "Read", dev->requested_blocks, dev->sector_pos); @@ -942,20 +960,31 @@ mo_blocks(mo_t *dev, int32_t *len, UNUSED(int first_batch), int out) *len = dev->requested_blocks * dev->drv->sector_size; for (int i = 0; i < dev->requested_blocks; i++) { - if (fseek(dev->drv->fp, dev->drv->base + (dev->sector_pos * dev->drv->sector_size) + (i * dev->drv->sector_size), SEEK_SET) == 1) - break; + if (fseek(dev->drv->fp, dev->drv->base + (dev->sector_pos * dev->drv->sector_size) + (i * dev->drv->sector_size), SEEK_SET) == -1) { + if (out) + mo_write_error(dev); + else + mo_read_error(dev); + return -1; + } if (feof(dev->drv->fp)) break; if (out) { - if (fwrite(dev->buffer + (i * dev->drv->sector_size), 1, dev->drv->sector_size, dev->drv->fp) != dev->drv->sector_size) - fatal("mo_blocks(): Error writing data\n"); + if (fwrite(dev->buffer + (i * dev->drv->sector_size), 1, dev->drv->sector_size, dev->drv->fp) != dev->drv->sector_size) { + mo_log("mo_blocks(): Error writing data\n"); + mo_write_error(dev); + return -1; + } fflush(dev->drv->fp); } else { - if (fread(dev->buffer + (i * dev->drv->sector_size), 1, dev->drv->sector_size, dev->drv->fp) != dev->drv->sector_size) - fatal("mo_blocks(): Error reading data\n"); + if (fread(dev->buffer + (i * dev->drv->sector_size), 1, dev->drv->sector_size, dev->drv->fp) != dev->drv->sector_size) { + mo_log("mo_blocks(): Error reading data\n"); + mo_read_error(dev); + return -1; + } } } @@ -1433,7 +1462,7 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) ret = mo_blocks(dev, &alloc_length, 1, 0); if (ret <= 0) { mo_set_phase(dev, SCSI_PHASE_STATUS); - dev->packet_status = PHASE_COMPLETE; + dev->packet_status = (ret < 0) ? PHASE_ERROR : PHASE_COMPLETE; dev->callback = 20.0 * MO_TIME; mo_set_callback(dev); mo_buf_free(dev); diff --git a/src/disk/zip.c b/src/disk/zip.c index a948cab2f..4a5a9b968 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -1048,6 +1048,24 @@ zip_write_protected(zip_t *dev) zip_cmd_error(dev); } +static void +zip_write_error(zip_t *dev) +{ + zip_sense_key = SENSE_MEDIUM_ERROR; + zip_asc = ASC_WRITE_ERROR; + zip_ascq = 0; + zip_cmd_error(dev); +} + +static void +zip_read_error(zip_t *dev) +{ + zip_sense_key = SENSE_MEDIUM_ERROR; + zip_asc = ASC_UNRECOVERED_READ_ERROR; + zip_ascq = 0; + zip_cmd_error(dev); +} + static void zip_invalid_lun(zip_t *dev) { @@ -1111,7 +1129,7 @@ zip_blocks(zip_t *dev, int32_t *len, UNUSED(int first_batch), int out) if (!dev->sector_len) { zip_command_complete(dev); - return -1; + return 0; } zip_log("%sing %i blocks starting from %i...\n", out ? "Writ" : "Read", dev->requested_blocks, dev->sector_pos); @@ -1125,20 +1143,31 @@ zip_blocks(zip_t *dev, int32_t *len, UNUSED(int first_batch), int out) *len = dev->requested_blocks << 9; for (int i = 0; i < dev->requested_blocks; i++) { - if (fseek(dev->drv->fp, dev->drv->base + (dev->sector_pos << 9) + (i << 9), SEEK_SET) == 1) - break; + if (fseek(dev->drv->fp, dev->drv->base + (dev->sector_pos << 9) + (i << 9), SEEK_SET) == -1) { + if (out) + zip_write_error(dev); + else + zip_read_error(dev); + return -1; + } if (feof(dev->drv->fp)) break; if (out) { - if (fwrite(dev->buffer + (i << 9), 1, 512, dev->drv->fp) != 512) - fatal("zip_blocks(): Error writing data\n"); + if (fwrite(dev->buffer + (i << 9), 1, 512, dev->drv->fp) != 512) { + zip_log("zip_blocks(): Error writing data\n"); + zip_write_error(dev); + return -1; + } fflush(dev->drv->fp); } else { - if (fread(dev->buffer + (i << 9), 1, 512, dev->drv->fp) != 512) - fatal("zip_blocks(): Error reading data\n"); + if (fread(dev->buffer + (i << 9), 1, 512, dev->drv->fp) != 512) { + zip_log("zip_blocks(): Error reading data\n"); + zip_read_error(dev); + return -1; + } } } @@ -1551,7 +1580,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) ret = zip_blocks(dev, &alloc_length, 1, 0); if (ret <= 0) { zip_set_phase(dev, SCSI_PHASE_STATUS); - dev->packet_status = PHASE_COMPLETE; + dev->packet_status = (ret < 0) ? PHASE_ERROR : PHASE_COMPLETE; dev->callback = 20.0 * ZIP_TIME; zip_set_callback(dev); zip_buf_free(dev);