From fa3394c04e4d89e0152dc667693fd193ab149fce Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 26 Dec 2020 02:26:45 +0100 Subject: [PATCH] Fixed parameter list in data out phase on MODE SELECT (10) command on all ATAPI and SCSI devices, fixes ATAPI and SCSI CD Audio volume control, fixes #1191. --- src/cdrom/cdrom.c | 5 ----- src/disk/mo.c | 15 ++++++++++----- src/disk/zip.c | 15 ++++++++++----- src/scsi/scsi_cdrom.c | 12 +++++++++--- src/scsi/scsi_disk.c | 12 +++++++++--- 5 files changed, 38 insertions(+), 21 deletions(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 4b4e74d55..5db9365bc 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -733,11 +733,6 @@ track_type_is_valid(uint8_t id, int type, int flags, int audio, int mode2) } if ((type != 1) && !audio) { - if (!(flags & 0x70)) { /* 0x00/0x08/0x80/0x88 are illegal modes */ - cdrom_log("CD-ROM %i: [Any Data Mode] 0x00/0x08/0x80/0x88 are illegal modes\n", id); - return 0; - } - if ((flags & 0x06) == 0x06) { cdrom_log("CD-ROM %i: [Any Data Mode] Invalid error flags\n", id); return 0; diff --git a/src/disk/mo.c b/src/disk/mo.c index 87b67c4b4..a5adbb108 100644 --- a/src/disk/mo.c +++ b/src/disk/mo.c @@ -1887,8 +1887,8 @@ mo_phase_data_out(scsi_common_t *sc) { mo_t *dev = (mo_t *) sc; - uint16_t block_desc_len; - uint16_t pos; + uint16_t block_desc_len, pos; + uint16_t param_list_len; uint8_t error = 0; uint8_t page, page_len; @@ -1914,10 +1914,15 @@ mo_phase_data_out(scsi_common_t *sc) break; case GPCMD_MODE_SELECT_6: case GPCMD_MODE_SELECT_10: - if (dev->current_cdb[0] == GPCMD_MODE_SELECT_10) + if (dev->current_cdb[0] == GPCMD_MODE_SELECT_10) { hdr_len = 8; - else + param_list_len = dev->current_cdb[7]; + param_list_len <<= 8; + param_list_len |= dev->current_cdb[8]; + } else { hdr_len = 4; + param_list_len = dev->current_cdb[4]; + } if (dev->drv->bus_type == MO_BUS_SCSI) { if (dev->current_cdb[0] == GPCMD_MODE_SELECT_6) { @@ -1935,7 +1940,7 @@ mo_phase_data_out(scsi_common_t *sc) pos = hdr_len + block_desc_len; while(1) { - if (pos >= dev->current_cdb[4]) { + if (pos >= param_list_len) { mo_log("MO %i: Buffer has only block descriptor\n", dev->id); break; } diff --git a/src/disk/zip.c b/src/disk/zip.c index 39ea4dc2a..2de8a2c0d 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -2081,8 +2081,8 @@ zip_phase_data_out(scsi_common_t *sc) { zip_t *dev = (zip_t *) sc; - uint16_t block_desc_len; - uint16_t pos; + uint16_t block_desc_len, pos; + uint16_t param_list_len; uint8_t error = 0; uint8_t page, page_len; @@ -2143,10 +2143,15 @@ zip_phase_data_out(scsi_common_t *sc) break; case GPCMD_MODE_SELECT_6: case GPCMD_MODE_SELECT_10: - if (dev->current_cdb[0] == GPCMD_MODE_SELECT_10) + if (dev->current_cdb[0] == GPCMD_MODE_SELECT_10) { hdr_len = 8; - else + param_list_len = dev->current_cdb[7]; + param_list_len <<= 8; + param_list_len |= dev->current_cdb[8]; + } else { hdr_len = 4; + param_list_len = dev->current_cdb[4]; + } if (dev->drv->bus_type == ZIP_BUS_SCSI) { if (dev->current_cdb[0] == GPCMD_MODE_SELECT_6) { @@ -2164,7 +2169,7 @@ zip_phase_data_out(scsi_common_t *sc) pos = hdr_len + block_desc_len; while(1) { - if (pos >= dev->current_cdb[4]) { + if (pos >= param_list_len) { zip_log("ZIP %i: Buffer has only block descriptor\n", dev->id); break; } diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index b1c823b46..4b148a08e 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -2490,6 +2490,7 @@ scsi_cdrom_phase_data_out(scsi_common_t *sc) { scsi_cdrom_t *dev = (scsi_cdrom_t *) sc; uint16_t block_desc_len, pos; + uint16_t param_list_len; uint16_t i = 0; uint8_t error = 0; @@ -2498,10 +2499,15 @@ scsi_cdrom_phase_data_out(scsi_common_t *sc) switch(dev->current_cdb[0]) { case GPCMD_MODE_SELECT_6: case GPCMD_MODE_SELECT_10: - if (dev->current_cdb[0] == GPCMD_MODE_SELECT_10) + if (dev->current_cdb[0] == GPCMD_MODE_SELECT_10) { hdr_len = 8; - else + param_list_len = dev->current_cdb[7]; + param_list_len <<= 8; + param_list_len |= dev->current_cdb[8]; + } else { hdr_len = 4; + param_list_len = dev->current_cdb[4]; + } if (dev->drv->bus_type == CDROM_BUS_SCSI) { if (dev->current_cdb[0] == GPCMD_MODE_SELECT_6) { @@ -2519,7 +2525,7 @@ scsi_cdrom_phase_data_out(scsi_common_t *sc) pos = hdr_len + block_desc_len; while(1) { - if (pos >= dev->current_cdb[4]) { + if (pos >= param_list_len) { scsi_cdrom_log("CD-ROM %i: Buffer has only block descriptor\n", dev->id); break; } diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index 763cfd05b..e411916fa 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -1077,6 +1077,7 @@ scsi_disk_phase_data_out(scsi_common_t *sc) uint32_t last_sector = hdd_image_get_last_sector(dev->id); uint32_t c, h, s, last_to_write = 0; uint16_t block_desc_len, pos; + uint16_t param_list_len; uint8_t hdr_len, val, old_val, ch, error = 0; uint8_t page, page_len; @@ -1133,10 +1134,15 @@ scsi_disk_phase_data_out(scsi_common_t *sc) break; case GPCMD_MODE_SELECT_6: case GPCMD_MODE_SELECT_10: - if (dev->current_cdb[0] == GPCMD_MODE_SELECT_10) + if (dev->current_cdb[0] == GPCMD_MODE_SELECT_10) { hdr_len = 8; - else + param_list_len = dev->current_cdb[7]; + param_list_len <<= 8; + param_list_len |= dev->current_cdb[8]; + } else { hdr_len = 4; + param_list_len = dev->current_cdb[4]; + } if (dev->current_cdb[0] == GPCMD_MODE_SELECT_6) { block_desc_len = dev->temp_buffer[2]; @@ -1151,7 +1157,7 @@ scsi_disk_phase_data_out(scsi_common_t *sc) pos = hdr_len + block_desc_len; while(1) { - if (pos >= dev->current_cdb[4]) { + if (pos >= param_list_len) { scsi_disk_log("SCSI HD %i: Buffer has only block descriptor\n", dev->id); break; }