Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/BlueSCSI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
12 changes: 12 additions & 0 deletions src/BlueSCSI_disk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) */
/************************************************/
Expand Down
4 changes: 4 additions & 0 deletions src/BlueSCSI_disk.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
61 changes: 34 additions & 27 deletions src/BlueSCSI_initiator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include <BlueSCSI_platform.h>
#include <minIni.h>
#include "SdFat.h"
#include "BlueSCSI_disk.h"

#include <scsi2sd.h>
extern "C" {
Expand Down Expand Up @@ -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()
{
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
{
Expand All @@ -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;
}

Expand All @@ -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];
Expand Down
19 changes: 16 additions & 3 deletions src/BlueSCSI_initiator.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,22 @@
#include <stdint.h>
#include <stdlib.h>

#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
Expand Down
6 changes: 3 additions & 3 deletions src/BlueSCSI_log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down
7 changes: 6 additions & 1 deletion src/BlueSCSI_log.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,14 @@

#include <stdint.h>
#include <stddef.h>
#include <scsi2sd.h>
#include <scsiPhy.h>
#include <hardware/timer.h>

// 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();

Expand All @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/BlueSCSI_log_trace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down