From 88298809c553eccca50d5032aa4899706bbea082 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 25 Dec 2016 16:36:27 +0100 Subject: [PATCH] Added Read Track Information command in ATAPI and SCSI. Removed unused scsi_cmds.h header. --- src/cdrom-ioctl.c | 1 + src/cdrom-iso.c | 1 + src/cdrom-null.c | 1 + src/cdrom.h | 5 ++- src/ide.c | 43 ++++++++++++++++++++++ src/scsi.h | 1 + src/scsi_cdrom.c | 46 ++++++++++++++++++++++- src/scsi_cmds.h | 93 ----------------------------------------------- 8 files changed, 95 insertions(+), 96 deletions(-) delete mode 100644 src/scsi_cmds.h diff --git a/src/cdrom-ioctl.c b/src/cdrom-ioctl.c index 99979c26d..9c26a6d5d 100644 --- a/src/cdrom-ioctl.c +++ b/src/cdrom-ioctl.c @@ -1040,6 +1040,7 @@ static CDROM ioctl_cdrom= ioctl_read_capacity, ioctl_read_header, ioctl_read_disc_information, + ioctl_read_track_information, ioctl_sector_data_type, ioctl_readsector_raw, ioctl_playaudio, diff --git a/src/cdrom-iso.c b/src/cdrom-iso.c index 1f7dc6963..ec073d9ba 100644 --- a/src/cdrom-iso.c +++ b/src/cdrom-iso.c @@ -419,6 +419,7 @@ static CDROM iso_cdrom = NULL, NULL, NULL, + NULL, iso_sector_data_type, iso_readsector_raw, iso_playaudio, diff --git a/src/cdrom-null.c b/src/cdrom-null.c index 306e78d9c..ab9ef29a4 100644 --- a/src/cdrom-null.c +++ b/src/cdrom-null.c @@ -130,6 +130,7 @@ static CDROM null_cdrom = NULL, NULL, NULL, + NULL, null_sector_data_type, null_readsector_raw, null_playaudio, diff --git a/src/cdrom.h b/src/cdrom.h index 133338433..67513f2f6 100644 --- a/src/cdrom.h +++ b/src/cdrom.h @@ -11,9 +11,10 @@ typedef struct CDROM int (*readtoc_raw)(uint8_t *b, int msf, int maxlen); uint8_t (*getcurrentsubchannel)(uint8_t *b, int msf); void (*read_capacity)(uint8_t *b); - void (*read_header)(uint8_t *in_cdb, uint8_t *b); + void (*read_header)(uint8_t *in_cdb, uint8_t *b); void (*read_disc_information)(uint8_t *b); - int (*sector_data_type)(int sector, int ismsf); + void (*read_track_information)(uint8_t *in_cdb, uint8_t *b); + int (*sector_data_type)(int sector, int ismsf); void (*readsector_raw)(uint8_t *b, int sector, int ismsf); void (*playaudio)(uint32_t pos, uint32_t len, int ismsf); void (*seek)(uint32_t pos); diff --git a/src/ide.c b/src/ide.c index d91b53a3a..e7afc0b8a 100644 --- a/src/ide.c +++ b/src/ide.c @@ -2549,6 +2549,49 @@ static void atapicommand(int ide_board) idecallback[ide_board]=60*IDE_TIME; ide->packlen=len; 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; + } + + if (cdrom->read_track_information) + { + cdrom->read_track_information(idebufferb, idebufferb); + } + else + { + idebufferb[1] = 34; + idebufferb[2] = 1; /* track number (LSB) */ + idebufferb[3] = 1; /* session number (LSB) */ + idebufferb[5] = (0 << 5) | (0 << 4) | (4 << 0); /* not damaged, primary copy, data track */ + idebufferb[6] = (0 << 7) | (0 << 6) | (0 << 5) | (0 << 6) | (1 << 0); /* not reserved track, not blank, not packet writing, not fixed packet, data mode 1 */ + idebufferb[7] = (0 << 1) | (0 << 0); /* last recorded address not valid, next recordable address not valid */ + idebufferb[8] = 0; /* track start address is 0 */ + idebufferb[24] = (cdrom->size() >> 24) & 0xff; /* track size */ + idebufferb[25] = (cdrom->size() >> 16) & 0xff; /* track size */ + idebufferb[26] = (cdrom->size() >> 8) & 0xff; /* track size */ + idebufferb[27] = cdrom->size() & 0xff; /* track size */ + idebufferb[32] = 0; /* track number (MSB) */ + idebufferb[33] = 0; /* session number (MSB) */ + } + + len=36; + ide->packetstatus = ATAPI_STATUS_DATA; + ide->cylinder=len; + ide->secount=2; + ide->pos=0; + idecallback[ide_board]=60*IDE_TIME; + ide->packlen=len; + break; case GPCMD_PLAY_AUDIO_10: case GPCMD_PLAY_AUDIO_12: diff --git a/src/scsi.h b/src/scsi.h index 439c2a966..a2063df36 100644 --- a/src/scsi.h +++ b/src/scsi.h @@ -32,6 +32,7 @@ #define GPCMD_PAUSE_RESUME 0x4b #define GPCMD_STOP_PLAY_SCAN 0x4e #define GPCMD_READ_DISC_INFORMATION 0x51 +#define GPCMD_READ_TRACK_INFORMATION 0x52 #define GPCMD_MODE_SELECT_10 0x55 #define GPCMD_MODE_SENSE_10 0x5a #define GPCMD_PLAY_AUDIO_12 0xa5 diff --git a/src/scsi_cdrom.c b/src/scsi_cdrom.c index 543ba6f42..b310442c6 100644 --- a/src/scsi_cdrom.c +++ b/src/scsi_cdrom.c @@ -1036,6 +1036,15 @@ void SCSICDROM_Command(uint8_t id, uint8_t *cdb) SCSIDMAResetPosition(id); break; + case GPCMD_READ_TRACK_INFORMATION: + SCSIPhase = SCSI_PHASE_DATAIN; + SCSIStatus = SCSI_STATUS_OK; + SCSICallback[id]=60*SCSI_TIME; + SCSIDevices[id].CmdBufferLength = 36; + + SCSIDMAResetPosition(id); + break; + case GPCMD_READ_DVD_STRUCTURE: { int len; @@ -1542,7 +1551,42 @@ SCSIOut: SCSIDevices[id].CmdBuffer[8] = 0x00; /* CD-ROM */ } 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; + } + + if (cdrom->read_track_information) + { + cdrom->read_track_information(SCSIDevices[id].Cdb, SCSIDevices[id].CmdBuffer); + } + else + { + SCSIDevices[id].CmdBuffer[1] = 34; + SCSIDevices[id].CmdBuffer[2] = 1; /* track number (LSB) */ + SCSIDevices[id].CmdBuffer[3] = 1; /* session number (LSB) */ + SCSIDevices[id].CmdBuffer[5] = (0 << 5) | (0 << 4) | (4 << 0); /* not damaged, primary copy, data track */ + SCSIDevices[id].CmdBuffer[6] = (0 << 7) | (0 << 6) | (0 << 5) | (0 << 6) | (1 << 0); /* not reserved track, not blank, not packet writing, not fixed packet, data mode 1 */ + SCSIDevices[id].CmdBuffer[7] = (0 << 1) | (0 << 0); /* last recorded address not valid, next recordable address not valid */ + SCSIDevices[id].CmdBuffer[8] = 0; /* track start address is 0 */ + SCSIDevices[id].CmdBuffer[24] = (cdrom->size() >> 24) & 0xff; /* track size */ + SCSIDevices[id].CmdBuffer[25] = (cdrom->size() >> 16) & 0xff; /* track size */ + SCSIDevices[id].CmdBuffer[26] = (cdrom->size() >> 8) & 0xff; /* track size */ + SCSIDevices[id].CmdBuffer[27] = cdrom->size() & 0xff; /* track size */ + SCSIDevices[id].CmdBuffer[32] = 0; /* track number (MSB) */ + SCSIDevices[id].CmdBuffer[33] = 0; /* session number (MSB) */ + } + break; + case GPCMD_READ_DVD_STRUCTURE: memset(SCSIDevices[id].CmdBuffer, 0, datalen > 256 * 512 + 4 ? 256 * 512 + 4 : datalen); diff --git a/src/scsi_cmds.h b/src/scsi_cmds.h deleted file mode 100644 index 00eb03ef4..000000000 --- a/src/scsi_cmds.h +++ /dev/null @@ -1,93 +0,0 @@ -/* Copyright holders: SA1988 - see COPYING for more details -*/ -/* ATAPI/SCSI Commands */ -#define TEST_UNIT_READY 0x00 -#define REQUEST_SENSE 0x03 -#define READ_6 0x08 -#define INQUIRY 0x12 -#define MODE_SELECT 0x15 -#define MODE_SENSE 0x1a /*actually MODE_SENSE_6 but I want to match QEMU's scheme*/ -#define START_STOP 0x1b /*LOAD_UNLOAD is the same*/ -#define ALLOW_MEDIUM_REMOVAL 0x1e -#define READ_CAPACITY_10 0x25 -#define READ_10 0x28 -#define SEEK_10 0x2b -#define READ_SUBCHANNEL 0x42 /*unimplemented on QEMU, so I came up with this name for this command*/ -#define READ_TOC 0x43 -#define READ_HEADER 0x44 /*unimplemented on QEMU, so I came up with this name for this command*/ -#define PLAY_AUDIO_10 0x45 -#define GET_CONFIGURATION 0x46 -#define PLAY_AUDIO_MSF 0x47 -#define GET_EVENT_NOTIFICATION 0x4a -#define PAUSE_RESUME 0x4b -#define STOP_PLAY_SCAN 0x4e -#define READ_DISC_INFORMATION 0x51 -#define MODE_SELECT_10 0x55 -#define MODE_SENSE_10 0x5a -#define PLAY_AUDIO_12 0xa5 /*deprecated*/ -#define READ_12 0xa8 -#define READ_DVD_STRUCTURE 0xad -#define SET_CD_SPEED 0xbb -#define MECHANISM_STATUS 0xbd -#define READ_CD 0xbe -#define SEND_DVD_STRUCTURE 0xbf - -/* SCSI Sense Keys */ -#define SENSE_NONE 0 -#define SENSE_NOT_READY 2 -#define SENSE_ILLEGAL_REQUEST 5 -#define SENSE_UNIT_ATTENTION 6 - -/* SCSI Additional Sense Codes */ -#define ASC_ILLEGAL_OPCODE 0x20 -#define ASC_INV_FIELD_IN_CMD_PACKET 0x24 -#define ASC_MEDIUM_MAY_HAVE_CHANGED 0x28 -#define ASC_MEDIUM_NOT_PRESENT 0x3a - -/* Mode page codes for mode sense/set */ -#define GPMODE_R_W_ERROR_PAGE 0x01 -#define GPMODE_CDROM_PAGE 0x0d -#define GPMODE_CDROM_AUDIO_PAGE 0x0e -#define GPMODE_CAPABILITIES_PAGE 0x2a -#define GPMODE_ALL_PAGES 0x3f - -/* - * SCSI Status codes -*/ -#define GOOD 0x00 -#define CHECK_CONDITION 0x02 -#define CONDITION_GOOD 0x04 -#define BUSY 0x08 -#define INTERMEDIATE_GOOD 0x10 -#define INTERMEDIATE_C_GOOD 0x14 -#define RESERVATION_CONFLICT 0x18 -#define COMMAND_TERMINATED 0x22 -#define TASK_SET_FULL 0x28 -#define ACA_ACTIVE 0x30 -#define TASK_ABORTED 0x40 - -#define STATUS_MASK 0x3e - -/* Event notification classes for GET EVENT STATUS NOTIFICATION */ -#define GESN_NO_EVENTS 0 -#define GESN_OPERATIONAL_CHANGE 1 -#define GESN_POWER_MANAGEMENT 2 -#define GESN_EXTERNAL_REQUEST 3 -#define GESN_MEDIA 4 -#define GESN_MULTIPLE_HOSTS 5 -#define GESN_DEVICE_BUSY 6 - -/* Event codes for MEDIA event status notification */ -#define MEC_NO_CHANGE 0 -#define MEC_EJECT_REQUESTED 1 -#define MEC_NEW_MEDIA 2 -#define MEC_MEDIA_REMOVAL 3 /* only for media changers */ -#define MEC_MEDIA_CHANGED 4 /* only for media changers */ -#define MEC_BG_FORMAT_COMPLETED 5 /* MRW or DVD+RW b/g format completed */ -#define MEC_BG_FORMAT_RESTARTED 6 /* MRW or DVD+RW b/g format restarted */ -#define MS_TRAY_OPEN 1 -#define MS_MEDIA_PRESENT 2 - -#define CHECK_READY 2 -#define ALLOW_UA 1 \ No newline at end of file