'S','C','S','I','-','2'\r
};\r
\r
+static void useCustomVPD(const TargetConfig* cfg, int pageCode)\r
+{\r
+ int cfgIdx = 0;\r
+ int found = 0;\r
+ while ((cfgIdx < sizeof(cfg->vpd) - 4) &&\r
+ (cfg->vpd[cfgIdx + 3] != 0)\r
+ )\r
+ {\r
+ int pageSize = cfg->vpd[cfgIdx + 3] + 4;\r
+ int dataPageCode = cfg->vpd[cfgIdx + 1];\r
+ if (dataPageCode == pageCode)\r
+ {\r
+ memcpy(scsiDev.data, &(cfg->vpd[cfgIdx]), pageSize);\r
+ scsiDev.dataLen = pageSize;\r
+ scsiDev.phase = DATA_IN;\r
+ found = 1;\r
+ break;\r
+ }\r
+ cfgIdx += pageSize;\r
+ }\r
+\r
+ if (!found)\r
+ {\r
+ // error.\r
+ scsiDev.status = CHECK_CONDITION;\r
+ scsiDev.target->sense.code = ILLEGAL_REQUEST;\r
+ scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;\r
+ scsiDev.phase = STATUS;\r
+ }\r
+}\r
+\r
void scsiInquiry()\r
{\r
uint8 evpd = scsiDev.cdb[1] & 1; // enable vital product data.\r
scsiDev.phase = DATA_IN;\r
}\r
}\r
+ else if (scsiDev.target->cfg->vpd[3] != 0)\r
+ {\r
+ useCustomVPD(scsiDev.target->cfg, pageCode);\r
+ }\r
else if (pageCode == 0x00)\r
{\r
memcpy(scsiDev.data, SupportedVitalPages, sizeof(SupportedVitalPages));\r
}\r
}\r
\r
-static int useCustomPages(TargetConfig* cfg, int pc, int pageCode, int* idx)\r
+static int useCustomPages(const TargetConfig* cfg, int pc, int pageCode, int* idx)\r
{\r
int found = 0;\r
int cfgIdx = 0;\r
- while ((cfgIdx < sizeof(cfg->modePages) + 2) &&\r
+ while ((cfgIdx < sizeof(cfg->modePages) - 2) &&\r
(cfg->modePages[cfgIdx + 1] != 0)\r
)\r
{\r
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))
{
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;
}
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
{
std::stringstream s;
std::vector<uint8_t> modePages(getModePages(config));
+ std::vector<uint8_t> vpd(getVPDPages(config));
s <<
"<SCSITarget id=\"" <<
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();
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();
}