From e9327bbc84f90807c230e0a90e639c5f636e5cb2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 25 Dec 2016 17:38:01 +0100 Subject: [PATCH] Fixed both the ATAPI and SCSI implementations of the READ TRACK INFORMATION command. --- src/ide.c | 44 +++++++++++++++++++++++++++++++------------- src/scsi_cdrom.c | 41 ++++++++++++++++++++++++++++++----------- 2 files changed, 61 insertions(+), 24 deletions(-) diff --git a/src/ide.c b/src/ide.c index e7afc0b8a..704101341 100644 --- a/src/ide.c +++ b/src/ide.c @@ -2551,24 +2551,36 @@ static void atapicommand(int ide_board) break; case GPCMD_READ_TRACK_INFORMATION: - if ((idebufferb[3] != 1) || (idebufferb[2] != 1)) - { - ide->atastat = READY_STAT | ERR_STAT; /*CHECK CONDITION*/ - ide->error = (SENSE_ILLEGAL_REQUEST << 4) | ABRT_ERR; - if (SCSISense.SenseKey == SENSE_UNIT_ATTENTION) - ide->error |= MCR_ERR; - SCSISense.Asc = ASC_INV_FIELD_IN_CMD_PACKET; - ide->packetstatus = ATAPI_STATUS_ERROR; - idecallback[ide_board]=50*IDE_TIME; - return; - } + max_len = idebufferb[7]; + max_len <<= 8; + max_len |= idebufferb[8]; if (cdrom->read_track_information) { cdrom->read_track_information(idebufferb, idebufferb); + + len = idebufferb[0]; + len <<= 8; + len |= idebufferb[1]; + len += 2; } else { + if ((idebufferb[3] != 1) || (idebufferb[2] != 1)) + { + ide->atastat = READY_STAT | ERR_STAT; /*CHECK CONDITION*/ + ide->error = (SENSE_ILLEGAL_REQUEST << 4) | ABRT_ERR; + /* if (SCSISense.SenseKey == SENSE_UNIT_ATTENTION) + ide->error |= MCR_ERR; */ + SCSISense.Asc = ASC_INV_FIELD_IN_CMD_PACKET; + ide->packetstatus = ATAPI_STATUS_ERROR; + idecallback[ide_board]=50*IDE_TIME; + return; + } + + len = 36; + + idebufferb[0] = 0; idebufferb[1] = 34; idebufferb[2] = 1; /* track number (LSB) */ idebufferb[3] = 1; /* session number (LSB) */ @@ -2583,8 +2595,14 @@ static void atapicommand(int ide_board) idebufferb[32] = 0; /* track number (MSB) */ idebufferb[33] = 0; /* session number (MSB) */ } - - len=36; + + if (len > max_len) + { + len = max_len; + idebufferb[0] = ((max_len - 2) >> 8) & 0xff; + idebufferb[1] = (max_len - 2) & 0xff; + } + ide->packetstatus = ATAPI_STATUS_DATA; ide->cylinder=len; ide->secount=2; diff --git a/src/scsi_cdrom.c b/src/scsi_cdrom.c index b310442c6..9c503ddd7 100644 --- a/src/scsi_cdrom.c +++ b/src/scsi_cdrom.c @@ -46,6 +46,7 @@ uint8_t SCSICommandTable[0x100] = [GPCMD_PAUSE_RESUME] = CHECK_READY, [GPCMD_STOP_PLAY_SCAN] = CHECK_READY, [GPCMD_READ_DISC_INFORMATION] = CHECK_READY, + [GPCMD_READ_TRACK_INFORMATION] = CHECK_READY, [GPCMD_MODE_SELECT_10] = 0, [GPCMD_MODE_SENSE_10] = 0, [GPCMD_PLAY_AUDIO_12] = CHECK_READY, @@ -1156,6 +1157,7 @@ void SCSICDROM_ReadData(uint8_t id, uint8_t *cdb, uint8_t *data, int datalen) unsigned PreambleLen; unsigned char Temp; int read_length = 0; + int max_length = 0; msf = cdb[1] & 2; @@ -1553,24 +1555,34 @@ SCSIOut: break; case GPCMD_READ_TRACK_INFORMATION: - if ((SCSIDevices[id].Cdb[3] != 1) || (SCSIDevices[id].Cdb[2] != 1)) - { - SCSIStatus = SCSI_STATUS_CHECK_CONDITION; - SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET, 0x00); - if (SCSISense.UnitAttention) - { - SCSISenseCodeError(SENSE_UNIT_ATTENTION, ASC_MEDIUM_MAY_HAVE_CHANGED, 0); - } - SCSICallback[id]=50*SCSI_TIME; - return; - } + max_length = SCSIDevices[id].Cdb[7]; + max_length <<= 8; + max_length |= SCSIDevices[id].Cdb[8]; if (cdrom->read_track_information) { cdrom->read_track_information(SCSIDevices[id].Cdb, SCSIDevices[id].CmdBuffer); + + datalen = SCSIDevices[id].CmdBuffer[0]; + datalen <<= 8; + datalen |= SCSIDevices[id].CmdBuffer[1]; + datalen += 2; } else { + if ((SCSIDevices[id].Cdb[3] != 1) || (SCSIDevices[id].Cdb[2] != 1)) + { + SCSIStatus = SCSI_STATUS_CHECK_CONDITION; + SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET, 0x00); + if (SCSISense.UnitAttention) + { + SCSISenseCodeError(SENSE_UNIT_ATTENTION, ASC_MEDIUM_MAY_HAVE_CHANGED, 0); + } + SCSICallback[id]=50*SCSI_TIME; + return; + } + + datalen = 36; SCSIDevices[id].CmdBuffer[1] = 34; SCSIDevices[id].CmdBuffer[2] = 1; /* track number (LSB) */ SCSIDevices[id].CmdBuffer[3] = 1; /* session number (LSB) */ @@ -1585,6 +1597,13 @@ SCSIOut: SCSIDevices[id].CmdBuffer[32] = 0; /* track number (MSB) */ SCSIDevices[id].CmdBuffer[33] = 0; /* session number (MSB) */ } + + if (datalen > max_length) + { + datalen = max_length; + SCSIDevices[id].CmdBuffer[0] = ((max_length - 2) >> 8) & 0xff; + SCSIDevices[id].CmdBuffer[1] = (max_length - 2) & 0xff; + } break; case GPCMD_READ_DVD_STRUCTURE: