Merge pull request #59 from TC1995/master

Buslogic fixes
This commit is contained in:
OBattler
2016-12-26 03:47:24 +01:00
committed by GitHub

View File

@@ -513,18 +513,17 @@ typedef struct Buslogic_t
int DmaChannel;
int IrqEnabled;
int Mbx24bit;
int CommandCallback;
} Buslogic_t;
int scsi_base = 0x330;
int scsi_dma = 6;
int scsi_irq = 11;
int aha154x_do_log = 0;
int buslogic_do_log = 0;
void BuslogicLog(const char *format, ...)
{
if (aha154x_do_log)
if (buslogic_do_log)
{
va_list ap;
va_start(ap, format);
@@ -536,7 +535,7 @@ void BuslogicLog(const char *format, ...)
static void BuslogicClearInterrupt(Buslogic_t *Buslogic)
{
BuslogicLog("Buslogic: Clearing Interrupt 0x%02X\n", Buslogic->Interrupt);
pclog("Buslogic: Clearing Interrupt 0x%02X\n", Buslogic->Interrupt);
Buslogic->Interrupt = 0;
picintc(1 << Buslogic->Irq);
}
@@ -567,7 +566,7 @@ static void BuslogicLocalRam(Buslogic_t *Buslogic)
static void BuslogicReset(Buslogic_t *Buslogic)
{
Buslogic->Status = STAT_IDLE | STAT_INIT;
Buslogic->Geometry = 0x80;
Buslogic->Geometry |= 0x80;
Buslogic->Command = 0xFF;
Buslogic->CmdParam = 0;
Buslogic->CmdParamLeft = 0;
@@ -585,9 +584,9 @@ static void BuslogicReset(Buslogic_t *Buslogic)
static void BuslogicResetControl(Buslogic_t *Buslogic, uint8_t Reset)
{
BuslogicReset(Buslogic);
if (Reset & CTRL_HRST)
if (Reset)
{
Buslogic->Status = STAT_STST;
Buslogic->Status |= STAT_STST;
Buslogic->Status &= ~STAT_IDLE;
}
}
@@ -881,7 +880,7 @@ uint8_t BuslogicRead(uint16_t Port, void *p)
break;
}
BuslogicLog("Buslogic: Read Port 0x%02X, Returned Value %02X\n", Port, Temp);
pclog("Buslogic: Read Port 0x%02X, Returned Value %02X\n", Port, Temp);
return Temp;
}
@@ -889,7 +888,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
{
Buslogic_t *Buslogic = (Buslogic_t *)p;
BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests;
BuslogicLog("Buslogic: Write Port 0x%02X, Value %02X\n", Port, Val);
pclog("Buslogic: Write Port 0x%02X, Value %02X\n", Port, Val);
switch (Port & 3)
{
@@ -902,7 +901,9 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
}
if (Val & CTRL_IRST)
{
BuslogicClearInterrupt(Buslogic);
}
break;
case 1:
@@ -927,12 +928,13 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
case 0x0B:
case 0x84:
case 0x85:
case 0x86:
case 0x95:
case 0x22:
Buslogic->CmdParamLeft = 0;
break;
case 0x0A:
//case 0x8D: //For Aha-154x
Buslogic->CmdParamLeft = 0;
break;
@@ -942,12 +944,15 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
case 0x0D:
case 0x1F:
case 0x21:
case 0x8B: //For Buslogic
case 0x8D: //For Buslogic
case 0x24:
case 0x25:
Buslogic->CmdParamLeft = 1;
break;
case 0x8B:
case 0x8D:
case 0x8F:
case 0x96: //For Buslogic
case 0x96:
Buslogic->CmdParamLeft = 1;
break;
@@ -973,11 +978,8 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
break;
case 0x28:
Buslogic->CmdParamLeft = 0;
break;
case 0x29:
Buslogic->CmdParamLeft = 2;
Buslogic->CmdParamLeft = 0;
break;
}
}
@@ -1081,18 +1083,13 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
break;
case 0x0A:
{
int i;
memset(Buslogic->DataBuf, 0, 8);
for (i=0;i<7;++i)
{
if (SCSIDevices[i].LunType == SCSI_CDROM)
Buslogic->DataBuf[i] = 1;
}
if (SCSIDevices[scsi_cdrom_id].LunType == SCSI_CDROM)
Buslogic->DataBuf[scsi_cdrom_id] = 1;
else
Buslogic->DataBuf[scsi_cdrom_id] = 0;
Buslogic->DataBuf[7] = 0;
Buslogic->DataReplyLeft = 8;
}
Buslogic->DataBuf[7] = 0;
Buslogic->DataReplyLeft = 8;
break;
case 0x0B:
@@ -1112,19 +1109,18 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
Reply->fParityCheckingEnabled = 1;
Reply->cMailbox = Buslogic->MailboxCount;
U32_TO_ADDR(Reply->MailboxAddress, Buslogic->MailboxOutAddr);
#if 1
Reply->uSignature = 'B';
/* The 'D' signature prevents Buslogic's OS/2 drivers from getting too
* friendly with BusLogic hardware and upsetting the HBA state.
* friendly with Adaptec hardware and upsetting the HBA state.
*/
Reply->uCharacterD = 'D'; /* BusLogic model. */
Reply->uHostBusType = 'A'; /* ISA bus. */
#endif
pclog("Return Setup Information: %d\n", Buslogic->CmdBuf[0]);
}
break;
#if 1
case 0x8B:
{
int i;
@@ -1132,7 +1128,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
/* The reply length is set by the guest and is found in the first byte of the command buffer. */
Buslogic->DataReplyLeft = Buslogic->CmdBuf[0];
memset(Buslogic->DataBuf, 0, Buslogic->DataReplyLeft);
const char aModelName[] = "540B "; /* Trailing \0 is fine, that's the filler anyway. */
const char aModelName[] = "542B "; /* Trailing \0 is fine, that's the filler anyway. */
int cCharsToTransfer = Buslogic->DataReplyLeft <= sizeof(aModelName)
? Buslogic->DataReplyLeft
: sizeof(aModelName);
@@ -1141,9 +1137,8 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
Buslogic->DataBuf[i] = aModelName[i];
}
break;
#endif
case 0x8D:
#if 1
{
Buslogic->DataReplyLeft = Buslogic->CmdBuf[0];
ReplyInquireExtendedSetupInformation *Reply = (ReplyInquireExtendedSetupInformation *)Buslogic->DataBuf;
@@ -1155,11 +1150,6 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
memcpy(Reply->aFirmwareRevision, "07B", sizeof(Reply->aFirmwareRevision));
pclog("Return Extended Setup Information: %d\n", Buslogic->CmdBuf[0]);
}
#endif
#if 0
Buslogic->DataReplyLeft = 0;
Buslogic->Status |= STAT_INVCMD;
#endif
break;
case 0x1C:
@@ -1245,11 +1235,6 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
}
break;
case 0x22:
Buslogic->DataReplyLeft = 0;
Buslogic->Status |= STAT_INVCMD;
break;
case 0x96:
if (Buslogic->CmdBuf[0] == 0)
Buslogic->ExtendedLUNCCBFormat = 0;
@@ -1259,12 +1244,13 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
Buslogic->DataReplyLeft = 0;
break;
case 0x28:
Buslogic->DataReplyLeft = 2;
break;
case 0x29:
case 0x22: //undocumented
case 0x28: //only for the Adaptec 154xC series
case 0x29: //only for the Adaptec 154xC series
case 0x86: //PCI only
case 0x95: //PCI only
Buslogic->DataReplyLeft = 0;
Buslogic->Status |= STAT_INVCMD;
break;
}
}
@@ -1276,7 +1262,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
break;
case 2:
Buslogic->Irq = Val; //For Buslogic
Buslogic->Interrupt = Val; //For Buslogic
break;
case 3:
@@ -1432,12 +1418,12 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer)
{
if (BuslogicRequests->Is24bit)
{
U32_TO_ADDR(BuslogicRequests->CmdBlock.old.DataLength, SCSIDevices[Id].InitLength);
U32_TO_ADDR(BuslogicRequests->CmdBlock.old.DataLength, SCSIStatus == SCSI_STATUS_OK ? 0 : SCSIDevices[Id].buffer_size);
pclog("24-bit Residual data length for reading: %d\n", ADDR_TO_U32(BuslogicRequests->CmdBlock.old.DataLength));
}
else
{
BuslogicRequests->CmdBlock.new.DataLength = SCSIDevices[Id].InitLength;
BuslogicRequests->CmdBlock.new.DataLength = SCSIStatus == SCSI_STATUS_OK ? 0 : SCSIDevices[Id].buffer_size;
pclog("32-bit Residual data length for reading: %d\n", BuslogicRequests->CmdBlock.new.DataLength);
}
}
@@ -1455,23 +1441,40 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer)
if (BuslogicRequests->RequestSenseBuffer)
BuslogicSenseBufferFree(BuslogicRequests, 1);
BuslogicMailboxIn(Buslogic, CCBPointer, &CmdBlock, CCB_SELECTION_TIMEOUT, SCSI_STATUS_OK,
BuslogicMailboxIn(Buslogic, CCBPointer, &BuslogicRequests->CmdBlock, CCB_SELECTION_TIMEOUT, SCSI_STATUS_OK,
MBI_ERROR);
}
}
else
{
pclog("ID equal or higher than 7 not supported at the moment\n");
BuslogicDataBufferFree(BuslogicRequests);
if (BuslogicRequests->RequestSenseBuffer)
BuslogicSenseBufferFree(BuslogicRequests, 1);
BuslogicMailboxIn(Buslogic, CCBPointer, &CmdBlock, CCB_INVALID_CCB, SCSI_STATUS_OK,
BuslogicMailboxIn(Buslogic, CCBPointer, &BuslogicRequests->CmdBlock, CCB_SELECTION_TIMEOUT, SCSI_STATUS_OK,
MBI_ERROR);
}
}
static void BuslogicSCSIRequestAbort(Buslogic_t *Buslogic, uint32_t CCBPointer)
{
BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests;
CCBU CmdBlock;
uint8_t Id;
//Fetch data from the Command Control Block.
DMAPageRead(CCBPointer, &CmdBlock, sizeof(CCB32));
BuslogicRequests->TargetID = Buslogic->Mbx24bit ? CmdBlock.old.Id : CmdBlock.new.Id;
Id = BuslogicRequests->TargetID;
//Only SCSI CD-ROMs are supported at the moment, SCSI hard disk support will come soon.
if (Id < ELEMENTS(SCSIDevices))
{
BuslogicMailboxIn(Buslogic, CCBPointer, &CmdBlock, 0x26, SCSI_STATUS_OK, MBI_NOT_FOUND);
}
}
static uint32_t BuslogicMailboxOut(Buslogic_t *Buslogic, Mailbox32_t *Mailbox32)
@@ -1512,15 +1515,20 @@ static void BuslogicStartMailbox(Buslogic_t *Buslogic)
Buslogic->MailboxOutPosCur = (Buslogic->MailboxOutPosCur + 1) % Buslogic->MailboxCount;
} while (Mailbox32.u.out.ActionCode == MBO_FREE && MailboxOutCur != Buslogic->MailboxOutPosCur);
Buslogic->MailboxOutPosCur = MailboxOutCur;
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));
if (Mailbox32.u.out.ActionCode == MBO_START)
{
pclog("Start Mailbox Command\n");
BuslogicSCSIRequestSetup(Buslogic, Mailbox32.CCBPointer);
} if (Mailbox32.u.out.ActionCode == MBO_ABORT)
{
pclog("Abort Mailbox Command\n");
BuslogicSCSIRequestAbort(Buslogic, Mailbox32.CCBPointer);
}
}
void BuslogicCommandCallback(void *p)
@@ -1562,7 +1570,7 @@ void BuslogicClose(void *p)
device_t BuslogicDevice =
{
"Buslogic BT-540B",
"Buslogic BT-542B",
0,
BuslogicInit,
BuslogicClose,