Merge pull request #58 from TC1995/master
Added Read Track Information command in ATAPI and SCSI.
This commit is contained in:
@@ -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,
|
||||
|
@@ -419,6 +419,7 @@ static CDROM iso_cdrom =
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
iso_sector_data_type,
|
||||
iso_readsector_raw,
|
||||
iso_playaudio,
|
||||
|
@@ -130,6 +130,7 @@ static CDROM null_cdrom =
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
null_sector_data_type,
|
||||
null_readsector_raw,
|
||||
null_playaudio,
|
||||
|
@@ -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);
|
||||
|
43
src/ide.c
43
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:
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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
|
Reference in New Issue
Block a user