From: Michael McMaster Date: Thu, 30 Jan 2020 09:17:49 +0000 (+1000) Subject: Fix for large writes and data corruption over 64k X-Git-Tag: 6.2.15 X-Git-Url: http://git.codesrc.com/gitweb.cgi?a=commitdiff_plain;h=3af82c5ca13a69a5bbef6760557d56aaddbe99cf;p=SCSI2SD-V6.git Fix for large writes and data corruption over 64k --- diff --git a/CHANGELOG b/CHANGELOG index ef65698a..3e76dc95 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +20200130 6.2.15 + - Fix issue writing more than 512kb of data in one write command + (bug introduced 6.2.7) + - Fix possible data corruption bug when reading or writing more than + 64kb per command (fixed in most cases by 6.2.14) + 20200101 6.2.14 - Fix for invalid CDROM READ TOC responses (Thanks Simon Gander) - Fix for data corruption for hosts that transfer more than 64k per diff --git a/rtl/fpga_bitmap.o b/rtl/fpga_bitmap.o index e423f333..e351fea8 100644 Binary files a/rtl/fpga_bitmap.o and b/rtl/fpga_bitmap.o differ diff --git a/src/firmware/config.c b/src/firmware/config.c index f2e6d1e7..929921a9 100755 --- a/src/firmware/config.c +++ b/src/firmware/config.c @@ -37,7 +37,7 @@ #include -static const uint16_t FIRMWARE_VERSION = 0x062E; +static const uint16_t FIRMWARE_VERSION = 0x062F; // Optional static config extern uint8_t* __fixed_config; diff --git a/src/firmware/disk.c b/src/firmware/disk.c index 3c562e30..f79842f0 100755 --- a/src/firmware/disk.c +++ b/src/firmware/disk.c @@ -736,8 +736,17 @@ void scsiDiskPoll() static_assert(SCSI_XFER_MAX >= sizeof(scsiDev.data), "Assumes SCSI_XFER_MAX >= sizeof(scsiDev.data)"); // Start reading and filling fifos as soon as possible. - DWT->CYCCNT = 0; // Start counting cycles - scsiSetDataCount(transfer.blocks * bytesPerSector); + // It's highly unlikely that someone is going to use huge transfers + // per scsi command, but if they do it'll be slower than usual. + // Note: Happens in Macintosh FWB HDD Toolkit benchmarks which default + // to 768kb + uint32_t totalTransferBytes = transfer.blocks * bytesPerSector; + int useSlowDataCount = totalTransferBytes >= SCSI_XFER_MAX; + if (!useSlowDataCount) + { + DWT->CYCCNT = 0; // Start counting cycles + scsiSetDataCount(totalTransferBytes); + } while ((i < totalSDSectors) && likely(scsiDev.phase == DATA_OUT) && @@ -762,6 +771,12 @@ void scsiDiskPoll() sdSpeedKBs, scsiDev.hostSpeedKBs); + if (useSlowDataCount) + { + DWT->CYCCNT = 0; // Start counting cycles + scsiSetDataCount(totalBytes); + } + uint32_t scsiBytesRead = 0; if (readAheadBytes > 0) { @@ -771,7 +786,7 @@ void scsiDiskPoll() &parityError); scsiBytesRead += readAheadBytes; - if (i == 0) + if (i == 0 && !useSlowDataCount) { uint32_t elapsedCycles = DWT->CYCCNT; @@ -864,6 +879,12 @@ void scsiDiskPoll() // do this in a half-duplex fashion. We need to write as much as // possible in each SD card transaction. // use sg_dd from sg_utils3 tools to test. + + if (useSlowDataCount) + { + scsiSetDataCount(sectors * bytesPerSector); + } + for (int scsiSector = i; scsiSector < i + sectors; ++scsiSector) { int dmaBytes = SD_SECTOR_SIZE;