Added support up to 16 ID/LUN's

Corrected residual length, fixes Win95's buslogic driver that was not showing the CD drive.
This commit is contained in:
TC1995
2016-12-27 22:38:09 +01:00
parent f2b3035a56
commit 3f04c30ac0
4 changed files with 50 additions and 30 deletions

View File

@@ -630,7 +630,7 @@ static void BuslogicMailboxIn(Buslogic_t *Buslogic, uint32_t CCBPointer, CCBU *C
DMAPageWrite(CCBPointer, CmdBlock, offsetof(CCBC, Cdb)); 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) if (Buslogic->Mbx24bit)
{ {
@@ -693,7 +693,7 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, CCBU *CmdB
if (CmdBlock->common.Cdb[0] == GPCMD_TEST_UNIT_READY) if (CmdBlock->common.Cdb[0] == GPCMD_TEST_UNIT_READY)
DataLength = 0; 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) 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) if (BuslogicRequests->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY)
DataLength = 0; 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 //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. //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 0x86:
case 0x95: case 0x95:
case 0x22: case 0x22:
case 0x23:
Buslogic->CmdParamLeft = 0; Buslogic->CmdParamLeft = 0;
break; break;
@@ -1085,11 +1086,24 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
break; break;
case 0x0A: case 0x0A:
if (SCSIDevices[scsi_cdrom_id].LunType == SCSI_CDROM) if (scsi_cdrom_id < 8)
Buslogic->DataBuf[scsi_cdrom_id] = 1; {
if (SCSIDevices[scsi_cdrom_id].LunType == SCSI_CDROM)
Buslogic->DataBuf[scsi_cdrom_id] = 1;
Buslogic->DataBuf[7] = 0; Buslogic->DataBuf[7] = 0;
Buslogic->DataReplyLeft = 8; 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; break;
case 0x0B: case 0x0B:
@@ -1395,7 +1409,7 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer)
SCSIPhase = SCSI_PHASE_COMMAND; SCSIPhase = SCSI_PHASE_COMMAND;
SCSIExecCommand(Id, Lun, BuslogicRequests->CmdBlock.common.Cdb); SCSIExecCommand(Id, Lun, BuslogicRequests->CmdBlock.common.Cdb);
SCSIGetLength(Id, &SCSIDevices[Id].InitLength); SCSIGetLength(Id, &SCSIDevices[Id].InitLength);
if (SCSIPhase == SCSI_PHASE_DATAOUT) 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);
@@ -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); 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 || if (BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES ||
BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES) BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)
{ {
if (BuslogicRequests->Is24bit) 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)); BuslogicLog("24-bit Residual data length for reading: %d\n", ADDR_TO_U32(BuslogicRequests->CmdBlock.old.DataLength));
} }
else 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); 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 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) if (SCSIDevices[Id].InitLength >= SCSIDevices[Id].buffer_size || SCSIDevices[Id].InitLength == 0)
{
BuslogicLog("Request complete\n");
BuslogicSCSIRequestComplete(Buslogic, BuslogicRequests); BuslogicSCSIRequestComplete(Buslogic, BuslogicRequests);
}
} }
else else
{ {
@@ -1497,7 +1509,7 @@ static void BuslogicStartMailbox(Buslogic_t *Buslogic)
uint8_t CmdStatus = MBO_FREE; uint8_t CmdStatus = MBO_FREE;
uint32_t CodeOffset = Buslogic->Mbx24bit ? offsetof(Mailbox_t, CmdStatus) : offsetof(Mailbox32_t, u.out.ActionCode); 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) if (Mailbox32.u.out.ActionCode == MBO_START)
{ {
@@ -1511,6 +1523,7 @@ static void BuslogicStartMailbox(Buslogic_t *Buslogic)
} }
else else
{ {
BuslogicLog("Start Mailbox Command with no mailboxes set\n");
BuslogicSCSIRequestSetup(Buslogic, Mailbox32.CCBPointer); BuslogicSCSIRequestSetup(Buslogic, Mailbox32.CCBPointer);
} }
} }
@@ -1535,9 +1548,9 @@ void *BuslogicInit()
timer_add(BuslogicCommandCallback, &SCSICallback[scsi_cdrom_id], &SCSICallback[scsi_cdrom_id], Buslogic); 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; return Buslogic;
} }

View File

@@ -13,7 +13,7 @@
#include "timer.h" #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*/ uint8_t scsi_cdrom_id = 3; /*common setting*/
//Get the transfer length of the command //Get the transfer length of the command
@@ -104,8 +104,17 @@ void SCSIReset(void)
SCSICallback[4]=0; SCSICallback[4]=0;
SCSICallback[5]=0; SCSICallback[5]=0;
SCSICallback[6]=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) if ((scsi_cdrom_id == drive) && cdrom_enabled && scsi_cdrom_enabled)
{ {

View File

@@ -174,7 +174,7 @@ int SectorLen;
extern uint8_t SCSIStatus; extern uint8_t SCSIStatus;
extern uint8_t SCSIPhase; extern uint8_t SCSIPhase;
extern int SCSICallback[7]; extern int SCSICallback[16];
extern uint8_t scsi_cdrom_id; extern uint8_t scsi_cdrom_id;
struct struct
@@ -253,7 +253,7 @@ struct
uint32_t CmdBufferLength; uint32_t CmdBufferLength;
int LunType; int LunType;
uint32_t InitLength; uint32_t InitLength;
} SCSIDevices[7]; } SCSIDevices[16];
extern void SCSIReset(void); extern void SCSIReset(void);

View File

@@ -681,13 +681,12 @@ void SCSICDROM_Command(uint8_t id, uint8_t lun, uint8_t *cdb)
{ {
if (lun > 0) if (lun > 0)
{ {
//pclog("Invalid LUN, only LUN 0 is supported\n"); SCSISenseCodeError(SENSE_UNIT_ATTENTION, 0x25, 0);
SCSIStatus = SCSI_STATUS_CHECK_CONDITION; SCSIStatus = SCSI_STATUS_CHECK_CONDITION;
SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE, 0);
SCSICallback[id]=50*SCSI_TIME; SCSICallback[id]=50*SCSI_TIME;
return; return;
} }
if (cdrom->medium_changed()) if (cdrom->medium_changed())
{ {
//pclog("Media changed\n"); //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); SCSISenseCodeError(SENSE_UNIT_ATTENTION, ASC_MEDIUM_MAY_HAVE_CHANGED, 0);
SCSIStatus = SCSI_STATUS_CHECK_CONDITION; SCSIStatus = SCSI_STATUS_CHECK_CONDITION;
SCSICallback[id]=50*SCSI_TIME; SCSICallback[id]=50*SCSI_TIME;
return;
} }
/* Unless the command is REQUEST SENSE, clear the sense. This will *NOT* /* 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_6:
case GPCMD_READ_10: case GPCMD_READ_10:
case GPCMD_READ_12: case GPCMD_READ_12:
//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
@@ -1285,7 +1283,7 @@ void SCSICDROM_ReadData(uint8_t id, uint8_t *cdb, uint8_t *data, int datalen)
data += read_length; 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++; SectorLBA++;
SectorLen--; SectorLen--;