Added the BusLogic BT-640A MCA;

Fixed the MCA write function of the AHA-1640 MCA - the host ID is now read from the correct variable and the sync and parity check values are now read as well.
This commit is contained in:
OBattler
2017-10-17 02:50:54 +02:00
parent 6674865c56
commit ca39d3a4c9
6 changed files with 200 additions and 45 deletions

View File

@@ -71,6 +71,7 @@ static SCSI_CARD scsi_cards[] = {
{ "[ISA] Ranco RT1000B", "rt1000b", &scsi_rt1000b_device, NULL },
{ "[ISA] Trantor T130B", "t130b", &scsi_t130b_device, NULL },
{ "[MCA] Adaptec AHA-1640", "aha1640", &aha1640_device, x54x_device_reset },
{ "[MCA] BusLogic BT-640A", "bt640a", &buslogic_640a_device,BuslogicDeviceReset },
{ "[PCI] BusLogic BT-958D", "bt958d", &buslogic_pci_device, BuslogicDeviceReset },
{ "", "", NULL, NULL },
};

View File

@@ -438,6 +438,9 @@ aha_setup_data(void *p)
ReplyISI = (ReplyInquireSetupInformation *)dev->DataBuf;
aha_setup = (aha_setup_t *)ReplyISI->VendorSpecificData;
ReplyISI->fSynchronousInitiationEnabled = dev->sync & 1;
ReplyISI->fParityCheckingEnabled = dev->parity & 1;
U32_TO_ADDR(aha_setup->BIOSMailboxAddress, dev->BIOSMailboxOutAddr);
aha_setup->uChecksum = 0xA3;
aha_setup->uUnknown = 0xC2;
@@ -496,36 +499,13 @@ aha_mca_write(int port, uint8_t val, void *priv)
/* Save the MCA register value. */
dev->pos_regs[port & 7] = val;
/* Get the new assigned I/O base address. */
switch(dev->pos_regs[3] & 0xc7) {
case 0x01: /* [1]=00xx x001 */
dev->Base = 0x0130;
break;
case 0x02: /* [1]=00xx x010 */
dev->Base = 0x0230;
break;
case 0x03: /* [1]=00xx x011 */
dev->Base = 0x0330;
break;
case 0x41:
dev->Base = 0x0134;
break;
case 0x42: /* [1]=01xx x010 */
dev->Base = 0x0234;
break;
case 0x43: /* [1]=01xx x011 */
dev->Base = 0x0334;
break;
}
/* This is always necessary so that the old handler doesn't remain. */
x54x_io_remove(dev, dev->Base);
/* Get the new assigned I/O base address. */
dev->Base = (dev->pos_regs[3] & 7) << 8;
dev->Base |= ((dev->pos_regs[3] & 0xc0) ? 4 : 0);
/* Save the new IRQ and DMA channel values. */
dev->Irq = (dev->pos_regs[4] & 0x07) + 8;
dev->DmaChannel = dev->pos_regs[5] & 0x0f;
@@ -567,13 +547,15 @@ aha_mca_write(int port, uint8_t val, void *priv)
* pos[2]=111xxxxx = 7
* pos[2]=000xxxxx = 0
*/
dev->HostID = (dev->pos_regs[4] >> 5) & 0x07;
dev->HostID = (dev->pos_regs[2] >> 5) & 0x07;
/*
* SYNC mode is pos[2]=xxxx1xxx.
*
* SCSI Parity is pos[2]=xxx1xxxx.
*/
dev->sync = (dev->pos_regs[2] >> 3) & 1;
dev->parity = (dev->pos_regs[2] >> 4) & 1;
/*
* The PS/2 Model 80 BIOS always enables a card if it finds one,

View File

@@ -265,9 +265,9 @@ BuslogicGetNVRFileName(buslogic_data_t *bl)
return L"bt542bh.nvr";
case CHIP_BUSLOGIC_ISA:
return L"bt545s.nvr";
#ifdef BUSLOGIC_NOT_WORKING
case CHIP_BUSLOGIC_MCA:
return L"bt640a.nvr";
#ifdef BUSLOGIC_NOT_WORKING
case CHIP_BUSLOGIC_VLB:
return L"bt445s.nvr";
#endif
@@ -302,13 +302,13 @@ BuslogicAutoSCSIRamSetDefaults(x54x_t *dev, uint8_t safe)
case CHIP_BUSLOGIC_ISA:
memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "545S", 4);
break;
case CHIP_BUSLOGIC_MCA:
memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "640A", 4);
break;
#ifdef BUSLOGIC_NOT_WORKING
case CHIP_BUSLOGIC_VLB:
memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "445S", 4);
break;
case CHIP_BUSLOGIC_MCA:
memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "640A", 4);
break;
#endif
case CHIP_BUSLOGIC_PCI:
memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "958D", 4);
@@ -794,7 +794,9 @@ buslogic_cmds(void *p)
switch (bl->chip) {
case CHIP_BUSLOGIC_ISA_542:
case CHIP_BUSLOGIC_ISA:
#ifdef BUSLOGIC_NOT_WORKING
case CHIP_BUSLOGIC_VLB:
#endif
ReplyIESI->uBusType = 'A'; /* ISA style */
break;
case CHIP_BUSLOGIC_MCA:
@@ -969,10 +971,14 @@ buslogic_setup_data(void *p)
ReplyInquireSetupInformation *ReplyISI;
buslogic_setup_t *bl_setup;
buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data;
HALocalRAM *HALR = &bl->LocalRAM;
ReplyISI = (ReplyInquireSetupInformation *)dev->DataBuf;
bl_setup = (buslogic_setup_t *)ReplyISI->VendorSpecificData;
ReplyISI->fSynchronousInitiationEnabled = HALR->structured.autoSCSIData.u16SynchronousPermittedMask ? 1 : 0;
ReplyISI->fParityCheckingEnabled = (HALR->structured.autoSCSIData.uSCSIConfiguration & 2) ? 1 : 0;
bl_setup->uSignature = 'B';
/* The 'D' signature prevents Buslogic's OS/2 drivers from getting too
* friendly with Adaptec hardware and upsetting the HBA state.
@@ -984,10 +990,10 @@ buslogic_setup_data(void *p)
case CHIP_BUSLOGIC_ISA:
bl_setup->uHostBusType = 'A';
break;
#ifdef BUSLOGIC_NOT_WORKING
case CHIP_BUSLOGIC_MCA:
bl_setup->uHostBusType = 'B';
break;
#ifdef BUSLOGIC_NOT_WORKING
case CHIP_BUSLOGIC_VLB:
bl_setup->uHostBusType = 'E';
break;
@@ -1256,6 +1262,131 @@ BuslogicInitializeLocalRAM(buslogic_data_t *bl)
}
static uint8_t
buslogic_mca_read(int port, void *priv)
{
x54x_t *dev = (x54x_t *)priv;
return(dev->pos_regs[port & 7]);
}
static void
buslogic_mca_write(int port, uint8_t val, void *priv)
{
x54x_t *dev = (x54x_t *) priv;
buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data;
HALocalRAM *HALR = &bl->LocalRAM;
/* MCA does not write registers below 0x0100. */
if (port < 0x0102) return;
/* Save the MCA register value. */
dev->pos_regs[port & 7] = val;
/* This is always necessary so that the old handler doesn't remain. */
x54x_io_remove(dev, dev->Base);
/* Get the new assigned I/O base address. */
dev->Base = dev->pos_regs[1] << 8;
dev->Base |= ((dev->pos_regs[0] & 0x10) ? 4 : 0);
/* Save the new IRQ and DMA channel values. */
dev->Irq = ((dev->pos_regs[0] >> 1) & 0x07) + 8;
dev->DmaChannel = dev->pos_regs[3] & 0x0f;
/* Extract the BIOS ROM address info. */
if (dev->pos_regs[0] & 0xe0) switch(dev->pos_regs[0] & 0xe0) {
case 0xe0: /* [0]=111x xxxx */
bl->bios_addr = 0xDC000;
break;
case 0x00: /* [0]=000x xxxx */
bl->bios_addr = 0;
break;
case 0xc0: /* [0]=110x xxxx */
bl->bios_addr = 0xD8000;
break;
case 0xa0: /* [0]=101x xxxx */
bl->bios_addr = 0xD4000;
break;
case 0x80: /* [0]=100x xxxx */
bl->bios_addr = 0xD0000;
break;
case 0x60: /* [0]=011x xxxx */
bl->bios_addr = 0xCC000;
break;
case 0x40: /* [0]=010x xxxx */
bl->bios_addr = 0xC8000;
break;
case 0x20: /* [0]=001x xxxx */
bl->bios_addr = 0xC4000;
break;
} else {
/* Disabled. */
bl->bios_addr = 0x000000;
}
/*
* Get misc SCSI config stuff. For now, we are only
* interested in the configured HA target ID:
*
* pos[2]=111xxxxx = 7
* pos[2]=000xxxxx = 0
*/
dev->HostID = (dev->pos_regs[2] >> 5) & 0x07;
/*
* SYNC mode is pos[2]=xxxxxx1x.
*
* SCSI Parity is pos[2]=xxx1xxxx.
*
* DOS Disk Space > 1GBytes is pos[2] = xxxx1xxx.
*/
/* Parity. */
HALR->structured.autoSCSIData.uSCSIConfiguration &= ~2;
HALR->structured.autoSCSIData.uSCSIConfiguration |= (dev->pos_regs[2] & 2);
/* Sync. */
HALR->structured.autoSCSIData.u16SynchronousPermittedMask = (dev->pos_regs[2] & 0x10) ? 0xffff : 0x0000;
/* DOS Disk Space > 1GBytes */
HALR->structured.autoSCSIData.uBIOSConfiguration &= ~4;
HALR->structured.autoSCSIData.uBIOSConfiguration |= (dev->pos_regs[2] & 8) ? 4 : 0;
/*
* The PS/2 Model 80 BIOS always enables a card if it finds one,
* even if no resources were assigned yet (because we only added
* the card, but have not run AutoConfig yet...)
*
* So, remove current address, if any.
*/
mem_mapping_disable(&dev->bios.mapping);
/* Initialize the device if fully configured. */
if (dev->pos_regs[2] & 0x01) {
/* Card enabled; register (new) I/O handler. */
x54x_io_set(dev, dev->Base);
/* Reset the device. */
x54x_reset_ctrl(dev, CTRL_HRST);
/* Enable or disable the BIOS ROM. */
if (bl->has_bios && (bl->bios_addr != 0x000000)) {
mem_mapping_enable(&bl->bios.mapping);
mem_mapping_set_addr(&bl->bios.mapping, bl->bios_addr, ROM_SIZE);
}
}
}
void
BuslogicDeviceReset(void *p)
{
@@ -1303,6 +1434,7 @@ buslogic_init(device_t *info)
dev->max_id = 7;
dev->int_geom_writable = 1;
dev->cdrom_boot = 0;
dev->mca32 = 0;
bl->chip = info->local;
bl->PCIBase = 0;
@@ -1310,6 +1442,9 @@ buslogic_init(device_t *info)
if (info->flags & DEVICE_PCI) {
bios_rom_addr = 0xd8000;
bl->has_bios = device_get_config_int("bios");
} else if (info->flags & DEVICE_MCA) {
bios_rom_addr = 0xd8000;
bl->has_bios = 1;
} else {
bios_rom_addr = device_get_config_hex20("bios_addr");
bl->has_bios = !!bios_rom_addr;
@@ -1356,19 +1491,20 @@ buslogic_init(device_t *info)
has_scam_rom = 0;
dev->fw_rev = "AA421E";
break;
#ifdef BUSLOGIC_NOT_WORKING
case CHIP_BUSLOGIC_MCA:
strcpy(dev->name, "BT-640A");
bios_rom_name = L"roms/scsi/buslogic/BT-640_BIOS.rom";
bios_rom_name = L"roms/scsi/buslogic/BT-640A_BIOS.rom";
bios_rom_size = 0x4000;
bios_rom_mask = 0x3fff;
has_autoscsi_rom = 1;
autoscsi_rom_name = L"roms/scsi/buslogic/BT-640_AutoSCSI.rom";
autoscsi_rom_size = 0x4000;
has_autoscsi_rom = 0;
has_scam_rom = 0;
dev->fw_rev = "BA421E";
dev->fw_rev = "BA150";
dev->mca32 = 1;
bl->fAggressiveRoundRobinMode = 1;
dev->pos_regs[0] = 0x08; /* MCA board ID */
dev->pos_regs[1] = 0x07;
mca_add(buslogic_mca_read, buslogic_mca_write, dev);
break;
#endif
case CHIP_BUSLOGIC_PCI:
strcpy(dev->name, "BT-958D");
bios_rom_name = L"roms/scsi/buslogic/BT-958D_BIOS.rom";
@@ -1437,9 +1573,10 @@ buslogic_init(device_t *info)
x54x_mem_init(dev, 0xfffd0000);
x54x_mem_disable(dev);
mem_mapping_disable(&bl->bios.mapping);
}
if ((bl->chip == CHIP_BUSLOGIC_MCA) || (bl->chip == CHIP_BUSLOGIC_PCI))
mem_mapping_disable(&bl->bios.mapping);
buslogic_log("Buslogic on port 0x%04X\n", dev->Base);
@@ -1607,6 +1744,15 @@ device_t buslogic_545s_device = {
BT_ISA_Config
};
device_t buslogic_640a_device = {
"Buslogic BT-640A MCA",
DEVICE_MCA,
CHIP_BUSLOGIC_ISA,
buslogic_init, x54x_close, NULL,
NULL, NULL, NULL, NULL,
NULL
};
device_t buslogic_pci_device = {
"Buslogic BT-958D PCI",
DEVICE_PCI,

View File

@@ -22,6 +22,7 @@
extern device_t buslogic_device;
extern device_t buslogic_545s_device;
extern device_t buslogic_640a_device;
extern device_t buslogic_pci_device;
extern void BuslogicDeviceReset(void *p);

View File

@@ -1860,7 +1860,14 @@ x54x_writel(uint32_t port, uint32_t val, void *priv)
void
x54x_io_set(x54x_t *dev, uint32_t base)
{
if (dev->bus & DEVICE_PCI) {
int bit32 = 0;
if (dev->bus & DEVICE_PCI)
bit32 = 1;
else if ((dev->bus & DEVICE_MCA) && dev->mca32)
bit32 = 1;
if (bit32) {
x54x_log("x54x: [PCI] Setting I/O handler at %04X\n", base);
io_sethandler(base, 4,
x54x_in, x54x_inw, x54x_inl,
@@ -1877,9 +1884,16 @@ x54x_io_set(x54x_t *dev, uint32_t base)
void
x54x_io_remove(x54x_t *dev, uint32_t base)
{
int bit32 = 0;
if (dev->bus & DEVICE_PCI)
bit32 = 1;
else if ((dev->bus & DEVICE_MCA) && dev->mca32)
bit32 = 1;
x54x_log("x54x: Removing I/O handler at %04X\n", base);
if (dev->bus & DEVICE_PCI) {
if (bit32) {
io_removehandler(base, 4,
x54x_in, x54x_inw, x54x_inl,
x54x_out, x54x_outw, x54x_outl, dev);
@@ -1894,7 +1908,14 @@ x54x_io_remove(x54x_t *dev, uint32_t base)
void
x54x_mem_init(x54x_t *dev, uint32_t addr)
{
if (dev->bus & DEVICE_PCI) {
int bit32 = 0;
if (dev->bus & DEVICE_PCI)
bit32 = 1;
else if ((dev->bus & DEVICE_MCA) && dev->mca32)
bit32 = 1;
if (bit32) {
mem_mapping_add(&dev->mmio_mapping, addr, 0x20,
x54x_read, x54x_readw, x54x_readl,
x54x_write, x54x_writew, x54x_writel,

View File

@@ -399,6 +399,9 @@ typedef struct {
uint8_t shram_mode;
uint8_t sync;
uint8_t parity;
volatile
uint8_t dma_buffer[128];
@@ -420,6 +423,7 @@ typedef struct {
uint8_t setup_info_len;
uint8_t max_id;
uint8_t pci_slot;
uint8_t mca32;
mem_mapping_t mmio_mapping;