From df78ce05297beb7015c404b08b9bdb7ee163bbb6 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 27 Dec 2016 18:48:38 +0100 Subject: [PATCH] Fixed once and for all the DOS CD-ROM bugs in the BT-54x SCSI adapter. Added notes regarding NT 3.1 297.1 and 340.1's setup bugs with the Adaptec driver in the BT-54x SCSI adapter. Bugfixes to the SCSI layer (SCSIReset()) --- src/buslogic.c | 113 ++++++++++++++++++++++------------------------- src/pc.c | 4 +- src/scsi.c | 36 ++++++++++----- src/scsi.h | 8 ++-- src/scsi_cdrom.c | 69 +++++++++++++++++------------ 5 files changed, 122 insertions(+), 108 deletions(-) diff --git a/src/buslogic.c b/src/buslogic.c index c204a973e..5f5e49622 100644 --- a/src/buslogic.c +++ b/src/buslogic.c @@ -3,8 +3,8 @@ */ /*Buslogic SCSI emulation (including Adaptec 154x ISA software backward compatibility)*/ -/* ToDo: */ -/* Improve DOS support */ +//Note: for the Adaptec-enabled Windows NT betas, install from HDD at the moment due to a bug in the round robin outgoing +//mailboxes. #include #include @@ -513,6 +513,7 @@ typedef struct Buslogic_t int DmaChannel; int IrqEnabled; int Mbx24bit; + int CommandEnable; } Buslogic_t; int scsi_base = 0x330; @@ -535,7 +536,7 @@ void BuslogicLog(const char *format, ...) static void BuslogicClearInterrupt(Buslogic_t *Buslogic) { - pclog("Buslogic: Clearing Interrupt 0x%02X\n", Buslogic->Interrupt); + BuslogicLog("Buslogic: Clearing Interrupt 0x%02X\n", Buslogic->Interrupt); Buslogic->Interrupt = 0; picintc(1 << Buslogic->Irq); } @@ -628,20 +629,20 @@ static void BuslogicMailboxIn(Buslogic_t *Buslogic, uint32_t CCBPointer, CCBU *C //Rewrite the CCB up to the CDB. DMAPageWrite(CCBPointer, CmdBlock, offsetof(CCBC, Cdb)); } - - pclog("Host Status 0x%02X, Target Status 0x%02X\n", HostStatus, TargetStatus); + BuslogicLog("Host Status 0x%02X, Target Status 0x%02X\n", HostStatus, TargetStatus); + if (Buslogic->Mbx24bit) { MailboxIn.CmdStatus = Mailbox32.u.in.CompletionCode; U32_TO_ADDR(MailboxIn.CCBPointer, Mailbox32.CCBPointer); - pclog("Mailbox 24-bit: Status=0x%02X, CCB at 0x%08X\n", MailboxIn.CmdStatus, ADDR_TO_U32(MailboxIn.CCBPointer)); + BuslogicLog("Mailbox 24-bit: Status=0x%02X, CCB at 0x%08X\n", MailboxIn.CmdStatus, ADDR_TO_U32(MailboxIn.CCBPointer)); DMAPageWrite(Incoming, &MailboxIn, sizeof(Mailbox_t)); } else { - pclog("Mailbox 32-bit: Status=0x%02X, CCB at 0x%08X\n", Mailbox32.u.in.CompletionCode, Mailbox32.CCBPointer); + BuslogicLog("Mailbox 32-bit: Status=0x%02X, CCB at 0x%08X\n", Mailbox32.u.in.CompletionCode, Mailbox32.CCBPointer); DMAPageWrite(Incoming, &Mailbox32, sizeof(Mailbox32_t)); } @@ -649,7 +650,7 @@ static void BuslogicMailboxIn(Buslogic_t *Buslogic, uint32_t CCBPointer, CCBU *C Buslogic->MailboxInPosCur++; if (Buslogic->MailboxInPosCur > Buslogic->MailboxCount) Buslogic->MailboxInPosCur = 0; - + Buslogic->Interrupt = INTR_MBIF | INTR_ANY; picint(1 << Buslogic->Irq); } @@ -692,7 +693,7 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, CCBU *CmdB if (CmdBlock->common.Cdb[0] == GPCMD_TEST_UNIT_READY) DataLength = 0; - pclog("Data Buffer write: length %d, pointer %d\n", DataLength, DataPointer); + BuslogicLog("Data Buffer write: length %d, pointer %d\n", DataLength, DataPointer); if (DataLength && CmdBlock->common.ControlByte != 0x03) { @@ -788,7 +789,7 @@ void BuslogicDataBufferFree(BuslogicRequests_t *BuslogicRequests) if (BuslogicRequests->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY) DataLength = 0; - pclog("Data Buffer read: length %d, pointer %d\n", DataLength, DataPointer); + BuslogicLog("Data Buffer read: length %d, pointer %d\n", DataLength, DataPointer); //If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without //checking its length, so do this procedure for both no length/read/write commands. @@ -907,8 +908,11 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) case 1: if ((Val == 0x02) && (Buslogic->Command == 0xFF)) { - SCSICallback[scsi_cdrom_id] = 1; - break; + if (Buslogic->MailboxCount) + { + SCSICallback[scsi_cdrom_id] = 1; + break; + } } if (Buslogic->Command == 0xFF) @@ -917,7 +921,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) Buslogic->CmdParam = 0; Buslogic->Status &= ~(STAT_INVCMD | STAT_IDLE); - pclog("Buslogic: Operation Code 0x%02X\n", Val); + BuslogicLog("Buslogic: Operation Code 0x%02X\n", Val); switch (Buslogic->Command) { case 0x00: @@ -990,7 +994,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) if (!Buslogic->CmdParamLeft) { - pclog("Running Operation Code 0x%02X\n", Buslogic->Command); + BuslogicLog("Running Operation Code 0x%02X\n", Buslogic->Command); switch (Buslogic->Command) { case 0x00: @@ -1010,7 +1014,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) BuslogicLog("Buslogic Initialize Mailbox Command\n"); BuslogicLog("Mailbox Out Address=0x%08X\n", Buslogic->MailboxOutAddr); BuslogicLog("Mailbox In Address=0x%08X\n", Buslogic->MailboxInAddr); - pclog("Initialized Mailbox, %d entries at 0x%08X\n", MailboxInit->Count, ADDR_TO_U32(MailboxInit->Address)); + BuslogicLog("Initialized Mailbox, %d entries at 0x%08X\n", MailboxInit->Count, ADDR_TO_U32(MailboxInit->Address)); Buslogic->Status &= ~STAT_INIT; Buslogic->DataReplyLeft = 0; @@ -1030,7 +1034,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) BuslogicLog("Buslogic Extended Initialize Mailbox Command\n"); BuslogicLog("Mailbox Out Address=0x%08X\n", Buslogic->MailboxOutAddr); BuslogicLog("Mailbox In Address=0x%08X\n", Buslogic->MailboxInAddr); - pclog("Initialized Extended Mailbox, %d entries at 0x%08X\n", MailboxInit->Count, MailboxInit->Address); + BuslogicLog("Initialized Extended Mailbox, %d entries at 0x%08X\n", MailboxInit->Count, MailboxInit->Address); Buslogic->Status &= ~STAT_INIT; Buslogic->DataReplyLeft = 0; @@ -1065,19 +1069,19 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) case 0x07: Buslogic->DataReplyLeft = 0; Buslogic->LocalRam.structured.autoSCSIData.uBusOnDelay = Buslogic->CmdBuf[0]; - pclog("Bus-on time: %d\n", Buslogic->CmdBuf[0]); + BuslogicLog("Bus-on time: %d\n", Buslogic->CmdBuf[0]); break; case 0x08: Buslogic->DataReplyLeft = 0; Buslogic->LocalRam.structured.autoSCSIData.uBusOffDelay = Buslogic->CmdBuf[0]; - pclog("Bus-off time: %d\n", Buslogic->CmdBuf[0]); + BuslogicLog("Bus-off time: %d\n", Buslogic->CmdBuf[0]); break; case 0x09: Buslogic->DataReplyLeft = 0; Buslogic->LocalRam.structured.autoSCSIData.uDMATransferRate = Buslogic->CmdBuf[0]; - pclog("DMA transfer rate: %02X\n", Buslogic->CmdBuf[0]); + BuslogicLog("DMA transfer rate: %02X\n", Buslogic->CmdBuf[0]); break; case 0x0A: @@ -1112,8 +1116,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) */ Reply->uCharacterD = 'D'; /* BusLogic model. */ Reply->uHostBusType = 'A'; /* ISA bus. */ - - pclog("Return Setup Information: %d\n", Buslogic->CmdBuf[0]); + BuslogicLog("Return Setup Information: %d\n", Buslogic->CmdBuf[0]); } break; @@ -1144,7 +1147,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) Reply->cMailbox = Buslogic->MailboxCount; Reply->uMailboxAddressBase = Buslogic->MailboxOutAddr; memcpy(Reply->aFirmwareRevision, "07B", sizeof(Reply->aFirmwareRevision)); - pclog("Return Extended Setup Information: %d\n", Buslogic->CmdBuf[0]); + BuslogicLog("Return Extended Setup Information: %d\n", Buslogic->CmdBuf[0]); } break; @@ -1321,7 +1324,7 @@ static void BuslogicSCSIRequestComplete(Buslogic_t *Buslogic, BuslogicRequests_t if (BuslogicRequests->RequestSenseBuffer) BuslogicSenseBufferFree(BuslogicRequests, (SCSIStatus != SCSI_STATUS_OK)); - + if (Status == SCSI_STATUS_OK) { BuslogicMailboxIn(Buslogic, CCBPointer, &CmdBlock, CCB_COMPLETE, SCSI_STATUS_OK, @@ -1330,7 +1333,7 @@ static void BuslogicSCSIRequestComplete(Buslogic_t *Buslogic, BuslogicRequests_t else if (Status == SCSI_STATUS_CHECK_CONDITION) { BuslogicMailboxIn(Buslogic, CCBPointer, &CmdBlock, CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, - MBI_ERROR); + MBI_ERROR); } } @@ -1344,19 +1347,18 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer) DMAPageRead(CCBPointer, &CmdBlock, sizeof(CCB32)); BuslogicRequests->TargetID = Buslogic->Mbx24bit ? CmdBlock.old.Id : CmdBlock.new.Id; - BuslogicRequests->LUN = Buslogic->Mbx24bit ? CmdBlock.old.Lun : CmdBlock.new.Lun; - Id = BuslogicRequests->TargetID; - Lun = BuslogicRequests->LUN; + BuslogicRequests->LUN = Buslogic->Mbx24bit ? CmdBlock.old.Lun : CmdBlock.new.Lun; + Lun = BuslogicRequests->LUN; - pclog("Scanning SCSI Target ID %i\n", Id); + BuslogicLog("Scanning SCSI Target ID %i\n", Id); //Only SCSI CD-ROMs are supported at the moment, SCSI hard disk support will come soon. if (Id < ELEMENTS(SCSIDevices)) - { - if (Id == scsi_cdrom_id && Lun == 0) - { - pclog("SCSI Target ID %i detected and working\n", Id); + { + if (Id == scsi_cdrom_id) + { + BuslogicLog("SCSI Target ID %i detected and working\n", Id); BuslogicRequests->CCBPointer = CCBPointer; BuslogicRequests->Is24bit = Buslogic->Mbx24bit; @@ -1366,17 +1368,16 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer) BuslogicDataBufferAllocate(BuslogicRequests, &BuslogicRequests->CmdBlock, BuslogicRequests->Is24bit); BuslogicSenseBufferAllocate(BuslogicRequests); -#if 1 //for finding bugs. uint32_t i; - pclog("SCSI Cdb[0]=0x%02X\n", BuslogicRequests->CmdBlock.common.Cdb[0]); + BuslogicLog("SCSI Cdb[0]=0x%02X\n", BuslogicRequests->CmdBlock.common.Cdb[0]); for (i = 1; i < BuslogicRequests->CmdBlock.common.CdbLength; i++) - pclog("SCSI Cdb[%i]=%i\n", i, BuslogicRequests->CmdBlock.common.Cdb[i]); + BuslogicLog("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); - 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); -#endif //First, get the data buffer otherwise putting it after the //exec function results into not getting read/write commands right and //failing to detect the device. @@ -1392,12 +1393,12 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer) //Finally, execute the SCSI command immediately and get the transfer length. SCSIPhase = SCSI_PHASE_COMMAND; - SCSIExecCommand(Id, BuslogicRequests->CmdBlock.common.Cdb); + SCSIExecCommand(Id, Lun, BuslogicRequests->CmdBlock.common.Cdb); SCSIGetLength(Id, &SCSIDevices[Id].InitLength); if (SCSIPhase == SCSI_PHASE_DATAOUT) { - SCSIWriteData(Id, BuslogicRequests->CmdBlock.common.Cdb, SCSIDevices[Id].CmdBuffer, SCSIDevices[Id].InitLength); + SCSIWriteData(Id, BuslogicRequests->CmdBlock.common.Cdb, SCSIDevices[Id].CmdBuffer, SCSIDevices[Id].InitLength); } else if (SCSIPhase == SCSI_PHASE_DATAIN) { @@ -1415,30 +1416,22 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer) if (BuslogicRequests->Is24bit) { U32_TO_ADDR(BuslogicRequests->CmdBlock.old.DataLength, SCSIStatus == SCSI_STATUS_OK ? 0 : SCSIDevices[Id].InitLength); - pclog("24-bit Residual data length for reading: %d\n", ADDR_TO_U32(BuslogicRequests->CmdBlock.old.DataLength)); + BuslogicLog("24-bit Residual data length for reading: %d\n", ADDR_TO_U32(BuslogicRequests->CmdBlock.old.DataLength)); } else { BuslogicRequests->CmdBlock.new.DataLength = SCSIStatus == SCSI_STATUS_OK ? 0 : SCSIDevices[Id].InitLength; - pclog("32-bit Residual data length for reading: %d\n", BuslogicRequests->CmdBlock.new.DataLength); + BuslogicLog("32-bit Residual data length for reading: %d\n", BuslogicRequests->CmdBlock.new.DataLength); } } //If the initialized data length is higher than the requested length, signal complete request. if (SCSIDevices[Id].InitLength >= SCSIDevices[Id].buffer_size || SCSIDevices[Id].InitLength == 0) - BuslogicSCSIRequestComplete(Buslogic, BuslogicRequests); + BuslogicSCSIRequestComplete(Buslogic, BuslogicRequests); } else { - pclog("No device is present in the SCSI bus\n"); - - BuslogicDataBufferFree(BuslogicRequests); - - if (BuslogicRequests->RequestSenseBuffer) - BuslogicSenseBufferFree(BuslogicRequests, 1); - - BuslogicMailboxIn(Buslogic, CCBPointer, &BuslogicRequests->CmdBlock, CCB_SELECTION_TIMEOUT, SCSI_STATUS_OK, - MBI_ERROR); + BuslogicMailboxIn(Buslogic, CCBPointer, &CmdBlock, CCB_SELECTION_TIMEOUT, SCSI_STATUS_OK, MBI_ERROR); } } } @@ -1508,14 +1501,18 @@ static void BuslogicStartMailbox(Buslogic_t *Buslogic) if (Mailbox32.u.out.ActionCode == MBO_START) { - pclog("Start Mailbox Command\n"); + BuslogicLog("Start Mailbox Command\n"); BuslogicSCSIRequestSetup(Buslogic, Mailbox32.CCBPointer); } else if (Mailbox32.u.out.ActionCode == MBO_ABORT) { - pclog("Abort Mailbox Command\n"); + BuslogicLog("Abort Mailbox Command\n"); BuslogicSCSIRequestAbort(Buslogic, Mailbox32.CCBPointer); } + else + { + BuslogicSCSIRequestSetup(Buslogic, Mailbox32.CCBPointer); + } } void BuslogicCommandCallback(void *p) @@ -1523,11 +1520,7 @@ void BuslogicCommandCallback(void *p) Buslogic_t *Buslogic = (Buslogic_t *)p; SCSICallback[scsi_cdrom_id] = 0; - - if (Buslogic->MailboxCount) - { - BuslogicStartMailbox(Buslogic); - } + BuslogicStartMailbox(Buslogic); } void *BuslogicInit() diff --git a/src/pc.c b/src/pc.c index 3958f471f..bc438c4df 100644 --- a/src/pc.c +++ b/src/pc.c @@ -294,7 +294,7 @@ void initpc(int argc, char *argv[]) resetide(); if (buslogic_enabled) { - SCSIReset(scsi_cdrom_id); + SCSIReset(); device_add(&BuslogicDevice); } @@ -421,7 +421,7 @@ void resetpchard() if (buslogic_enabled) { - SCSIReset(scsi_cdrom_id); + SCSIReset(); device_add(&BuslogicDevice); } diff --git a/src/scsi.c b/src/scsi.c index c66234a0b..81664009b 100644 --- a/src/scsi.c +++ b/src/scsi.c @@ -23,9 +23,9 @@ void SCSIGetLength(uint8_t id, int *datalen) } //Execute SCSI command -void SCSIExecCommand(uint8_t id, uint8_t *cdb) +void SCSIExecCommand(uint8_t id, uint8_t lun, uint8_t *cdb) { - SCSICDROM_Command(id, cdb); + SCSICDROM_Command(id, lun, cdb); } //Read pending data from the resulting SCSI command @@ -43,7 +43,7 @@ void SCSIWriteData(uint8_t id, uint8_t *cdb, uint8_t *data, int datalen) ///// void SCSIDMAResetPosition(uint8_t Id) { - //Reset position in memory after reaching the + //Reset position in memory after reaching its limit SCSIDevices[Id].pos = 0; } @@ -90,21 +90,33 @@ void SCSIWrite(uint8_t Id, uint32_t len_size) ///// //Initialization function for the SCSI layer -void SCSIReset(uint8_t Id) +void SCSIReset(void) { page_flags[GPMODE_CDROM_AUDIO_PAGE] &= 0xFD; /* Clear changed flag for CDROM AUDIO mode page. */ memset(mode_pages_in[GPMODE_CDROM_AUDIO_PAGE], 0, 256); /* Clear the page itself. */ - if (cdrom_enabled && scsi_cdrom_enabled) + int drive; + + SCSICallback[0]=0; + SCSICallback[1]=0; + SCSICallback[2]=0; + SCSICallback[3]=0; + SCSICallback[4]=0; + SCSICallback[5]=0; + SCSICallback[6]=0; + + for (drive=0;drive<7;drive++) { - SCSICallback[Id]=0; - SCSIDevices[Id].LunType = SCSI_CDROM; + if ((scsi_cdrom_id == drive) && cdrom_enabled && scsi_cdrom_enabled) + { + SCSIDevices[drive].LunType = SCSI_CDROM; + } + else + { + SCSIDevices[drive].LunType = SCSI_NONE; + } } - else - { - SCSIDevices[Id].LunType = SCSI_NONE; - } - + page_flags[GPMODE_CDROM_AUDIO_PAGE] &= ~PAGE_CHANGED; SCSISense.UnitAttention = 0; diff --git a/src/scsi.h b/src/scsi.h index a2063df36..3567ba577 100644 --- a/src/scsi.h +++ b/src/scsi.h @@ -244,20 +244,18 @@ extern int cdrom_sector_size, cdrom_sector_ismsf; #define SCSI_PHASE_BUS_FREE ( 8 ) #define SCSI_PHASE_SELECT ( 9 ) -#define BUFFER_LEN 262144 - struct -{ +{ uint32_t buffer_size; uint32_t pos; uint8_t *Cdb; - uint8_t CmdBuffer[BUFFER_LEN]; + uint8_t CmdBuffer[262144]; uint32_t CmdBufferLength; int LunType; uint32_t InitLength; } SCSIDevices[7]; -extern void SCSIReset(uint8_t Id); +extern void SCSIReset(void); uint32_t SCSICDROMModeSense(uint8_t *buf, uint32_t pos, uint8_t type); uint8_t SCSICDROMSetProfile(uint8_t *buf, uint8_t *index, uint16_t profile); diff --git a/src/scsi_cdrom.c b/src/scsi_cdrom.c index aa06caf78..0c6486ef0 100644 --- a/src/scsi_cdrom.c +++ b/src/scsi_cdrom.c @@ -23,14 +23,14 @@ uint8_t SCSICommandTable[0x100] = { [GPCMD_TEST_UNIT_READY] = CHECK_READY | NONDATA, [GPCMD_REQUEST_SENSE] = ALLOW_UA, - [GPCMD_READ_6] = CHECK_READY | READDATA, + [GPCMD_READ_6] = CHECK_READY, [GPCMD_INQUIRY] = ALLOW_UA, [GPCMD_MODE_SELECT_6] = 0, [GPCMD_MODE_SENSE_6] = 0, [GPCMD_START_STOP_UNIT] = CHECK_READY, [GPCMD_PREVENT_REMOVAL] = CHECK_READY, [GPCMD_READ_CDROM_CAPACITY] = CHECK_READY, - [GPCMD_READ_10] = CHECK_READY | READDATA, + [GPCMD_READ_10] = CHECK_READY, [GPCMD_SEEK] = CHECK_READY | NONDATA, [GPCMD_READ_SUBCHANNEL] = CHECK_READY, [GPCMD_READ_TOC_PMA_ATIP] = CHECK_READY | ALLOW_UA, /* Read TOC - can get through UNIT_ATTENTION, per VIDE-CDD.SYS @@ -50,14 +50,14 @@ uint8_t SCSICommandTable[0x100] = [GPCMD_MODE_SELECT_10] = 0, [GPCMD_MODE_SENSE_10] = 0, [GPCMD_PLAY_AUDIO_12] = CHECK_READY, - [GPCMD_READ_12] = CHECK_READY | READDATA, + [GPCMD_READ_12] = CHECK_READY, [GPCMD_READ_DVD_STRUCTURE] = CHECK_READY, - [GPCMD_READ_CD_MSF] = CHECK_READY | READDATA, + [GPCMD_READ_CD_MSF] = CHECK_READY, [GPCMD_SET_SPEED] = 0, [GPCMD_PLAY_CD] = CHECK_READY, [GPCMD_MECHANISM_STATUS] = 0, - [GPCMD_READ_CD] = CHECK_READY | READDATA, - [GPCMD_SEND_DVD_STRUCTURE] = CHECK_READY + [GPCMD_READ_CD] = CHECK_READY, + [GPCMD_SEND_DVD_STRUCTURE] = CHECK_READY }; uint8_t mode_sense_pages[0x40] = @@ -677,14 +677,23 @@ static int SCSICDROM_TOC(uint8_t id, uint8_t *cdb) return TocFormat; } -void SCSICDROM_Command(uint8_t id, uint8_t *cdb) -{ - if (cdrom->medium_changed()) +void SCSICDROM_Command(uint8_t id, uint8_t lun, uint8_t *cdb) +{ + if (lun > 0) { - pclog("Media changed\n"); - SCSICDROM_Insert(); + //pclog("Invalid LUN, only LUN 0 is supported\n"); + SCSIStatus = SCSI_STATUS_CHECK_CONDITION; + SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE, 0); + SCSICallback[id]=50*SCSI_TIME; + return; } + 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 @@ -697,7 +706,7 @@ void SCSICDROM_Command(uint8_t id, uint8_t *cdb) execution under it, error out and report the condition. */ if (!(SCSICommandTable[cdb[0]] & ALLOW_UA) && SCSISense.UnitAttention) { - pclog("UNIT ATTENTION: Command not allowed to pass through\n"); + //pclog("UNIT ATTENTION: Command not allowed to pass through\n"); SCSISenseCodeError(SENSE_UNIT_ATTENTION, ASC_MEDIUM_MAY_HAVE_CHANGED, 0); SCSIStatus = SCSI_STATUS_CHECK_CONDITION; SCSICallback[id]=50*SCSI_TIME; @@ -714,13 +723,15 @@ void SCSICDROM_Command(uint8_t id, uint8_t *cdb) /* Next it's time for NOT READY. */ if ((SCSICommandTable[cdb[0]] & CHECK_READY) && !cdrom->ready()) { - pclog("Not ready\n"); + //pclog("Not ready\n"); SCSISenseCodeError(SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT, 0); SCSIStatus = SCSI_STATUS_CHECK_CONDITION; SCSICallback[id]=50*SCSI_TIME; return; } + SCSICallback[id] = 0; + 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))) @@ -779,12 +790,12 @@ void SCSICDROM_Command(uint8_t id, uint8_t *cdb) if (SectorLBA > (cdrom->size() - 1)) { - pclog("Trying to read beyond the end of disc\n"); + //pclog("Trying to read beyond the end of disc\n"); SCSIStatus = SCSI_STATUS_CHECK_CONDITION; SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE, 0); SCSICallback[id]=50*SCSI_TIME; break; - } + } if (!SectorLen) { @@ -1137,7 +1148,7 @@ void SCSICDROM_Command(uint8_t id, uint8_t *cdb) if (SectorLBA > (cdrom->size() - 1)) { - pclog("Trying to read beyond the end of disc\n"); + //pclog("Trying to read beyond the end of disc\n"); SCSIStatus = SCSI_STATUS_CHECK_CONDITION; SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE, 0); if (SCSISense.UnitAttention) @@ -1176,11 +1187,11 @@ void SCSICDROM_Command(uint8_t id, uint8_t *cdb) break; // case GPCMD_SEND_DVD_STRUCTURE: - default: + default: SCSIStatus = SCSI_STATUS_CHECK_CONDITION; SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE, 0); SCSICallback[id]=50*SCSI_TIME; - break; + break; } } @@ -1201,7 +1212,7 @@ void SCSICDROM_ReadData(uint8_t id, uint8_t *cdb, uint8_t *data, int datalen) int ret = 0; msf = cdb[1] & 2; - + switch (cdb[0]) { case GPCMD_REQUEST_SENSE: @@ -1257,7 +1268,7 @@ void SCSICDROM_ReadData(uint8_t id, uint8_t *cdb, uint8_t *data, int datalen) case GPCMD_READ_6: case GPCMD_READ_10: case GPCMD_READ_12: - 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 @@ -1274,7 +1285,7 @@ void SCSICDROM_ReadData(uint8_t id, uint8_t *cdb, uint8_t *data, int datalen) data += read_length; } - pclog("True LBA: %d, buffer half: %d\n", SectorLBA, SectorLen * 2048); + //pclog("True LBA: %d, buffer half: %d\n", SectorLBA, SectorLen * 2048); SectorLBA++; SectorLen--; @@ -1284,7 +1295,7 @@ void SCSICDROM_ReadData(uint8_t id, uint8_t *cdb, uint8_t *data, int datalen) break; } } - break; + return; case GPCMD_INQUIRY: if (cdb[1] & 1) @@ -1371,7 +1382,7 @@ SCSIOut: SCSIDevices[id].CmdBuffer[1] = (datalen - 2)&255; SCSIDevices[id].CmdBuffer[2] = 3; /*120mm data CD-ROM*/ } - break; + return; case GPCMD_READ_CDROM_CAPACITY: if (cdrom->read_capacity) @@ -1388,7 +1399,7 @@ SCSIOut: SCSIDevices[id].CmdBuffer[3] = Size & 0xff; SCSIDevices[id].CmdBuffer[6] = 8; /* 2048 = 0x0800 */ } - pclog("Sector size %04X\n", Size); + //pclog("Sector size %i\n", Size); break; case GPCMD_READ_SUBCHANNEL: @@ -1417,7 +1428,7 @@ SCSIOut: datalen = cdrom->readtoc_raw(SCSIDevices[id].CmdBuffer, msf, datalen); break; } - break; + return; case GPCMD_READ_HEADER: if (cdrom->read_header) @@ -1443,7 +1454,7 @@ SCSIOut: SCSIDevices[id].CmdBuffer[0]=1; /*2048 bytes user data*/ SCSIDevices[id].CmdBuffer[1]=SCSIDevices[id].CmdBuffer[2]=SCSIDevices[id].CmdBuffer[3]=0; } - break; + return; case GPCMD_GET_CONFIGURATION: Index = 0; @@ -1670,7 +1681,7 @@ SCSIOut: 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 @@ -1687,7 +1698,7 @@ SCSIOut: data += read_length; } - pclog("True LBA: %d, buffer half: %d\n", SectorLBA, SectorLen * cdrom_sector_size); + //pclog("True LBA: %d, buffer half: %d\n", SectorLBA, SectorLen * cdrom_sector_size); SectorLBA++; SectorLen--; @@ -1697,7 +1708,7 @@ SCSIOut: break; } } - break; + return; case GPCMD_MECHANISM_STATUS: SCSIDevices[id].CmdBuffer[0] = 0;