#27 Functionality will not transmit packets to the tap device ras0. Need to manually enable the link using 'ip link set dev ras0 up'

This commit is contained in:
akuker
2020-09-20 17:08:08 -05:00
parent 0a21896fd3
commit f375f7a8d2
7 changed files with 468 additions and 187 deletions

View File

@@ -17,6 +17,8 @@
#include "filepath.h" #include "filepath.h"
#include "gpiobus.h" #include "gpiobus.h"
#include "devices/scsi_host_bridge.h" #include "devices/scsi_host_bridge.h"
#include "devices/scsi_nuvolink.h"
#include "controllers/scsidev_ctrl.h"
//=========================================================================== //===========================================================================
// //
@@ -301,9 +303,7 @@ BUS::phase_t FASTCALL SASIDEV::Process()
// For the monitor tool, we shouldn't need to reset. We're just logging information // For the monitor tool, we shouldn't need to reset. We're just logging information
// Reset // Reset
if (ctrl.bus->GetRST()) { if (ctrl.bus->GetRST()) {
#if defined(DISK_LOG) LOGINFO("RESET signal received");
Log(Log::Normal, "RESET signal received");
#endif // DISK_LOG
// Reset the controller // Reset the controller
Reset(); Reset();
@@ -371,9 +371,7 @@ void FASTCALL SASIDEV::BusFree()
// Phase change // Phase change
if (ctrl.phase != BUS::busfree) { if (ctrl.phase != BUS::busfree) {
#if defined(DISK_LOG) LOGINFO("Bus free phase");
Log(Log::Normal, "Bus free phase");
#endif // DISK_LOG
// Phase Setting // Phase Setting
ctrl.phase = BUS::busfree; ctrl.phase = BUS::busfree;
@@ -552,65 +550,69 @@ void FASTCALL SASIDEV::Execute()
#endif // RASCSI #endif // RASCSI
// Process by command // Process by command
switch (ctrl.cmd[0]) { switch ((SCSIDEV::scsi_command)ctrl.cmd[0]) {
// TEST UNIT READY // TEST UNIT READY
case 0x00: case SCSIDEV::eCmdTestUnitReady:
CmdTestUnitReady(); CmdTestUnitReady();
return; return;
// REZERO UNIT // REZERO UNIT
case 0x01: case SCSIDEV::eCmdRezero:
CmdRezero(); CmdRezero();
return; return;
// REQUEST SENSE // REQUEST SENSE
case 0x03: case SCSIDEV::eCmdRequestSense:
CmdRequestSense(); CmdRequestSense();
return; return;
// FORMAT UNIT // FORMAT UNIT
case 0x04: // This doesn't exist in the SCSI Spec, but was in the original RaSCSI code.
CmdFormat(); // leaving it here for now....
return; case SCSIDEV::eCmdFormat:
// FORMAT UNIT
case 0x06: case 0x06:
CmdFormat(); CmdFormat();
return; return;
// REASSIGN BLOCKS // REASSIGN BLOCKS
case 0x07: case SCSIDEV::eCmdReassign:
CmdReassign(); CmdReassign();
return; return;
// READ(6) // READ(6)
case 0x08: case SCSIDEV::eCmdRead6:
CmdRead6(); CmdRead6();
return; return;
// WRITE(6) // WRITE(6)
case 0x0a: case SCSIDEV::eCmdWrite6:
CmdWrite6(); CmdWrite6();
return; return;
// SEEK(6) // SEEK(6)
case 0x0b: case SCSIDEV::eCmdSeek6:
CmdSeek6(); CmdSeek6();
return; return;
// ASSIGN(SASIのみ) // ASSIGN(SASIのみ)
case 0x0e: // This doesn't exist in the SCSI Spec, but was in the original RaSCSI code.
// leaving it here for now....
case SCSIDEV::eCmdSasiCmdAssign:
CmdAssign(); CmdAssign();
return; return;
// SPECIFY(SASIのみ) // SPECIFY(SASIのみ)
case 0xc2: // This doesn't exist in the SCSI Spec, but was in the original RaSCSI code.
// leaving it here for now....
case SCSIDEV::eCmdInvalid:
CmdSpecify(); CmdSpecify();
return; return;
default:
break;
} }
// Unsupported command // Unsupported command
Log(Log::Warning, "Unsupported command $%02X", ctrl.cmd[0]); LOGWARN("%s Unsupported command $%02X", __PRETTY_FUNCTION__, (WORD)ctrl.cmd[0]);
CmdInvalid(); CmdInvalid();
} }
@@ -872,9 +874,7 @@ void FASTCALL SASIDEV::DataOut()
return; return;
} }
#if defined(DISK_LOG) LOGTRACE("%s Data out phase", __PRETTY_FUNCTION__);
Log(Log::Normal, "Data out phase");
#endif // DISK_LOG
// Phase Setting // Phase Setting
ctrl.phase = BUS::dataout; ctrl.phase = BUS::dataout;
@@ -893,11 +893,13 @@ void FASTCALL SASIDEV::DataOut()
// Request data // Request data
ctrl.bus->SetREQ(TRUE); ctrl.bus->SetREQ(TRUE);
#endif // RASCSI #endif // RASCSI
LOGTRACE("%s returning.....",__PRETTY_FUNCTION__);
return; return;
} }
#ifdef RASCSI #ifdef RASCSI
// Receive // Receive
LOGTRACE("%s transitioning to Receive()",__PRETTY_FUNCTION__);
Receive(); Receive();
#else #else
// Requesting // Requesting
@@ -946,7 +948,7 @@ void FASTCALL SASIDEV::Error()
} }
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Warning, "Error occured (going to status phase)"); LOGWARN("Error occured (going to status phase)");
#endif // DISK_LOG #endif // DISK_LOG
// Logical Unit // Logical Unit
@@ -1667,6 +1669,7 @@ void FASTCALL SASIDEV::ReceiveNext()
// Data out phase // Data out phase
case BUS::dataout: case BUS::dataout:
LOGTRACE("%s transitioning to FlushUnit()",__PRETTY_FUNCTION__);
// Flush // Flush
FlushUnit(); FlushUnit();
@@ -1740,6 +1743,7 @@ BOOL FASTCALL SASIDEV::XferOut(BOOL cont)
{ {
DWORD lun; DWORD lun;
SCSIBR *bridge; SCSIBR *bridge;
SCSINuvolink *nuvolink;
ASSERT(this); ASSERT(this);
ASSERT(ctrl.phase == BUS::dataout); ASSERT(ctrl.phase == BUS::dataout);
@@ -1750,12 +1754,48 @@ BOOL FASTCALL SASIDEV::XferOut(BOOL cont)
return FALSE; return FALSE;
} }
// MODE SELECT or WRITE system switch ((SCSIDEV::scsi_command) ctrl.cmd[0]) {
switch (ctrl.cmd[0]) { case SCSIDEV::eCmdChangeMacAddr:
// MODE SELECT case SCSIDEV::eCmdSetMcastReg:
case 0x15: LOGTRACE("%s received multicast/mac address %02X", __PRETTY_FUNCTION__, (WORD)ctrl.cmd[0]);
// MODE SELECT(10) // Replace the nuvolink with SEND MESSAGE 6
case 0x55: if (ctrl.unit[lun]->GetID() == MAKEID('S', 'C', 'N', 'L')) {
nuvolink = (SCSINuvolink*)ctrl.unit[lun];
if (!nuvolink->SendMessage6(ctrl.cmd, ctrl.buffer)) {
// write failed
return FALSE;
}
// If normal, work setting
ctrl.offset = 0;
break;
}
else {
LOGERROR("%s Received an unexpected command that was not for nuvolink %02X", __PRETTY_FUNCTION__, (WORD)ctrl.cmd[0]);
break;
}
case SCSIDEV::eCmdSendPacket:
LOGTRACE("%s Send packet %02X", __PRETTY_FUNCTION__, (WORD)ctrl.cmd[0]);
// Replace the nuvolink with SEND MESSAGE 6
if (ctrl.unit[lun]->GetID() == MAKEID('S', 'C', 'N', 'L')) {
nuvolink = (SCSINuvolink*)ctrl.unit[lun];
if (!nuvolink->SendMessage6(ctrl.cmd, ctrl.buffer)) {
// write failed
return FALSE;
}
// If normal, work setting
ctrl.offset = 0;
break;
}
else {
LOGERROR("%s Received an unexpected command that was not for nuvolink %02X", __PRETTY_FUNCTION__, (WORD)ctrl.cmd[0]);
break;
}
case SCSIDEV::eCmdModeSelect:
case SCSIDEV::eCmdModeSelect10:
if (!ctrl.unit[lun]->ModeSelect( if (!ctrl.unit[lun]->ModeSelect(
ctrl.cmd, ctrl.buffer, ctrl.offset)) { ctrl.cmd, ctrl.buffer, ctrl.offset)) {
// MODE SELECT failed // MODE SELECT failed
@@ -1763,10 +1803,8 @@ BOOL FASTCALL SASIDEV::XferOut(BOOL cont)
} }
break; break;
// WRITE(6) case SCSIDEV::eCmdWrite6:
case 0x0a: case SCSIDEV::eCmdWrite10:
// WRITE(10)
case 0x2a:
// Replace the host bridge with SEND MESSAGE 10 // Replace the host bridge with SEND MESSAGE 10
if (ctrl.unit[lun]->GetID() == MAKEID('S', 'C', 'B', 'R')) { if (ctrl.unit[lun]->GetID() == MAKEID('S', 'C', 'B', 'R')) {
bridge = (SCSIBR*)ctrl.unit[lun]; bridge = (SCSIBR*)ctrl.unit[lun];
@@ -1780,8 +1818,7 @@ BOOL FASTCALL SASIDEV::XferOut(BOOL cont)
break; break;
} }
// WRITE AND VERIFY case SCSIDEV::eCmdWriteAndVerify10:
case 0x2e:
// Write // Write
if (!ctrl.unit[lun]->Write(ctrl.buffer, ctrl.next - 1)) { if (!ctrl.unit[lun]->Write(ctrl.buffer, ctrl.next - 1)) {
// Write failed // Write failed
@@ -1806,10 +1843,11 @@ BOOL FASTCALL SASIDEV::XferOut(BOOL cont)
break; break;
// SPECIFY(SASI only) // SPECIFY(SASI only)
case 0xc2: case SCSIDEV::eCmdInvalid:
break; break;
default: default:
LOGWARN("Received an unexpected command (%02X) in %s", (WORD)ctrl.cmd[0] , __PRETTY_FUNCTION__)
ASSERT(FALSE); ASSERT(FALSE);
break; break;
} }
@@ -1826,6 +1864,8 @@ BOOL FASTCALL SASIDEV::XferOut(BOOL cont)
void FASTCALL SASIDEV::FlushUnit() void FASTCALL SASIDEV::FlushUnit()
{ {
DWORD lun; DWORD lun;
DWORD len;
SCSINuvolink *nuvolink;
ASSERT(this); ASSERT(this);
ASSERT(ctrl.phase == BUS::dataout); ASSERT(ctrl.phase == BUS::dataout);
@@ -1837,45 +1877,108 @@ void FASTCALL SASIDEV::FlushUnit()
} }
// WRITE system only // WRITE system only
switch (ctrl.cmd[0]) { switch ((SCSIDEV::scsi_command)ctrl.cmd[0]) {
// WRITE(6) case SCSIDEV::eCmdSetMcastReg:
case 0x0a: LOGTRACE("%s received a eCmdSetMcastReg with size %d", __PRETTY_FUNCTION__, (WORD)ctrl.length);
// WRITE(10) // Get the number of bytes
case 0x2a: len = ctrl.cmd [4];
// WRITE AND VERIFY
case 0x2e: LOGDEBUG("Mcast message len: %d (%08X)", (WORD)len, (WORD)len);
LOGDEBUG("Mcast contents: %02X %02X %02X %02X %02X %02X", \
(WORD)ctrl.buffer[0],\
(WORD)ctrl.buffer[1],\
(WORD)ctrl.buffer[2],\
(WORD)ctrl.buffer[3],\
(WORD)ctrl.buffer[4],\
(WORD)ctrl.buffer[5]);
break;
case SCSIDEV::eCmdChangeMacAddr:
LOGTRACE("%s received a eCmdChangeMacAddr with size %d", __PRETTY_FUNCTION__, (WORD)ctrl.length);
// Get the number of bytes
len = ctrl.cmd [4];
LOGDEBUG("Mcast message len: %d (%08X)", (WORD)len, (WORD)len);
LOGDEBUG("Mcast contents: %02X %02X %02X %02X %02X %02X", \
(WORD)ctrl.buffer[0],\
(WORD)ctrl.buffer[1],\
(WORD)ctrl.buffer[2],\
(WORD)ctrl.buffer[3],\
(WORD)ctrl.buffer[4],\
(WORD)ctrl.buffer[5]);
break;
case SCSIDEV::eCmdSendPacket:
LOGTRACE("%s received a eCmdSendPacket with size %d", __PRETTY_FUNCTION__, (WORD)ctrl.length);
// Get the number of bytes
len = ctrl.cmd [3];
len <<= 8;
len += ctrl.cmd [4];
LOGDEBUG("Packet len: %d (%08X)", (WORD)len, (WORD)len)
if (ctrl.unit[lun]->GetID() == MAKEID('S', 'C', 'N', 'L')) {
nuvolink = (SCSINuvolink*)ctrl.unit[lun];
LOGERROR("buffer addr %016lX", (DWORD)ctrl.buffer);
if (!nuvolink->SendPacket(ctrl.buffer,len)) {
// write failed
return;
}
// If normal, work setting
ctrl.offset = 0;
break;
}
else {
LOGERROR("%s Received an unexpected command that was not for nuvolink %02X", __PRETTY_FUNCTION__, (WORD)ctrl.cmd[0]);
break;
}
break;
case SCSIDEV::eCmdWrite6:
case SCSIDEV::eCmdWrite10:
case SCSIDEV::eCmdWriteAndVerify10:
// Flush // Flush
if (!ctrl.unit[lun]->IsCacheWB()) { if (!ctrl.unit[lun]->IsCacheWB()) {
ctrl.unit[lun]->Flush(); ctrl.unit[lun]->Flush();
} }
break; break;
// Mode Select (6) case SCSIDEV::eCmdModeSelect:
case 0x15: case SCSIDEV::eCmdModeSelect10:
// MODE SELECT(10)
case 0x55:
// Debug code related to Issue #2 on github, where we get an unhandled Model select when // Debug code related to Issue #2 on github, where we get an unhandled Model select when
// the mac is rebooted // the mac is rebooted
// https://github.com/akuker/RASCSI/issues/2 // https://github.com/akuker/RASCSI/issues/2
Log(Log::Warning, "Received \'Mode Select\'\n"); LOGWARN("Received \'Mode Select\'\n");
Log(Log::Warning, " Operation Code: [%02X]\n", ctrl.cmd[0]); LOGWARN(" Operation Code: [%02X]\n", (WORD)ctrl.cmd[0]);
Log(Log::Warning, " Logical Unit %01X, PF %01X, SP %01X [%02X]\n", ctrl.cmd[1] >> 5, 1 & (ctrl.cmd[1] >> 4), ctrl.cmd[1] & 1, ctrl.cmd[1]); LOGWARN(" Logical Unit %01X, PF %01X, SP %01X [%02X]\n",\
Log(Log::Warning, " Reserved: %02X\n", ctrl.cmd[2]); (WORD)ctrl.cmd[1] >> 5, 1 & ((WORD)ctrl.cmd[1] >> 4), \
Log(Log::Warning, " Reserved: %02X\n", ctrl.cmd[3]); (WORD)ctrl.cmd[1] & 1, (WORD)ctrl.cmd[1]);
Log(Log::Warning, " Parameter List Len %02X\n", ctrl.cmd[4]); LOGWARN(" Reserved: %02X\n", (WORD)ctrl.cmd[2]);
Log(Log::Warning, " Reserved: %02X\n", ctrl.cmd[5]); LOGWARN(" Reserved: %02X\n", (WORD)ctrl.cmd[3]);
Log(Log::Warning, " Ctrl Len: %08X\n",ctrl.length); LOGWARN(" Parameter List Len %02X\n", (WORD)ctrl.cmd[4]);
LOGWARN(" Reserved: %02X\n",(WORD)ctrl.cmd[5]);
LOGWARN(" Ctrl Len: %08X\n",(WORD)ctrl.length);
if (!ctrl.unit[lun]->ModeSelect( if (!ctrl.unit[lun]->ModeSelect(
ctrl.cmd, ctrl.buffer, ctrl.offset)) { ctrl.cmd, ctrl.buffer, ctrl.offset)) {
// MODE SELECT failed // MODE SELECT failed
Log(Log::Warning, "Error occured while processing Mode Select command %02X\n", (unsigned char)ctrl.cmd[0]); LOGWARN("Error occured while processing Mode Select command %02X\n", (unsigned char)ctrl.cmd[0]);
return; return;
} }
break; break;
default: default:
Log(Log::Warning, "Received an invalid flush command %02X!!!!!\n",ctrl.cmd[0]); LOGWARN("Received an unexpected flush command %02X!!!!!\n",(WORD)ctrl.cmd[0]);
ASSERT(FALSE); // The following statement makes debugging a huge pain. You can un-comment it
// if you're not trying to add new devices....
// ASSERT(FALSE);
break; break;
} }
} }

