mirror of
https://github.com/fhgwright/SCSI2SD.git
synced 2025-02-06 15:29:56 +00:00
Allow custom VPD pages
This commit is contained in:
parent
760222798c
commit
8dc9a838f5
@ -93,6 +93,37 @@ static const uint8 AscImpOperatingDefinition[] =
|
||||
'S','C','S','I','-','2'
|
||||
};
|
||||
|
||||
static void useCustomVPD(const TargetConfig* cfg, int pageCode)
|
||||
{
|
||||
int cfgIdx = 0;
|
||||
int found = 0;
|
||||
while ((cfgIdx < sizeof(cfg->vpd) - 4) &&
|
||||
(cfg->vpd[cfgIdx + 3] != 0)
|
||||
)
|
||||
{
|
||||
int pageSize = cfg->vpd[cfgIdx + 3] + 4;
|
||||
int dataPageCode = cfg->vpd[cfgIdx + 1];
|
||||
if (dataPageCode == pageCode)
|
||||
{
|
||||
memcpy(scsiDev.data, &(cfg->vpd[cfgIdx]), pageSize);
|
||||
scsiDev.dataLen = pageSize;
|
||||
scsiDev.phase = DATA_IN;
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
cfgIdx += pageSize;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
// error.
|
||||
scsiDev.status = CHECK_CONDITION;
|
||||
scsiDev.target->sense.code = ILLEGAL_REQUEST;
|
||||
scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
|
||||
scsiDev.phase = STATUS;
|
||||
}
|
||||
}
|
||||
|
||||
void scsiInquiry()
|
||||
{
|
||||
uint8 evpd = scsiDev.cdb[1] & 1; // enable vital product data.
|
||||
@ -127,6 +158,10 @@ void scsiInquiry()
|
||||
scsiDev.phase = DATA_IN;
|
||||
}
|
||||
}
|
||||
else if (scsiDev.target->cfg->vpd[3] != 0)
|
||||
{
|
||||
useCustomVPD(scsiDev.target->cfg, pageCode);
|
||||
}
|
||||
else if (pageCode == 0x00)
|
||||
{
|
||||
memcpy(scsiDev.data, SupportedVitalPages, sizeof(SupportedVitalPages));
|
||||
|
@ -197,11 +197,11 @@ static void pageIn(int pc, int dataIdx, const uint8* pageData, int pageLen)
|
||||
}
|
||||
}
|
||||
|
||||
static int useCustomPages(TargetConfig* cfg, int pc, int pageCode, int* idx)
|
||||
static int useCustomPages(const TargetConfig* cfg, int pc, int pageCode, int* idx)
|
||||
{
|
||||
int found = 0;
|
||||
int cfgIdx = 0;
|
||||
while ((cfgIdx < sizeof(cfg->modePages) + 2) &&
|
||||
while ((cfgIdx < sizeof(cfg->modePages) - 2) &&
|
||||
(cfg->modePages[cfgIdx + 1] != 0)
|
||||
)
|
||||
{
|
||||
|
@ -154,7 +154,8 @@ typedef struct __attribute__((packed))
|
||||
uint8_t reserved[960]; // Pad out to 1024 bytes for main section.
|
||||
|
||||
uint8_t modePages[1024];
|
||||
uint8_t unused[2048]; // Total size is 4k.
|
||||
uint8_t vpd[1024];
|
||||
uint8_t unused[1024]; // Total size is 4k.
|
||||
} TargetConfig;
|
||||
|
||||
typedef struct __attribute__((packed))
|
||||
|
@ -90,7 +90,7 @@ namespace
|
||||
{
|
||||
std::vector<uint8_t> result;
|
||||
int i = 0;
|
||||
while (i < sizeof(cfg.modePages) + 2)
|
||||
while (i < sizeof(cfg.modePages) - 2)
|
||||
{
|
||||
int pageLen = cfg.modePages[i+1];
|
||||
if (pageLen == 0) break;
|
||||
@ -102,6 +102,23 @@ namespace
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> getVPDPages(const TargetConfig& cfg)
|
||||
{
|
||||
std::vector<uint8_t> result;
|
||||
int i = 0;
|
||||
while (i < sizeof(cfg.vpd) - 4)
|
||||
{
|
||||
int pageLen = cfg.vpd[i+3];
|
||||
if (pageLen == 0) break;
|
||||
std::copy(
|
||||
&cfg.vpd[i],
|
||||
&cfg.vpd[i+pageLen+4],
|
||||
std::back_inserter(result));
|
||||
i += pageLen + 4;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
BoardConfig
|
||||
@ -217,6 +234,7 @@ ConfigUtil::toXML(const TargetConfig& config)
|
||||
{
|
||||
std::stringstream s;
|
||||
std::vector<uint8_t> modePages(getModePages(config));
|
||||
std::vector<uint8_t> vpd(getVPDPages(config));
|
||||
|
||||
s <<
|
||||
"<SCSITarget id=\"" <<
|
||||
@ -299,6 +317,13 @@ ConfigUtil::toXML(const TargetConfig& config)
|
||||
wxBase64Encode(&modePages[0], modePages.size())) <<
|
||||
"\n" <<
|
||||
" </modePages>\n" <<
|
||||
"\n" <<
|
||||
" <!-- Custom inquiry VPD pages, base64 encoded, up to 1024 bytes.-->\n" <<
|
||||
" <vpd>\n" <<
|
||||
(vpd.size() == 0 ? "" :
|
||||
wxBase64Encode(&vpd[0], vpd.size())) <<
|
||||
"\n" <<
|
||||
" </vpd>\n" <<
|
||||
"</SCSITarget>\n";
|
||||
|
||||
return s.str();
|
||||
@ -511,6 +536,15 @@ parseTarget(wxXmlNode* node)
|
||||
size_t len = std::min(buf.GetDataLen(), sizeof(result.modePages));
|
||||
memcpy(result.modePages, buf.GetData(), len);
|
||||
}
|
||||
else if (child->GetName() == "vpd")
|
||||
{
|
||||
wxMemoryBuffer buf =
|
||||
wxBase64Decode(child->GetNodeContent(), wxBase64DecodeMode_SkipWS);
|
||||
size_t len = std::min(buf.GetDataLen(), sizeof(result.vpd));
|
||||
memcpy(result.vpd, buf.GetData(), len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
child = child->GetNext();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user