diff --git a/src/raspberrypi/devices/disk.cpp b/src/raspberrypi/devices/disk.cpp index 9dd55c55..db14051f 100644 --- a/src/raspberrypi/devices/disk.cpp +++ b/src/raspberrypi/devices/disk.cpp @@ -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,20 +793,21 @@ void Disk::Seek(SASIDEV *controller) controller->Status(); } -//--------------------------------------------------------------------------- -// -// SEEK(6) -// Does not check LBA (SASI IOCS) -// -//--------------------------------------------------------------------------- void Disk::Seek6(SASIDEV *controller) { - Seek(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) { - Seek(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; diff --git a/src/raspberrypi/devices/disk.h b/src/raspberrypi/devices/disk.h index 68fa3059..47109c5c 100644 --- a/src/raspberrypi/devices/disk.h +++ b/src/raspberrypi/devices/disk.h @@ -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 sector_sizes; diff --git a/src/raspberrypi/devices/host_services.cpp b/src/raspberrypi/devices/host_services.cpp index f5dd0d75..18368ae5 100644 --- a/src/raspberrypi/devices/host_services.cpp +++ b/src/raspberrypi/devices/host_services.cpp @@ -59,7 +59,7 @@ void HostServices::TestUnitReady(SCSIDEV *controller) vector 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) diff --git a/src/raspberrypi/devices/primary_device.cpp b/src/raspberrypi/devices/primary_device.cpp index cd9a1742..c1d6a6b5 100644 --- a/src/raspberrypi/devices/primary_device.cpp +++ b/src/raspberrypi/devices/primary_device.cpp @@ -82,15 +82,19 @@ void PrimaryDevice::ReportLuns(SASIDEV *controller) memset(buf, 0, allocation_length); int size = 0; - for (int lun = 0; lun < controller->GetCtrl()->device->GetSupportedLuns(); lun++) { - if (controller->GetCtrl()->unit[lun]) { - size += 8; - buf[size + 7] = lun; - } - } - buf[2] = size >> 8; - buf[3] = size; + // 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; + buf[size + 7] = lun; + } + } + + buf[2] = size >> 8; + buf[3] = size; + } size += 8; diff --git a/src/raspberrypi/scsi.h b/src/raspberrypi/scsi.h index e5f1ac20..f8cb6f80 100644 --- a/src/raspberrypi/scsi.h +++ b/src/raspberrypi/scsi.h @@ -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 };