From e49c41118357e67d63a4bdb0f4ce0ca1b5aaa805 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 16 Oct 2017 18:40:34 +0200 Subject: [PATCH] Fixed AHA and BusLogic software reset - fixes unnecessary stalls (mostly with BusLogic SCSI BIOS'es); Fixed BusLogic BT-958D reset - now it actually resets again. --- src/scsi/scsi_aha154x.c | 8 +- src/scsi/scsi_buslogic.c | 8 +- src/scsi/scsi_x54x.c | 156 ++++++++++++++++++++------------------- src/scsi/scsi_x54x.h | 4 +- 4 files changed, 86 insertions(+), 90 deletions(-) diff --git a/src/scsi/scsi_aha154x.c b/src/scsi/scsi_aha154x.c index dd0020c9e..914709fc6 100644 --- a/src/scsi/scsi_aha154x.c +++ b/src/scsi/scsi_aha154x.c @@ -10,7 +10,7 @@ * made by Adaptec, Inc. These controllers were designed for * the ISA bus. * - * Version: @(#)scsi_aha154x.c 1.0.29 2017/10/14 + * Version: @(#)scsi_aha154x.c 1.0.30 2017/10/16 * * Authors: Fred N. van Kempen, * Original Buslogic version by SA1988 and Miran Grca. @@ -49,9 +49,6 @@ enum { }; -#define AHA_RESET_DURATION_US UINT64_C(50000) - - #define CMD_WRITE_EEPROM 0x22 /* UNDOC: Write EEPROM */ #define CMD_READ_EEPROM 0x23 /* UNDOC: Read EEPROM */ #define CMD_SHADOW_RAM 0x24 /* UNDOC: BIOS shadow ram */ @@ -789,7 +786,6 @@ aha_init(device_t *info) dev->rom_addr = device_get_config_hex20("bios_addr"); dev->HostID = 7; /* default HA ID */ dev->setup_info_len = sizeof(aha_setup_t); - dev->reset_duration = AHA_RESET_DURATION_US; dev->max_id = 7; dev->int_geom_writable = 0; dev->cdrom_boot = 0; @@ -887,7 +883,7 @@ aha_init(device_t *info) if (dev->Base != 0) { /* Initialize the device. */ - x54x_reset_ctrl(dev, CTRL_HRST); + x54x_device_reset(dev); if (!(dev->bus & DEVICE_MCA)) { /* Register our address space. */ diff --git a/src/scsi/scsi_buslogic.c b/src/scsi/scsi_buslogic.c index a1ddc7daa..4d8cc3756 100644 --- a/src/scsi/scsi_buslogic.c +++ b/src/scsi/scsi_buslogic.c @@ -11,7 +11,7 @@ * 1 - BT-545S ISA; * 2 - BT-958D PCI * - * Version: @(#)scsi_buslogic.c 1.0.23 2017/10/14 + * Version: @(#)scsi_buslogic.c 1.0.24 2017/10/16 * * Authors: TheCollector1995, * Miran Grca, @@ -45,9 +45,6 @@ #include "scsi_x54x.h" -#define BUSLOGIC_RESET_DURATION_US UINT64_C(5000) - - /* * Auto SCSI structure which is located * in host adapter RAM and contains several @@ -1301,7 +1298,6 @@ buslogic_init(device_t *info) dev->DmaChannel = device_get_config_int("dma"); dev->HostID = 7; /* default HA ID */ dev->setup_info_len = sizeof(buslogic_setup_t); - dev->reset_duration = BUSLOGIC_RESET_DURATION_US; dev->max_id = 7; dev->int_geom_writable = 1; dev->cdrom_boot = 0; @@ -1445,7 +1441,7 @@ buslogic_init(device_t *info) buslogic_log("Buslogic on port 0x%04X\n", dev->Base); - x54x_reset_ctrl(dev, CTRL_HRST); + x54x_device_reset(dev); if (bl->chip != CHIP_BUSLOGIC_ISA_542) { BuslogicInitializeLocalRAM(bl); diff --git a/src/scsi/scsi_x54x.c b/src/scsi/scsi_x54x.c index 2f4e0b906..bfb091ddd 100644 --- a/src/scsi/scsi_x54x.c +++ b/src/scsi/scsi_x54x.c @@ -11,7 +11,7 @@ * series of SCSI Host Adapters made by Mylex. * These controllers were designed for various buses. * - * Version: @(#)scsi_x54x.c 1.0.1 2017/10/14 + * Version: @(#)scsi_x54x.c 1.0.2 2017/10/16 * * Authors: TheCollector1995, * Miran Grca, @@ -45,6 +45,9 @@ #include "scsi_x54x.h" +#define X54X_RESET_DURATION_US UINT64_C(50000) + + static void x54x_cmd_thread(void *priv); static thread_t *poll_tid; @@ -167,63 +170,6 @@ clear_irq(x54x_t *dev) } -static void -x54x_reset(x54x_t *dev) -{ - dev->ResetCB = 0LL; - - dev->Status = STAT_IDLE | STAT_INIT; - dev->Geometry = 0x80; - dev->Command = 0xFF; - dev->CmdParam = 0; - dev->CmdParamLeft = 0; - dev->IrqEnabled = 1; - dev->MailboxCount = 0; - dev->MailboxOutPosCur = 0; - dev->MailboxInPosCur = 0; - dev->MailboxOutInterrupts = 0; - dev->PendingInterrupt = 0; - - if (dev->ven_reset) { - dev->ven_reset(dev); - } - - clear_irq(dev); -} - - -void -x54x_reset_ctrl(x54x_t *dev, uint8_t Reset) -{ - /* Only if configured.. */ - if (dev->Base == 0x0000) return; - - /* Say hello! */ - x54x_log("%s %s (IO=0x%04X, IRQ=%d, DMA=%d, BIOS @%05lX) ID=%d\n", - dev->vendor, dev->name, dev->Base, dev->Irq, dev->DmaChannel, - dev->rom_addr, dev->HostID); - - x54x_reset(dev); - if (Reset) { - dev->Status |= STAT_STST; - dev->Status &= ~STAT_IDLE; - } - dev->ResetCB = dev->reset_duration * TIMER_USEC; -} - - -static void -x54x_reset_poll(void *priv) -{ - x54x_t *dev = (x54x_t *)priv; - - dev->Status &= ~STAT_STST; - dev->Status |= STAT_IDLE; - - dev->ResetCB = 0LL; -} - - static void target_check(uint8_t id, uint8_t lun) { @@ -1397,6 +1343,38 @@ x54x_cmd_thread(void *priv) } +void +x54x_busy_set(void) +{ + busy = 1; +} + + +void +x54x_thread_start(x54x_t *dev) +{ + if (!poll_tid) { + x54x_log("Starting thread...\n"); + poll_tid = thread_create(x54x_cmd_thread, dev); + } +} + + +void +x54x_busy_clear(void) +{ + busy = 0; + x54x_log("Thread set event - poll complete\n"); + thread_set_event(poll_complete); +} + +uint8_t +x54x_busy(void) +{ + return !!busy; +} + + static uint8_t x54x_in(uint16_t port, void *priv) { @@ -1467,35 +1445,56 @@ x54x_readl(uint32_t port, void *priv) } -void -x54x_busy_set(void) +static void +x54x_reset_poll(void *priv) { - busy = 1; + x54x_t *dev = (x54x_t *)priv; + + dev->Status &= ~STAT_STST; + dev->Status |= STAT_IDLE; + + dev->ResetCB = 0LL; } -void -x54x_thread_start(x54x_t *dev) +static void +x54x_reset(x54x_t *dev) { - if (!poll_tid) { - x54x_log("Starting thread...\n"); - poll_tid = thread_create(x54x_cmd_thread, dev); + dev->Geometry = 0x80; + dev->Command = 0xFF; + dev->CmdParam = 0; + dev->CmdParamLeft = 0; + dev->IrqEnabled = 1; + dev->MailboxCount = 0; + dev->MailboxOutPosCur = 0; + dev->MailboxInPosCur = 0; + dev->MailboxOutInterrupts = 0; + dev->PendingInterrupt = 0; + + if (dev->ven_reset) { + dev->ven_reset(dev); } + + clear_irq(dev); } void -x54x_busy_clear(void) +x54x_reset_ctrl(x54x_t *dev, uint8_t Reset) { - busy = 0; - x54x_log("Thread set event - poll complete\n"); - thread_set_event(poll_complete); -} + /* Say hello! */ + x54x_log("%s %s (IO=0x%04X, IRQ=%d, DMA=%d, BIOS @%05lX) ID=%d\n", + dev->vendor, dev->name, dev->Base, dev->Irq, dev->DmaChannel, + dev->rom_addr, dev->HostID); -uint8_t -x54x_busy(void) -{ - return !!busy; + x54x_reset(dev); + + if (Reset) { + dev->Status = STAT_STST; + dev->ResetCB = X54X_RESET_DURATION_US * TIMER_USEC; + } else { + dev->Status = STAT_INIT | STAT_IDLE; + } } @@ -1525,6 +1524,7 @@ x54x_out(uint16_t port, uint8_t val, void *priv) reset = (val & CTRL_HRST); x54x_log("Reset completed = %x\n", reset); x54x_reset_ctrl(dev, reset); + x54x_log("Controller reset: "); x54x_busy_clear(); break; } @@ -1532,6 +1532,7 @@ x54x_out(uint16_t port, uint8_t val, void *priv) if (val & CTRL_IRST) { x54x_busy_set(); clear_irq(dev); + x54x_log("Interrupt reset: "); x54x_busy_clear(); } break; @@ -1543,6 +1544,7 @@ x54x_out(uint16_t port, uint8_t val, void *priv) dev->MailboxReq++; x54x_thread_start(dev); + x54x_log("Start SCSI command: "); x54x_busy_clear(); return; } @@ -1628,6 +1630,7 @@ x54x_out(uint16_t port, uint8_t val, void *priv) dev->Status &= ~STAT_INIT; dev->DataReplyLeft = 0; + x54x_log("Mailbox init: "); x54x_busy_clear(); break; @@ -1997,4 +2000,7 @@ x54x_device_reset(void *priv) x54x_t *dev = (x54x_t *)priv; x54x_reset_ctrl(dev, 1); + + dev->ResetCB = 0LL; + dev->Status = STAT_IDLE | STAT_INIT; } diff --git a/src/scsi/scsi_x54x.h b/src/scsi/scsi_x54x.h index a63e90610..86cad8256 100644 --- a/src/scsi/scsi_x54x.h +++ b/src/scsi/scsi_x54x.h @@ -11,7 +11,7 @@ * of SCSI Host Adapters made by Mylex. * These controllers were designed for various buses. * - * Version: @(#)scsi_x54x.h 1.0.0 2017/10/14 + * Version: @(#)scsi_x54x.h 1.0.1 2017/10/16 * * Authors: TheCollector1995, * Miran Grca, @@ -421,8 +421,6 @@ typedef struct { uint8_t max_id; uint8_t pci_slot; - uint32_t reset_duration; - mem_mapping_t mmio_mapping; uint8_t int_geom_writable;