View File

@@ -908,6 +908,13 @@ void FASTCALL SCSIDEV::CmdWrite10()
return; return;
} }
// // Receive message with Nuvolink
// if (ctrl.unit[lun]->GetID() == MAKEID('S', 'C', 'N', 'L')) {
// CmdSendMessage10();
// return;
// }
// TODO: .... I don't think this is needed (akuker)
// Get record number and block number // Get record number and block number
record = ctrl.cmd[2]; record = ctrl.cmd[2];
record <<= 8; record <<= 8;
@@ -1157,7 +1164,7 @@ void FASTCALL SCSIDEV::CmdMediaSense(){
void FASTCALL SCSIDEV::CmdResetStatistics(){ void FASTCALL SCSIDEV::CmdResetStatistics(){
DWORD lun; // DWORD lun;
ASSERT(this); ASSERT(this);
@@ -1168,25 +1175,84 @@ void FASTCALL SCSIDEV::CmdResetStatistics(){
void FASTCALL SCSIDEV::CmdSendPacket(){ void FASTCALL SCSIDEV::CmdSendPacket(){
DWORD lun;
ASSERT(this); ASSERT(this);
LOGTRACE("<%d> Received CmdSendPacket command for Nuvolink (%s)", this->GetID(), __PRETTY_FUNCTION__); LOGTRACE("<%d> Received CmdSendPacket command for Nuvolink (%s)", this->GetID(), __PRETTY_FUNCTION__);
// Logical Unit
lun = (ctrl.cmd[1] >> 5) & 0x07;
if (!ctrl.unit[lun]) {
LOGERROR("%s Invalid logical unit specified: %d", __PRETTY_FUNCTION__, (WORD)lun);
Error();
return;
}
// Send Packet with Nuvolink
if (ctrl.unit[lun]->GetID() == MAKEID('S', 'C', 'N', 'L')) {
LOGTRACE("%s Moving to CmdSendMessage6()", __PRETTY_FUNCTION__);
CmdSendMessage6();
return;
}
else
{
LOGERROR("Received a CmdSendPacket command for a non-nuvolink device");
}
Status(); Status();
} }
void FASTCALL SCSIDEV::CmdChangeMacAddr(){ void FASTCALL SCSIDEV::CmdChangeMacAddr(){
DWORD lun;
ASSERT(this); ASSERT(this);
LOGTRACE("<%d> Received CmdChangeMacAddr command for Nuvolink", this->GetID()); LOGTRACE("<%d> Received CmdChangeMacAddr command for Nuvolink", this->GetID());
// Logical Unit
lun = (ctrl.cmd[1] >> 5) & 0x07;
if (!ctrl.unit[lun]) {
LOGERROR("%s Invalid logical unit specified: %d", __PRETTY_FUNCTION__, (WORD)lun);
Error();
return;
}
// Receive message with Nuvolink
if (ctrl.unit[lun]->GetID() == MAKEID('S', 'C', 'N', 'L')) {
LOGTRACE("%s Moving to CmdSendMessage6()", __PRETTY_FUNCTION__);
CmdSendMessage6();
return;
}
else
{
LOGERROR("Received a CmdChangeMacAddr command for a non-nuvolink device");
}
Status(); Status();
} }
void SCSIDEV::FASTCALL CmdSetMcastReg(){ void FASTCALL SCSIDEV::CmdSetMcastReg(){
DWORD lun; DWORD lun;
ASSERT(this); ASSERT(this);
LOGTRACE("<%d> Received CmdSetMcastReg command for Nuvolink", this->GetID());
// Logical Unit
lun = (ctrl.cmd[1] >> 5) & 0x07;
if (!ctrl.unit[lun]) {
LOGERROR("%s Invalid logical unit specified: %d", __PRETTY_FUNCTION__, (WORD)lun);
Error();
return;
}
LOGTRACE("<%d> Received CmdSetMcastReg command for Nuvolink", this->GetID());
// Receive message with Nuvolink
if (ctrl.unit[lun]->GetID() == MAKEID('S', 'C', 'N', 'L')) {
LOGTRACE("%s Moving to CmdSendMessage10()", __PRETTY_FUNCTION__);
CmdSendMessage6();
return;
}
else
{
LOGERROR("Received a CmdSetMcastReg command for a non-nuvolink device");
}
Status(); Status();
} }
@@ -1414,6 +1480,8 @@ void FASTCALL SCSIDEV::CmdGetMessage10()
// //
// SEND MESSAGE(10) // SEND MESSAGE(10)
// //
// This Send Message command is used by the X68000 host driver
//
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void FASTCALL SCSIDEV::CmdSendMessage10() void FASTCALL SCSIDEV::CmdSendMessage10()
{ {
@@ -1429,8 +1497,7 @@ void FASTCALL SCSIDEV::CmdSendMessage10()
} }
// Error if not a host bridge // Error if not a host bridge
if ((ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'B', 'R')) && if (ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'B', 'R')) {
(ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'N', 'L'))) {
LOGERROR("Received CmdSendMessage10 for a non-bridge device"); LOGERROR("Received CmdSendMessage10 for a non-bridge device");
Error(); Error();
return; return;
@@ -1464,6 +1531,75 @@ void FASTCALL SCSIDEV::CmdSendMessage10()
DataOut(); DataOut();
} }
//---------------------------------------------------------------------------
//
// SEND MESSAGE(6)
//
// This Send Message command is used by the Nuvolink
//
//---------------------------------------------------------------------------
void FASTCALL SCSIDEV::CmdSendMessage6()
{
DWORD lun;
ASSERT(this);
// Logical Unit
lun = (ctrl.cmd[1] >> 5) & 0x07;
if (!ctrl.unit[lun]) {
Error();
return;
}
// Error if not a host bridge
if (ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'N', 'L')) {
LOGERROR("Received CmdSendMessage6 for a non-nuvolink device");
Error();
return;
}
// Reallocate buffer (because it is not transfer for each block)
if (ctrl.bufsize < 0x1000000) {
LOGTRACE("%s Re-allocating ctrl buffer", __PRETTY_FUNCTION__);
free(ctrl.buffer);
ctrl.bufsize = 0x1000000;
ctrl.buffer = (BYTE *)malloc(ctrl.bufsize);
}
// Set transfer amount
ctrl.length = ctrl.cmd[3];
ctrl.length <<= 8;
ctrl.length += ctrl.cmd[4];
for(int i=0; i< 8; i++)
{
LOGDEBUG("ctrl.cmd Byte %d: %02X",i, (int)ctrl.cmd[i]);
}
LOGTRACE("%s transfer %d bytes",__PRETTY_FUNCTION__, (unsigned int)ctrl.length);
if (ctrl.length <= 0) {
// Failure (Error)
Error();
return;
}
// Set next block
ctrl.blocks = 1;
ctrl.next = 1;
LOGTRACE("%s transitioning to DataOut()",__PRETTY_FUNCTION__);
// Light phase
DataOut();
}
//=========================================================================== //===========================================================================
// //
// Data Transfer // Data Transfer

