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'
|
'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()
|
void scsiInquiry()
|
||||||
{
|
{
|
||||||
uint8 evpd = scsiDev.cdb[1] & 1; // enable vital product data.
|
uint8 evpd = scsiDev.cdb[1] & 1; // enable vital product data.
|
||||||
@ -127,6 +158,10 @@ void scsiInquiry()
|
|||||||
scsiDev.phase = DATA_IN;
|
scsiDev.phase = DATA_IN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (scsiDev.target->cfg->vpd[3] != 0)
|
||||||
|
{
|
||||||
|
useCustomVPD(scsiDev.target->cfg, pageCode);
|
||||||
|
}
|
||||||
else if (pageCode == 0x00)
|
else if (pageCode == 0x00)
|
||||||
{
|
{
|
||||||
memcpy(scsiDev.data, SupportedVitalPages, sizeof(SupportedVitalPages));
|
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 found = 0;
|
||||||
int cfgIdx = 0;
|
int cfgIdx = 0;
|
||||||
while ((cfgIdx < sizeof(cfg->modePages) + 2) &&
|
while ((cfgIdx < sizeof(cfg->modePages) - 2) &&
|
||||||
(cfg->modePages[cfgIdx + 1] != 0)
|
(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 reserved[960]; // Pad out to 1024 bytes for main section.
|
||||||
|
|
||||||
uint8_t modePages[1024];
|
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;
|
} TargetConfig;
|
||||||
|
|
||||||
typedef struct __attribute__((packed))
|
typedef struct __attribute__((packed))
|
||||||
|
@ -90,7 +90,7 @@ namespace
|
|||||||
{
|
{
|
||||||
std::vector<uint8_t> result;
|
std::vector<uint8_t> result;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (i < sizeof(cfg.modePages) + 2)
|
while (i < sizeof(cfg.modePages) - 2)
|
||||||
{
|
{
|
||||||
int pageLen = cfg.modePages[i+1];
|
int pageLen = cfg.modePages[i+1];
|
||||||
if (pageLen == 0) break;
|
if (pageLen == 0) break;
|
||||||
@ -102,6 +102,23 @@ namespace
|
|||||||
}
|
}
|
||||||
return result;
|
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
|
BoardConfig
|
||||||
@ -217,6 +234,7 @@ ConfigUtil::toXML(const TargetConfig& config)
|
|||||||
{
|
{
|
||||||
std::stringstream s;
|
std::stringstream s;
|
||||||
std::vector<uint8_t> modePages(getModePages(config));
|
std::vector<uint8_t> modePages(getModePages(config));
|
||||||
|
std::vector<uint8_t> vpd(getVPDPages(config));
|
||||||
|
|
||||||
s <<
|
s <<
|
||||||
"<SCSITarget id=\"" <<
|
"<SCSITarget id=\"" <<
|
||||||
@ -299,6 +317,13 @@ ConfigUtil::toXML(const TargetConfig& config)
|
|||||||
wxBase64Encode(&modePages[0], modePages.size())) <<
|
wxBase64Encode(&modePages[0], modePages.size())) <<
|
||||||
"\n" <<
|
"\n" <<
|
||||||
" </modePages>\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";
|
"</SCSITarget>\n";
|
||||||
|
|
||||||
return s.str();
|
return s.str();
|
||||||
@ -511,6 +536,15 @@ parseTarget(wxXmlNode* node)
|
|||||||
size_t len = std::min(buf.GetDataLen(), sizeof(result.modePages));
|
size_t len = std::min(buf.GetDataLen(), sizeof(result.modePages));
|
||||||
memcpy(result.modePages, buf.GetData(), len);
|
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();
|
child = child->GetNext();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user