mirror of
https://github.com/akuker/RASCSI.git
synced 2024-12-23 21:29:30 +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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO For SCSI the specification mandates that the block address is verified
|
|
||||||
void Disk::Seek(SASIDEV *controller)
|
void Disk::Seek(SASIDEV *controller)
|
||||||
{
|
{
|
||||||
if (!CheckReady()) {
|
if (!CheckReady()) {
|
||||||
@ -794,21 +793,22 @@ void Disk::Seek(SASIDEV *controller)
|
|||||||
controller->Status();
|
controller->Status();
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// SEEK(6)
|
|
||||||
// Does not check LBA (SASI IOCS)
|
|
||||||
//
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
void Disk::Seek6(SASIDEV *controller)
|
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);
|
Seek(controller);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Disk::Seek10(SASIDEV *controller)
|
void Disk::Seek10(SASIDEV *controller)
|
||||||
{
|
{
|
||||||
|
uint64_t start;
|
||||||
|
if (GetStartAndCount(controller, start, ctrl->blocks, SEEK10)) {
|
||||||
Seek(controller);
|
Seek(controller);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Disk::StartStop(const DWORD *cdb)
|
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)
|
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 = ctrl->cmd[1] & 0x1f;
|
||||||
start <<= 8;
|
start <<= 8;
|
||||||
start |= ctrl->cmd[2];
|
start |= ctrl->cmd[2];
|
||||||
@ -1044,26 +1044,29 @@ bool Disk::GetStartAndCount(SASIDEV *controller, uint64_t& start, uint32_t& coun
|
|||||||
count <<= 8;
|
count <<= 8;
|
||||||
count |= ctrl->cmd[13];
|
count |= ctrl->cmd[13];
|
||||||
}
|
}
|
||||||
else {
|
else if (mode != SEEK6 && mode != SEEK10) {
|
||||||
count = ctrl->cmd[7];
|
count = ctrl->cmd[7];
|
||||||
count <<= 8;
|
count <<= 8;
|
||||||
count |= ctrl->cmd[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
|
// Check capacity
|
||||||
uint64_t capacity = GetBlockCount();
|
uint64_t capacity = GetBlockCount();
|
||||||
if (start > capacity || start + count > capacity) {
|
if (start > capacity || start + count > capacity) {
|
||||||
LOGTRACE("%s", ("Capacity of " + to_string(capacity) + " blocks exceeded: Trying to access block "
|
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);
|
controller->Error(sense_key::ILLEGAL_REQUEST, asc::LBA_OUT_OF_RANGE);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not process 0 blocks
|
// Do not process 0 blocks
|
||||||
if (!count) {
|
if (!count && (mode != SEEK6 && mode != SEEK10)) {
|
||||||
LOGTRACE("NOT processing 0 blocks");
|
LOGTRACE("NOT processing 0 blocks");
|
||||||
controller->Status();
|
controller->Status();
|
||||||
return false;
|
return false;
|
||||||
|
@ -36,7 +36,7 @@ using namespace std;
|
|||||||
class Disk : public ModePageDevice, ScsiBlockCommands
|
class Disk : public ModePageDevice, ScsiBlockCommands
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
enum access_mode { RW6, RW10, RW16 };
|
enum access_mode { RW6, RW10, RW16, SEEK6, SEEK10 };
|
||||||
|
|
||||||
// The supported configurable block sizes, empty if not configurable
|
// The supported configurable block sizes, empty if not configurable
|
||||||
unordered_set<uint32_t> sector_sizes;
|
unordered_set<uint32_t> sector_sizes;
|
||||||
|
@ -59,7 +59,7 @@ void HostServices::TestUnitReady(SCSIDEV *controller)
|
|||||||
|
|
||||||
vector<BYTE> HostServices::Inquiry() const
|
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)
|
void HostServices::StartStopUnit(SCSIDEV *controller)
|
||||||
|
@ -82,6 +82,9 @@ void PrimaryDevice::ReportLuns(SASIDEV *controller)
|
|||||||
memset(buf, 0, allocation_length);
|
memset(buf, 0, allocation_length);
|
||||||
|
|
||||||
int size = 0;
|
int size = 0;
|
||||||
|
|
||||||
|
// Only SELECT REPORT mode 0 is supported
|
||||||
|
if (!ctrl->cmd[2]) {
|
||||||
for (int lun = 0; lun < controller->GetCtrl()->device->GetSupportedLuns(); lun++) {
|
for (int lun = 0; lun < controller->GetCtrl()->device->GetSupportedLuns(); lun++) {
|
||||||
if (controller->GetCtrl()->unit[lun]) {
|
if (controller->GetCtrl()->unit[lun]) {
|
||||||
size += 8;
|
size += 8;
|
||||||
@ -91,6 +94,7 @@ void PrimaryDevice::ReportLuns(SASIDEV *controller)
|
|||||||
|
|
||||||
buf[2] = size >> 8;
|
buf[2] = size >> 8;
|
||||||
buf[3] = size;
|
buf[3] = size;
|
||||||
|
}
|
||||||
|
|
||||||
size += 8;
|
size += 8;
|
||||||
|
|
||||||
|
@ -127,6 +127,10 @@ namespace scsi_defs {
|
|||||||
enum scsi_level : int {
|
enum scsi_level : int {
|
||||||
SCSI_1_CCS = 1,
|
SCSI_1_CCS = 1,
|
||||||
SCSI_2 = 2,
|
SCSI_2 = 2,
|
||||||
|
SPC = 3,
|
||||||
|
SPC_2 = 4,
|
||||||
|
SPC_3 = 5,
|
||||||
|
SPC_4 = 6,
|
||||||
SPC_5 = 7
|
SPC_5 = 7
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user