diff --git a/cpp/devices/device_factory.cpp b/cpp/devices/device_factory.cpp index f4f036cf..f34bd78e 100644 --- a/cpp/devices/device_factory.cpp +++ b/cpp/devices/device_factory.cpp @@ -9,7 +9,6 @@ #include "shared/piscsi_util.h" #include "scsihd.h" -#include "scsihd_nec.h" #include "scsimo.h" #include "scsicd.h" #include "scsi_printer.h" @@ -46,16 +45,13 @@ shared_ptr DeviceFactory::CreateDevice(PbDeviceType type, int lun shared_ptr device; switch (type) { case SCHD: { - if (const string ext = GetExtensionLowerCase(filename); ext == "hdn" || ext == "hdi" || ext == "nhd") { - device = make_shared(lun); - } else { - device = make_shared(lun, false, ext == "hd1" ? scsi_level::scsi_1_ccs : scsi_level::scsi_2); - - // Some Apple tools require a particular drive identification - if (ext == "hda") { - device->SetVendor("QUANTUM"); - device->SetProduct("FIREBALL"); - } + const string ext = GetExtensionLowerCase(filename); + device = make_shared(lun, false, ext == "hd1" ? scsi_level::scsi_1_ccs : scsi_level::scsi_2); + + // Some Apple tools require a particular drive identification + if (ext == "hda") { + device->SetVendor("QUANTUM"); + device->SetProduct("FIREBALL"); } break; } diff --git a/cpp/devices/device_factory.h b/cpp/devices/device_factory.h index acaf0e0f..253a56ae 100644 --- a/cpp/devices/device_factory.h +++ b/cpp/devices/device_factory.h @@ -39,9 +39,6 @@ class DeviceFactory { "hd1", SCHD }, { "hds", SCHD }, { "hda", SCHD }, - { "hdn", SCHD }, - { "hdi", SCHD }, - { "nhd", SCHD }, { "hdr", SCRM }, { "mos", SCMO }, { "is1", SCCD }, diff --git a/cpp/devices/scsihd_nec.cpp b/cpp/devices/scsihd_nec.cpp deleted file mode 100644 index 5592e95c..00000000 --- a/cpp/devices/scsihd_nec.cpp +++ /dev/null @@ -1,178 +0,0 @@ -//--------------------------------------------------------------------------- -// -// SCSI Target Emulator PiSCSI -// for Raspberry Pi -// -// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp) -// Copyright (C) 2014-2020 GIMONS -// Copyright (C) 2021-2023 Uwe Seimet -// Copyright (C) akuker -// -// Licensed under the BSD 3-Clause License. -// See LICENSE file in the project root folder. -// -//--------------------------------------------------------------------------- - -#include "shared/piscsi_util.h" -#include "shared/piscsi_exceptions.h" -#include "scsi_command_util.h" -#include "scsihd_nec.h" -#include - -using namespace piscsi_util; -using namespace scsi_command_util; - -void SCSIHD_NEC::Open() -{ - assert(!IsReady()); - - off_t size = GetFileSize(); - - array root_sector; - ifstream in(GetFilename(), ios::binary); - in.read(root_sector.data(), root_sector.size()); - if (!in.good() || size < static_cast(root_sector.size())) { - throw io_exception("Can't read NEC hard disk file root sector"); - } - - // Effective size must be a multiple of 512 - size = (size / 512) * 512; - - // Determine parameters by extension - const auto [image_size, sector_size] = SetParameters(root_sector, static_cast(size)); - - SetSectorSizeShiftCount(static_cast(size)); - - SetBlockCount(image_size >> GetSectorSizeShiftCount()); - - FinalizeSetup(image_offset); -} - -pair SCSIHD_NEC::SetParameters(span data, int size) -{ - array root_sector = {}; - memcpy(root_sector.data(), data.data(), root_sector.size()); - - int image_size; - int sector_size; - - // PC-9801-55 NEC compatible? - if (const string ext = GetExtensionLowerCase(GetFilename()); ext == "hdn") { - // Assuming sector size 512, number of sectors 25, number of heads 8 as default settings - image_offset = 0; - image_size = size; - sector_size = 512; - sectors = 25; - heads = 8; - cylinders = size >> 9; - cylinders >>= 3; - cylinders /= 25; - } - // Anex86 HD image? - else if (ext == "hdi") { - image_offset = GetInt32LittleEndian(&root_sector[8]); - image_size = GetInt32LittleEndian(&root_sector[12]); - sector_size = GetInt32LittleEndian(&root_sector[16]); - sectors = GetInt32LittleEndian(&root_sector[20]); - heads = GetInt32LittleEndian(&root_sector[24]); - cylinders = GetInt32LittleEndian(&root_sector[28]); - } - // T98Next HD image? - else if (ext == "nhd") { - if (!memcmp(root_sector.data(), "T98HDDIMAGE.R0\0", 15)) { - image_offset = GetInt32LittleEndian(&root_sector[0x110]); - cylinders = GetInt32LittleEndian(&root_sector[0x114]); - heads = GetInt16LittleEndian(&root_sector[0x118]); - sectors = GetInt16LittleEndian(&root_sector[0x11a]); - sector_size = GetInt16LittleEndian(&root_sector[0x11c]); - image_size = static_cast(static_cast(cylinders * heads * sectors * sector_size)); - } - else { - throw io_exception("Invalid NEC image file format"); - } - } - else { - throw io_exception("Invalid NEC image file extension"); - } - - if (sector_size == 0) { - throw io_exception("Invalid NEC sector size 0"); - } - - // Image size consistency check - if (image_offset + image_size > size) { - throw io_exception("NEC image offset/size consistency check failed"); - } - - if (CalculateShiftCount(sector_size) == 0) { - throw io_exception("Invalid NEC sector size of " + to_string(sector_size) + " byte(s)"); - } - - return { image_size, sector_size }; -} - -vector SCSIHD_NEC::InquiryInternal() const -{ - return HandleInquiry(device_type::direct_access, scsi_level::scsi_1_ccs, false); -} - -void SCSIHD_NEC::AddFormatPage(map>& pages, bool changeable) const -{ - vector buf(24); - - // Page can be saved - buf[0] = (byte)0x80; - - // Make the number of bytes in the physical sector appear mutable (although it cannot actually be) - if (changeable) { - SetInt16(buf, 0x0c, -1); - - pages[3] = buf; - - return; - } - - if (IsReady()) { - // Set the number of tracks in one zone (PC-9801-55 seems to see this value) - SetInt16(buf, 0x02, heads); - - // Set the number of sectors per track - SetInt16(buf, 0x0a, sectors); - - // Set the number of bytes in the physical sector - SetInt16(buf, 0x0c, GetSectorSizeInBytes()); - } - - // Set removable attributes (remains of the old days) - if (IsRemovable()) { - buf[20] = (byte)0x20; - } - - pages[3] = buf; -} - -void SCSIHD_NEC::AddDrivePage(map>& pages, bool changeable) const -{ - vector buf(20); - - // No changeable area - if (!changeable && IsReady()) { - // Set the number of cylinders - SetInt32(buf, 0x01, cylinders); - - // Set the number of heads - buf[0x5] = (byte)heads; - } - - pages[4] = buf; -} - -int SCSIHD_NEC::GetInt16LittleEndian(const uint8_t *buf) -{ - return (static_cast(buf[1]) << 8) | buf[0]; -} - -int SCSIHD_NEC::GetInt32LittleEndian(const uint8_t *buf) -{ - return (static_cast(buf[3]) << 24) | (static_cast(buf[2]) << 16) | (static_cast(buf[1]) << 8) | buf[0]; -} diff --git a/cpp/devices/scsihd_nec.h b/cpp/devices/scsihd_nec.h deleted file mode 100644 index 4c2fabe2..00000000 --- a/cpp/devices/scsihd_nec.h +++ /dev/null @@ -1,62 +0,0 @@ -//--------------------------------------------------------------------------- -// -// SCSI Target Emulator PiSCSI -// for Raspberry Pi -// -// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp) -// Copyright (C) 2014-2020 GIMONS -// Copyright (C) akuker -// -// Licensed under the BSD 3-Clause License. -// See LICENSE file in the project root folder. -// -// [ SCSI NEC Compatible Hard Disk] -// -//--------------------------------------------------------------------------- - -#pragma once - -#include "scsihd.h" -#include -#include -#include -#include - -using namespace std; - -//=========================================================================== -// -// SCSI hard disk (PC-9801-55 NEC compatible / Anex86 / T98Next) -// -//=========================================================================== -class SCSIHD_NEC : public SCSIHD //NOSONAR The inheritance hierarchy depth is acceptable in this case -{ -public: - - explicit SCSIHD_NEC(int lun) : SCSIHD(lun, false, scsi_level::scsi_1_ccs, { 512 }) {} - ~SCSIHD_NEC() override = default; - - void Open() override; - -protected: - - vector InquiryInternal() const override; - - void AddFormatPage(map>&, bool) const override; - void AddDrivePage(map>&, bool) const override; - -private: - - pair SetParameters(span, int); - - static int GetInt16LittleEndian(const uint8_t *); - static int GetInt32LittleEndian(const uint8_t *); - - // Image file offset - off_t image_offset = 0; - - // Geometry data - int cylinders = 0; - int heads = 0; - int sectors = 0; -}; diff --git a/cpp/hal/gpiobus.cpp b/cpp/hal/gpiobus.cpp index 897f6adb..64d99371 100644 --- a/cpp/hal/gpiobus.cpp +++ b/cpp/hal/gpiobus.cpp @@ -15,7 +15,7 @@ #include #include #include -#include +#include #ifdef __linux__ #include #endif @@ -25,54 +25,27 @@ using namespace std; bool GPIOBUS::Init(mode_e mode) { - GPIO_FUNCTION_TRACE - - // Save operation mode actmode = mode; return true; } -//--------------------------------------------------------------------------- -// -// Receive command handshake -// -//--------------------------------------------------------------------------- int GPIOBUS::CommandHandShake(vector &buf) { - // Only works in TARGET mode - assert(actmode == mode_e::TARGET); - - GPIO_FUNCTION_TRACE + assert(actmode == mode_e::TARGET); DisableIRQ(); - // Assert REQ signal - SetREQ(ON); - - // Wait for ACK signal - bool ret = WaitACK(ON); + SetREQ(true); - // Wait until the signal line stabilizes - SysTimer::SleepNsec(SCSI_DELAY_BUS_SETTLE_DELAY_NS); + bool ack = WaitACK(true); - // Get data buf[0] = GetDAT(); - // Disable REQ signal - SetREQ(OFF); + SetREQ(false); - // Timeout waiting for ACK assertion - if (!ret) { - EnableIRQ(); - return 0; - } - - // Wait for ACK to clear - ret = WaitACK(OFF); - - // Timeout waiting for ACK to clear - if (!ret) { + // Timeout waiting for ACK to change + if (!ack || !WaitACK(false)) { EnableIRQ(); return 0; } @@ -87,34 +60,27 @@ int GPIOBUS::CommandHandShake(vector &buf) // PiSCSI becomes ICD compatible by ignoring the prepended $1F byte before processing the CDB. if (buf[0] == 0x1F) { - SetREQ(ON); - - ret = WaitACK(ON); + SetREQ(true); - SysTimer::SleepNsec(SCSI_DELAY_BUS_SETTLE_DELAY_NS); + ack = WaitACK(true); // Get the actual SCSI command buf[0] = GetDAT(); - SetREQ(OFF); + SetREQ(false); - if (!ret) { - EnableIRQ(); - return 0; - } - - ret = WaitACK(OFF); - - if (!ret) { + // Timeout waiting for ACK to change + if (!ack || !WaitACK(false)) { EnableIRQ(); return 0; } } const int command_byte_count = GetCommandByteCount(buf[0]); - if (command_byte_count == 0) { + if (!command_byte_count) { EnableIRQ(); + // Unknown command return 0; } @@ -124,31 +90,16 @@ int GPIOBUS::CommandHandShake(vector &buf) for (bytes_received = 1; bytes_received < command_byte_count; bytes_received++) { ++offset; - // Assert REQ signal - SetREQ(ON); - - // Wait for ACK signal - ret = WaitACK(ON); + SetREQ(true); - // Wait until the signal line stabilizes - SysTimer::SleepNsec(SCSI_DELAY_BUS_SETTLE_DELAY_NS); + ack = WaitACK(true); - // Get data buf[offset] = GetDAT(); - // Clear the REQ signal - SetREQ(OFF); + SetREQ(false); - // Check for timeout waiting for ACK assertion - if (!ret) { - break; - } - - // Wait for ACK to clear - ret = WaitACK(OFF); - - // Check for timeout waiting for ACK to clear - if (!ret) { + // Timeout waiting for ACK to change + if (!ack || !WaitACK(false)) { break; } } @@ -158,63 +109,37 @@ int GPIOBUS::CommandHandShake(vector &buf) return bytes_received; } -//--------------------------------------------------------------------------- -// -// Data reception handshake -// -//--------------------------------------------------------------------------- +// Handshake for DATA IN and MESSAGE IN int GPIOBUS::ReceiveHandShake(uint8_t *buf, int count) { - GPIO_FUNCTION_TRACE - int i; + int bytes_received; - // Disable IRQs DisableIRQ(); if (actmode == mode_e::TARGET) { - for (i = 0; i < count; i++) { - // Assert the REQ signal - SetREQ(ON); + for (bytes_received = 0; bytes_received < count; bytes_received++) { + SetREQ(true); - // Wait for ACK - bool ret = WaitACK(ON); + const bool ack = WaitACK(true); - // Wait until the signal line stabilizes - SysTimer::SleepNsec(SCSI_DELAY_BUS_SETTLE_DELAY_NS); - - // Get data *buf = GetDAT(); - // Clear the REQ signal - SetREQ(OFF); - - // Check for timeout waiting for ACK signal - if (!ret) { - break; - } - - // Wait for ACK to clear - ret = WaitACK(OFF); + SetREQ(false); - // Check for timeout waiting for ACK to clear - if (!ret) { + // Timeout waiting for ACK to change + if (!ack || !WaitACK(false)) { break; } - // Advance the buffer pointer to receive the next byte buf++; } } else { - // Get phase Acquire(); - phase_t phase = GetPhase(); - - for (i = 0; i < count; i++) { - // Wait for the REQ signal to be asserted - bool ret = WaitREQ(ON); + const phase_t phase = GetPhase(); + for (bytes_received = 0; bytes_received < count; bytes_received++) { // Check for timeout waiting for REQ signal - if (!ret) { + if (!WaitREQ(true)) { break; } @@ -224,23 +149,16 @@ int GPIOBUS::ReceiveHandShake(uint8_t *buf, int count) break; } - // Wait until the signal line stabilizes - SysTimer::SleepNsec(SCSI_DELAY_BUS_SETTLE_DELAY_NS); - - // Get data *buf = GetDAT(); - // Assert the ACK signal - SetACK(ON); + SetACK(true); - // Wait for REQ to clear - ret = WaitREQ(OFF); + const bool req = WaitREQ(true); - // Clear the ACK signal - SetACK(OFF); + SetACK(false); // Check for timeout waiting for REQ to clear - if (!ret) { + if (!req) { break; } @@ -250,95 +168,71 @@ int GPIOBUS::ReceiveHandShake(uint8_t *buf, int count) break; } - // Advance the buffer pointer to receive the next byte buf++; } } - // Re-enable IRQ EnableIRQ(); - // Return the number of bytes received - return i; + return bytes_received; } -//--------------------------------------------------------------------------- -// -// Data transmission handshake -// -//--------------------------------------------------------------------------- +// Handshake for DATA OUT and MESSAGE OUT int GPIOBUS::SendHandShake(uint8_t *buf, int count, int delay_after_bytes) { - GPIO_FUNCTION_TRACE - int i; + int bytes_sent; - // Disable IRQs DisableIRQ(); if (actmode == mode_e::TARGET) { - for (i = 0; i < count; i++) { - if (i == delay_after_bytes) { + for (bytes_sent = 0; bytes_sent < count; bytes_sent++) { + if (bytes_sent == delay_after_bytes) { spdlog::trace("DELAYING for " + to_string(SCSI_DELAY_SEND_DATA_DAYNAPORT_NS) + " ns after " + - to_string(delay_after_bytes) + " bytes"); + to_string(delay_after_bytes) + " bytes"); EnableIRQ(); const timespec ts = { .tv_sec = 0, .tv_nsec = SCSI_DELAY_SEND_DATA_DAYNAPORT_NS}; nanosleep(&ts, nullptr); DisableIRQ(); } - // Set the DATA signals SetDAT(*buf); - // Wait for ACK to clear - bool ret = WaitACK(OFF); - // Check for timeout waiting for ACK to clear - if (!ret) { + if (!WaitACK(false)) { break; } - // Already waiting for ACK to clear - - // Assert the REQ signal - SetREQ(ON); + SetREQ(true); - // Wait for ACK - ret = WaitACK(ON); + const bool ack = WaitACK(true); - // Clear REQ signal - SetREQ(OFF); + SetREQ(false); // Check for timeout waiting for ACK to clear - if (!ret) { + // TODO Do we really have to clear REQ here and everywhere else before checking this? + if (!ack) { break; } - // Advance the data buffer pointer to receive the next byte buf++; } - // Wait for ACK to clear - WaitACK(OFF); + WaitACK(false); } else { - // Get Phase Acquire(); - phase_t phase = GetPhase(); + const phase_t phase = GetPhase(); - for (i = 0; i < count; i++) { - // Set the DATA signals + for (bytes_sent = 0; bytes_sent < count; bytes_sent++) { SetDAT(*buf); - // Wait for REQ to be asserted - bool ret = WaitREQ(ON); - // Check for timeout waiting for REQ to be asserted - if (!ret) { + if (!WaitREQ(true)) { break; } - // Signal the last MESSAGE OUT byte - if (phase == phase_t::msgout && i == count - 1) { - SetATN(false); + // Signal the last MESSAGE OUT byte + if (phase == phase_t::msgout && bytes_sent == count - 1) { + SetATN(false); } // Phase error @@ -347,19 +241,14 @@ int GPIOBUS::SendHandShake(uint8_t *buf, int count, int delay_after_bytes) break; } - // Already waiting for REQ assertion - - // Assert the ACK signal - SetACK(ON); + SetACK(true); - // Wait for REQ to clear - ret = WaitREQ(OFF); + const bool req = WaitREQ(false); - // Clear the ACK signal - SetACK(OFF); + SetACK(true); // Check for timeout waiting for REQ to clear - if (!ret) { + if (!req) { break; } @@ -369,29 +258,20 @@ int GPIOBUS::SendHandShake(uint8_t *buf, int count, int delay_after_bytes) break; } - // Advance the data buffer pointer to receive the next byte buf++; } } - // Re-enable IRQ EnableIRQ(); - // Return number of transmissions - return i; + return bytes_sent; } -//--------------------------------------------------------------------------- -// -// SEL signal event polling -// -//--------------------------------------------------------------------------- bool GPIOBUS::PollSelectEvent() { #ifndef USE_SEL_EVENT_ENABLE return false; #else - GPIO_FUNCTION_TRACE errno = 0; if (epoll_event epev; epoll_wait(epfd, &epev, 1, -1) <= 0) { @@ -412,7 +292,7 @@ bool GPIOBUS::WaitSignal(int pin, bool ast) { const auto now = chrono::steady_clock::now(); - // Wait up to 3 s + // Wait for up to 3 s do { Acquire(); diff --git a/cpp/test/device_factory_test.cpp b/cpp/test/device_factory_test.cpp index 49ac25cd..807cfe1d 100644 --- a/cpp/test/device_factory_test.cpp +++ b/cpp/test/device_factory_test.cpp @@ -23,9 +23,6 @@ TEST(DeviceFactoryTest, GetTypeForFile) EXPECT_EQ(device_factory.GetTypeForFile("test.hds"), SCHD); EXPECT_EQ(device_factory.GetTypeForFile("test.HDS"), SCHD); EXPECT_EQ(device_factory.GetTypeForFile("test.hda"), SCHD); - EXPECT_EQ(device_factory.GetTypeForFile("test.hdn"), SCHD); - EXPECT_EQ(device_factory.GetTypeForFile("test.hdi"), SCHD); - EXPECT_EQ(device_factory.GetTypeForFile("test.nhd"), SCHD); EXPECT_EQ(device_factory.GetTypeForFile("test.hdr"), SCRM); EXPECT_EQ(device_factory.GetTypeForFile("test.mos"), SCMO); EXPECT_EQ(device_factory.GetTypeForFile("test.iso"), SCCD); @@ -43,13 +40,10 @@ TEST(DeviceFactoryTest, GetExtensionMapping) DeviceFactory device_factory; auto mapping = device_factory.GetExtensionMapping(); - EXPECT_EQ(10, mapping.size()); + EXPECT_EQ(7, mapping.size()); EXPECT_EQ(SCHD, mapping["hd1"]); EXPECT_EQ(SCHD, mapping["hds"]); EXPECT_EQ(SCHD, mapping["hda"]); - EXPECT_EQ(SCHD, mapping["hdn"]); - EXPECT_EQ(SCHD, mapping["hdi"]); - EXPECT_EQ(SCHD, mapping["nhd"]); EXPECT_EQ(SCRM, mapping["hdr"]); EXPECT_EQ(SCMO, mapping["mos"]); EXPECT_EQ(SCCD, mapping["iso"]); @@ -98,14 +92,6 @@ TEST(DeviceFactoryTest, SCHD_Device_Defaults) device = device_factory.CreateDevice(UNDEFINED, 0, "test.hds"); EXPECT_NE(nullptr, device); EXPECT_EQ(SCHD, device->GetType()); - - device = device_factory.CreateDevice(UNDEFINED, 0, "test.hdi"); - EXPECT_NE(nullptr, device); - EXPECT_EQ(SCHD, device->GetType()); - - device = device_factory.CreateDevice(UNDEFINED, 0, "test.nhd"); - EXPECT_NE(nullptr, device); - EXPECT_EQ(SCHD, device->GetType()); } void TestRemovableDrive(PbDeviceType type, const string& filename, const string& product) diff --git a/cpp/test/mocks.h b/cpp/test/mocks.h index ef7b49bf..f678d0fa 100644 --- a/cpp/test/mocks.h +++ b/cpp/test/mocks.h @@ -14,7 +14,7 @@ #include "test_shared.h" #include "hal/bus.h" #include "controllers/scsi_controller.h" -#include "devices/scsihd_nec.h" +#include "devices/scsihd.h" #include "devices/scsicd.h" #include "devices/scsimo.h" #include "devices/host_services.h" @@ -361,26 +361,15 @@ class MockSCSIHD : public SCSIHD //NOSONAR Ignore inheritance hierarchy depth in FRIEND_TEST(ScsiHdTest, SetUpModePages); FRIEND_TEST(ScsiHdTest, GetSectorSizes); FRIEND_TEST(ScsiHdTest, ModeSelect); - FRIEND_TEST(PiscsiExecutorTest, SetSectorSize); + FRIEND_TEST(PiscsiExecutorTest, ProcessDeviceCmd); public: - MockSCSIHD(int lun, bool removable) : SCSIHD(lun, removable, scsi_level::scsi_2) {} + MockSCSIHD(int lun, bool removable) : SCSIHD(lun, removable, scsi_level::scsi_2) {} explicit MockSCSIHD(const unordered_set& sector_sizes) : SCSIHD(0, false, scsi_level::scsi_2, sector_sizes) {} ~MockSCSIHD() override = default; }; -class MockSCSIHD_NEC : public SCSIHD_NEC //NOSONAR Ignore inheritance hierarchy depth in unit tests -{ - FRIEND_TEST(ScsiHdNecTest, SetUpModePages); - FRIEND_TEST(ScsiHdNecTest, TestAddErrorPage); - FRIEND_TEST(ScsiHdNecTest, TestAddFormatPage); - FRIEND_TEST(ScsiHdNecTest, TestAddDrivePage); - FRIEND_TEST(PiscsiExecutorTest, ProcessDeviceCmd); - - using SCSIHD_NEC::SCSIHD_NEC; -}; - class MockSCSICD : public SCSICD //NOSONAR Ignore inheritance hierarchy depth in unit tests { FRIEND_TEST(ScsiCdTest, GetSectorSizes); diff --git a/cpp/test/piscsi_executor_test.cpp b/cpp/test/piscsi_executor_test.cpp index 9c046d40..0692eb81 100644 --- a/cpp/test/piscsi_executor_test.cpp +++ b/cpp/test/piscsi_executor_test.cpp @@ -63,7 +63,7 @@ TEST(PiscsiExecutorTest, ProcessDeviceCmd) controller_manager->DeleteAllControllers(); definition.set_type(SCRM); - auto device2 = make_shared(LUN); + auto device2 = make_shared(LUN, false); device2->SetRemovable(true); device2->SetProtectable(true); device2->SetReady(true); @@ -483,7 +483,8 @@ TEST(PiscsiExecutorTest, CreateDevice) EXPECT_EQ(nullptr, executor->CreateDevice(context, UNDEFINED, 0, "")); #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" - EXPECT_EQ(nullptr, executor->CreateDevice(context, SAHD, 0, "")); + EXPECT_EQ(nullptr, executor->CreateDevice(context, SAHD, 0, "")); + EXPECT_EQ(nullptr, executor->CreateDevice(context, SCBR, 0, "")); #pragma GCC diagnostic pop EXPECT_NE(nullptr, executor->CreateDevice(context, UNDEFINED, 0, "services")); EXPECT_NE(nullptr, executor->CreateDevice(context, SCHS, 0, "")); diff --git a/cpp/test/piscsi_response_test.cpp b/cpp/test/piscsi_response_test.cpp index 510c2637..9b5e0b44 100644 --- a/cpp/test/piscsi_response_test.cpp +++ b/cpp/test/piscsi_response_test.cpp @@ -137,7 +137,7 @@ TEST(PiscsiResponseTest, GetDevicesInfo) EXPECT_EQ(ID, devices1[0].id()); EXPECT_EQ(LUN1, devices1[0].unit()); - auto device2 = make_shared(LUN2); + auto device2 = make_shared(LUN2, false); EXPECT_TRUE(controller_manager.AttachToController(*bus, ID, device2)); PbResult result2; @@ -171,7 +171,7 @@ TEST(PiscsiResponseTest, GetDeviceTypesInfo) PbDeviceTypesInfo info; response.GetDeviceTypesInfo(info); - EXPECT_EQ(8, info.properties().size()); + EXPECT_EQ(7, info.properties().size()); } TEST(PiscsiResponseTest, GetServerInfo) @@ -254,5 +254,5 @@ TEST(PiscsiResponseTest, GetMappingInfo) PbMappingInfo info; response.GetMappingInfo(info); - EXPECT_EQ(10, info.mapping().size()); + EXPECT_EQ(7, info.mapping().size()); } diff --git a/cpp/test/scsihd_nec_test.cpp b/cpp/test/scsihd_nec_test.cpp deleted file mode 100644 index f16c33a6..00000000 --- a/cpp/test/scsihd_nec_test.cpp +++ /dev/null @@ -1,230 +0,0 @@ -//--------------------------------------------------------------------------- -// -// SCSI Target Emulator PiSCSI -// for Raspberry Pi -// -// Copyright (C) 2022-2023 Uwe Seimet -// -//--------------------------------------------------------------------------- - -#include "mocks.h" -#include "shared/piscsi_exceptions.h" -#include "devices/scsihd_nec.h" -#include -#include - -using namespace std; -using namespace filesystem; - -void ScsiHdNecTest_SetUpModePages(map>& pages) -{ - EXPECT_EQ(5, pages.size()) << "Unexpected number of mode pages"; - EXPECT_EQ(12, pages[1].size()); - EXPECT_EQ(24, pages[3].size()); - EXPECT_EQ(20, pages[4].size()); - EXPECT_EQ(12, pages[8].size()); - EXPECT_EQ(30, pages[48].size()); -} - -TEST(ScsiHdNecTest, Inquiry) -{ - TestInquiry::Inquiry(SCHD, device_type::direct_access, scsi_level::scsi_1_ccs, "PiSCSI ", 0x1f, false, "file.hdn"); -} - -TEST(ScsiHdNecTest, SetUpModePages) -{ - map> pages; - MockSCSIHD_NEC hd(0); - - // Non changeable - hd.SetUpModePages(pages, 0x3f, false); - ScsiHdNecTest_SetUpModePages(pages); - - // Changeable - pages.clear(); - hd.SetUpModePages(pages, 0x3f, true); - ScsiHdNecTest_SetUpModePages(pages); -} - -TEST(ScsiHdNecTest, TestAddErrorPage) -{ - map> pages; - MockSCSIHD_NEC hd(0); - - hd.SetBlockCount(0x1234); - hd.SetReady(true); - // Non changeable - hd.SetUpModePages(pages, 0x01, false); - EXPECT_EQ(1, pages.size()) << "Unexpected number of mode pages"; - const vector& page_1 = pages[1]; - EXPECT_EQ(0x26, to_integer(page_1[2])); -} - -TEST(ScsiHdNecTest, TestAddFormatPage) -{ - map> pages; - MockSCSIHD_NEC hd(0); - - hd.SetBlockCount(0x1234); - hd.SetReady(true); - hd.SetUpModePages(pages, 0x03, false); - EXPECT_EQ(1, pages.size()) << "Unexpected number of mode pages"; - vector& page_3 = pages[3]; - EXPECT_EQ(0x80, to_integer(page_3[0]) & 0x80); - EXPECT_EQ(0, to_integer(page_3[20])); - - hd.SetRemovable(true); - // Non changeable - hd.SetUpModePages(pages, 0x03, false); - EXPECT_EQ(0x20, to_integer(page_3[20])); - - pages.clear(); - // Changeable - hd.SetUpModePages(pages, 0x03, true); - EXPECT_EQ(0xffff, GetInt16(page_3, 12)); -} - -TEST(ScsiHdNecTest, TestAddDrivePage) -{ - map> pages; - MockSCSIHD_NEC hd(0); - - hd.SetBlockCount(0x1234); - hd.SetReady(true); - // Non changeable - hd.SetUpModePages(pages, 0x04, false); - EXPECT_EQ(1, pages.size()) << "Unexpected number of mode pages"; - - pages.clear(); - // Changeable - hd.SetUpModePages(pages, 0x04, true); - EXPECT_EQ(1, pages.size()) << "Unexpected number of mode pages"; -} - -TEST(ScsiHdNecTest, SetParameters) -{ - MockSCSIHD_NEC hd_hdn(0); - MockSCSIHD_NEC hd_hdi(0); - MockSCSIHD_NEC hd_nhd(0); - - EXPECT_THROW(hd_hdn.Open(), io_exception) << "Missing filename"; - - path tmp = CreateTempFile(511); - hd_hdn.SetFilename(string(tmp)); - EXPECT_THROW(hd_hdn.Open(), io_exception) << "Root sector file is too small"; - remove(tmp); - - tmp = CreateTempFile(512); - hd_hdn.SetFilename(string(tmp)); - EXPECT_THROW(hd_hdn.Open(), io_exception) << "Invalid file extension"; - - const auto hdn = path((string)tmp + ".HDN"); - rename(tmp, hdn); - hd_hdn.SetFilename(string(hdn)); - hd_hdn.Open(); - remove(hdn); - - tmp = CreateTempFile(512); - const auto hdi = path((string)tmp + ".hdi"); - rename(tmp, hdi); - hd_hdi.SetFilename(string(hdi)); - EXPECT_THROW(hd_hdi.Open(), io_exception) << "Invalid sector size"; - - ofstream out; - out.open(hdi); - const array cylinders1 = { 1, 0, 0, 0 }; - out.seekp(28); - out.write(cylinders1.data(), cylinders1.size()); - const array heads1 = { 1, 0, 0, 0 }; - out.seekp(24); - out.write(heads1.data(), heads1.size()); - const array sectors1 = { 1, 0, 0, 0 }; - out.seekp(20); - out.write(sectors1.data(), sectors1.size()); - const array sector_size1 = { 0, 2, 0, 0 }; - out.seekp(16); - out.write(sector_size1.data(), sector_size1.size()); - const array image_size = { 0, 2, 0, 0 }; - out.seekp(12); - out.write(image_size.data(), image_size.size()); - out.close(); - resize_file(hdi, 512); - hd_hdi.Open(); - - remove(hdi); - - tmp = CreateTempFile(512); - const auto nhd = path((string)tmp + ".nhd"); - rename(tmp, nhd); - hd_nhd.SetFilename(string(nhd)); - EXPECT_THROW(hd_nhd.Open(), io_exception) << "Invalid file format"; - - out.open(nhd); - out << "T98HDDIMAGE.R0"; - out.close(); - resize_file(nhd, 512); - EXPECT_THROW(hd_nhd.Open(), io_exception) << "Invalid sector size"; - - out.open(nhd); - out << "T98HDDIMAGE.R0"; - // 512 bytes per sector - array sector_size2 = { 0, 2 }; - out.seekp(0x11c); - out.write(sector_size2.data(), sector_size2.size()); - out.close(); - resize_file(nhd, 512); - EXPECT_THROW(hd_nhd.Open(), io_exception) << "Drive has 0 blocks"; - - out.open(nhd); - out << "T98HDDIMAGE.R0"; - const array cylinders2 = { 1, 0 }; - out.seekp(0x114); - out.write(cylinders2.data(), cylinders2.size()); - const array heads2 = { 1, 0 }; - out.seekp(0x118); - out.write(heads2.data(), heads2.size()); - const array sectors2 = { 1, 0 }; - out.seekp(0x11a); - out.write(sectors2.data(), sectors2.size()); - out.seekp(0x11c); - out.write(sector_size2.data(), sector_size2.size()); - const array image_offset = { 1, 0, 0, 0 }; - out.seekp(0x110); - out.write(image_offset.data(), image_offset.size()); - out.close(); - resize_file(nhd, 512); - EXPECT_THROW(hd_nhd.Open(), io_exception) << "Invalid image offset/size"; - - out.open(nhd); - out << "T98HDDIMAGE.R0"; - out.seekp(0x114); - out.write(cylinders2.data(), cylinders2.size()); - out.seekp(0x118); - out.write(heads2.data(), heads2.size()); - out.seekp(0x11a); - out.write(sectors2.data(), sectors2.size()); - // 1 byte per sector - sector_size2 = { 1, 0 }; - out.seekp(0x11c); - out.write(sector_size2.data(), sector_size2.size()); - out.close(); - resize_file(nhd, 512); - EXPECT_THROW(hd_nhd.Open(), io_exception) << "Invalid NEC disk/sector size"; - - out.open(nhd); - out << "T98HDDIMAGE.R0"; - out.seekp(0x114); - out.write(cylinders2.data(), cylinders2.size()); - out.seekp(0x118); - out.write(heads2.data(), heads2.size()); - out.seekp(0x11a); - out.write(sectors2.data(), sectors2.size()); - sector_size2 = { 0, 2 }; - out.seekp(0x11c); - out.write(sector_size2.data(), sector_size2.size()); - out.close(); - resize_file(nhd, 512); - hd_nhd.Open(); - - remove(nhd); -} diff --git a/cpp/test/storage_device_test.cpp b/cpp/test/storage_device_test.cpp index 033766f4..d082ce48 100644 --- a/cpp/test/storage_device_test.cpp +++ b/cpp/test/storage_device_test.cpp @@ -79,7 +79,7 @@ TEST(StorageDeviceTest, GetIdsForReservedFile) auto bus = make_shared(); ControllerManager controller_manager; MockAbstractController controller(bus, ID); - auto device = make_shared(LUN); + auto device = make_shared(LUN, false); device->SetFilename("filename"); StorageDevice::UnreserveAll(); @@ -107,7 +107,7 @@ TEST(StorageDeviceTest, UnreserveAll) auto bus = make_shared(); ControllerManager controller_manager; MockAbstractController controller(bus, ID); - auto device = make_shared(LUN); + auto device = make_shared(LUN, false); device->SetFilename("filename"); EXPECT_TRUE(controller_manager.AttachToController(*bus, ID, device)); @@ -126,7 +126,7 @@ TEST(StorageDeviceTest, GetSetReservedFiles) auto bus = make_shared(); ControllerManager controller_manager; MockAbstractController controller(bus, ID); - auto device = make_shared(LUN); + auto device = make_shared(LUN, false); device->SetFilename("filename"); EXPECT_TRUE(controller_manager.AttachToController(*bus, ID, device));