From 760222798cbb5008f265b7a0510ee7bed4c5bd75 Mon Sep 17 00:00:00 2001 From: Michael McMaster Date: Wed, 13 Jan 2016 21:22:16 +1000 Subject: [PATCH] Support custom mode pages --- CHANGELOG | 3 ++ software/SCSI2SD/src/mode.c | 33 +++++++++++++++++ software/include/scsi2sd.h | 3 +- software/scsi2sd-util/ConfigUtil.cc | 57 ++++++++++++++++++++++++----- 4 files changed, 85 insertions(+), 11 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index efe8538..e773d33 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,6 @@ +2016xxxx 4.x + - Added support for configurable mode pages + 20160111 4.6 - Fixed bug when using sector size that isn't a multiple of 4 (eg. 522 bytes) diff --git a/software/SCSI2SD/src/mode.c b/software/SCSI2SD/src/mode.c index 5cdf5de..c362878 100755 --- a/software/SCSI2SD/src/mode.c +++ b/software/SCSI2SD/src/mode.c @@ -197,6 +197,33 @@ static void pageIn(int pc, int dataIdx, const uint8* pageData, int pageLen) } } +static int useCustomPages(TargetConfig* cfg, int pc, int pageCode, int* idx) +{ + int found = 0; + int cfgIdx = 0; + while ((cfgIdx < sizeof(cfg->modePages) + 2) && + (cfg->modePages[cfgIdx + 1] != 0) + ) + { + int pageSize = cfg->modePages[cfgIdx + 1] + 2; + int dataPageCode = cfg->modePages[cfgIdx] & 0x3f; + if ((dataPageCode == pageCode) || + (pageCode == 0x3f) + ) + { + pageIn(pc, *idx, &cfg->modePages[cfgIdx], pageSize); + *idx += pageSize; + found = 1; + if (pageCode != 0x3f) + { + break; + } + } + cfgIdx += pageSize; + } + return found; +} + static void doModeSense( int sixByteCmd, int dbd, int pc, int pageCode, int allocLength) { @@ -305,6 +332,12 @@ static void doModeSense( int pageFound = 0; + if (scsiDev.target->cfg->modePages[1] != 0) + { + pageFound = useCustomPages(scsiDev.target->cfg, pc, pageCode, &idx); + pageCode = 0xFF; // dodgy, skip rest of logic + } + if (pageCode == 0x01 || pageCode == 0x3F) { pageFound = 1; diff --git a/software/include/scsi2sd.h b/software/include/scsi2sd.h index 1da8316..54f6bb9 100755 --- a/software/include/scsi2sd.h +++ b/software/include/scsi2sd.h @@ -153,7 +153,8 @@ typedef struct __attribute__((packed)) uint8_t reserved[960]; // Pad out to 1024 bytes for main section. - uint8_t vpd[3072]; // Total size is 4k. + uint8_t modePages[1024]; + uint8_t unused[2048]; // Total size is 4k. } TargetConfig; typedef struct __attribute__((packed)) diff --git a/software/scsi2sd-util/ConfigUtil.cc b/software/scsi2sd-util/ConfigUtil.cc index 5a8713b..2074ad5 100644 --- a/software/scsi2sd-util/ConfigUtil.cc +++ b/software/scsi2sd-util/ConfigUtil.cc @@ -23,6 +23,12 @@ #include +#include +#ifndef WX_PRECOMP +#include +#endif +#include +#include #include @@ -80,6 +86,22 @@ namespace return toLE32(in); } + std::vector getModePages(const TargetConfig& cfg) + { + std::vector result; + int i = 0; + while (i < sizeof(cfg.modePages) + 2) + { + int pageLen = cfg.modePages[i+1]; + if (pageLen == 0) break; + std::copy( + &cfg.modePages[i], + &cfg.modePages[i+pageLen+2], + std::back_inserter(result)); + i += pageLen + 2; + } + return result; + } } BoardConfig @@ -194,6 +216,7 @@ std::string ConfigUtil::toXML(const TargetConfig& config) { std::stringstream s; + std::vector modePages(getModePages(config)); s << "\n" << " " << std::string(config.serial, 16) << "\n" << + "\n" << + " \n" << + " \n" << + (modePages.size() == 0 ? "" : + wxBase64Encode(&modePages[0], modePages.size())) << + "\n" << + " \n" << "\n"; return s.str(); @@ -292,7 +322,7 @@ ConfigUtil::toXML(const BoardConfig& config) " \n" << " " << (config.flags & CONFIG_ENABLE_SCSI2 ? "true" : "false") << @@ -318,9 +348,9 @@ ConfigUtil::toXML(const BoardConfig& config) "\n" << " \n" << " " << (config.flags & CONFIG_ENABLE_SEL_LATCH? "true" : "false") << @@ -328,12 +358,12 @@ ConfigUtil::toXML(const BoardConfig& config) " \n" << " " << (config.flags & CONFIG_MAP_LUNS_TO_IDS ? "true" : "false") << @@ -474,6 +504,13 @@ parseTarget(wxXmlNode* node) memset(result.serial, ' ', sizeof(result.serial)); memcpy(result.serial, s.c_str(), s.size()); } + else if (child->GetName() == "modePages") + { + wxMemoryBuffer buf = + wxBase64Decode(child->GetNodeContent(), wxBase64DecodeMode_SkipWS); + size_t len = std::min(buf.GetDataLen(), sizeof(result.modePages)); + memcpy(result.modePages, buf.GetData(), len); + } child = child->GetNext(); } -- 2.38.5