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));
}
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;
}

View File

@@ -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)
{

View File

@@ -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);

View File

@@ -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--;