diff --git a/src/BlueSCSI.cpp b/src/BlueSCSI.cpp index c6772c16..828df74f 100644 --- a/src/BlueSCSI.cpp +++ b/src/BlueSCSI.cpp @@ -924,14 +924,14 @@ STATIC_TESTABLE void reinitSCSI() if (g_log_debug) { logmsg("-- Debug = Yes"); - g_scsi_log_mask = ini_getl("SCSI", "DebugLogMask", 0xFF, CONFIGFILE) & 0xFF; + g_scsi_log_mask = ini_getl("SCSI", "DebugLogMask", BLUESCSI_DEFAULT_LOG_MASK, CONFIGFILE) & BLUESCSI_DEFAULT_LOG_MASK; if (g_scsi_log_mask == 0) { dbgmsg("DebugLogMask set to 0x00, this will silence all debug messages when a SCSI ID has been selected"); } - else if (g_scsi_log_mask != 0xFF) + else if (g_scsi_log_mask != BLUESCSI_DEFAULT_LOG_MASK) { - dbgmsg("DebugLogMask set to ", (uint8_t) g_scsi_log_mask, " only SCSI ID's matching the bit mask will be logged"); + dbgmsg("DebugLogMask set to ", g_scsi_log_mask, " only SCSI ID's matching the bit mask will be logged"); } g_log_ignore_busy_free = ini_getbool("SCSI", "DebugIgnoreBusyFree", 0, CONFIGFILE); diff --git a/src/BlueSCSI_disk.cpp b/src/BlueSCSI_disk.cpp index e61d3195..a64c72fd 100644 --- a/src/BlueSCSI_disk.cpp +++ b/src/BlueSCSI_disk.cpp @@ -119,6 +119,18 @@ static bool hasExtension(const char *filename, const char *ext) bool testHasExtension(const char *filename, const char *ext) { return hasExtension(filename, ext); } #endif +// Encode a SCSI ID (0..15) as a single filename character: '0'..'9' or 'A'..'F'. +// Wide-bus image filenames (HD00_imaged, CD00_imaged, etc.) place the target +// ID in one character; for IDs >= 10 we need hex rather than overflowing past '9'. +char scsiEncodeID(uint8_t scsi_id) +{ + if (scsi_id <= 9) + return '0' + scsi_id; + if (scsi_id >= 0xA && scsi_id <= 0xF) + return 'A' + (scsi_id - 0xA); + return '\0'; +} + /************************************************/ /* ROM drive support (in microcontroller flash) */ /************************************************/ diff --git a/src/BlueSCSI_disk.h b/src/BlueSCSI_disk.h index 0eed5312..7ff60caf 100644 --- a/src/BlueSCSI_disk.h +++ b/src/BlueSCSI_disk.h @@ -194,4 +194,8 @@ bool scsiDiskCheckAnyNetworkDevicesConfigured(); // Switch to next Drive image if multiple have been configured bool switchNextImage(image_config_t &img, const char* next_filename = nullptr); +// Encode a SCSI ID (0..15) as a single filename character: '0'..'9' or 'A'..'F'. +// Returns '\0' for out-of-range inputs. +char scsiEncodeID(uint8_t scsi_id); + #endif /* BLUESCSI_DISK_H */ diff --git a/src/BlueSCSI_initiator.cpp b/src/BlueSCSI_initiator.cpp index 6b422825..c9313f0d 100644 --- a/src/BlueSCSI_initiator.cpp +++ b/src/BlueSCSI_initiator.cpp @@ -37,6 +37,7 @@ #include #include #include "SdFat.h" +#include "BlueSCSI_disk.h" #include extern "C" { @@ -226,30 +227,31 @@ void delay_with_poll(uint32_t ms) } } -static int scsiTypeToIniType(int scsi_type, bool removable) +// Map a SCSI peripheral device type to a human-readable name. +// Returns nullptr for unsupported (non-block) types — the initiator skips +// those rather than attempting to clone them. +static const char *initiatorPeripheralTypeName(uint8_t device_type, bool removable) { - int ini_type = -1; - switch (scsi_type) + switch (device_type) { - case SCSI_DEVICE_TYPE_DIRECT_ACCESS: - ini_type = removable ? S2S_CFG_REMOVABLE : S2S_CFG_FIXED; - break; - case 1: - ini_type = -1; // S2S_CFG_SEQUENTIAL - break; - case SCSI_DEVICE_TYPE_CD: - ini_type = S2S_CFG_OPTICAL; - break; - case SCSI_DEVICE_TYPE_MO: - ini_type = S2S_CFG_MO; - break; - default: - ini_type = -1; - break; + case SCSI_DEVICE_TYPE_DIRECT_ACCESS: return removable ? "Removable " : "Disk"; + case SCSI_DEVICE_TYPE_SEQUENTIAL: return "Sequential (Tape)"; + case SCSI_DEVICE_TYPE_WRITE_ONCE: return "Write Once"; + case SCSI_DEVICE_TYPE_CD: return "Optical (CD/DVD)"; + case SCSI_DEVICE_TYPE_MO: return "Optical Memory (Magneto-optical)"; + case SCSI_DEVICE_TYPE_MEDIA_CHANGER: return "Media Changer"; + case SCSI_DEVICE_TYPE_DISK_ARRAY: return "Disk Array"; + default: return nullptr; } - return ini_type; } +#ifdef UNIT_TEST +extern "C" const char *initiatorTestPeripheralTypeName(uint8_t device_type, bool removable) +{ + return initiatorPeripheralTypeName(device_type, removable); +} +#endif + // Check if VHD output should be used for the current target static bool initiatorShouldWriteVhd() { @@ -303,7 +305,7 @@ void scsiInitiatorMainLoop() if (!g_initiator_state.imaging) { // Scan for SCSI drives one at a time - g_initiator_state.target_id = (g_initiator_state.target_id + 1) % 8; + g_initiator_state.target_id = (g_initiator_state.target_id + 1) % S2S_MAX_TARGETS; g_initiator_state.sectorsize = 0; g_initiator_state.sectorcount = 0; g_initiator_state.sectors_done = 0; @@ -430,16 +432,21 @@ void scsiInitiatorMainLoop() g_initiator_state.max_sector_per_transfer = max_by_buffer; } - int ini_type = scsiTypeToIniType(g_initiator_state.device_type, g_initiator_state.removable); logmsg("SCSI Version ", (int) g_initiator_state.ansi_version); logmsg("[SCSI", g_initiator_state.target_id,"]"); logmsg(" Vendor = \"", vendor,"\""); logmsg(" Product = \"", product,"\""); logmsg(" Version = \"", revision,"\""); - if (ini_type == -1) - logmsg("Type = Not Supported, trying direct access"); - else - logmsg(" Type = ", ini_type); + + const char *typeName = initiatorPeripheralTypeName( + g_initiator_state.device_type, g_initiator_state.removable); + if (typeName == nullptr) + { + logmsg(" SCSI Peripheral device type id ", g_initiator_state.device_type, " unsupported. Skipping this device"); + g_initiator_state.drives_imaged |= 1 << g_initiator_state.target_id; + return; + } + logmsg(" SCSI Device Type = ", typeName); if (g_initiator_state.device_type == SCSI_DEVICE_TYPE_CD) { @@ -453,7 +460,7 @@ void scsiInitiatorMainLoop() } else if (g_initiator_state.device_type != SCSI_DEVICE_TYPE_DIRECT_ACCESS) { - logmsg("Unhandled scsi device type: ", g_initiator_state.device_type, ". Handling it as Direct Access Device."); + logmsg(" No specific handler for the device type, treating as Direct Access Device."); g_initiator_state.device_type = SCSI_DEVICE_TYPE_DIRECT_ACCESS; } @@ -478,7 +485,7 @@ void scsiInitiatorMainLoop() if (g_initiator_state.sectorcount > 0) { char filename[32] = {0}; - filename_base[2] += g_initiator_state.target_id; + filename_base[2] = scsiEncodeID(g_initiator_state.target_id); if (g_initiator_state.eject_when_done) { auto removable_count = g_initiator_state.removable_count[g_initiator_state.target_id]; diff --git a/src/BlueSCSI_initiator.h b/src/BlueSCSI_initiator.h index 89ebf3e8..fdf36e5c 100644 --- a/src/BlueSCSI_initiator.h +++ b/src/BlueSCSI_initiator.h @@ -26,9 +26,22 @@ #include #include -#define SCSI_DEVICE_TYPE_CD 0x5 -#define SCSI_DEVICE_TYPE_MO 0x7 -#define SCSI_DEVICE_TYPE_DIRECT_ACCESS 0x0 +enum scsi_device_type_t { + SCSI_DEVICE_TYPE_DIRECT_ACCESS = 0x00, + SCSI_DEVICE_TYPE_SEQUENTIAL = 0x01, + SCSI_DEVICE_TYPE_PRINTER = 0x02, + SCSI_DEVICE_TYPE_PROCESSOR = 0x03, + SCSI_DEVICE_TYPE_WRITE_ONCE = 0x04, + SCSI_DEVICE_TYPE_CD = 0x05, + SCSI_DEVICE_TYPE_SCANNER = 0x06, + SCSI_DEVICE_TYPE_MO = 0x07, + SCSI_DEVICE_TYPE_MEDIA_CHANGER = 0x08, + SCSI_DEVICE_TYPE_COMMUNICATION = 0x09, + SCSI_DEVICE_TYPE_ASC_IT8_A = 0x0A, + SCSI_DEVICE_TYPE_ASC_IT8_B = 0x0B, + SCSI_DEVICE_TYPE_DISK_ARRAY = 0x0C, + SCSI_DEVICE_TYPE_UNKNOWN = 0x1F +}; #define INITIATOR_IMAGE_SKIP_IF_EXISTS 0 #define INITIATOR_IMAGE_INCREMENT_IF_EXISTS 1 diff --git a/src/BlueSCSI_log.cpp b/src/BlueSCSI_log.cpp index d033ee7c..7e274598 100644 --- a/src/BlueSCSI_log.cpp +++ b/src/BlueSCSI_log.cpp @@ -32,7 +32,7 @@ const char *g_log_firmwareversion = BLUE_FW_VERSION " " __DATE__ " " __TIME__; bool g_log_debug = false; bool g_log_ignore_busy_free = false; -uint8_t g_scsi_log_mask = 0xFF; +uint32_t g_scsi_log_mask = BLUESCSI_DEFAULT_LOG_MASK; // This memory buffer can be read by debugger and is also saved to log.txt #define LOGBUFMASK (LOGBUFSIZE - 1) @@ -163,9 +163,9 @@ bool dbgmsg_start() if (g_log_debug) { // Check if log mask is not the default value, the selection was a success, and the selected ID was not match, then skip logging - if ( g_scsi_log_mask != 0xFF + if ( g_scsi_log_mask != BLUESCSI_DEFAULT_LOG_MASK && (SCSI_STS_SELECTION_SUCCEEDED & *SCSI_STS_SELECTED) - && (0 == (g_scsi_log_mask & (1 << (*SCSI_STS_SELECTED & 7)))) + && (0 == (g_scsi_log_mask & (1UL << (*SCSI_STS_SELECTED & (S2S_MAX_TARGETS - 1))))) ) { return false; diff --git a/src/BlueSCSI_log.h b/src/BlueSCSI_log.h index b5290294..2c33ef0f 100644 --- a/src/BlueSCSI_log.h +++ b/src/BlueSCSI_log.h @@ -28,9 +28,14 @@ #include #include +#include #include #include +// Default log mask has one bit per SCSI target; width tracks S2S_MAX_TARGETS +// so DebugLogMask works on both narrow (S2S_MAX_TARGETS=8) and wide builds. +#define BLUESCSI_DEFAULT_LOG_MASK ((1UL << S2S_MAX_TARGETS) - 1UL) + // Get total number of bytes that have been written to log uint32_t log_get_buffer_len(); @@ -42,7 +47,7 @@ const char *log_get_buffer(uint32_t *startpos, uint32_t *available = nullptr); // Whether to enable debug messages extern "C" bool g_log_debug; extern "C" bool g_log_ignore_busy_free; -extern "C" uint8_t g_scsi_log_mask; +extern "C" uint32_t g_scsi_log_mask; // Firmware version string extern const char *g_log_firmwareversion; diff --git a/src/BlueSCSI_log_trace.cpp b/src/BlueSCSI_log_trace.cpp index d07e4639..7b00760e 100644 --- a/src/BlueSCSI_log_trace.cpp +++ b/src/BlueSCSI_log_trace.cpp @@ -332,7 +332,7 @@ void scsiLogDataOut(const uint8_t *buf, uint32_t length) { if (buf == scsiDev.cdb || g_LogInitiatorCommand) { - dbgmsg("---- COMMAND: ", getCommandName(buf[0])); + dbgmsg("---- COMMAND: ", buf[0], " (", getCommandName(buf[0]), ")"); } if (g_LogData)