From 20277f7090167e907d5e6ab9115693a9cea30578 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 26 Apr 2024 22:05:54 +0200 Subject: [PATCH] Workaround to prevent timeouts with the T130B driver on NT 3.1. And more logging cleanups. This should make the T130B driver for NT 3.1 work normally, at least. --- src/scsi/scsi_ncr53c400.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/scsi/scsi_ncr53c400.c b/src/scsi/scsi_ncr53c400.c index d605f1bdb..1ed8e520e 100644 --- a/src/scsi/scsi_ncr53c400.c +++ b/src/scsi/scsi_ncr53c400.c @@ -110,6 +110,7 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) ncr53c400_t *ncr400 = (ncr53c400_t *) priv; ncr_t *ncr = &ncr400->ncr; scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + int actual_block = 0; addr &= 0x3fff; @@ -129,7 +130,7 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) if (!(ncr400->status_ctrl & CTRL_DATA_DIR) && (ncr400->buffer_host_pos < MIN(128, dev->buffer_length))) { ncr400->buffer[ncr400->buffer_host_pos++] = val; - ncr53c400_log("Write host pos = %i, val = %02x\n", ncr400->buffer_host_pos, val); + ncr53c400_log("Write host pos=%i, val=%02x.\n", ncr400->buffer_host_pos, val); if (ncr400->buffer_host_pos == MIN(128, dev->buffer_length)) { ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; @@ -141,7 +142,7 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) case 0x3980: switch (addr) { case 0x3980: /* Control */ - ncr53c400_log("NCR 53c400 control = %02x, mode = %02x.\n", val, ncr->mode); + ncr53c400_log("NCR 53c400 control=%02x, mode=%02x.\n", val, ncr->mode); if ((val & CTRL_DATA_DIR) && !(ncr400->status_ctrl & CTRL_DATA_DIR)) { ncr400->buffer_host_pos = MIN(128, dev->buffer_length); ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; @@ -153,7 +154,7 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) break; case 0x3981: /* block counter register */ - ncr53c400_log("Write block counter register: val=%d, dma mode=%x, period=%lf\n", val, ncr->dma_mode, ncr->period); + ncr53c400_log("Write block counter register: val=%d, dma mode=%x, period=%lf.\n", val, ncr->dma_mode, ncr->period); ncr400->block_count = val; ncr400->block_count_loaded = 1; @@ -164,10 +165,19 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) ncr400->buffer_host_pos = 0; ncr400->status_ctrl &= ~STATUS_BUFFER_NOT_READY; } - if ((ncr->mode & MODE_DMA) && !timer_is_on(&ncr400->timer) && (dev->buffer_length > 0)) { + if ((ncr->mode & MODE_DMA) && (dev->buffer_length > 0) && !timer_is_on(&ncr400->timer)) { memset(ncr400->buffer, 0, MIN(128, dev->buffer_length)); - ncr53c400_log("DMA timer on\n"); - timer_on_auto(&ncr400->timer, ncr->period); + ncr53c400_log("DMA timer on, callback=%lf, scsi buflen=%d.\n", scsi_device_get_callback(dev), dev->buffer_length); + actual_block = ncr400->block_count; + if (!actual_block) + actual_block = 256; + + /*Sometimes the actual block count doesn't match the SCSI buffer length / 128.*/ + if (actual_block != (dev->buffer_length / 128)) { + /*FIXME: To be improved further, this is just to workaround callback de-syncs when split transfers occur.*/ + timer_on_auto(&ncr400->timer, (ncr->period / ((double)(actual_block * 40.0)))); + } else + timer_on_auto(&ncr400->timer, ncr->period); } break; @@ -202,12 +212,12 @@ ncr53c400_read(uint32_t addr, void *priv) else { switch (addr & 0x3f80) { case 0x3800: - ncr53c400_log("Read intRAM %02x %02x\n", addr & 0x3f, ncr400->int_ram[addr & 0x3f]); + ncr53c400_log("Read intRAM %02x %02x.\n", addr & 0x3f, ncr400->int_ram[addr & 0x3f]); ret = ncr400->int_ram[addr & 0x3f]; break; case 0x3880: - ncr53c400_log("Read 5380 %04x\n", addr); + ncr53c400_log("Read 5380 %04x.\n", addr); ret = ncr5380_read(addr, ncr); break; @@ -217,11 +227,11 @@ ncr53c400_read(uint32_t addr, void *priv) ncr53c400_log("No Read.\n"); } else { ret = ncr400->buffer[ncr400->buffer_host_pos++]; - ncr53c400_log("Read host pos = %i, ret = %02x\n", ncr400->buffer_host_pos, ret); + ncr53c400_log("Read host pos=%i, ret=%02x.\n", ncr400->buffer_host_pos, ret); if (ncr400->buffer_host_pos == MIN(128, dev->buffer_length)) { ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; - ncr53c400_log("Transfer busy read, status = %02x\n", ncr400->status_ctrl); + ncr53c400_log("Transfer busy read, status = %02x.\n", ncr400->status_ctrl); } } break; @@ -230,7 +240,7 @@ ncr53c400_read(uint32_t addr, void *priv) switch (addr) { case 0x3980: /* status */ ret = ncr400->status_ctrl; - ncr53c400_log("NCR status ctrl read=%02x\n", ncr400->status_ctrl & STATUS_BUFFER_NOT_READY); + ncr53c400_log("NCR status ctrl read=%02x.\n", ncr400->status_ctrl & STATUS_BUFFER_NOT_READY); if (!ncr400->busy) ret |= STATUS_5380_ACCESSIBLE; if (ncr->mode & 0x30) { /*Parity bits*/ @@ -239,11 +249,12 @@ ncr53c400_read(uint32_t addr, void *priv) ncr->mode = 0; /*Required by RTASPI10.SYS otherwise it won't initialize.*/ } } - ncr53c400_log("NCR 53c400 status = %02x.\n", ret); + ncr53c400_log("NCR 53c400 status=%02x.\n", ret); break; case 0x3981: /* block counter register*/ ret = ncr400->block_count; + ncr53c400_log("NCR 53c400 block count read=%02x.\n", ret); break; case 0x3982: /* switch register read */ @@ -394,7 +405,7 @@ ncr53c400_timer_on_auto(void *ext_priv, double period) { ncr53c400_t *ncr400 = (ncr53c400_t *) ext_priv; - ncr53c400_log("53c400: PERIOD=%lf.\n", period); + ncr53c400_log("53c400: PERIOD=%lf, timer=%x.\n", period, !!timer_is_on(&ncr400->timer)); if (period == 0.0) timer_stop(&ncr400->timer); else