From 85dc3c4ad61f142ecf68d0f8c4d7d5490ccd37d3 Mon Sep 17 00:00:00 2001 From: androda <3105206+androda@users.noreply.github.com> Date: Mon, 14 Oct 2024 06:30:24 -0600 Subject: [PATCH] Setting To Ignore Parity For Initiator Mode Data Transfers --- lib/BlueSCSI_platform_RP2040/scsiHostPhy.cpp | 26 +++++++++++++++---- lib/BlueSCSI_platform_RP2040/scsiHostPhy.h | 2 ++ .../scsi_accel_host.cpp | 5 ++-- .../scsi_accel_host.h | 2 +- src/BlueSCSI.cpp | 5 ++++ 5 files changed, 32 insertions(+), 8 deletions(-) diff --git a/lib/BlueSCSI_platform_RP2040/scsiHostPhy.cpp b/lib/BlueSCSI_platform_RP2040/scsiHostPhy.cpp index 18331048..1885125b 100644 --- a/lib/BlueSCSI_platform_RP2040/scsiHostPhy.cpp +++ b/lib/BlueSCSI_platform_RP2040/scsiHostPhy.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2022 Rabbit Hole Computing™ +// Copyright (c) 2024 Tech by Androda, LLC #include "scsiHostPhy.h" #include "BlueSCSI_platform.h" @@ -13,6 +14,7 @@ extern "C" { } volatile int g_scsiHostPhyReset; +bool perform_parity_checking = true; // Release bus and pulse RST signal, initialize PHY to host mode. void scsiHostPhyReset(void) @@ -168,7 +170,7 @@ static inline void scsiHostWriteOneByte(uint8_t value) } // Read one byte from SCSI target using the handshake mechanism. -static inline uint8_t scsiHostReadOneByte(int* parityError) +static inline uint8_t scsiHostReadOneByte(int* parityError, uint32_t *parityResult) { SCSIHOST_WAIT_ACTIVE(REQ); uint16_t r = SCSI_IN_DATA(); @@ -178,8 +180,8 @@ static inline uint8_t scsiHostReadOneByte(int* parityError) if (parityError && r != (g_scsi_parity_lookup[r & 0xFF] ^ SCSI_IO_DATA_MASK)) { - log("Parity error in scsiReadOneByte(): ", (uint32_t)r); *parityError = 1; + *parityResult = (uint32_t)r; } return (uint8_t)r; @@ -213,6 +215,7 @@ uint32_t scsiHostWrite(const uint8_t *data, uint32_t count) uint32_t scsiHostRead(uint8_t *data, uint32_t count) { int parityError = 0; + uint32_t parityResult; uint32_t fullcount = count; int cd_start = SCSI_IN(CD); @@ -221,7 +224,12 @@ uint32_t scsiHostRead(uint8_t *data, uint32_t count) if ((count & 1) == 0 && ((uint32_t)data & 1) == 0) { // Even number of bytes, use accelerated routine - count = scsi_accel_host_read(data, count, &parityError, &g_scsiHostPhyReset); + count = scsi_accel_host_read(data, count, &parityError, &parityResult, &g_scsiHostPhyReset); + if (parityError && perform_parity_checking) { + log("Parity error in scsi_accel_host_read(): ", parityResult); + } else { + parityError = 0; + } } else { @@ -235,8 +243,12 @@ uint32_t scsiHostRead(uint8_t *data, uint32_t count) count = i; } } - - data[i] = scsiHostReadOneByte(&parityError); + data[i] = scsiHostReadOneByte(&parityError, &parityResult); + if (parityError && perform_parity_checking) { + log("Parity error in scsiReadOneByte(): ", parityResult); + } else { + parityError = 0; + } } } @@ -264,3 +276,7 @@ void scsiHostPhyRelease() SCSI_RELEASE_OUTPUTS(); SCSI_RELEASE_DATA_REQ(); } + +void setInitiatorModeParityCheck(bool checkParity) { + perform_parity_checking = checkParity; +} diff --git a/lib/BlueSCSI_platform_RP2040/scsiHostPhy.h b/lib/BlueSCSI_platform_RP2040/scsiHostPhy.h index 82c5666d..2a16c3e6 100644 --- a/lib/BlueSCSI_platform_RP2040/scsiHostPhy.h +++ b/lib/BlueSCSI_platform_RP2040/scsiHostPhy.h @@ -30,3 +30,5 @@ uint32_t scsiHostRead(uint8_t *data, uint32_t count); // Release all bus signals void scsiHostPhyRelease(); + +void setInitiatorModeParityCheck(bool checkParity); diff --git a/lib/BlueSCSI_platform_RP2040/scsi_accel_host.cpp b/lib/BlueSCSI_platform_RP2040/scsi_accel_host.cpp index 8039a0f8..2ae6b610 100644 --- a/lib/BlueSCSI_platform_RP2040/scsi_accel_host.cpp +++ b/lib/BlueSCSI_platform_RP2040/scsi_accel_host.cpp @@ -1,5 +1,6 @@ // Accelerated SCSI subroutines for SCSI initiator/host side communication // Copyright (c) 2022 Rabbit Hole Computing™ +// Copyright (c) 2024 Tech by Androda, LLC #include "scsi_accel_host.h" #include "BlueSCSI_platform.h" @@ -65,7 +66,7 @@ static void scsi_accel_host_config_gpio() } } -uint32_t scsi_accel_host_read(uint8_t *buf, uint32_t count, int *parityError, volatile int *resetFlag) +uint32_t scsi_accel_host_read(uint8_t *buf, uint32_t count, int *parityError, uint32_t *parityResult, volatile int *resetFlag) { // Currently this method just reads from the PIO RX fifo directly in software loop. // The SD card access is parallelized using DMA, so there is limited benefit from using DMA here. @@ -117,8 +118,8 @@ uint32_t scsi_accel_host_read(uint8_t *buf, uint32_t count, int *parityError, vo uint8_t byte1 = ~(paritycheck >> 16); if (paritycheck != ((g_scsi_parity_lookup[byte1] << 16) | g_scsi_parity_lookup[byte0])) { - log("Parity error in scsi_accel_host_read(): ", paritycheck); *parityError = 1; + *parityResult = paritycheck; } g_scsi_host_state = SCSIHOST_IDLE; diff --git a/lib/BlueSCSI_platform_RP2040/scsi_accel_host.h b/lib/BlueSCSI_platform_RP2040/scsi_accel_host.h index 8dda56f7..b18bfa03 100644 --- a/lib/BlueSCSI_platform_RP2040/scsi_accel_host.h +++ b/lib/BlueSCSI_platform_RP2040/scsi_accel_host.h @@ -8,4 +8,4 @@ void scsi_accel_host_init(); // Read data from SCSI bus. // Number of bytes to read must be divisible by two. -uint32_t scsi_accel_host_read(uint8_t *buf, uint32_t count, int *parityError, volatile int *resetFlag); +uint32_t scsi_accel_host_read(uint8_t *buf, uint32_t count, int *parityError, uint32_t *parityResult, volatile int *resetFlag); diff --git a/src/BlueSCSI.cpp b/src/BlueSCSI.cpp index 8be778ae..3a76422e 100644 --- a/src/BlueSCSI.cpp +++ b/src/BlueSCSI.cpp @@ -610,6 +610,11 @@ extern "C" void bluescsi_setup(void) if (ini_getbool("SCSI", "InitiatorMode", false, CONFIGFILE)) { platform_enable_initiator_mode(); + if (! ini_getbool("SCSI", "InitiatorParity", true, CONFIGFILE)) + { + log("Initiator Mode Skipping Parity Check."); + setInitiatorModeParityCheck(false); + } } if (SD.clusterCount() == 0) {