diff --git a/src/buslogic.c b/src/buslogic.c index c35702292..229b4baef 100644 --- a/src/buslogic.c +++ b/src/buslogic.c @@ -1414,69 +1414,75 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, 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++) - 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); - BuslogicLog("CDB Length %i\n", BuslogicRequests->CmdBlock.common.CdbLength); - BuslogicLog("CCB Opcode %x\n", BuslogicRequests->CmdBlock.common.Opcode); - - if ((BuslogicRequests->CmdBlock.common.ControlByte != 0x03) && (BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND)) + pclog("Transfer Control %02X\n", BuslogicRequests->CmdBlock.common.ControlByte); + pclog("CDB Length %i\n", BuslogicRequests->CmdBlock.common.CdbLength); + pclog("CCB Opcode %x\n", BuslogicRequests->CmdBlock.common.Opcode); + + //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"); - 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)) + if (cdrom->medium_changed()) { - 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; 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()) - { - 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 @@ -1522,8 +1528,8 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, BuslogicSenseBufferFree(BuslogicRequests, (SCSIStatus != SCSI_STATUS_OK)); } - BuslogicLog("Request complete\n"); - BuslogicLog("SCSI Status %02X, Sense %02X, Asc %02X, Ascq %02X\n", SCSIStatus, SCSISense.SenseKey, SCSISense.Asc, SCSISense.Ascq); + pclog("Request complete\n"); + 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 || diff --git a/src/scsi_cdrom.c b/src/scsi_cdrom.c index a004bee43..9c73b734f 100644 --- a/src/scsi_cdrom.c +++ b/src/scsi_cdrom.c @@ -642,7 +642,7 @@ int cdrom_read_data(uint8_t *buffer) 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"); ScsiPrev=Command; @@ -698,6 +698,64 @@ void SCSICDROM_Command(uint8_t id, uint8_t *cmdbuffer, uint8_t *cdb) 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; 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))) @@ -773,7 +831,9 @@ void SCSICDROM_Command(uint8_t id, uint8_t *cmdbuffer, uint8_t *cdb) } /* Clear the sense stuff as per the spec. */ - SCSIClearSense(cdb[0], 0); + ScsiPrev=cdb[0]; + if (cdrom->ready()) + SCSISenseCodeOk(); return; case GPCMD_READ_6: @@ -1529,6 +1589,8 @@ SCSIOut: SCSIDMAResetPosition(id); break; } + + } 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_CD_MSF: case GPCMD_READ_CD: - pclog("Total data length requested: %d\n", datalen); + pclog("Total data length requested: %d\n", datalen); while (datalen > 0) { read_length = cdrom_read_data(data); //Fill the buffer the data it needs