Validate SEEK block address (#719)

* Validate SEEK block address

* Ignore block count for SEEK

* Updated REPORT LUNS
This commit is contained in:
Uwe Seimet 2022-03-03 19:53:11 +01:00 committed by GitHub
parent 305a7fb99d
commit af9638ce48
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 35 additions and 24 deletions

View File

@ -783,7 +783,6 @@ bool Disk::Write(const DWORD *cdb, const BYTE *buf, DWORD block)
return true;
}
// TODO For SCSI the specification mandates that the block address is verified
void Disk::Seek(SASIDEV *controller)
{
if (!CheckReady()) {
@ -794,21 +793,22 @@ void Disk::Seek(SASIDEV *controller)
controller->Status();
}
//---------------------------------------------------------------------------
//
// SEEK(6)
// Does not check LBA (SASI IOCS)
//
//---------------------------------------------------------------------------
void Disk::Seek6(SASIDEV *controller)
{
// For SASI do not check LBA (SASI IOCS)
uint64_t start;
if (IsSASIHD() || GetStartAndCount(controller, start, ctrl->blocks, SEEK6)) {
Seek(controller);
}
}
void Disk::Seek10(SASIDEV *controller)
{
uint64_t start;
if (GetStartAndCount(controller, start, ctrl->blocks, SEEK10)) {
Seek(controller);
}
}
bool Disk::StartStop(const DWORD *cdb)
{
@ -1003,7 +1003,7 @@ bool Disk::ValidateBlockAddress(SASIDEV *controller, access_mode mode)
bool Disk::GetStartAndCount(SASIDEV *controller, uint64_t& start, uint32_t& count, access_mode mode)
{
if (mode == RW6) {
if (mode == RW6 || mode == SEEK6) {
start = ctrl->cmd[1] & 0x1f;
start <<= 8;
start |= ctrl->cmd[2];
@ -1044,26 +1044,29 @@ bool Disk::GetStartAndCount(SASIDEV *controller, uint64_t& start, uint32_t& coun
count <<= 8;
count |= ctrl->cmd[13];
}
else {
else if (mode != SEEK6 && mode != SEEK10) {
count = ctrl->cmd[7];
count <<= 8;
count |= ctrl->cmd[8];
}
else {
count = 0;
}
}
LOGTRACE("%s READ/WRITE/VERIFY command record=$%08X blocks=%d", __PRETTY_FUNCTION__, (uint32_t)start, count);
LOGTRACE("%s READ/WRITE/VERIFY/SEEK command record=$%08X blocks=%d", __PRETTY_FUNCTION__, (uint32_t)start, count);
// Check capacity
uint64_t capacity = GetBlockCount();
if (start > capacity || start + count > capacity) {
LOGTRACE("%s", ("Capacity of " + to_string(capacity) + " blocks exceeded: Trying to access block "
+ to_string(start) + ", block count " + to_string(ctrl->blocks)).c_str());
+ to_string(start) + ", block count " + to_string(count)).c_str());
controller->Error(sense_key::ILLEGAL_REQUEST, asc::LBA_OUT_OF_RANGE);
return false;
}
// Do not process 0 blocks
if (!count) {
if (!count && (mode != SEEK6 && mode != SEEK10)) {
LOGTRACE("NOT processing 0 blocks");
controller->Status();
return false;

View File

@ -36,7 +36,7 @@ using namespace std;
class Disk : public ModePageDevice, ScsiBlockCommands
{
private:
enum access_mode { RW6, RW10, RW16 };
enum access_mode { RW6, RW10, RW16, SEEK6, SEEK10 };
// The supported configurable block sizes, empty if not configurable
unordered_set<uint32_t> sector_sizes;

View File

@ -59,7 +59,7 @@ void HostServices::TestUnitReady(SCSIDEV *controller)
vector<BYTE> HostServices::Inquiry() const
{
return PrimaryDevice::Inquiry(device_type::PROCESSOR, scsi_level::SPC_5, false);
return PrimaryDevice::Inquiry(device_type::PROCESSOR, scsi_level::SPC_3, false);
}
void HostServices::StartStopUnit(SCSIDEV *controller)

View File

@ -82,6 +82,9 @@ void PrimaryDevice::ReportLuns(SASIDEV *controller)
memset(buf, 0, allocation_length);
int size = 0;
// Only SELECT REPORT mode 0 is supported
if (!ctrl->cmd[2]) {
for (int lun = 0; lun < controller->GetCtrl()->device->GetSupportedLuns(); lun++) {
if (controller->GetCtrl()->unit[lun]) {
size += 8;
@ -91,6 +94,7 @@ void PrimaryDevice::ReportLuns(SASIDEV *controller)
buf[2] = size >> 8;
buf[3] = size;
}
size += 8;

View File

@ -127,6 +127,10 @@ namespace scsi_defs {
enum scsi_level : int {
SCSI_1_CCS = 1,
SCSI_2 = 2,
SPC = 3,
SPC_2 = 4,
SPC_3 = 5,
SPC_4 = 6,
SPC_5 = 7
};