From a05c7f34d4812e34171563d5bac07eb61a0ee52c Mon Sep 17 00:00:00 2001 From: Tony Kuker Date: Mon, 5 Apr 2021 14:17:05 -0500 Subject: [PATCH] Added short delay after the DaynaPort reports its metadeta during a READ operation --- src/raspberrypi/controllers/sasidev_ctrl.cpp | 2 +- src/raspberrypi/controllers/scsidev_ctrl.cpp | 15 +++++++++++++-- src/raspberrypi/devices/scsi_daynaport.cpp | 10 +++++----- src/raspberrypi/devices/scsi_daynaport.h | 11 +++++------ src/raspberrypi/gpiobus.cpp | 12 +++++++++++- src/raspberrypi/gpiobus.h | 2 +- src/raspberrypi/scsi.h | 4 +++- 7 files changed, 39 insertions(+), 17 deletions(-) diff --git a/src/raspberrypi/controllers/sasidev_ctrl.cpp b/src/raspberrypi/controllers/sasidev_ctrl.cpp index caa0aa54..954d5b54 100644 --- a/src/raspberrypi/controllers/sasidev_ctrl.cpp +++ b/src/raspberrypi/controllers/sasidev_ctrl.cpp @@ -1385,7 +1385,7 @@ void FASTCALL SASIDEV::Send() // Check that the length isn't 0 if (ctrl.length != 0) { len = ctrl.bus->SendHandShake( - &ctrl.buffer[ctrl.offset], ctrl.length); + &ctrl.buffer[ctrl.offset], ctrl.length, BUS::SEND_NO_DELAY); // If you can not send it all, move on to the status phase if (len != (int)ctrl.length) { diff --git a/src/raspberrypi/controllers/scsidev_ctrl.cpp b/src/raspberrypi/controllers/scsidev_ctrl.cpp index da9b6b79..d0cb1442 100644 --- a/src/raspberrypi/controllers/scsidev_ctrl.cpp +++ b/src/raspberrypi/controllers/scsidev_ctrl.cpp @@ -1566,8 +1566,19 @@ void FASTCALL SCSIDEV::Send() //if Length! = 0, send if (ctrl.length != 0) { LOGTRACE("%s sending handhake with offset %lu, length %lu", __PRETTY_FUNCTION__, ctrl.offset, ctrl.length); - len = ctrl.bus->SendHandShake( - &ctrl.buffer[ctrl.offset], ctrl.length); + + // 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. + if (ctrl.unit[0]->GetID() == MAKEID('S', 'C', 'D', 'P')) { + len = ((GPIOBUS*)ctrl.bus)->SendHandShake( + &ctrl.buffer[ctrl.offset], ctrl.length, SCSIDaynaPort::DAYNAPORT_READ_HEADER_SZ); + } + else + { + len = ctrl.bus->SendHandShake( + &ctrl.buffer[ctrl.offset], ctrl.length, BUS::SEND_NO_DELAY); + } // If you cannot send all, move to status phase if (len != (int)ctrl.length) { diff --git a/src/raspberrypi/devices/scsi_daynaport.cpp b/src/raspberrypi/devices/scsi_daynaport.cpp index 44a58026..048bce05 100644 --- a/src/raspberrypi/devices/scsi_daynaport.cpp +++ b/src/raspberrypi/devices/scsi_daynaport.cpp @@ -228,14 +228,14 @@ int FASTCALL SCSIDaynaPort::Read(const DWORD *cdb, BYTE *buf, DWORD block) // The first 2 bytes are reserved for the length of the packet // The next 4 bytes are reserved for a flag field //rx_packet_size = m_tap->Rx(response->data); - rx_packet_size = m_tap->Rx(&buf[m_read_header_size]); + rx_packet_size = m_tap->Rx(&buf[DAYNAPORT_READ_HEADER_SZ]); // If we didn't receive anything, return size of 0 if(rx_packet_size <= 0){ LOGTRACE("%s No packet received", __PRETTY_FUNCTION__); response->length = 0; response->flags = e_no_more_data; - return m_read_header_size; + return DAYNAPORT_READ_HEADER_SZ; } LOGTRACE("%s Packet Sz %d (%08X) read: %d", __PRETTY_FUNCTION__, (unsigned int) rx_packet_size, (unsigned int) rx_packet_size, read_count); @@ -283,7 +283,7 @@ int FASTCALL SCSIDaynaPort::Read(const DWORD *cdb, BYTE *buf, DWORD block) { response->length = 0; response->flags = e_no_more_data; - return m_read_header_size; + return DAYNAPORT_READ_HEADER_SZ; } } else @@ -312,7 +312,7 @@ int FASTCALL SCSIDaynaPort::Read(const DWORD *cdb, BYTE *buf, DWORD block) // Return the packet size + 2 for the length + 4 for the flag field // The CRC was already appended by the ctapdriver - return rx_packet_size + m_read_header_size; + return rx_packet_size + DAYNAPORT_READ_HEADER_SZ; } // If we got to this point, there are still messages in the queue, so // we should loop back and get the next one. @@ -320,7 +320,7 @@ int FASTCALL SCSIDaynaPort::Read(const DWORD *cdb, BYTE *buf, DWORD block) response->length = 0; response->flags = e_no_more_data; - return m_read_header_size; + return DAYNAPORT_READ_HEADER_SZ; } //--------------------------------------------------------------------------- diff --git a/src/raspberrypi/devices/scsi_daynaport.h b/src/raspberrypi/devices/scsi_daynaport.h index a28e5863..933b8667 100644 --- a/src/raspberrypi/devices/scsi_daynaport.h +++ b/src/raspberrypi/devices/scsi_daynaport.h @@ -78,6 +78,11 @@ public: static const BYTE CMD_SCSILINK_SETMODE = 0x80; static const BYTE CMD_SCSILINK_SETMAC = 0x40; + // The READ response has a header which consists of: + // 2 bytes - payload size + // 4 bytes - status flags + static const DWORD DAYNAPORT_READ_HEADER_SZ = 2 + 4; + private: typedef struct __attribute__((packed)) { BYTE operation_code; @@ -190,12 +195,6 @@ private: static const BYTE m_bcast_addr[6]; static const BYTE m_apple_talk_addr[6]; - // The READ response has a header which consists of: - // 2 bytes - payload size - // 4 bytes - status flags - // 1 byte - magic pad bit, that I don't know why it works..... - const DWORD m_read_header_size = 2 + 4; - #endif // RASCSI && !BAREMETAL }; diff --git a/src/raspberrypi/gpiobus.cpp b/src/raspberrypi/gpiobus.cpp index 6996bcb3..3ec5da35 100644 --- a/src/raspberrypi/gpiobus.cpp +++ b/src/raspberrypi/gpiobus.cpp @@ -1109,7 +1109,7 @@ int FASTCALL GPIOBUS::ReceiveHandShake(BYTE *buf, int count) // Data transmission handshake // //--------------------------------------------------------------------------- -int FASTCALL GPIOBUS::SendHandShake(BYTE *buf, int count) +int FASTCALL GPIOBUS::SendHandShake(BYTE *buf, int count, int delay_after_bytes) { int i; BOOL ret; @@ -1120,6 +1120,11 @@ int FASTCALL GPIOBUS::SendHandShake(BYTE *buf, int count) if (actmode == TARGET) { for (i = 0; i < count; i++) { + if(i==delay_after_bytes){ + LOGTRACE("%s DELAYING for 100us after %d bytes", __PRETTY_FUNCTION__, (int)delay_after_bytes); + SysTimer::SleepUsec(100); + } + // Set the DATA signals SetDAT(*buf); @@ -1158,6 +1163,11 @@ int FASTCALL GPIOBUS::SendHandShake(BYTE *buf, int count) phase = Aquire() & GPIO_MCI; for (i = 0; i < count; i++) { + + if(i==delay_after_bytes){ + SysTimer::SleepUsec(100); + } + // Set the DATA signals SetDAT(*buf); diff --git a/src/raspberrypi/gpiobus.h b/src/raspberrypi/gpiobus.h index a3f64bec..f549aaef 100644 --- a/src/raspberrypi/gpiobus.h +++ b/src/raspberrypi/gpiobus.h @@ -564,7 +564,7 @@ public: // Command receive handshake int FASTCALL ReceiveHandShake(BYTE *buf, int count); // Data receive handshake - int FASTCALL SendHandShake(BYTE *buf, int count); + int FASTCALL SendHandShake(BYTE *buf, int count, int delay_after_bytes); // Data transmission handshake static BUS::phase_t FASTCALL GetPhaseRaw(DWORD raw_data); diff --git a/src/raspberrypi/scsi.h b/src/raspberrypi/scsi.h index 906d0fd0..ed8a8e96 100644 --- a/src/raspberrypi/scsi.h +++ b/src/raspberrypi/scsi.h @@ -125,7 +125,7 @@ public: // コマンド受信ハンドシェイク virtual int FASTCALL ReceiveHandShake(BYTE *buf, int count) = 0; // データ受信ハンドシェイク - virtual int FASTCALL SendHandShake(BYTE *buf, int count) = 0; + virtual int FASTCALL SendHandShake(BYTE *buf, int count, int delay_after_bytes) = 0; // データ送信ハンドシェイク @@ -133,6 +133,8 @@ public: // Get SCSI input signal value virtual void FASTCALL SetSignal(int pin, BOOL ast) = 0; // Set SCSI output signal value + static const int SEND_NO_DELAY = -1; + // Passed into SendHandShake when we don't want to delay protected: phase_t m_current_phase = phase_t::reserved;