mirror of
https://github.com/akuker/RASCSI.git
synced 2024-06-10 02:29:33 +00:00
Postpone removal of delay
This commit is contained in:
parent
6b658cf7e2
commit
a46880f912
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user