SCSI auto-sense is now done as an actual pseudo-execution of the REQUEST SENSE command.

This commit is contained in:
OBattler
2017-01-21 01:48:55 +01:00
parent 13e85cc7a6
commit 45183ea026
3 changed files with 88 additions and 49 deletions

View File

@@ -1609,6 +1609,10 @@ static void BuslogicSenseBufferFree(BuslogicRequests_t *BuslogicRequests, int Co
{
uint8_t SenseLength = BuslogicConvertSenseLength(BuslogicRequests->CmdBlock.common.RequestSenseLength);
uint8_t cdrom_id = scsi_cdrom_drives[BuslogicRequests->TargetID][BuslogicRequests->LUN];
uint8_t temp_sense[256];
cdrom_request_sense_for_scsi(cdrom_id, temp_sense, SenseLength);
if (SenseLength && Copy)
{
@@ -1632,7 +1636,8 @@ static void BuslogicSenseBufferFree(BuslogicRequests_t *BuslogicRequests, int Co
if (SenseBufferAddress)
{
BuslogicLog("BuslogicSenseBufferFree(): Writing %i bytes at %08X\n", SenseLength, SenseBufferAddress);
DMAPageWrite(SenseBufferAddress, cdrom[cdrom_id].sense, SenseLength);
DMAPageWrite(SenseBufferAddress, temp_sense, SenseLength);
BuslogicLog("First 8 bytes of written sense data: %02X %02X %02X\n", temp_sense[2], temp_sense[12], temp_sense[13]);
}
}
}

View File

@@ -1551,6 +1551,84 @@ void cdrom_reset(uint8_t id)
cdrom[id].unit_attention = 0;
}
void cdrom_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length)
{
/*Will return 18 bytes of 0*/
if (alloc_length != 0)
{
memset(buffer, 0, alloc_length);
memcpy(buffer, cdrom[id].sense, alloc_length);
}
buffer[0] = 0x70;
if ((cdrom_sense_key > 0) && ((cdrom[id].cd_status < CD_STATUS_PLAYING) || (cdrom[id].cd_status == CD_STATUS_STOPPED)) && cdrom[id].completed)
{
buffer[2]=SENSE_ILLEGAL_REQUEST;
buffer[12]=ASC_AUDIO_PLAY_OPERATION;
buffer[13]=ASCQ_AUDIO_PLAY_OPERATION_COMPLETED;
}
else if ((cdrom_sense_key == 0) && (cdrom[id].cd_status >= CD_STATUS_PLAYING) && (cdrom[id].cd_status != CD_STATUS_STOPPED))
{
buffer[2]=SENSE_ILLEGAL_REQUEST;
buffer[12]=ASC_AUDIO_PLAY_OPERATION;
buffer[13]=(cdrom[id].cd_status == CD_STATUS_PLAYING) ? ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS : ASCQ_AUDIO_PLAY_OPERATION_PAUSED;
}
else
{
if (cdrom[id].unit_attention)
{
buffer[2]=SENSE_UNIT_ATTENTION;
buffer[12]=ASC_MEDIUM_MAY_HAVE_CHANGED;
buffer[13]=0;
}
}
// cdrom_log("CD-ROM %i: Reporting sense: %02X %02X %02X\n", id, cdbufferb[2], cdbufferb[12], cdbufferb[13]);
if (buffer[2] == SENSE_UNIT_ATTENTION)
{
/* If the last remaining sense is unit attention, clear
that condition. */
cdrom[id].unit_attention = 0;
}
/* Clear the sense stuff as per the spec. */
cdrom_sense_clear(id, GPCMD_REQUEST_SENSE, 0);
break;
}
void cdrom_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_length)
{
int ready = 0;
if (cdrom_drives[id].handler->medium_changed(id))
{
// cdrom_log("CD-ROM %i: Medium has changed...\n", id);
cdrom_insert(id);
}
ready = cdrom_drives[id].handler->ready(id);
if (!ready && cdrom[id].unit_attention)
{
/* If the drive is not ready, there is no reason to keep the
UNIT ATTENTION condition present, as we only use it to mark
disc changes. */
cdrom[id].unit_attention = 0;
}
/* If the UNIT ATTENTION condition is set and the command does not allow
execution under it, error out and report the condition. */
if (cdrom[id].unit_attention == 1)
{
// cdrom_log("CD-ROM %i: Unit attention now 2\n", id);
cdrom[id].unit_attention = 2;
}
cdrom_request_sense(id, buffer, alloc_length);
}
void cdrom_command(uint8_t id, uint8_t *cdb)
{
uint8_t *cdbufferb = (uint8_t *) cdrom[id].buffer;
@@ -1650,54 +1728,9 @@ void cdrom_command(uint8_t id, uint8_t *cdb)
cdrom_seek(id, 0);
break;
case GPCMD_REQUEST_SENSE: /* Used by ROS 4+ */
alloc_length = cdb[4];
temp_command = cdb[0];
/*Will return 18 bytes of 0*/
if (alloc_length != 0)
{
memset(cdbufferb, 0, alloc_length);
memcpy(cdbufferb, cdrom[id].sense, alloc_length);
}
cdbufferb[0] = 0x70;
if ((cdrom_sense_key > 0) && ((cdrom[id].cd_status < CD_STATUS_PLAYING) || (cdrom[id].cd_status == CD_STATUS_STOPPED)) && completed)
{
cdbufferb[2]=SENSE_ILLEGAL_REQUEST;
cdbufferb[12]=ASC_AUDIO_PLAY_OPERATION;
cdbufferb[13]=ASCQ_AUDIO_PLAY_OPERATION_COMPLETED;
}
else if ((cdrom_sense_key == 0) && (cdrom[id].cd_status >= CD_STATUS_PLAYING) && (cdrom[id].cd_status != CD_STATUS_STOPPED))
{
cdbufferb[2]=SENSE_ILLEGAL_REQUEST;
cdbufferb[12]=ASC_AUDIO_PLAY_OPERATION;
cdbufferb[13]=(cdrom[id].cd_status == CD_STATUS_PLAYING) ? ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS : ASCQ_AUDIO_PLAY_OPERATION_PAUSED;
}
else
{
if (cdrom[id].unit_attention)
{
cdbufferb[2]=SENSE_UNIT_ATTENTION;
cdbufferb[12]=ASC_MEDIUM_MAY_HAVE_CHANGED;
cdbufferb[13]=0;
}
}
// cdrom_log("CD-ROM %i: Reporting sense: %02X %02X %02X\n", id, cdbufferb[2], cdbufferb[12], cdbufferb[13]);
if (cdbufferb[2] == SENSE_UNIT_ATTENTION)
{
/* If the last remaining sense is unit attention, clear
that condition. */
cdrom[id].unit_attention = 0;
}
/* Clear the sense stuff as per the spec. */
cdrom_sense_clear(id, temp_command, 0);
cdrom_data_command_finish(id, 18, 18, alloc_length, 0);
case GPCMD_REQUEST_SENSE:
cdrom_request_sense(id, cdbufferb, cdb[4]);
cdrom_data_command_finish(id, 18, 18, cdb[4], 0);
break;
case GPCMD_SET_SPEED:

View File

@@ -193,6 +193,7 @@ void cdrom_write(uint8_t channel, uint32_t val, int length);
int cdrom_lba_to_msf_accurate(int lba);
void cdrom_reset(uint8_t id);
void cdrom_set_signature(int id);
void cdrom_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_length);
#define cdrom_sense_error cdrom[id].sense[0]
#define cdrom_sense_key cdrom[id].sense[2]