mirror of
https://github.com/fhgwright/SCSI2SD.git
synced 2025-04-10 01:37:07 +00:00
Support custom mode pages
This commit is contained in:
parent
2be1bfb906
commit
760222798c
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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))
|
||||
|
@ -23,6 +23,12 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <wx/wxprec.h>
|
||||
#ifndef WX_PRECOMP
|
||||
#include <wx/wx.h>
|
||||
#endif
|
||||
#include <wx/base64.h>
|
||||
#include <wx/buffer.h>
|
||||
#include <wx/xml/xml.h>
|
||||
|
||||
|
||||
@ -80,6 +86,22 @@ namespace
|
||||
return toLE32(in);
|
||||
}
|
||||
|
||||
std::vector<uint8_t> getModePages(const TargetConfig& cfg)
|
||||
{
|
||||
std::vector<uint8_t> 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<uint8_t> modePages(getModePages(config));
|
||||
|
||||
s <<
|
||||
"<SCSITarget id=\"" <<
|
||||
@ -269,6 +292,13 @@ ConfigUtil::toXML(const TargetConfig& config)
|
||||
"\n" <<
|
||||
" <!-- 16 character serial number -->\n" <<
|
||||
" <serial>" << std::string(config.serial, 16) << "</serial>\n" <<
|
||||
"\n" <<
|
||||
" <!-- Custom mode pages, base64 encoded, up to 1024 bytes.-->\n" <<
|
||||
" <modePages>\n" <<
|
||||
(modePages.size() == 0 ? "" :
|
||||
wxBase64Encode(&modePages[0], modePages.size())) <<
|
||||
"\n" <<
|
||||
" </modePages>\n" <<
|
||||
"</SCSITarget>\n";
|
||||
|
||||
return s.str();
|
||||
@ -292,7 +322,7 @@ ConfigUtil::toXML(const BoardConfig& config)
|
||||
" <!-- ********************************************************\n" <<
|
||||
" Only set to true when using with a fast SCSI2 host\n " <<
|
||||
" controller. This can cause problems with older/slower\n" <<
|
||||
" hardware.\n" <<
|
||||
" hardware.\n" <<
|
||||
" ********************************************************* -->\n" <<
|
||||
" <enableScsi2>" <<
|
||||
(config.flags & CONFIG_ENABLE_SCSI2 ? "true" : "false") <<
|
||||
@ -318,9 +348,9 @@ ConfigUtil::toXML(const BoardConfig& config)
|
||||
"</enableDisconnect>\n" <<
|
||||
|
||||
" <!-- ********************************************************\n" <<
|
||||
" Respond to very short duration selection attempts. This supports\n" <<
|
||||
" non-standard hardware, but is generally safe to enable.\n" <<
|
||||
" Required for Philips P2000C.\n" <<
|
||||
" Respond to very short duration selection attempts. This supports\n" <<
|
||||
" non-standard hardware, but is generally safe to enable.\n" <<
|
||||
" Required for Philips P2000C.\n" <<
|
||||
" ********************************************************* -->\n" <<
|
||||
" <selLatch>" <<
|
||||
(config.flags & CONFIG_ENABLE_SEL_LATCH? "true" : "false") <<
|
||||
@ -328,12 +358,12 @@ ConfigUtil::toXML(const BoardConfig& config)
|
||||
|
||||
|
||||
" <!-- ********************************************************\n" <<
|
||||
" Convert luns to IDs. The unit must already be configured to respond\n" <<
|
||||
" on the ID. Allows dual drives to be accessed from a \n" <<
|
||||
" XEBEC S1410 SASI bridge.\n" <<
|
||||
" eg. Configured for dual drives as IDs 0 and 1, but the XEBEC will\n" <<
|
||||
" access the second disk as ID0, lun 1.\n" <<
|
||||
" See ttp://bitsavers.trailing-edge.com/pdf/xebec/104524C_S1410Man_Aug83.pdf\n" <<
|
||||
" Convert luns to IDs. The unit must already be configured to respond\n" <<
|
||||
" on the ID. Allows dual drives to be accessed from a \n" <<
|
||||
" XEBEC S1410 SASI bridge.\n" <<
|
||||
" eg. Configured for dual drives as IDs 0 and 1, but the XEBEC will\n" <<
|
||||
" access the second disk as ID0, lun 1.\n" <<
|
||||
" See ttp://bitsavers.trailing-edge.com/pdf/xebec/104524C_S1410Man_Aug83.pdf\n" <<
|
||||
" ********************************************************* -->\n" <<
|
||||
" <mapLunsToIds>" <<
|
||||
(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();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user