View File

@@ -74,6 +74,7 @@ public:
eCmdModeSelect10 = 0x55, eCmdModeSelect10 = 0x55,
eCmdModeSense10 = 0x5A, eCmdModeSense10 = 0x5A,
eCmdInvalid = 0xC2, // (SASI only/Suppress warning when using SxSI) eCmdInvalid = 0xC2, // (SASI only/Suppress warning when using SxSI)
eCmdSasiCmdAssign = 0x0e, // This isn't used by SCSI, and can probably be removed.
}; };
public: public:
@@ -157,6 +158,8 @@ private:
// GET MESSAGE(10) command // GET MESSAGE(10) command
void FASTCALL CmdSendMessage10(); void FASTCALL CmdSendMessage10();
// SEND MESSAGE(10) command // SEND MESSAGE(10) command
void FASTCALL CmdSendMessage6();
// SEND MESSAGE(6) command
void FASTCALL CmdMediaSense(); void FASTCALL CmdMediaSense();
// Nuvolink-specific command // Nuvolink-specific command
void FASTCALL CmdResetStatistics(); void FASTCALL CmdResetStatistics();

View File

@@ -62,13 +62,6 @@ SCSINuvolink::SCSINuvolink() : Disk()
tap->GetMacAddr(mac_addr); tap->GetMacAddr(mac_addr);
mac_addr[5]++; mac_addr[5]++;
} }
mac_addr[0]=0x01;
mac_addr[1]=0x02;
mac_addr[2]=0x03;
mac_addr[3]=0x04;
mac_addr[4]=0x05;
mac_addr[5]=0x06;
// Packet reception flag OFF // Packet reception flag OFF
packet_enable = FALSE; packet_enable = FALSE;
#endif // RASCSI && !BAREMETAL #endif // RASCSI && !BAREMETAL
@@ -99,7 +92,7 @@ SCSINuvolink::~SCSINuvolink()
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
int FASTCALL SCSINuvolink::Inquiry( int FASTCALL SCSINuvolink::Inquiry(
const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor) const DWORD *cdb, BYTE *buffer, DWORD major, DWORD minor)
{ {
DWORD response_size; DWORD response_size;
DWORD temp_data_dword; DWORD temp_data_dword;
@@ -107,7 +100,7 @@ int FASTCALL SCSINuvolink::Inquiry(
ASSERT(this); ASSERT(this);
ASSERT(cdb); ASSERT(cdb);
ASSERT(buf); ASSERT(buffer);
ASSERT(cdb[0] == 0x12); ASSERT(cdb[0] == 0x12);
LOGTRACE("%s Inquiry with major %ld, minor %ld",__PRETTY_FUNCTION__, major, minor); LOGTRACE("%s Inquiry with major %ld, minor %ld",__PRETTY_FUNCTION__, major, minor);
@@ -115,7 +108,7 @@ int FASTCALL SCSINuvolink::Inquiry(
// The LSB of cdb[3] is used as an extension to the size // The LSB of cdb[3] is used as an extension to the size
// field in cdb[4] // field in cdb[4]
response_size = (((DWORD)cdb[3] & 0x1) << 8) + cdb[4]; response_size = (((DWORD)cdb[3] & 0x1) << 8) + cdb[4];
LOGWARN("size is %d (%08X)",response_size, response_size); LOGWARN("size is %d (%08X)",(int)response_size, (WORD)response_size);
for(int i=0; i< 5; i++) for(int i=0; i< 5; i++)
{ {
@@ -130,95 +123,95 @@ int FASTCALL SCSINuvolink::Inquiry(
} }
// Clear the buffer // Clear the buffer
memset(buf, 0, response_size); memset(buffer, 0, response_size);
// Basic data // Basic data
// buf[0] ... Communication Device // buffer[0] ... Communication Device
// buf[2] ... SCSI-2 compliant command system // buffer[2] ... SCSI-2 compliant command system
// buf[3] ... SCSI-2 compliant Inquiry response // buffer[3] ... SCSI-2 compliant Inquiry response
// buf[4] ... Inquiry additional data // buffer[4] ... Inquiry additional data
buf[0] = 0x09; /* Communication device */ buffer[0] = 0x09; /* Communication device */
// SCSI-2 p.104 4.4.3 Incorrect logical unit handling // SCSI-2 p.104 4.4.3 Incorrect logical unit handling
if (((cdb[1] >> 5) & 0x07) != disk.lun) { if (((cdb[1] >> 5) & 0x07) != disk.lun) {
buf[0] = 0x7f; buffer[0] = 0x7f;
} }
/* SCSI 2 device */ /* SCSI 2 device */
buf[2] = 0x02; buffer[2] = 0x02;
/* SCSI 2 response type */ /* SCSI 2 response type */
buf[3] = (response_size >> 8) | 0x02; buffer[3] = (response_size >> 8) | 0x02;
/* No additional length */ /* No additional length */
buf[4] = response_size; buffer[4] = response_size;
// Vendor name // Vendor name
memcpy(&buf[8], m_vendor_name, strlen( m_vendor_name)); memcpy(&buffer[8], m_vendor_name, strlen( m_vendor_name));
// Product name // Product name
memcpy(&buf[16], m_device_name, strlen(m_device_name)); memcpy(&buffer[16], m_device_name, strlen(m_device_name));
// Revision // Revision
memcpy(&buf[32], m_revision, strlen(m_revision)); memcpy(&buffer[32], m_revision, strlen(m_revision));
// MAC Address currently configured // MAC Address currently configured
memcpy(&buf[36], mac_addr, sizeof(mac_addr)); memcpy(&buffer[36], mac_addr, sizeof(mac_addr));
// Build-in Hardware MAC address // Build-in Hardware MAC address
memcpy(&buf[56], mac_addr, sizeof(mac_addr)); memcpy(&buffer[56], mac_addr, sizeof(mac_addr));
// For now, all of the statistics are just garbage data to // For now, all of the statistics are just garbage data to
// make sure that the inquiry response is formatted correctly // make sure that the inquiry response is formatted correctly
if(response_size > 96){ if(response_size > 96){
// Header for SCSI statistics // Header for SCSI statistics
buf[96] = 0x04; // Decimal 1234 buffer[96] = 0x04; // Decimal 1234
buf[97] = 0xD2; buffer[97] = 0xD2;
// Header for SCSI errors section // Header for SCSI errors section
buf[184]=0x09; // Decimal 2345 buffer[184]=0x09; // Decimal 2345
buf[185]=0x29; buffer[185]=0x29;
// Header for network statistics // Header for network statistics
buf[244]=0x0D; buffer[244]=0x0D;
buf[245]=0x80; buffer[245]=0x80;
// Received Packet Count // Received Packet Count
temp_data_dword=100; temp_data_dword=100;
memcpy(&buf[246], &temp_data_dword, sizeof(temp_data_dword)); memcpy(&buffer[246], &temp_data_dword, sizeof(temp_data_dword));
// Transmitted Packet Count // Transmitted Packet Count
temp_data_dword=200; temp_data_dword=200;
memcpy(&buf[250], &temp_data_dword, sizeof(temp_data_dword)); memcpy(&buffer[250], &temp_data_dword, sizeof(temp_data_dword));
// Transmitted Request Count // Transmitted Request Count
temp_data_dword=300; temp_data_dword=300;
memcpy(&buf[254], &temp_data_dword, sizeof(temp_data_dword)); memcpy(&buffer[254], &temp_data_dword, sizeof(temp_data_dword));
// Reset Count // Reset Count
temp_data_word=50; temp_data_word=50;
memcpy(&buf[258], &temp_data_word, sizeof(temp_data_word)); memcpy(&buffer[258], &temp_data_word, sizeof(temp_data_word));
// Header for network errors // Header for network errors
buf[260]=0x11; // Decimal 4567 buffer[260]=0x11; // Decimal 4567
buf[261]=0xD7; buffer[261]=0xD7;
// unexp_rst // unexp_rst
buf[262]=0x01; buffer[262]=0x01;
buf[263]=0x02; buffer[263]=0x02;
//transmit_errors //transmit_errors
buf[264]=0x03; buffer[264]=0x03;
buf[265]=0x04; buffer[265]=0x04;
// re_int // re_int
buf[266]=0x05; buffer[266]=0x05;
buf[267]=0x06; buffer[267]=0x06;
// te_int // te_int
buf[268]=0x07; buffer[268]=0x07;
buf[269]=0x08; buffer[269]=0x08;
// ow_int // ow_int
buf[270]=0x09; buffer[270]=0x09;
buf[271]=0x0A; buffer[271]=0x0A;
buf[272]=0x0B; buffer[272]=0x0B;
buf[273]=0x0C; buffer[273]=0x0C;
buf[274]=0x0D; buffer[274]=0x0D;
buf[275]=0x0E; buffer[275]=0x0E;
} }
// Success // Success
@@ -246,7 +239,7 @@ BOOL FASTCALL SCSINuvolink::TestUnitReady(const DWORD* /*cdb*/)
// GET MESSAGE(10) // GET MESSAGE(10)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
int FASTCALL SCSINuvolink::GetMessage10(const DWORD *cdb, BYTE *buf) int FASTCALL SCSINuvolink::GetMessage6(const DWORD *cdb, BYTE *buffer)
{ {
int type; int type;
int phase; int phase;
@@ -257,7 +250,7 @@ int FASTCALL SCSINuvolink::GetMessage10(const DWORD *cdb, BYTE *buf)
#endif // RASCSI && !BAREMETAL #endif // RASCSI && !BAREMETAL
ASSERT(this); ASSERT(this);
LOGTRACE("SCSINuvolink::GetMessage10"); LOGTRACE("SCSINuvolink::GetMessage");
// Type // Type
type = cdb[2]; type = cdb[2];
@@ -280,26 +273,26 @@ int FASTCALL SCSINuvolink::GetMessage10(const DWORD *cdb, BYTE *buf)
switch (func) { switch (func) {
case 0: // Get MAC address case 0: // Get MAC address
return GetMacAddr(buf); return GetMacAddr(buffer);
case 1: // Received packet acquisition (size/buffer) case 1: // Received packet acquisition (size/buffer)
if (phase == 0) { if (phase == 0) {
// Get packet size // Get packet size
ReceivePacket(); ReceivePacket();
buf[0] = (BYTE)(packet_len >> 8); buffer[0] = (BYTE)(packet_len >> 8);
buf[1] = (BYTE)packet_len; buffer[1] = (BYTE)packet_len;
return 2; return 2;
} else { } else {
// Get package data // Get package data
GetPacketBuf(buf); GetPacketBuf(buffer);
return packet_len; return packet_len;
} }
case 2: // Received packet acquisition (size + buffer simultaneously) case 2: // Received packet acquisition (size + buffer simultaneously)
ReceivePacket(); ReceivePacket();
buf[0] = (BYTE)(packet_len >> 8); buffer[0] = (BYTE)(packet_len >> 8);
buf[1] = (BYTE)packet_len; buffer[1] = (BYTE)packet_len;
GetPacketBuf(&buf[2]); GetPacketBuf(&buffer[2]);
return packet_len + 2; return packet_len + 2;
case 3: // Simultaneous acquisition of multiple packets (size + buffer simultaneously) case 3: // Simultaneous acquisition of multiple packets (size + buffer simultaneously)
@@ -308,13 +301,13 @@ int FASTCALL SCSINuvolink::GetMessage10(const DWORD *cdb, BYTE *buf)
total_len = 0; total_len = 0;
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
ReceivePacket(); ReceivePacket();
*buf++ = (BYTE)(packet_len >> 8); *buffer++ = (BYTE)(packet_len >> 8);
*buf++ = (BYTE)packet_len; *buffer++ = (BYTE)packet_len;
total_len += 2; total_len += 2;
if (packet_len == 0) if (packet_len == 0)
break; break;
GetPacketBuf(buf); GetPacketBuf(buffer);
buf += packet_len; buffer += packet_len;
total_len += packet_len; total_len += packet_len;
} }
return total_len; return total_len;
@@ -325,13 +318,13 @@ int FASTCALL SCSINuvolink::GetMessage10(const DWORD *cdb, BYTE *buf)
case 2: // Host Drive case 2: // Host Drive
// switch (phase) { // switch (phase) {
// case 0: // Get result code // case 0: // Get result code
// return ReadFsResult(buf); // return ReadFsResult(buffer);
// case 1: // Return data acquisition // case 1: // Return data acquisition
// return ReadFsOut(buf); // return ReadFsOut(buffer);
// case 2: // Return additional data acquisition // case 2: // Return additional data acquisition
// return ReadFsOpt(buf); // return ReadFsOpt(buffer);
// } // }
break; break;
} }
@@ -346,63 +339,62 @@ int FASTCALL SCSINuvolink::GetMessage10(const DWORD *cdb, BYTE *buf)
// SEND MESSAGE(10) // SEND MESSAGE(10)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
BOOL FASTCALL SCSINuvolink::SendMessage10(const DWORD *cdb, BYTE *buf) BOOL FASTCALL SCSINuvolink::SendMessage6(const DWORD *cdb, BYTE *buffer)
{ {
int type; // int type;
int func; int func;
int len; int len;
ASSERT(this); ASSERT(this);
ASSERT(cdb); ASSERT(cdb);
ASSERT(buf); ASSERT(buffer);
LOGTRACE("SCSINuvolink::SendMessage10"); LOGTRACE("%s Entering....", __PRETTY_FUNCTION__);
// SendMessage6 is 6 bytes
for(int i=0; i< 6; i++)
{
LOGDEBUG("%s Byte %d: %02X",__PRETTY_FUNCTION__, i, (int)cdb[i]);
}
// Type // Type
type = cdb[2]; // type = cdb[2];
// Function number // Function number
func = cdb[3]; func = cdb[0];
// Phase // Phase
// phase = cdb[9]; // phase = cdb[9];
// Get the number of lights // Get the number of bytes
len = cdb[6]; len = cdb[4];
len <<= 8;
len |= cdb[7];
len <<= 8;
len |= cdb[8];
switch (type) { // // Do not process if TAP is invalid
#if defined(RASCSI) && !defined(BAREMETAL) // if (!m_bTapEnable) {
case 1: // Ethernet // LOGWARN("%s TAP is invalid and not working...", __PRETTY_FUNCTION__);
// Do not process if TAP is invalid // return FALSE;
if (!m_bTapEnable) { // }
return FALSE;
}
switch (func) { switch (func) {
case 0: // MAC address setting case 0x06: // MAC address setting
SetMacAddr(buf); LOGWARN("%s Unhandled Set MAC Address happening here...", __PRETTY_FUNCTION__);
return TRUE; SetMacAddr(buffer);
return TRUE;
case 0x09: // Set Multicast Registers
LOGWARN("%s Set Multicast registers happening here...", __PRETTY_FUNCTION__);
SetMulticastRegisters(buffer, len);
return TRUE;
case 1: // Send packet case 0x05: // Send message
SendPacket(buf, len); LOGWARN("%s Send message happening here...(%d)", __PRETTY_FUNCTION__, len);
return TRUE; // SendPacket(buffer,len);
} return TRUE;
break;
#endif // RASCSI && !BAREMETAL
case 2: // Host drive
// switch (phase) {
// case 0: // issue command
// WriteFs(func, buf);
// return TRUE;
// case 1: // additional data writing // case 1: // Send packet
// WriteFsOpt(buf, len); // SendPacket(buffer, len);
// return TRUE; // return TRUE;
// } default:
LOGWARN("%s Unexpected command type found %02X",__PRETTY_FUNCTION__, func);
break; break;
} }
@@ -411,6 +403,23 @@ BOOL FASTCALL SCSINuvolink::SendMessage10(const DWORD *cdb, BYTE *buf)
return FALSE; return FALSE;
} }
//---------------------------------------------------------------------------
//
// Set the Multicast Configuration
//
//---------------------------------------------------------------------------
void FASTCALL SCSINuvolink::SetMulticastRegisters(BYTE *buffer, int len){
LOGINFO("%s I should be setting the multicast registers here, but I'll just print instead...", __PRETTY_FUNCTION__);
LOGINFO("%s Got %d bytes", __PRETTY_FUNCTION__, len)
for(int i=0; i<len; i++){
LOGINFO("%s Byte %d: %02X", __PRETTY_FUNCTION__, i, (WORD)buffer[i]);
}
}
#if defined(RASCSI) && !defined(BAREMETAL) #if defined(RASCSI) && !defined(BAREMETAL)
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //
@@ -436,9 +445,14 @@ void FASTCALL SCSINuvolink::SetMacAddr(BYTE *mac)
{ {
ASSERT(this); ASSERT(this);
ASSERT(mac); ASSERT(mac);
LOGTRACE("SCSINuvolink::SetMacAddr"); LOGTRACE("%s Setting mac address", __PRETTY_FUNCTION__);
memcpy(mac_addr, mac, 6); for(size_t i=0; i<sizeof(mac_addr); i++)
{
LOGTRACE("%d: %02X",i,(WORD)mac[i]);
}
memcpy(mac_addr, mac, sizeof(mac_addr));
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -487,13 +501,13 @@ void FASTCALL SCSINuvolink::ReceivePacket()
// Get Packet // Get Packet
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void FASTCALL SCSINuvolink::GetPacketBuf(BYTE *buf) void FASTCALL SCSINuvolink::GetPacketBuf(BYTE *buffer)
{ {
int len; int len;
ASSERT(this); ASSERT(this);
ASSERT(tap); ASSERT(tap);
ASSERT(buf); ASSERT(buffer);
LOGTRACE("SCSINuvolink::GetPacketBuf"); LOGTRACE("SCSINuvolink::GetPacketBuf");
// Size limit // Size limit
@@ -503,7 +517,7 @@ void FASTCALL SCSINuvolink::GetPacketBuf(BYTE *buf)
} }
// Copy // Copy
memcpy(buf, packet_buf, len); memcpy(buffer, packet_buf, len);
// Received // Received
packet_enable = FALSE; packet_enable = FALSE;
@@ -514,14 +528,36 @@ void FASTCALL SCSINuvolink::GetPacketBuf(BYTE *buf)
// Send Packet // Send Packet
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void FASTCALL SCSINuvolink::SendPacket(BYTE *buf, int len) BOOL SCSINuvolink::SendPacket(BYTE *buffer, int len)
{ {
ASSERT(this); ASSERT(this);
ASSERT(tap); ASSERT(tap);
ASSERT(buf); ASSERT(buffer);
LOGTRACE("SCSINuvolink::SendPacket");
tap->Tx(buf, len); LOGERROR("%s buffer addr %016lX len:%d", __PRETTY_FUNCTION__, (DWORD)buffer, len);
LOGDEBUG("%s Total Len: %d", __PRETTY_FUNCTION__, len);
LOGDEBUG("%s Destination Addr: %02X:%02X:%02X:%02X:%02X:%02X",\
__PRETTY_FUNCTION__, (WORD)buffer[0], (WORD)buffer[1], (WORD)buffer[2], (WORD)buffer[3], (WORD)buffer[4], (WORD)buffer[5]);
LOGDEBUG("%s Source Addr: %02X:%02X:%02X:%02X:%02X:%02X",\
__PRETTY_FUNCTION__, (WORD)buffer[6], (WORD)buffer[7], (WORD)buffer[8], (WORD)buffer[9], (WORD)buffer[10], (WORD)buffer[11]);
LOGDEBUG("%s EtherType: %02X:%02X", __PRETTY_FUNCTION__, (WORD)buffer[12], (WORD)buffer[13]);
for(int i=0; i<len; i+=8){
LOGDEBUG("Packet contents: %02X: %02X %02X %02X %02X %02X %02X %02X %02X", i,\
(WORD)buffer[i],\
(WORD)buffer[i+1],\
(WORD)buffer[i+2],\
(WORD)buffer[i+3],\
(WORD)buffer[i+4],\
(WORD)buffer[i+5],\
(WORD)buffer[i+6],\
(WORD)buffer[i+7]);
}
tap->Tx(buffer, len);
return TRUE;
} }
#endif // RASCSI && !BAREMETAL #endif // RASCSI && !BAREMETAL

View File

@@ -48,10 +48,13 @@ public:
// INQUIRY command // INQUIRY command
BOOL FASTCALL TestUnitReady(const DWORD *cdb); BOOL FASTCALL TestUnitReady(const DWORD *cdb);
// TEST UNIT READY command // TEST UNIT READY command
int FASTCALL GetMessage10(const DWORD *cdb, BYTE *buf); int FASTCALL GetMessage6(const DWORD *cdb, BYTE *buf);
// GET MESSAGE10 command // GET MESSAGE10 command
BOOL FASTCALL SendMessage10(const DWORD *cdb, BYTE *buf); BOOL FASTCALL SendMessage6(const DWORD *cdb, BYTE *buf);
// SEND MESSAGE10 command // SEND MESSAGE10 command
BOOL SendPacket(BYTE *buf, int len);
// Send a packet
private: private:
enum nuvolink_command_enum : BYTE { enum nuvolink_command_enum : BYTE {
@@ -82,8 +85,8 @@ private:
// Receive a packet // Receive a packet
void FASTCALL GetPacketBuf(BYTE *buf); void FASTCALL GetPacketBuf(BYTE *buf);
// Get a packet // Get a packet
void FASTCALL SendPacket(BYTE *buf, int len); void FASTCALL SetMulticastRegisters(BYTE *buf, int len);
// Send a packet // Change the multicast registers
CTapDriver *tap; CTapDriver *tap;
// TAP driver // TAP driver

View File

@@ -458,7 +458,7 @@ BOOL ProcessCmd(FILE *fp, int id, int un, int cmd, int type, char *file)
// Check the Controller Number // Check the Controller Number
if (id < 0 || id >= CtrlMax) { if (id < 0 || id >= CtrlMax) {
FPRT(fp, "Error : Invalid ID\n"); FPRT(fp, "%s Error : Invalid ID %d\n", __PRETTY_FUNCTION__, id);
return FALSE; return FALSE;
} }

View File

@@ -179,13 +179,13 @@ int main(int argc, char* argv[])
// Check the ID number // Check the ID number
if (id < 0 || id > 7) { if (id < 0 || id > 7) {
fprintf(stderr, "Error : Invalid ID\n"); fprintf(stderr, "%s Error : Invalid ID %d \n", __PRETTY_FUNCTION__, id);
exit(EINVAL); exit(EINVAL);
} }
// Check the unit number // Check the unit number
if (un < 0 || un > 1) { if (un < 0 || un > 1) {
fprintf(stderr, "Error : Invalid UNIT\n"); fprintf(stderr, "%s Error : Invalid UNIT %d \n", __PRETTY_FUNCTION__, un);
exit(EINVAL); exit(EINVAL);
} }