Revert "Revert "Postpone removal of delay""

This reverts commit c46d3b7154.
This commit is contained in:
Uwe Seimet 2023-11-08 23:56:57 +01:00
parent c46d3b7154
commit 4570c0163c
12 changed files with 45 additions and 8 deletions

View File

@ -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<int>(GetLength())) {
// If you cannot send all, move to status phase
Error(sense_key::aborted_command);

View File

@ -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;
}

View File

@ -46,6 +46,8 @@ public:
virtual bool WriteByteSequence(span<const uint8_t>);
int GetSendDelay() const { return send_delay; }
bool CheckReservation(int, scsi_command, bool) const;
void DiscardReservation();
@ -69,6 +71,8 @@ protected:
virtual vector<uint8_t> 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<scsi_command, operation> commands;
int send_delay = BUS::SEND_NO_DELAY;
int reserving_initiator = NOT_RESERVED;
};

View File

@ -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

View File

@ -92,7 +92,7 @@ class BUS : public PinControl
virtual unique_ptr<DataSample> GetSample(uint64_t timestamp = 0) = 0;
virtual int CommandHandShake(vector<uint8_t> &) = 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;

View File

@ -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);

View File

@ -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;

View File

@ -214,7 +214,7 @@ void ScsiDump::Command(scsi_command cmd, vector<uint8_t>& cdb) const
cdb[0] = static_cast<uint8_t>(cmd);
cdb[1] = static_cast<uint8_t>(static_cast<byte>(cdb[1]) | static_cast<byte>(target_lun << 5));
if (static_cast<int>(cdb.size()) !=
bus->SendHandShake(cdb.data(), static_cast<int>(cdb.size()))) {
bus->SendHandShake(cdb.data(), static_cast<int>(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");
}
}

View File

@ -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;

View File

@ -57,7 +57,7 @@ public:
MOCK_METHOD(uint32_t, Acquire, (), (override));
MOCK_METHOD(int, CommandHandShake, (vector<uint8_t>&), (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));

View File

@ -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;

View File

@ -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());
}