Added short delay after the DaynaPort reports its metadeta during a READ operation

This commit is contained in:
Tony Kuker 2021-04-05 14:17:05 -05:00
parent e68f6f09e2
commit a05c7f34d4
7 changed files with 39 additions and 17 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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