From 3f04c30ac0dab5f68efc49dc5fe9608361b9a5b8 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 27 Dec 2016 22:38:09 +0100 Subject: [PATCH] Added support up to 16 ID/LUN's Corrected residual length, fixes Win95's buslogic driver that was not showing the CD drive. --- src/buslogic.c | 51 ++++++++++++++++++++++++++++++------------------ src/scsi.c | 13 ++++++++++-- src/scsi.h | 4 ++-- src/scsi_cdrom.c | 12 +++++------- 4 files changed, 50 insertions(+), 30 deletions(-) diff --git a/src/buslogic.c b/src/buslogic.c index 5f5e49622..57b692b30 100644 --- a/src/buslogic.c +++ b/src/buslogic.c @@ -630,7 +630,7 @@ static void BuslogicMailboxIn(Buslogic_t *Buslogic, uint32_t CCBPointer, CCBU *C DMAPageWrite(CCBPointer, CmdBlock, offsetof(CCBC, Cdb)); } - BuslogicLog("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) { @@ -693,7 +693,7 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, CCBU *CmdB if (CmdBlock->common.Cdb[0] == GPCMD_TEST_UNIT_READY) DataLength = 0; - BuslogicLog("Data Buffer write: length %d, pointer %d\n", DataLength, DataPointer); + BuslogicLog("Data Buffer write: length %d, pointer 0x%04X\n", DataLength, DataPointer); if (DataLength && CmdBlock->common.ControlByte != 0x03) { @@ -789,7 +789,7 @@ void BuslogicDataBufferFree(BuslogicRequests_t *BuslogicRequests) if (BuslogicRequests->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY) DataLength = 0; - BuslogicLog("Data Buffer read: length %d, pointer %d\n", DataLength, DataPointer); + BuslogicLog("Data Buffer read: length %d, pointer 0x%04X\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. @@ -933,6 +933,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) case 0x86: case 0x95: case 0x22: + case 0x23: Buslogic->CmdParamLeft = 0; break; @@ -1085,11 +1086,24 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) break; case 0x0A: - if (SCSIDevices[scsi_cdrom_id].LunType == SCSI_CDROM) - Buslogic->DataBuf[scsi_cdrom_id] = 1; + if (scsi_cdrom_id < 8) + { + if (SCSIDevices[scsi_cdrom_id].LunType == SCSI_CDROM) + Buslogic->DataBuf[scsi_cdrom_id] = 1; - Buslogic->DataBuf[7] = 0; - Buslogic->DataReplyLeft = 8; + Buslogic->DataBuf[7] = 0; + Buslogic->DataReplyLeft = 8; + } + break; + + case 0x23: + if (scsi_cdrom_id >= 8) + { + if (SCSIDevices[scsi_cdrom_id].LunType == SCSI_CDROM) + Buslogic->DataBuf[scsi_cdrom_id] = 1; + + Buslogic->DataReplyLeft = 8; + } break; case 0x0B: @@ -1395,7 +1409,7 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer) SCSIPhase = SCSI_PHASE_COMMAND; 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); @@ -1404,30 +1418,28 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer) { SCSIReadData(Id, BuslogicRequests->CmdBlock.common.Cdb, SCSIDevices[Id].CmdBuffer, SCSIDevices[Id].InitLength); } - else if (SCSIPhase == SCSI_PHASE_STATUS) - { - //If the running command doesn't return any length, end the request immediately. - SCSIDevices[Id].InitLength = 0; - } - + if (BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES || BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES) { if (BuslogicRequests->Is24bit) { - U32_TO_ADDR(BuslogicRequests->CmdBlock.old.DataLength, SCSIStatus == SCSI_STATUS_OK ? 0 : SCSIDevices[Id].InitLength); + U32_TO_ADDR(BuslogicRequests->CmdBlock.old.DataLength, SCSIDevices[Id].InitLength); 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; + BuslogicRequests->CmdBlock.new.DataLength = SCSIDevices[Id].InitLength; 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) + { + BuslogicLog("Request complete\n"); BuslogicSCSIRequestComplete(Buslogic, BuslogicRequests); + } } else { @@ -1497,7 +1509,7 @@ static void BuslogicStartMailbox(Buslogic_t *Buslogic) uint8_t CmdStatus = MBO_FREE; uint32_t CodeOffset = Buslogic->Mbx24bit ? offsetof(Mailbox_t, CmdStatus) : offsetof(Mailbox32_t, u.out.ActionCode); - DMAPageWrite(Outgoing + CodeOffset, &CmdStatus, sizeof(CmdStatus)); + DMAPageWrite(Outgoing + CodeOffset, &CmdStatus, sizeof(CmdStatus)); if (Mailbox32.u.out.ActionCode == MBO_START) { @@ -1511,6 +1523,7 @@ static void BuslogicStartMailbox(Buslogic_t *Buslogic) } else { + BuslogicLog("Start Mailbox Command with no mailboxes set\n"); BuslogicSCSIRequestSetup(Buslogic, Mailbox32.CCBPointer); } } @@ -1535,9 +1548,9 @@ void *BuslogicInit() timer_add(BuslogicCommandCallback, &SCSICallback[scsi_cdrom_id], &SCSICallback[scsi_cdrom_id], Buslogic); - pclog("Buslogic on port 0x%04X\n", scsi_base); + BuslogicLog("Buslogic on port 0x%04X\n", scsi_base); - BuslogicResetControl(Buslogic, CTRL_HRST); + BuslogicReset(Buslogic); return Buslogic; } diff --git a/src/scsi.c b/src/scsi.c index 81664009b..2b63544a9 100644 --- a/src/scsi.c +++ b/src/scsi.c @@ -13,7 +13,7 @@ #include "timer.h" -int SCSICallback[7] = {0,0,0,0,0,0,0}; +int SCSICallback[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; uint8_t scsi_cdrom_id = 3; /*common setting*/ //Get the transfer length of the command @@ -104,8 +104,17 @@ void SCSIReset(void) SCSICallback[4]=0; SCSICallback[5]=0; SCSICallback[6]=0; + SCSICallback[7]=0; + SCSICallback[8]=0; + SCSICallback[9]=0; + SCSICallback[10]=0; + SCSICallback[11]=0; + SCSICallback[12]=0; + SCSICallback[13]=0; + SCSICallback[14]=0; + SCSICallback[15]=0; - for (drive=0;drive<7;drive++) + for (drive=0;drive<16;drive++) { if ((scsi_cdrom_id == drive) && cdrom_enabled && scsi_cdrom_enabled) { diff --git a/src/scsi.h b/src/scsi.h index 3567ba577..f9978131e 100644 --- a/src/scsi.h +++ b/src/scsi.h @@ -174,7 +174,7 @@ int SectorLen; extern uint8_t SCSIStatus; extern uint8_t SCSIPhase; -extern int SCSICallback[7]; +extern int SCSICallback[16]; extern uint8_t scsi_cdrom_id; struct @@ -253,7 +253,7 @@ struct uint32_t CmdBufferLength; int LunType; uint32_t InitLength; -} SCSIDevices[7]; +} SCSIDevices[16]; extern void SCSIReset(void); diff --git a/src/scsi_cdrom.c b/src/scsi_cdrom.c index 0c6486ef0..b95a4fac6 100644 --- a/src/scsi_cdrom.c +++ b/src/scsi_cdrom.c @@ -681,13 +681,12 @@ void SCSICDROM_Command(uint8_t id, uint8_t lun, uint8_t *cdb) { if (lun > 0) { - //pclog("Invalid LUN, only LUN 0 is supported\n"); + SCSISenseCodeError(SENSE_UNIT_ATTENTION, 0x25, 0); SCSIStatus = SCSI_STATUS_CHECK_CONDITION; - SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE, 0); SCSICallback[id]=50*SCSI_TIME; - return; + return; } - + if (cdrom->medium_changed()) { //pclog("Media changed\n"); @@ -710,7 +709,6 @@ void SCSICDROM_Command(uint8_t id, uint8_t lun, uint8_t *cdb) SCSISenseCodeError(SENSE_UNIT_ATTENTION, ASC_MEDIUM_MAY_HAVE_CHANGED, 0); SCSIStatus = SCSI_STATUS_CHECK_CONDITION; SCSICallback[id]=50*SCSI_TIME; - return; } /* Unless the command is REQUEST SENSE, clear the sense. This will *NOT* @@ -1268,7 +1266,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 @@ -1285,7 +1283,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--;