mirror of
https://github.com/akuker/RASCSI.git
synced 2024-12-23 06:30:04 +00:00
Validate SEEK block address (#719)
* Validate SEEK block address * Ignore block count for SEEK * Updated REPORT LUNS
This commit is contained in:
parent
305a7fb99d
commit
af9638ce48
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user