From 4570c0163c144cb9e2815b83f0426a97007c4012 Mon Sep 17 00:00:00 2001 From: Uwe Seimet Date: Wed, 8 Nov 2023 23:56:57 +0100 Subject: [PATCH] Revert "Revert "Postpone removal of delay"" This reverts commit c46d3b71545fd941db276be887f81b61a532237a. --- cpp/controllers/scsi_controller.cpp | 5 ++++- cpp/devices/ctapdriver.cpp | 1 + cpp/devices/primary_device.h | 6 ++++++ cpp/devices/scsi_daynaport.cpp | 4 ++++ cpp/hal/bus.h | 2 +- cpp/hal/gpiobus.cpp | 8 +++++++- cpp/hal/gpiobus.h | 2 +- cpp/scsidump/scsidump_core.cpp | 4 ++-- cpp/shared/piscsi_version.cpp | 2 +- cpp/test/mocks.h | 2 +- cpp/test/primary_device_test.cpp | 9 +++++++++ cpp/test/scsi_daynaport_test.cpp | 8 ++++++++ 12 files changed, 45 insertions(+), 8 deletions(-) diff --git a/cpp/controllers/scsi_controller.cpp b/cpp/controllers/scsi_controller.cpp index 762d0868..26bb553e 100644 --- a/cpp/controllers/scsi_controller.cpp +++ b/cpp/controllers/scsi_controller.cpp @@ -433,7 +433,10 @@ void ScsiController::Send() if (HasValidLength()) { LogTrace("Sending data, offset: " + to_string(GetOffset()) + ", length: " + to_string(GetLength())); - if (const int len = GetBus().SendHandShake(GetBuffer().data() + GetOffset(), GetLength()); + // The delay should be taken from the respective LUN, but as there are no Daynaport drivers for + // LUNs other than 0 this work-around works. + if (const int len = GetBus().SendHandShake(GetBuffer().data() + GetOffset(), GetLength(), + HasDeviceForLun(0) ? GetDeviceForLun(0)->GetSendDelay() : 0); len != static_cast(GetLength())) { // If you cannot send all, move to status phase Error(sense_key::aborted_command); diff --git a/cpp/devices/ctapdriver.cpp b/cpp/devices/ctapdriver.cpp index c5c59a1e..85fc2adc 100644 --- a/cpp/devices/ctapdriver.cpp +++ b/cpp/devices/ctapdriver.cpp @@ -336,6 +336,7 @@ bool CTapDriver::HasPendingPackets() const fds.events = POLLIN | POLLERR; fds.revents = 0; poll(&fds, 1, 0); + spdlog::trace(to_string(fds.revents) + " revents"); return fds.revents & POLLIN; } diff --git a/cpp/devices/primary_device.h b/cpp/devices/primary_device.h index 1959c7e9..c30bc123 100644 --- a/cpp/devices/primary_device.h +++ b/cpp/devices/primary_device.h @@ -46,6 +46,8 @@ public: virtual bool WriteByteSequence(span); + int GetSendDelay() const { return send_delay; } + bool CheckReservation(int, scsi_command, bool) const; void DiscardReservation(); @@ -69,6 +71,8 @@ protected: virtual vector InquiryInternal() const = 0; void CheckReady(); + void SetSendDelay(int s) { send_delay = s; } + void SendDiagnostic() override; void ReserveUnit() override; void ReleaseUnit() override; @@ -106,5 +110,7 @@ private: unordered_map commands; + int send_delay = BUS::SEND_NO_DELAY; + int reserving_initiator = NOT_RESERVED; }; diff --git a/cpp/devices/scsi_daynaport.cpp b/cpp/devices/scsi_daynaport.cpp index 3d14c993..a945bd17 100644 --- a/cpp/devices/scsi_daynaport.cpp +++ b/cpp/devices/scsi_daynaport.cpp @@ -50,6 +50,10 @@ bool SCSIDaynaPort::Init(const param_map& params) AddCommand(scsi_command::eCmdSetMcastAddr, [this] { SetMcastAddr(); }); AddCommand(scsi_command::eCmdEnableInterface, [this] { EnableInterface(); }); + // The Daynaport needs to have a delay after the size/flags field of the read response. + // In the MacOS driver, it looks like the driver is doing two "READ" system calls. + SetSendDelay(DAYNAPORT_READ_HEADER_SZ); + tap_enabled = tap.Init(GetParams()); if (!tap_enabled) { // Not terminating on regular Linux PCs is helpful for testing diff --git a/cpp/hal/bus.h b/cpp/hal/bus.h index 8c1f49e2..23740fe2 100644 --- a/cpp/hal/bus.h +++ b/cpp/hal/bus.h @@ -92,7 +92,7 @@ class BUS : public PinControl virtual unique_ptr GetSample(uint64_t timestamp = 0) = 0; virtual int CommandHandShake(vector &) = 0; virtual int ReceiveHandShake(uint8_t *buf, int count) = 0; - virtual int SendHandShake(uint8_t *buf, int count) = 0; + virtual int SendHandShake(uint8_t *buf, int count, int delay_after_bytes) = 0; // SEL signal event polling virtual bool PollSelectEvent() = 0; diff --git a/cpp/hal/gpiobus.cpp b/cpp/hal/gpiobus.cpp index f714dc9b..4b4ead70 100644 --- a/cpp/hal/gpiobus.cpp +++ b/cpp/hal/gpiobus.cpp @@ -265,7 +265,7 @@ int GPIOBUS::ReceiveHandShake(uint8_t *buf, int count) // Data transmission handshake // //--------------------------------------------------------------------------- -int GPIOBUS::SendHandShake(uint8_t *buf, int count) +int GPIOBUS::SendHandShake(uint8_t *buf, int count, int delay_after_bytes) { GPIO_FUNCTION_TRACE int i; @@ -275,6 +275,12 @@ int GPIOBUS::SendHandShake(uint8_t *buf, int count) if (actmode == mode_e::TARGET) { for (i = 0; i < count; i++) { + if (i == delay_after_bytes) { + spdlog::trace("DELAYING for " + to_string(SCSI_DELAY_SEND_DATA_DAYNAPORT_US) + " after " + + to_string(delay_after_bytes) + " bytes"); + SysTimer::SleepUsec(SCSI_DELAY_SEND_DATA_DAYNAPORT_US); + } + // Set the DATA signals SetDAT(*buf); diff --git a/cpp/hal/gpiobus.h b/cpp/hal/gpiobus.h index 9b7a2478..fe774115 100644 --- a/cpp/hal/gpiobus.h +++ b/cpp/hal/gpiobus.h @@ -178,7 +178,7 @@ class GPIOBUS : public BUS // Data receive handshake int ReceiveHandShake(uint8_t *, int) override; // Data transmission handshake - int SendHandShake(uint8_t *, int) override; + int SendHandShake(uint8_t *, int, int) override; // SEL signal event polling bool PollSelectEvent() override; diff --git a/cpp/scsidump/scsidump_core.cpp b/cpp/scsidump/scsidump_core.cpp index 55bb6780..41c1dabd 100644 --- a/cpp/scsidump/scsidump_core.cpp +++ b/cpp/scsidump/scsidump_core.cpp @@ -214,7 +214,7 @@ void ScsiDump::Command(scsi_command cmd, vector& cdb) const cdb[0] = static_cast(cmd); cdb[1] = static_cast(static_cast(cdb[1]) | static_cast(target_lun << 5)); if (static_cast(cdb.size()) != - bus->SendHandShake(cdb.data(), static_cast(cdb.size()))) { + bus->SendHandShake(cdb.data(), static_cast(cdb.size()), BUS::SEND_NO_DELAY)) { BusFree(); throw phase_exception(command_mapping.find(cmd)->second.second + string(" failed")); @@ -234,7 +234,7 @@ void ScsiDump::DataOut(int length) { WaitForPhase(phase_t::dataout); - if (!bus->SendHandShake(buffer.data(), length)) { + if (!bus->SendHandShake(buffer.data(), length, BUS::SEND_NO_DELAY)) { throw phase_exception("DATA OUT failed"); } } diff --git a/cpp/shared/piscsi_version.cpp b/cpp/shared/piscsi_version.cpp index cbc124d5..05c297fd 100644 --- a/cpp/shared/piscsi_version.cpp +++ b/cpp/shared/piscsi_version.cpp @@ -13,7 +13,7 @@ // The following should be updated for each release const int piscsi_major_version = 23; // Last two digits of year -const int piscsi_minor_version = 11; // Month +const int piscsi_minor_version = 10; // Month const int piscsi_patch_version = -1; // Patch number - increment for each update using namespace std; diff --git a/cpp/test/mocks.h b/cpp/test/mocks.h index 044fddd2..fcf45cd5 100644 --- a/cpp/test/mocks.h +++ b/cpp/test/mocks.h @@ -57,7 +57,7 @@ public: MOCK_METHOD(uint32_t, Acquire, (), (override)); MOCK_METHOD(int, CommandHandShake, (vector&), (override)); MOCK_METHOD(int, ReceiveHandShake, (uint8_t *, int), (override)); - MOCK_METHOD(int, SendHandShake, (uint8_t *, int), (override)); + MOCK_METHOD(int, SendHandShake, (uint8_t *, int, int), (override)); MOCK_METHOD(bool, GetSignal, (int), (const override)); MOCK_METHOD(void, SetSignal, (int, bool), (override)); MOCK_METHOD(bool, PollSelectEvent, (), (override)); diff --git a/cpp/test/primary_device_test.cpp b/cpp/test/primary_device_test.cpp index 3fdb4b8b..0a3739a0 100644 --- a/cpp/test/primary_device_test.cpp +++ b/cpp/test/primary_device_test.cpp @@ -339,6 +339,15 @@ TEST(PrimaryDeviceTest, WriteByteSequence) EXPECT_FALSE(device->WriteByteSequence({})) << "Primary device does not support writing byte sequences"; } +TEST(PrimaryDeviceTest, GetSetSendDelay) +{ + MockPrimaryDevice device(0); + + EXPECT_EQ(-1, device.GetSendDelay()) << "Wrong delay default value"; + device.SetSendDelay(1234); + EXPECT_EQ(1234, device.GetSendDelay()); +} + TEST(PrimaryDeviceTest, Init) { param_map params; diff --git a/cpp/test/scsi_daynaport_test.cpp b/cpp/test/scsi_daynaport_test.cpp index e2a434be..712b3b38 100644 --- a/cpp/test/scsi_daynaport_test.cpp +++ b/cpp/test/scsi_daynaport_test.cpp @@ -177,3 +177,11 @@ TEST(ScsiDaynaportTest, EnableInterface) Property(&scsi_exception::get_sense_key, sense_key::aborted_command), Property(&scsi_exception::get_asc, asc::no_additional_sense_information)))); } + +TEST(ScsiDaynaportTest, GetSendDelay) +{ + SCSIDaynaPort daynaport(0); + daynaport.Init({}); + + EXPECT_EQ(6, daynaport.GetSendDelay()); +}