CD-ROM: Report image backend I/O errors as media CRC errors to the drive
This commit is contained in:
@@ -1520,13 +1520,13 @@ track_type_is_valid(UNUSED(uint8_t id), int type, int flags, int audio, int mode
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
read_sector_to_buffer(cdrom_t *dev, uint8_t *rbuf, uint32_t msf, uint32_t lba, int mode2, int len)
|
||||
{
|
||||
uint8_t *bb = rbuf;
|
||||
const int offset = (!!(mode2 & 0x03)) ? 24 : 16;
|
||||
|
||||
dev->ops->read_sector(dev, CD_READ_DATA, rbuf + offset, lba);
|
||||
int ret = dev->ops->read_sector(dev, CD_READ_DATA, rbuf + offset, lba);
|
||||
|
||||
/* Sync bytes */
|
||||
bb[0] = 0;
|
||||
@@ -1546,25 +1546,30 @@ read_sector_to_buffer(cdrom_t *dev, uint8_t *rbuf, uint32_t msf, uint32_t lba, i
|
||||
memset(bb, 0, 280);
|
||||
else if (!mode2)
|
||||
memset(bb, 0, 288);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
read_audio(cdrom_t *dev, uint32_t lba, uint8_t *b)
|
||||
{
|
||||
dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba);
|
||||
int ret = dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba);
|
||||
|
||||
memcpy(b, raw_buffer, 2352);
|
||||
|
||||
cdrom_sector_size = 2352;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
read_mode1(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int mode2, uint8_t *b)
|
||||
{
|
||||
int ret;
|
||||
if ((dev->cd_status == CD_STATUS_DATA_ONLY) || (dev->ops->sector_size(dev, lba) == 2048))
|
||||
read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2048);
|
||||
ret = read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2048);
|
||||
else
|
||||
dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba);
|
||||
ret = dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba);
|
||||
|
||||
cdrom_sector_size = 0;
|
||||
|
||||
@@ -1610,15 +1615,18 @@ read_mode1(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int
|
||||
cdrom_sector_size += 288;
|
||||
b += 288;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
read_mode2_non_xa(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int mode2, uint8_t *b)
|
||||
{
|
||||
int ret;
|
||||
if ((dev->cd_status == CD_STATUS_DATA_ONLY) || (dev->ops->sector_size(dev, lba) == 2336))
|
||||
read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2336);
|
||||
ret = read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2336);
|
||||
else
|
||||
dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba);
|
||||
ret = dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba);
|
||||
|
||||
cdrom_sector_size = 0;
|
||||
|
||||
@@ -1654,15 +1662,18 @@ read_mode2_non_xa(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t m
|
||||
cdrom_sector_size += 2336;
|
||||
b += 2336;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
read_mode2_xa_form1(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int mode2, uint8_t *b)
|
||||
{
|
||||
int ret;
|
||||
if ((dev->cd_status == CD_STATUS_DATA_ONLY) || (dev->ops->sector_size(dev, lba) == 2048))
|
||||
read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2048);
|
||||
ret = read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2048);
|
||||
else
|
||||
dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba);
|
||||
ret = dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba);
|
||||
|
||||
cdrom_sector_size = 0;
|
||||
|
||||
@@ -1705,15 +1716,18 @@ read_mode2_xa_form1(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t
|
||||
cdrom_sector_size += 280;
|
||||
b += 280;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
read_mode2_xa_form2(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int mode2, uint8_t *b)
|
||||
{
|
||||
int ret;
|
||||
if ((dev->cd_status == CD_STATUS_DATA_ONLY) || (dev->ops->sector_size(dev, lba) == 2324))
|
||||
read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2324);
|
||||
ret = read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2324);
|
||||
else
|
||||
dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba);
|
||||
ret = dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba);
|
||||
|
||||
cdrom_sector_size = 0;
|
||||
|
||||
@@ -1748,6 +1762,8 @@ read_mode2_xa_form2(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t
|
||||
cdrom_sector_size += 2328;
|
||||
b += 2328;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -1763,6 +1779,7 @@ cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, int c
|
||||
int m;
|
||||
int s;
|
||||
int f;
|
||||
int ret = 0;
|
||||
|
||||
if (dev->cd_status == CD_STATUS_EMPTY)
|
||||
return 0;
|
||||
@@ -1827,21 +1844,21 @@ cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, int c
|
||||
return 0;
|
||||
}
|
||||
|
||||
read_audio(dev, lba, temp_b);
|
||||
ret = read_audio(dev, lba, temp_b);
|
||||
} else if (cdrom_sector_type == 2) {
|
||||
if (audio || mode2) {
|
||||
cdrom_log("CD-ROM %i: [Mode 1] Attempting to read a sector of another type\n", dev->id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
read_mode1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
ret = read_mode1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
} else if (cdrom_sector_type == 3) {
|
||||
if (audio || !mode2 || (mode2 & 0x03)) {
|
||||
cdrom_log("CD-ROM %i: [Mode 2 Formless] Attempting to read a sector of another type\n", dev->id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
read_mode2_non_xa(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
ret = read_mode2_non_xa(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
} else if (cdrom_sector_type == 4) {
|
||||
if (audio || !mode2 || ((mode2 & 0x03) != 1)) {
|
||||
cdrom_log("CD-ROM %i: [XA Mode 2 Form 1] Attempting to read a sector of another type\n", dev->id);
|
||||
@@ -1855,7 +1872,7 @@ cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, int c
|
||||
return 0;
|
||||
}
|
||||
|
||||
read_mode2_xa_form2(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
ret = read_mode2_xa_form2(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
} else if (cdrom_sector_type == 8) {
|
||||
if (audio) {
|
||||
cdrom_log("CD-ROM %i: [Any Data] Attempting to read a data sector from an audio track\n", dev->id);
|
||||
@@ -1863,9 +1880,9 @@ cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, int c
|
||||
}
|
||||
|
||||
if (mode2 && ((mode2 & 0x03) == 1))
|
||||
read_mode2_xa_form1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
ret = read_mode2_xa_form1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
else if (!mode2)
|
||||
read_mode1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
ret = read_mode1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
else {
|
||||
cdrom_log("CD-ROM %i: [Any Data] Attempting to read a data sector whose cooked size is not 2048 bytes\n", dev->id);
|
||||
return 0;
|
||||
@@ -1873,16 +1890,16 @@ cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, int c
|
||||
} else {
|
||||
if (mode2) {
|
||||
if ((mode2 & 0x03) == 0x01)
|
||||
read_mode2_xa_form1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
ret = read_mode2_xa_form1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
else if ((mode2 & 0x03) == 0x02)
|
||||
read_mode2_xa_form2(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
ret = read_mode2_xa_form2(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
else
|
||||
read_mode2_non_xa(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
ret = read_mode2_non_xa(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
} else {
|
||||
if (audio)
|
||||
read_audio(dev, lba, temp_b);
|
||||
ret = read_audio(dev, lba, temp_b);
|
||||
else
|
||||
read_mode1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
ret = read_mode1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1914,7 +1931,7 @@ cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, int c
|
||||
|
||||
*len = cdrom_sector_size;
|
||||
|
||||
return 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Peform a master init on the entire module. */
|
||||
|
||||
@@ -181,13 +181,13 @@ bin_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count)
|
||||
if (fseeko64(tf->fp, seek, SEEK_SET) == -1) {
|
||||
cdrom_image_backend_log("CDROM: binary_read failed during seek!\n");
|
||||
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fread(buffer, count, 1, tf->fp) != 1) {
|
||||
cdrom_image_backend_log("CDROM: binary_read failed during read!\n");
|
||||
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (UNLIKELY(tf->motorola)) {
|
||||
@@ -502,8 +502,8 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector)
|
||||
if (raw && !track_is_raw) {
|
||||
memset(buffer, 0x00, 2448);
|
||||
const int ret = trk->file->read(trk->file, buffer + offset, seek, length);
|
||||
if (!ret)
|
||||
return 0;
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
/* Construct the rest of the raw sector. */
|
||||
memset(buffer + 1, 0xff, 10);
|
||||
buffer += 12;
|
||||
@@ -534,7 +534,7 @@ cdi_read_sectors(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector, uint3
|
||||
|
||||
for (uint32_t i = 0; i < num; i++) {
|
||||
success = cdi_read_sector(cdi, &buf[i * sector_size], raw, sector + i);
|
||||
if (!success)
|
||||
if (success <= 0)
|
||||
break;
|
||||
/* Based on the DOSBox patch, but check all 8 bytes and makes sure it's not an
|
||||
audio track. */
|
||||
|
||||
@@ -716,8 +716,11 @@ viso_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count)
|
||||
}
|
||||
|
||||
/* Read data. */
|
||||
if (entry->file && (fseeko64(entry->file, seek - entry->data_offset, SEEK_SET) != -1))
|
||||
if (!entry->file || (fseeko64(entry->file, seek - entry->data_offset, SEEK_SET) == -1))
|
||||
return -1;
|
||||
read = fread(buffer, 1, sector_remain, entry->file);
|
||||
if (sector_remain && !read)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Fill remainder with 00 bytes if needed. */
|
||||
|
||||
@@ -197,7 +197,7 @@ mitsumi_cdrom_read_sector(mcd_t *dev, int first)
|
||||
}
|
||||
cdrom_stop(&cdrom);
|
||||
ret = cdrom_readsector_raw(&cdrom, dev->buf, cdrom.seek_pos, 0, 2, 0x10, (int *) &dev->readcount, 0);
|
||||
if (!ret)
|
||||
if (ret <= 0)
|
||||
return 0;
|
||||
if (dev->mode & 0x40) {
|
||||
dev->buf[12] = CD_BCD((dev->readmsf >> 16) & 0xff);
|
||||
|
||||
@@ -189,6 +189,7 @@
|
||||
/* SCSI Sense Keys */
|
||||
#define SENSE_NONE 0
|
||||
#define SENSE_NOT_READY 2
|
||||
#define SENSE_MEDIUM_ERROR 3
|
||||
#define SENSE_ILLEGAL_REQUEST 5
|
||||
#define SENSE_UNIT_ATTENTION 6
|
||||
|
||||
@@ -196,6 +197,7 @@
|
||||
#define ASC_NONE 0x00
|
||||
#define ASC_AUDIO_PLAY_OPERATION 0x00
|
||||
#define ASC_NOT_READY 0x04
|
||||
#define ASC_UNRECOVERED_READ_ERROR 0x11
|
||||
#define ASC_ILLEGAL_OPCODE 0x20
|
||||
#define ASC_LBA_OUT_OF_RANGE 0x21
|
||||
#define ASC_INV_FIELD_IN_CMD_PACKET 0x24
|
||||
@@ -212,6 +214,7 @@
|
||||
#define ASCQ_NONE 0x00
|
||||
#define ASCQ_UNIT_IN_PROCESS_OF_BECOMING_READY 0x01
|
||||
#define ASCQ_INITIALIZING_COMMAND_REQUIRED 0x02
|
||||
#define ASCQ_CIRC_UNRECOVERED_ERROR 0x06
|
||||
#define ASCQ_CAPACITY_DATA_CHANGED 0x09
|
||||
#define ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS 0x11
|
||||
#define ASCQ_AUDIO_PLAY_OPERATION_PAUSED 0x12
|
||||
|
||||
@@ -207,7 +207,7 @@ plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector)
|
||||
plat_cdrom_close();
|
||||
dummy_cdrom_ioctl_log("ReadSector status=%d, sector=%d, size=%" PRId64 ".\n", status, sector, (long long) size);
|
||||
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -342,7 +342,7 @@ plat_cdrom_get_sector_size(UNUSED(uint32_t sector))
|
||||
int
|
||||
plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector)
|
||||
{
|
||||
BOOL status;
|
||||
int status;
|
||||
long size = 0;
|
||||
int buflen = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE;
|
||||
|
||||
@@ -370,7 +370,7 @@ plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector)
|
||||
plat_cdrom_close();
|
||||
win_cdrom_ioctl_log("ReadSector status=%d, sector=%d, size=%" PRId64 ".\n", status, sector, (long long) size);
|
||||
|
||||
return (size == buflen) && (status > 0);
|
||||
return (status > 0) ? (size == buflen) : -1;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -1244,6 +1244,15 @@ scsi_cdrom_not_ready(scsi_cdrom_t *dev)
|
||||
scsi_cdrom_cmd_error(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
scsi_cdrom_circ_error(scsi_cdrom_t *dev)
|
||||
{
|
||||
scsi_cdrom_sense_key = SENSE_MEDIUM_ERROR;
|
||||
scsi_cdrom_asc = ASC_UNRECOVERED_READ_ERROR;
|
||||
scsi_cdrom_ascq = ASCQ_CIRC_UNRECOVERED_ERROR;
|
||||
scsi_cdrom_cmd_error(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
scsi_cdrom_invalid_lun(scsi_cdrom_t *dev)
|
||||
{
|
||||
@@ -1367,6 +1376,10 @@ scsi_cdrom_read_data(scsi_cdrom_t *dev, int msf, int type, int flags, int32_t *l
|
||||
if (!ret) {
|
||||
scsi_cdrom_illegal_mode(dev);
|
||||
return 0;
|
||||
} else if (ret < 0) {
|
||||
pclog("we have a circ\n");
|
||||
scsi_cdrom_circ_error(dev);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user