Skip to content

Commit

Permalink
Update handling of allocation length for SCSI-1-CCS, update tape erro…
Browse files Browse the repository at this point in the history
…r code
  • Loading branch information
uweseimet committed Oct 26, 2024
1 parent 5ec9d7f commit d239b81
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 10 deletions.
6 changes: 5 additions & 1 deletion cpp/base/primary_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,11 @@ void PrimaryDevice::RequestSense()

const vector<byte> &buf = GetController()->GetDeviceForLun(effective_lun)->HandleRequestSense();

const auto length = static_cast<int>(min(buf.size(), static_cast<size_t>(GetCdbByte(4))));
int allocation_length = GetCdbByte(4);
if (!allocation_length && level == scsi_level::scsi_1_ccs) {
allocation_length = 4;
}
const auto length = static_cast<int>(min(buf.size(), static_cast<size_t>(allocation_length)));
GetController()->CopyToBuffer(buf.data(), length);

// Clear the previous status
Expand Down
24 changes: 18 additions & 6 deletions cpp/devices/tape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ int Tape::WriteData(span<const uint8_t> buf, scsi_command)
const int length = GetController()->GetChunkSize();

if (static_cast<off_t>(position + length) > GetFileSize()) {
throw scsi_exception(sense_key::blank_check);
throw scsi_exception(sense_key::volume_overflow);
}

if (!tar_mode) {
Expand Down Expand Up @@ -291,7 +291,7 @@ void Tape::SetUpModePages(map<int, vector<byte>> &pages, int page, bool changeab
AddDeviceConfigurationPage(pages, changeable);
}

// Page 17 (medium partition page)
// Page 17 (medium partition page 1)
if (page == 0x11 || page == 0x3f) {
AddMediumPartitionPage(pages, changeable);
}
Expand Down Expand Up @@ -342,11 +342,23 @@ void Tape::AddDeviceConfigurationPage(map<int, vector<byte>> &pages, bool change

void Tape::AddMediumPartitionPage(map<int, vector<byte> > &pages, bool changeable) const
{
vector<byte> buf(8);
vector<byte> buf(10);

if (!changeable) {
// Fixed data partitions, PSUM (descriptor unit in MB)
buf[4] = (byte)0b10010000;
// Maximum additional partitions
buf[2] = (byte)1;

// PSUM (descriptor unit in MB)
buf[4] = (byte)0b00010000;

// Logical unit is capable of format and partition recognition
buf[5] = (byte)0x03;

// Approximate partition size in MB
if (IsReady()) {
const auto capacity = static_cast<uint32_t>(GetFileSize()) / 1048576;
SetInt16(buf, 8, capacity > 0 ? capacity : 1);
}
}

pages[17] = buf;
Expand Down Expand Up @@ -560,7 +572,7 @@ void Tape::WriteMetaData(Tape::object_type type, uint32_t size)
assert(size < 65536);

if (static_cast<off_t>(position + sizeof(meta_data_t)) > GetFileSize()) {
throw scsi_exception(sense_key::blank_check);
throw scsi_exception(sense_key::volume_overflow);
}

meta_data_t meta_data;
Expand Down
9 changes: 8 additions & 1 deletion cpp/test/host_services_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ TEST(HostServicesTest, ExecuteOperation)
controller->SetCdbByte(1, 0b001);
TestShared::Dispatch(*services, scsi_command::execute_operation, sense_key::illegal_request,
asc::invalid_field_in_cdb, "Illegal length");

controller->SetCdbByte(8, 1);
EXPECT_NO_THROW(services->Dispatch(scsi_command::execute_operation));
}

TEST(HostServicesTest, ReceiveOperationResults)
Expand Down Expand Up @@ -203,6 +206,10 @@ TEST(HostServicesTest, SetUpModePages)
TEST(HostServicesTest, WriteData)
{
auto [controller, services] = CreateDevice(SCHS);
array<uint8_t, 1> buf = { };

EXPECT_EQ(0, services->WriteData(buf, scsi_command::execute_operation));

EXPECT_EQ(0, services->WriteData( { }, scsi_command::execute_operation));
controller->SetCdbByte(8, 1);
EXPECT_THROW(services->WriteData(buf, scsi_command::execute_operation), scsi_exception)<< "protobuf data are invalid";
}
1 change: 1 addition & 0 deletions cpp/test/mocks.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ class MockAbstractController : public AbstractController // NOSONAR Having many
FRIEND_TEST(HostServicesTest, StartStopUnit);
FRIEND_TEST(HostServicesTest, ExecuteOperation);
FRIEND_TEST(HostServicesTest, ReceiveOperationResults);
FRIEND_TEST(HostServicesTest, WriteData);
FRIEND_TEST(HostServicesTest, ModeSense6);
FRIEND_TEST(HostServicesTest, ModeSense10);
FRIEND_TEST(HostServicesTest, SetUpModePages);
Expand Down
4 changes: 2 additions & 2 deletions cpp/test/tape_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ static void ValidateModePages(map<int, vector<byte>> &pages)
EXPECT_EQ(8U, pages[10].size());
EXPECT_EQ(14U, pages[15].size());
EXPECT_EQ(16U, pages[16].size());
EXPECT_EQ(8U, pages[17].size());
EXPECT_EQ(10U, pages[17].size());
}

static void CheckPosition(AbstractController &controller, PrimaryDevice &tape, uint32_t position)
Expand Down Expand Up @@ -278,7 +278,7 @@ TEST(TapeTest, WriteFileMarks6)

// Count > 0
controller->SetCdbByte(2, 1);
TestShared::Dispatch(*tape, scsi_command::write_filemarks6, sense_key::blank_check,
TestShared::Dispatch(*tape, scsi_command::write_filemarks6, sense_key::volume_overflow,
asc::no_additional_sense_information);

tape->SetProtected(true);
Expand Down

0 comments on commit d239b81

Please sign in to comment.