Merge branch 'master' of https://github.com/OBattler/PCem-Experimental
This commit is contained in:
114
src/buslogic.c
114
src/buslogic.c
@@ -1414,69 +1414,75 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer,
|
|||||||
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
BuslogicLog("SCSI Cdb[0]=0x%02X\n", BuslogicRequests->CmdBlock.common.Cdb[0]);
|
pclog("SCSI Cdb[0]=0x%02X\n", BuslogicRequests->CmdBlock.common.Cdb[0]);
|
||||||
for (i = 1; i < BuslogicRequests->CmdBlock.common.CdbLength; i++)
|
for (i = 1; i < BuslogicRequests->CmdBlock.common.CdbLength; i++)
|
||||||
BuslogicLog("SCSI Cdb[%i]=%i\n", i, BuslogicRequests->CmdBlock.common.Cdb[i]);
|
pclog("SCSI Cdb[%i]=%i\n", i, BuslogicRequests->CmdBlock.common.Cdb[i]);
|
||||||
|
|
||||||
BuslogicLog("Transfer Control %02X\n", BuslogicRequests->CmdBlock.common.ControlByte);
|
pclog("Transfer Control %02X\n", BuslogicRequests->CmdBlock.common.ControlByte);
|
||||||
BuslogicLog("CDB Length %i\n", BuslogicRequests->CmdBlock.common.CdbLength);
|
pclog("CDB Length %i\n", BuslogicRequests->CmdBlock.common.CdbLength);
|
||||||
BuslogicLog("CCB Opcode %x\n", BuslogicRequests->CmdBlock.common.Opcode);
|
pclog("CCB Opcode %x\n", BuslogicRequests->CmdBlock.common.Opcode);
|
||||||
|
|
||||||
if ((BuslogicRequests->CmdBlock.common.ControlByte != 0x03) && (BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND))
|
//This not ready/unit attention stuff below is only for the Buslogic!
|
||||||
|
//The Adaptec one is in scsi_cdrom.c.
|
||||||
|
|
||||||
|
if (scsi_model)
|
||||||
{
|
{
|
||||||
if (cdrom->medium_changed())
|
if ((BuslogicRequests->CmdBlock.common.ControlByte != 0x03) && (BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND))
|
||||||
{
|
{
|
||||||
BuslogicLog("Media changed\n");
|
if (cdrom->medium_changed())
|
||||||
SCSICDROM_Insert();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cdrom->ready() && SCSISense.UnitAttention)
|
|
||||||
{
|
|
||||||
/* 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. */
|
|
||||||
SCSISense.UnitAttention = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If the UNIT ATTENTION condition is set and the command does not allow
|
|
||||||
execution under it, error out and report the condition. */
|
|
||||||
if (SCSISense.UnitAttention == 1)
|
|
||||||
{
|
|
||||||
SCSISense.UnitAttention = 2;
|
|
||||||
if (!(SCSICommandTable[BuslogicRequests->CmdBlock.common.Cdb[0]] & ALLOW_UA))
|
|
||||||
{
|
{
|
||||||
SCSISenseCodeError(SENSE_UNIT_ATTENTION, ASC_MEDIUM_MAY_HAVE_CHANGED, 0);
|
pclog("Media changed\n");
|
||||||
|
SCSICDROM_Insert();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cdrom->ready() && SCSISense.UnitAttention)
|
||||||
|
{
|
||||||
|
/* 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. */
|
||||||
|
SCSISense.UnitAttention = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the UNIT ATTENTION condition is set and the command does not allow
|
||||||
|
execution under it, error out and report the condition. */
|
||||||
|
if (SCSISense.UnitAttention == 1)
|
||||||
|
{
|
||||||
|
SCSISense.UnitAttention = 2;
|
||||||
|
if (!(SCSICommandTable[BuslogicRequests->CmdBlock.common.Cdb[0]] & ALLOW_UA))
|
||||||
|
{
|
||||||
|
SCSISenseCodeError(SENSE_UNIT_ATTENTION, ASC_MEDIUM_MAY_HAVE_CHANGED, 0);
|
||||||
|
SCSIStatus = SCSI_STATUS_CHECK_CONDITION;
|
||||||
|
SCSICallback[Id]=50*SCSI_TIME;
|
||||||
|
BuslogicMailboxIn(Buslogic, BuslogicRequests->CCBPointer, &BuslogicRequests->CmdBlock, CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (SCSISense.UnitAttention == 2)
|
||||||
|
{
|
||||||
|
if (BuslogicRequests->CmdBlock.common.Cdb[0]!=GPCMD_REQUEST_SENSE)
|
||||||
|
{
|
||||||
|
SCSISense.UnitAttention = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unless the command is REQUEST SENSE, clear the sense. This will *NOT*
|
||||||
|
clear the UNIT ATTENTION condition if it's set. */
|
||||||
|
if (BuslogicRequests->CmdBlock.common.Cdb[0]!=GPCMD_REQUEST_SENSE)
|
||||||
|
{
|
||||||
|
SCSIClearSense(BuslogicRequests->CmdBlock.common.Cdb[0], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Next it's time for NOT READY. */
|
||||||
|
if ((SCSICommandTable[BuslogicRequests->CmdBlock.common.Cdb[0]] & CHECK_READY) && !cdrom->ready())
|
||||||
|
{
|
||||||
|
pclog("Not ready\n");
|
||||||
|
SCSISenseCodeError(SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT, 0);
|
||||||
SCSIStatus = SCSI_STATUS_CHECK_CONDITION;
|
SCSIStatus = SCSI_STATUS_CHECK_CONDITION;
|
||||||
SCSICallback[Id]=50*SCSI_TIME;
|
SCSICallback[Id]=50*SCSI_TIME;
|
||||||
BuslogicMailboxIn(Buslogic, BuslogicRequests->CCBPointer, &BuslogicRequests->CmdBlock, CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR);
|
BuslogicMailboxIn(Buslogic, BuslogicRequests->CCBPointer, &BuslogicRequests->CmdBlock, CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (SCSISense.UnitAttention == 2)
|
|
||||||
{
|
|
||||||
if (BuslogicRequests->CmdBlock.common.Cdb[0]!=GPCMD_REQUEST_SENSE)
|
|
||||||
{
|
|
||||||
SCSISense.UnitAttention = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unless the command is REQUEST SENSE, clear the sense. This will *NOT*
|
|
||||||
clear the UNIT ATTENTION condition if it's set. */
|
|
||||||
if (BuslogicRequests->CmdBlock.common.Cdb[0]!=GPCMD_REQUEST_SENSE)
|
|
||||||
{
|
|
||||||
SCSIClearSense(BuslogicRequests->CmdBlock.common.Cdb[0], 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Next it's time for NOT READY. */
|
|
||||||
if ((SCSICommandTable[BuslogicRequests->CmdBlock.common.Cdb[0]] & CHECK_READY) && !cdrom->ready())
|
|
||||||
{
|
|
||||||
BuslogicLog("Not ready\n");
|
|
||||||
SCSISenseCodeError(SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT, 0);
|
|
||||||
SCSIStatus = SCSI_STATUS_CHECK_CONDITION;
|
|
||||||
SCSICallback[Id]=50*SCSI_TIME;
|
|
||||||
BuslogicMailboxIn(Buslogic, BuslogicRequests->CCBPointer, &BuslogicRequests->CmdBlock, CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//First, get the data buffer otherwise putting it after the
|
//First, get the data buffer otherwise putting it after the
|
||||||
@@ -1522,8 +1528,8 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer,
|
|||||||
BuslogicSenseBufferFree(BuslogicRequests, (SCSIStatus != SCSI_STATUS_OK));
|
BuslogicSenseBufferFree(BuslogicRequests, (SCSIStatus != SCSI_STATUS_OK));
|
||||||
}
|
}
|
||||||
|
|
||||||
BuslogicLog("Request complete\n");
|
pclog("Request complete\n");
|
||||||
BuslogicLog("SCSI Status %02X, Sense %02X, Asc %02X, Ascq %02X\n", SCSIStatus, SCSISense.SenseKey, SCSISense.Asc, SCSISense.Ascq);
|
pclog("SCSI Status %02X, Sense %02X, Asc %02X, Ascq %02X\n", SCSIStatus, SCSISense.SenseKey, SCSISense.Asc, SCSISense.Ascq);
|
||||||
|
|
||||||
|
|
||||||
if (BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES ||
|
if (BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES ||
|
||||||
|
@@ -642,7 +642,7 @@ int cdrom_read_data(uint8_t *buffer)
|
|||||||
|
|
||||||
void SCSIClearSense(uint8_t Command, uint8_t IgnoreUA)
|
void SCSIClearSense(uint8_t Command, uint8_t IgnoreUA)
|
||||||
{
|
{
|
||||||
if ((SCSISense.SenseKey == SENSE_UNIT_ATTENTION) || IgnoreUA || (SCSISense.SenseKey == SENSE_ILLEGAL_REQUEST && SCSISense.Asc == ASC_INV_FIELD_IN_CMD_PACKET))
|
if ((SCSISense.SenseKey == SENSE_UNIT_ATTENTION) || IgnoreUA)
|
||||||
{
|
{
|
||||||
pclog("Sense cleared\n");
|
pclog("Sense cleared\n");
|
||||||
ScsiPrev=Command;
|
ScsiPrev=Command;
|
||||||
@@ -698,6 +698,64 @@ void SCSICDROM_Command(uint8_t id, uint8_t *cmdbuffer, uint8_t *cdb)
|
|||||||
|
|
||||||
msf = cdb[1] & 2;
|
msf = cdb[1] & 2;
|
||||||
|
|
||||||
|
//The not ready/unit attention stuff below is only for the Adaptec!
|
||||||
|
//The Buslogic one is located in buslogic.c.
|
||||||
|
|
||||||
|
if (!scsi_model)
|
||||||
|
{
|
||||||
|
if (cdrom->medium_changed())
|
||||||
|
{
|
||||||
|
pclog("Media changed\n");
|
||||||
|
SCSICDROM_Insert();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cdrom->ready() && SCSISense.UnitAttention)
|
||||||
|
{
|
||||||
|
/* 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. */
|
||||||
|
SCSISense.UnitAttention = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the UNIT ATTENTION condition is set and the command does not allow
|
||||||
|
execution under it, error out and report the condition. */
|
||||||
|
if (SCSISense.UnitAttention == 1)
|
||||||
|
{
|
||||||
|
SCSISense.UnitAttention = 2;
|
||||||
|
if (!(SCSICommandTable[cdb[0]] & ALLOW_UA))
|
||||||
|
{
|
||||||
|
SCSISenseCodeError(SENSE_UNIT_ATTENTION, ASC_MEDIUM_MAY_HAVE_CHANGED, 0);
|
||||||
|
SCSIStatus = SCSI_STATUS_CHECK_CONDITION;
|
||||||
|
SCSICallback[id]=50*SCSI_TIME;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (SCSISense.UnitAttention == 2)
|
||||||
|
{
|
||||||
|
if (cdb[0]!=GPCMD_REQUEST_SENSE)
|
||||||
|
{
|
||||||
|
SCSISense.UnitAttention = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unless the command is REQUEST SENSE, clear the sense. This will *NOT*
|
||||||
|
clear the UNIT ATTENTION condition if it's set. */
|
||||||
|
if (cdb[0]!=GPCMD_REQUEST_SENSE)
|
||||||
|
{
|
||||||
|
SCSIClearSense(cdb[0], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Next it's time for NOT READY. */
|
||||||
|
if ((SCSICommandTable[cdb[0]] & CHECK_READY) && !cdrom->ready())
|
||||||
|
{
|
||||||
|
pclog("Not ready\n");
|
||||||
|
SCSISenseCodeError(SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT, 0);
|
||||||
|
SCSIStatus = SCSI_STATUS_CHECK_CONDITION;
|
||||||
|
SCSICallback[id]=50*SCSI_TIME;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
prev_status = cd_status;
|
prev_status = cd_status;
|
||||||
cd_status = cdrom->status();
|
cd_status = cdrom->status();
|
||||||
if (((prev_status == CD_STATUS_PLAYING) || (prev_status == CD_STATUS_PAUSED)) && ((cd_status != CD_STATUS_PLAYING) && (cd_status != CD_STATUS_PAUSED)))
|
if (((prev_status == CD_STATUS_PLAYING) || (prev_status == CD_STATUS_PAUSED)) && ((cd_status != CD_STATUS_PLAYING) && (cd_status != CD_STATUS_PAUSED)))
|
||||||
@@ -773,7 +831,9 @@ void SCSICDROM_Command(uint8_t id, uint8_t *cmdbuffer, uint8_t *cdb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Clear the sense stuff as per the spec. */
|
/* Clear the sense stuff as per the spec. */
|
||||||
SCSIClearSense(cdb[0], 0);
|
ScsiPrev=cdb[0];
|
||||||
|
if (cdrom->ready())
|
||||||
|
SCSISenseCodeOk();
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case GPCMD_READ_6:
|
case GPCMD_READ_6:
|
||||||
@@ -1529,6 +1589,8 @@ SCSIOut:
|
|||||||
SCSIDMAResetPosition(id);
|
SCSIDMAResetPosition(id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SCSICDROM_ReadData(uint8_t id, uint8_t *cdb, uint8_t *data, int datalen)
|
void SCSICDROM_ReadData(uint8_t id, uint8_t *cdb, uint8_t *data, int datalen)
|
||||||
@@ -1542,7 +1604,7 @@ void SCSICDROM_ReadData(uint8_t id, uint8_t *cdb, uint8_t *data, int datalen)
|
|||||||
case GPCMD_READ_12:
|
case GPCMD_READ_12:
|
||||||
case GPCMD_READ_CD_MSF:
|
case GPCMD_READ_CD_MSF:
|
||||||
case GPCMD_READ_CD:
|
case GPCMD_READ_CD:
|
||||||
pclog("Total data length requested: %d\n", datalen);
|
pclog("Total data length requested: %d\n", datalen);
|
||||||
while (datalen > 0)
|
while (datalen > 0)
|
||||||
{
|
{
|
||||||
read_length = cdrom_read_data(data); //Fill the buffer the data it needs
|
read_length = cdrom_read_data(data); //Fill the buffer the data it needs
|
||||||
|
Reference in New Issue
Block a user