SCSI command dispatcher update, reduction of circular dependencies (#117)

* Unified command handling of SCSI command dispatcher

* Added missing cast

* Updated casts

* Comment update

* Moved enums to base class to reduce circular dependencies

* Added EXTRA_FLAGS to Makefile and fixed typo (#118)

* scsidev_ctrl inherited from sasidev without any need

* Reverted last change ...

* Removed unused include

* Added missing field initialization in constructor

* Formatting update

* Fixed command names used for logging

* Replaced SCSI command dispatch switch

* Source code formatting update

* Renaming

* Renaming

* Renaming

* Renaming

* For SCSI (scsidev_ctrl) the scsi_command enum is not relevant anymore

* Always log status code in status phase

* Log additional sense code (ASC)
This commit is contained in:
uweseimet 2021-07-05 02:50:24 +02:00 committed by GitHub
parent e2409098dd
commit 9898cb1a13
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 199 additions and 329 deletions

View File

@ -17,7 +17,6 @@
#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 "controllers/scsidev_ctrl.h"
#include "devices/scsi_daynaport.h" #include "devices/scsi_daynaport.h"
#include "exceptions.h" #include "exceptions.h"
@ -550,53 +549,53 @@ void FASTCALL SASIDEV::Execute()
#endif // RASCSI #endif // RASCSI
// Process by command // Process by command
switch ((SCSIDEV::scsi_command)ctrl.cmd[0]) { switch ((SASIDEV::scsi_command)ctrl.cmd[0]) {
// TEST UNIT READY // TEST UNIT READY
case SCSIDEV::eCmdTestUnitReady: case SASIDEV::eCmdTestUnitReady:
CmdTestUnitReady(); CmdTestUnitReady();
return; return;
// REZERO UNIT // REZERO UNIT
case SCSIDEV::eCmdRezero: case SASIDEV::eCmdRezero:
CmdRezero(); CmdRezero();
return; return;
// REQUEST SENSE // REQUEST SENSE
case SCSIDEV::eCmdRequestSense: case SASIDEV::eCmdRequestSense:
CmdRequestSense(); CmdRequestSense();
return; return;
// FORMAT UNIT // FORMAT UNIT
// This doesn't exist in the SCSI Spec, but was in the original RaSCSI code. // This doesn't exist in the SCSI Spec, but was in the original RaSCSI code.
// leaving it here for now.... // leaving it here for now....
case SCSIDEV::eCmdFormat: case SASIDEV::eCmdFormat:
CmdFormat(); CmdFormat();
return; return;
// REASSIGN BLOCKS // REASSIGN BLOCKS
case SCSIDEV::eCmdReassign: case SASIDEV::eCmdReassign:
CmdReassign(); CmdReassign();
return; return;
// READ(6) // READ(6)
case SCSIDEV::eCmdRead6: case SASIDEV::eCmdRead6:
CmdRead6(); CmdRead6();
return; return;
// WRITE(6) // WRITE(6)
case SCSIDEV::eCmdWrite6: case SASIDEV::eCmdWrite6:
CmdWrite6(); CmdWrite6();
return; return;
// SEEK(6) // SEEK(6)
case SCSIDEV::eCmdSeek6: case SASIDEV::eCmdSeek6:
CmdSeek6(); CmdSeek6();
return; return;
// ASSIGN(SASIのみ) // ASSIGN(SASIのみ)
// This doesn't exist in the SCSI Spec, but was in the original RaSCSI code. // This doesn't exist in the SCSI Spec, but was in the original RaSCSI code.
// leaving it here for now.... // leaving it here for now....
case SCSIDEV::eCmdSasiCmdAssign: case SASIDEV::eCmdSasiCmdAssign:
CmdAssign(); CmdAssign();
return; return;
@ -613,7 +612,7 @@ void FASTCALL SASIDEV::Execute()
// SPECIFY(SASIのみ) // SPECIFY(SASIのみ)
// This doesn't exist in the SCSI Spec, but was in the original RaSCSI code. // This doesn't exist in the SCSI Spec, but was in the original RaSCSI code.
// leaving it here for now.... // leaving it here for now....
case SCSIDEV::eCmdInvalid: case SASIDEV::eCmdInvalid:
CmdSpecify(); CmdSpecify();
return; return;
default: default:
@ -656,8 +655,6 @@ void FASTCALL SASIDEV::Status()
} }
#endif // RASCSI #endif // RASCSI
LOGTRACE("%s Status phase", __PRETTY_FUNCTION__);
// Phase Setting // Phase Setting
ctrl.phase = BUS::status; ctrl.phase = BUS::status;
@ -676,9 +673,10 @@ void FASTCALL SASIDEV::Status()
// Request status // Request status
ctrl.bus->SetDAT(ctrl.buffer[0]); ctrl.bus->SetDAT(ctrl.buffer[0]);
ctrl.bus->SetREQ(TRUE); ctrl.bus->SetREQ(TRUE);
#endif // RASCSI
LOGTRACE( "%s Status Phase $%02X",__PRETTY_FUNCTION__, (unsigned int)ctrl.status); LOGTRACE( "%s Status Phase $%02X",__PRETTY_FUNCTION__, (unsigned int)ctrl.status);
#endif // RASCSI
return; return;
} }
@ -983,7 +981,7 @@ void FASTCALL SASIDEV::CmdRequestSense()
ASSERT(ctrl.length > 0); ASSERT(ctrl.length > 0);
LOGTRACE("%s Sense key $%02X",__PRETTY_FUNCTION__, (WORD)ctrl.buffer[2]); LOGTRACE("%s Sense key $%02X, ASC $%02X",__PRETTY_FUNCTION__, (WORD)ctrl.buffer[2], (WORD)ctrl.buffer[12]);
// Read phase // Read phase
DataIn(); DataIn();
@ -1713,9 +1711,9 @@ BOOL FASTCALL SASIDEV::XferOut(BOOL cont)
return FALSE; return FALSE;
} }
switch ((SCSIDEV::scsi_command) ctrl.cmd[0]) { switch ((SASIDEV::scsi_command) ctrl.cmd[0]) {
case SCSIDEV::eCmdModeSelect: case SASIDEV::eCmdModeSelect:
case SCSIDEV::eCmdModeSelect10: case SASIDEV::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
@ -1723,9 +1721,9 @@ BOOL FASTCALL SASIDEV::XferOut(BOOL cont)
} }
break; break;
case SCSIDEV::eCmdWrite6: case SASIDEV::eCmdWrite6:
case SCSIDEV::eCmdWrite10: case SASIDEV::eCmdWrite10:
case SCSIDEV::eCmdWriteAndVerify10: case SASIDEV::eCmdWriteAndVerify10:
// If we're a host bridge, use the host bridge's SendMessage10 // If we're a host bridge, use the host bridge's SendMessage10
// function // function
if (ctrl.unit[lun]->GetID() == MAKEID('S', 'C', 'B', 'R')) { if (ctrl.unit[lun]->GetID() == MAKEID('S', 'C', 'B', 'R')) {
@ -1779,10 +1777,10 @@ BOOL FASTCALL SASIDEV::XferOut(BOOL cont)
break; break;
// SPECIFY(SASI only) // SPECIFY(SASI only)
case SCSIDEV::eCmdInvalid: case SASIDEV::eCmdInvalid:
break; break;
case SCSIDEV::eCmdSetMcastAddr: case SASIDEV::eCmdSetMcastAddr:
LOGTRACE("%s Done with DaynaPort Set Multicast Address", __PRETTY_FUNCTION__); LOGTRACE("%s Done with DaynaPort Set Multicast Address", __PRETTY_FUNCTION__);
break; break;
default: default:
@ -1814,17 +1812,17 @@ void FASTCALL SASIDEV::FlushUnit()
} }
// WRITE system only // WRITE system only
switch ((SCSIDEV::scsi_command)ctrl.cmd[0]) { switch ((SASIDEV::scsi_command)ctrl.cmd[0]) {
case SCSIDEV::eCmdWrite6: case SASIDEV::eCmdWrite6:
case SCSIDEV::eCmdWrite10: case SASIDEV::eCmdWrite10:
case SCSIDEV::eCmdWriteAndVerify10: case SASIDEV::eCmdWriteAndVerify10:
// Flush // Flush
if (!ctrl.unit[lun]->IsCacheWB()) { if (!ctrl.unit[lun]->IsCacheWB()) {
ctrl.unit[lun]->Flush(); ctrl.unit[lun]->Flush();
} }
break; break;
case SCSIDEV::eCmdModeSelect: case SASIDEV::eCmdModeSelect:
case SCSIDEV::eCmdModeSelect10: case SASIDEV::eCmdModeSelect10:
// 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
@ -1846,10 +1844,10 @@ void FASTCALL SASIDEV::FlushUnit()
return; return;
} }
break; break;
case SCSIDEV::eCmdSetIfaceMode: case SASIDEV::eCmdSetIfaceMode:
LOGWARN("%s Trying to flush a command set interface mode. This should be a daynaport?", __PRETTY_FUNCTION__); LOGWARN("%s Trying to flush a command set interface mode. This should be a daynaport?", __PRETTY_FUNCTION__);
break; break;
case SCSIDEV::eCmdSetMcastAddr: case SASIDEV::eCmdSetMcastAddr:
// TODO: Eventually, we should store off the multicast address configuration data here... // TODO: Eventually, we should store off the multicast address configuration data here...
break; break;
default: default:

View File

@ -18,7 +18,6 @@
#include "os.h" #include "os.h"
#include "scsi.h" #include "scsi.h"
#include "fileio.h" #include "fileio.h"
#include "devices/disk.h"
#include "log.h" #include "log.h"
#include "xm6.h" #include "xm6.h"
@ -30,6 +29,74 @@
//=========================================================================== //===========================================================================
class SASIDEV class SASIDEV
{ {
protected:
enum scsi_message_code : BYTE {
eMsgCodeAbort = 0x06,
eMsgCodeAbortTag = 0x0D,
eMsgCodeBusDeviceReset = 0x0C,
eMsgCodeClearQueue = 0x0E,
eMsgCodeCommandComplete = 0x00,
eMsgCodeDisconnect = 0x04,
eMsgCodeIdentify = 0x80,
eMsgCodeIgnoreWideResidue = 0x23, // (Two Bytes)
eMsgCodeInitiateRecovery = 0x0F,
eMsgCodeInitiatorDetectedError = 0x05,
eMsgCodeLinkedCommandComplete = 0x0A,
eMsgCodeLinkedCommandCompleteWithFlag = 0x0B,
eMsgCodeMessageParityError = 0x09,
eMsgCodeMessageReject = 0x07,
eMsgCodeNoOperation = 0x08,
eMsgCodeHeadOfQueueTag = 0x21,
eMsgCodeOrderedQueueTag = 0x22,
eMsgCodeSimpleQueueTag = 0x20,
eMsgCodeReleaseRecovery = 0x10,
eMsgCodeRestorePointers = 0x03,
eMsgCodeSaveDataPointer = 0x02,
eMsgCodeTerminateIOProcess = 0x11,
};
private:
enum scsi_command : BYTE {
eCmdTestUnitReady = 0x00,
eCmdRezero = 0x01,
eCmdRequestSense = 0x03,
eCmdFormat = 0x04,
eCmdReassign = 0x07,
eCmdRead6 = 0x08,
eCmdRetrieveStats = 0x09, // DaynaPort specific command
eCmdWrite6 = 0x0A,
eCmdSeek6 = 0x0B,
eCmdSetIfaceMode = 0x0C, // DaynaPort specific command
eCmdSetMcastAddr = 0x0D, // DaynaPort specific command
eCmdEnableInterface = 0x0E, // DaynaPort specific command
eCmdInquiry = 0x12,
eCmdModeSelect = 0x15,
eCmdReserve6 = 0x16,
eCmdRelease6 = 0x17,
eCmdModeSense = 0x1A,
eCmdStartStop = 0x1B,
eCmdSendDiag = 0x1D,
eCmdRemoval = 0x1E,
eCmdReadCapacity = 0x25,
eCmdRead10 = 0x28,
eCmdWrite10 = 0x2A,
eCmdSeek10 = 0x2B,
eCmdWriteAndVerify10 = 0x2E,
eCmdVerify = 0x2F,
eCmdSynchronizeCache = 0x35,
eCmdReadDefectData10 = 0x37,
eCmdReadToc = 0x43,
eCmdPlayAudio10 = 0x45,
eCmdPlayAudioMSF = 0x47,
eCmdPlayAudioTrack = 0x48,
eCmdModeSelect10 = 0x55,
eCmdReserve10 = 0x56,
eCmdRelease10 = 0x57,
eCmdModeSense10 = 0x5A,
eCmdInvalid = 0xC2, // (SASI only/Suppress warning when using SxSI)
eCmdSasiCmdAssign = 0x0e, // This isn't used by SCSI, and can probably be removed.
};
public: public:
enum { enum {
UnitMax = 8 // Maximum number of logical units UnitMax = 8 // Maximum number of logical units

View File

@ -44,6 +44,59 @@ SCSIDEV::SCSIDEV(Device *dev) : SASIDEV(dev)
scsi.atnmsg = FALSE; scsi.atnmsg = FALSE;
scsi.msc = 0; scsi.msc = 0;
memset(scsi.msb, 0x00, sizeof(scsi.msb)); memset(scsi.msb, 0x00, sizeof(scsi.msb));
SetupCommand(0x00, "CmdTestUnitReady", &SCSIDEV::CmdTestUnitReady);
SetupCommand(0x01, "CmdRezero", &SCSIDEV::CmdRezero);
SetupCommand(0x03, "CmdRequestSense", &SCSIDEV::CmdRequestSense);
SetupCommand(0x04, "CmdFormat", &SCSIDEV::CmdFormat);
SetupCommand(0x07, "CmdReassign", &SCSIDEV::CmdReassign);
SetupCommand(0x08, "CmdRead6", &SCSIDEV::CmdRead6);
SetupCommand(0x0a, "CmdWrite6", &SCSIDEV::CmdWrite6);
SetupCommand(0x0b, "CmdSeek6", &SCSIDEV::CmdSeek6);
SetupCommand(0x12, "CmdInquiry", &SCSIDEV::CmdInquiry);
SetupCommand(0x15, "CmdModeSelect", &SCSIDEV::CmdModeSelect);
SetupCommand(0x16, "CmdReserve6", &SCSIDEV::CmdReserve6);
SetupCommand(0x17, "CmdRelease6", &SCSIDEV::CmdRelease6);
SetupCommand(0x1a, "CmdModeSense", &SCSIDEV::CmdModeSense);
SetupCommand(0x1b, "CmdStartStop", &SCSIDEV::CmdStartStop);
SetupCommand(0x1d, "CmdSendDiag", &SCSIDEV::CmdSendDiag);
SetupCommand(0x1e, "CmdRemoval", &SCSIDEV::CmdRemoval);
SetupCommand(0x25, "CmdReadCapacity", &SCSIDEV::CmdReadCapacity);
SetupCommand(0x28, "CmdRead10", &SCSIDEV::CmdRead10);
SetupCommand(0x2a, "CmdWrite10", &SCSIDEV::CmdWrite10);
SetupCommand(0x2e, "CmdWriteAndVerify10", &SCSIDEV::CmdWrite10);
SetupCommand(0x2b, "CmdSeek10", &SCSIDEV::CmdSeek10);
SetupCommand(0x2f, "CmdVerify", &SCSIDEV::CmdVerify);
SetupCommand(0x35, "CmdSynchronizeCache", &SCSIDEV::CmdSynchronizeCache);
SetupCommand(0x37, "CmdReadDefectData10", &SCSIDEV::CmdReadDefectData10);
SetupCommand(0x55, "CmdModeSelect10", &SCSIDEV::CmdModeSelect10);
SetupCommand(0x56, "CmdReserve10", &SCSIDEV::CmdReserve10);
SetupCommand(0x57, "CmdRelease10", &SCSIDEV::CmdRelease10);
SetupCommand(0x5a, "CmdModeSense10", &SCSIDEV::CmdModeSense10);
// MMC specific. TODO Move to separate class
SetupCommand(0x43, "CmdReadToc", &SCSIDEV::CmdReadToc);
SetupCommand(0x45, "CmdPlayAudio10", &SCSIDEV::CmdPlayAudio10);
SetupCommand(0x47, "CmdPlayAudioMSF", &SCSIDEV::CmdPlayAudioMSF);
SetupCommand(0x48, "CmdPlayAudioTrack", &SCSIDEV::CmdPlayAudioTrack);
// DaynaPort specific. TODO Move to separate class
SetupCommand(0x09, "CmdRetrieveStats", &SCSIDEV::CmdRetrieveStats);
SetupCommand(0x0c, "CmdSetIfaceMode", &SCSIDEV::CmdSetIfaceMode);
SetupCommand(0x0d, "CmdSetMcastAddr", &SCSIDEV::CmdSetMcastAddr);
SetupCommand(0x0e, "CmdEnableInterface", &SCSIDEV::CmdEnableInterface);
}
SCSIDEV::~SCSIDEV()
{
for (auto const& command : scsi_commands) {
free(command.second);
}
}
void FASTCALL SCSIDEV::SetupCommand(BYTE opcode, const char* name, void FASTCALL (SCSIDEV::*execute)(void))
{
scsi_commands[opcode] = new command_t(name, execute);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -255,213 +308,19 @@ void FASTCALL SCSIDEV::Execute()
ctrl.execstart = SysTimer::GetTimerLow(); ctrl.execstart = SysTimer::GetTimerLow();
#endif // RASCSI #endif // RASCSI
// Process by command // If the command is valid it must be contained in the command map
switch ((scsi_command)ctrl.cmd[0]) { if (!scsi_commands.count(ctrl.cmd[0])) {
// TEST UNIT READY LOGWARN("%s Received unsupported command: $%02X", __PRETTY_FUNCTION__, (BYTE)ctrl.cmd[0]);
case eCmdTestUnitReady: CmdInvalid();
LOGDEBUG("++++ CMD ++++ %s Received eCmdTestUnitReady", __PRETTY_FUNCTION__); return;
CmdTestUnitReady();
return;
// REZERO
case eCmdRezero:
CmdRezero();
return;
// REQUEST SENSE
case eCmdRequestSense:
LOGDEBUG("++++ CMD ++++ %s Received eCmdRequestSense", __PRETTY_FUNCTION__);
CmdRequestSense();
return;
// FORMAT UNIT
case eCmdFormat:
CmdFormat();
return;
// REASSIGN BLOCKS
case eCmdReassign:
CmdReassign();
return;
// READ(6)
case eCmdRead6:
LOGTRACE("++++ CMD ++++ %s Received eCmdRead6", __PRETTY_FUNCTION__);
CmdRead6();
return;
case eCmdRetrieveStats:
LOGDEBUG("++++ CMD ++++ %s Received eCmdRetrieveStats", __PRETTY_FUNCTION__);
CmdRetrieveStats();
return;
case eCmdSetIfaceMode:
LOGDEBUG("++++ CMD ++++ %s Received eCmdSetIfaceMode", __PRETTY_FUNCTION__);
CmdSetIfaceMode();
return;
case eCmdSetMcastAddr:
LOGDEBUG("++++ CMD ++++ %s Received eCmdSetMcastAddr", __PRETTY_FUNCTION__);
CmdSetMcastAddr();
return;
case eCmdEnableInterface:
LOGDEBUG("++++ CMD ++++ %s Received eCmdEnableInterface", __PRETTY_FUNCTION__);
CmdEnableInterface();
return;
// WRITE(6)
case eCmdWrite6:
LOGDEBUG("++++ CMD ++++ %s Received eCmdWrite6", __PRETTY_FUNCTION__);
CmdWrite6();
return;
// SEEK(6)
case eCmdSeek6:
LOGDEBUG("++++ CMD ++++ %s Received eCmdSeek6", __PRETTY_FUNCTION__);
CmdSeek6();
return;
// INQUIRY
case eCmdInquiry:
LOGDEBUG("++++ CMD ++++ %s Received eCmdInquiry", __PRETTY_FUNCTION__);
CmdInquiry();
return;
// MODE SELECT
case eCmdModeSelect:
LOGDEBUG("++++ CMD ++++ %s Received eCmdModeSelect", __PRETTY_FUNCTION__);
CmdModeSelect();
return;
// RESERVE(6)
case eCmdReserve6:
LOGDEBUG("++++ CMD ++++ %s Received eCmdReserve6", __PRETTY_FUNCTION__);
CmdReserve6();
return;
// RESERVE(10)
case eCmdReserve10:
LOGDEBUG("++++ CMD ++++ %s Received eCmdReserve10", __PRETTY_FUNCTION__);
CmdReserve10();
return;
// RELEASE(6)
case eCmdRelease6:
LOGDEBUG("++++ CMD ++++ %s Received eCmdRelease6", __PRETTY_FUNCTION__);
CmdRelease6();
return;
// RELEASE(10)
case eCmdRelease10:
LOGDEBUG("++++ CMD ++++ %s Received eCmdRelease10", __PRETTY_FUNCTION__);
CmdRelease10();
return;
// MODE SENSE
case eCmdModeSense:
LOGDEBUG("++++ CMD ++++ %s Received eCmdModeSense", __PRETTY_FUNCTION__);
CmdModeSense();
return;
// START STOP UNIT
case eCmdStartStop:
LOGDEBUG("++++ CMD ++++ %s Received eCmdStartStop", __PRETTY_FUNCTION__);
CmdStartStop();
return;
// SEND DIAGNOSTIC
case eCmdSendDiag:
LOGDEBUG("++++ CMD ++++ %s Received eCmdSendDiag", __PRETTY_FUNCTION__);
CmdSendDiag();
return;
// PREVENT/ALLOW MEDIUM REMOVAL
case eCmdRemoval:
CmdRemoval();
return;
// READ CAPACITY
case eCmdReadCapacity:
CmdReadCapacity();
return;
// READ(10)
case eCmdRead10:
LOGDEBUG("++++ CMD ++++ %s Received eCmdRead10", __PRETTY_FUNCTION__);
CmdRead10();
return;
// WRITE(10)
// WRITE and VERIFY(10)
case eCmdWrite10:
case eCmdWriteAndVerify10:
LOGDEBUG("++++ CMD ++++ %s Received eCmdWrite10", __PRETTY_FUNCTION__);
CmdWrite10();
return;
// SEEK(10)
case eCmdSeek10:
CmdSeek10();
return;
// VERIFY
case eCmdVerify:
CmdVerify();
return;
// SYNCHRONIZE CACHE
case eCmdSynchronizeCache:
CmdSynchronizeCache();
return;
// READ DEFECT DATA(10)
case eCmdReadDefectData10:
CmdReadDefectData10();
return;
// READ TOC
case eCmdReadToc:
CmdReadToc();
return;
// PLAY AUDIO(10)
case eCmdPlayAudio10:
CmdPlayAudio10();
return;
// PLAY AUDIO MSF
case eCmdPlayAudioMSF:
CmdPlayAudioMSF();
return;
// PLAY AUDIO TRACK
case eCmdPlayAudioTrack:
CmdPlayAudioTrack();
return;
// MODE SELECT(10)
case eCmdModeSelect10:
CmdModeSelect10();
return;
// MDOE SENSE(10)
case eCmdModeSense10:
CmdModeSense10();
return;
// SPECIFY (SASI only/Suppress warning when using SxSI)
case eCmdInvalid:
CmdInvalid();
return;
default:
// No other support
LOGWARN("%s Received unsupported command: $%02X", __PRETTY_FUNCTION__, (BYTE)ctrl.cmd[0]);
CmdInvalid();
} }
return;
command_t* command = scsi_commands[ctrl.cmd[0]];
LOGDEBUG("++++ CMD ++++ %s Received %s ($%02X)", __PRETTY_FUNCTION__, command->name, (unsigned int)ctrl.cmd[0]);
// Process by command
(this->*command->execute)();
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -616,7 +475,7 @@ void FASTCALL SCSIDEV::CmdModeSelect()
LOGTRACE( "%s MODE SELECT Command", __PRETTY_FUNCTION__); LOGTRACE( "%s MODE SELECT Command", __PRETTY_FUNCTION__);
DWORD lun = GetLun(); DWORD lun = GetLun();
// Command processing on drive // Command processing on drive
ctrl.length = ctrl.unit[lun]->SelectCheck(ctrl.cmd); ctrl.length = ctrl.unit[lun]->SelectCheck(ctrl.cmd);
@ -718,7 +577,7 @@ void FASTCALL SCSIDEV::CmdModeSense()
LOGTRACE( "%s MODE SENSE Command ", __PRETTY_FUNCTION__); LOGTRACE( "%s MODE SENSE Command ", __PRETTY_FUNCTION__);
DWORD lun = GetLun(); DWORD lun = GetLun();
// Command processing on drive // Command processing on drive
ctrl.length = ctrl.unit[lun]->ModeSense(ctrl.cmd, ctrl.buffer); ctrl.length = ctrl.unit[lun]->ModeSense(ctrl.cmd, ctrl.buffer);
@ -748,7 +607,7 @@ void FASTCALL SCSIDEV::CmdStartStop()
LOGTRACE( "%s START STOP UNIT Command ", __PRETTY_FUNCTION__); LOGTRACE( "%s START STOP UNIT Command ", __PRETTY_FUNCTION__);
DWORD lun = GetLun(); DWORD lun = GetLun();
// Command processing on drive // Command processing on drive
status = ctrl.unit[lun]->StartStop(ctrl.cmd); status = ctrl.unit[lun]->StartStop(ctrl.cmd);
@ -775,7 +634,7 @@ void FASTCALL SCSIDEV::CmdSendDiag()
LOGTRACE( "%s SEND DIAGNOSTIC Command ", __PRETTY_FUNCTION__); LOGTRACE( "%s SEND DIAGNOSTIC Command ", __PRETTY_FUNCTION__);
DWORD lun = GetLun(); DWORD lun = GetLun();
// Command processing on drive // Command processing on drive
status = ctrl.unit[lun]->SendDiag(ctrl.cmd); status = ctrl.unit[lun]->SendDiag(ctrl.cmd);
@ -802,7 +661,7 @@ void FASTCALL SCSIDEV::CmdRemoval()
LOGTRACE( "%s PREVENT/ALLOW MEDIUM REMOVAL Command ", __PRETTY_FUNCTION__); LOGTRACE( "%s PREVENT/ALLOW MEDIUM REMOVAL Command ", __PRETTY_FUNCTION__);
DWORD lun = GetLun(); DWORD lun = GetLun();
// Command processing on drive // Command processing on drive
status = ctrl.unit[lun]->Removal(ctrl.cmd); status = ctrl.unit[lun]->Removal(ctrl.cmd);
@ -829,7 +688,7 @@ void FASTCALL SCSIDEV::CmdReadCapacity()
LOGTRACE( "%s READ CAPACITY Command ", __PRETTY_FUNCTION__); LOGTRACE( "%s READ CAPACITY Command ", __PRETTY_FUNCTION__);
DWORD lun = GetLun(); DWORD lun = GetLun();
// Command processing on drive // Command processing on drive
length = ctrl.unit[lun]->ReadCapacity(ctrl.cmd, ctrl.buffer); length = ctrl.unit[lun]->ReadCapacity(ctrl.cmd, ctrl.buffer);
@ -857,7 +716,7 @@ void FASTCALL SCSIDEV::CmdRead10()
ASSERT(this); ASSERT(this);
DWORD lun = GetLun(); DWORD lun = GetLun();
// Receive message if host bridge // Receive message if host bridge
if (ctrl.unit[lun]->GetID() == MAKEID('S', 'C', 'B', 'R')) { if (ctrl.unit[lun]->GetID() == MAKEID('S', 'C', 'B', 'R')) {
@ -911,7 +770,7 @@ void FASTCALL SCSIDEV::CmdWrite10()
ASSERT(this); ASSERT(this);
DWORD lun = GetLun(); DWORD lun = GetLun();
// Receive message with host bridge // Receive message with host bridge
if (ctrl.unit[lun]->GetID() == MAKEID('S', 'C', 'B', 'R')) { if (ctrl.unit[lun]->GetID() == MAKEID('S', 'C', 'B', 'R')) {
@ -967,7 +826,7 @@ void FASTCALL SCSIDEV::CmdSeek10()
LOGTRACE( "%s SEEK(10) Command ", __PRETTY_FUNCTION__); LOGTRACE( "%s SEEK(10) Command ", __PRETTY_FUNCTION__);
DWORD lun = GetLun(); DWORD lun = GetLun();
// Command processing on drive // Command processing on drive
status = ctrl.unit[lun]->Seek(ctrl.cmd); status = ctrl.unit[lun]->Seek(ctrl.cmd);
@ -993,7 +852,7 @@ void FASTCALL SCSIDEV::CmdVerify()
ASSERT(this); ASSERT(this);
DWORD lun = GetLun(); DWORD lun = GetLun();
// Get record number and block number // Get record number and block number
record = ctrl.cmd[2]; record = ctrl.cmd[2];
@ -1054,7 +913,7 @@ void FASTCALL SCSIDEV::CmdSynchronizeCache()
{ {
ASSERT(this); ASSERT(this);
GetLun(); GetLun();
// Make it do something (not implemented)... // Make it do something (not implemented)...
@ -1073,7 +932,7 @@ void FASTCALL SCSIDEV::CmdReadDefectData10()
LOGTRACE( "%s READ DEFECT DATA(10) Command ", __PRETTY_FUNCTION__); LOGTRACE( "%s READ DEFECT DATA(10) Command ", __PRETTY_FUNCTION__);
DWORD lun = GetLun(); DWORD lun = GetLun();
// Command processing on drive // Command processing on drive
ctrl.length = ctrl.unit[lun]->ReadDefectData10(ctrl.cmd, ctrl.buffer); ctrl.length = ctrl.unit[lun]->ReadDefectData10(ctrl.cmd, ctrl.buffer);
@ -1097,7 +956,7 @@ void FASTCALL SCSIDEV::CmdReadToc()
{ {
ASSERT(this); ASSERT(this);
DWORD lun = GetLun(); DWORD lun = GetLun();
// Command processing on drive // Command processing on drive
ctrl.length = ctrl.unit[lun]->ReadToc(ctrl.cmd, ctrl.buffer); ctrl.length = ctrl.unit[lun]->ReadToc(ctrl.cmd, ctrl.buffer);
@ -1122,7 +981,7 @@ void FASTCALL SCSIDEV::CmdPlayAudio10()
ASSERT(this); ASSERT(this);
DWORD lun = GetLun(); DWORD lun = GetLun();
// Command processing on drive // Command processing on drive
status = ctrl.unit[lun]->PlayAudio(ctrl.cmd); status = ctrl.unit[lun]->PlayAudio(ctrl.cmd);
@ -1147,7 +1006,7 @@ void FASTCALL SCSIDEV::CmdPlayAudioMSF()
ASSERT(this); ASSERT(this);
DWORD lun = GetLun(); DWORD lun = GetLun();
// Command processing on drive // Command processing on drive
status = ctrl.unit[lun]->PlayAudioMSF(ctrl.cmd); status = ctrl.unit[lun]->PlayAudioMSF(ctrl.cmd);
@ -1172,7 +1031,7 @@ void FASTCALL SCSIDEV::CmdPlayAudioTrack()
ASSERT(this); ASSERT(this);
DWORD lun = GetLun(); DWORD lun = GetLun();
// Command processing on drive // Command processing on drive
status = ctrl.unit[lun]->PlayAudioTrack(ctrl.cmd); status = ctrl.unit[lun]->PlayAudioTrack(ctrl.cmd);
@ -1197,7 +1056,7 @@ void FASTCALL SCSIDEV::CmdModeSelect10()
LOGTRACE( "%s MODE SELECT10 Command ", __PRETTY_FUNCTION__); LOGTRACE( "%s MODE SELECT10 Command ", __PRETTY_FUNCTION__);
DWORD lun = GetLun(); DWORD lun = GetLun();
// Command processing on drive // Command processing on drive
ctrl.length = ctrl.unit[lun]->SelectCheck10(ctrl.cmd); ctrl.length = ctrl.unit[lun]->SelectCheck10(ctrl.cmd);
@ -1222,7 +1081,7 @@ void FASTCALL SCSIDEV::CmdModeSense10()
LOGTRACE( "%s MODE SENSE(10) Command ", __PRETTY_FUNCTION__); LOGTRACE( "%s MODE SENSE(10) Command ", __PRETTY_FUNCTION__);
DWORD lun = GetLun(); DWORD lun = GetLun();
// Command processing on drive // Command processing on drive
ctrl.length = ctrl.unit[lun]->ModeSense10(ctrl.cmd, ctrl.buffer); ctrl.length = ctrl.unit[lun]->ModeSense10(ctrl.cmd, ctrl.buffer);
@ -1250,7 +1109,7 @@ void FASTCALL SCSIDEV::CmdGetMessage10()
ASSERT(this); ASSERT(this);
DWORD lun = GetLun(); DWORD lun = GetLun();
// 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')) &&
@ -1296,7 +1155,7 @@ void FASTCALL SCSIDEV::CmdSendMessage10()
{ {
ASSERT(this); ASSERT(this);
DWORD lun = GetLun(); DWORD lun = GetLun();
// 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')) {
@ -1344,7 +1203,7 @@ void FASTCALL SCSIDEV::CmdRetrieveStats()
ASSERT(this); ASSERT(this);
DWORD lun = GetLun(); DWORD lun = GetLun();
// Error if not a DaynaPort SCSI Link // Error if not a DaynaPort SCSI Link
if (ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'D', 'P')){ if (ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'D', 'P')){
@ -1384,7 +1243,7 @@ void FASTCALL SCSIDEV::CmdSetIfaceMode()
LOGTRACE("%s",__PRETTY_FUNCTION__); LOGTRACE("%s",__PRETTY_FUNCTION__);
DWORD lun = GetLun(); DWORD lun = GetLun();
// Error if not a DaynaPort SCSI Link // Error if not a DaynaPort SCSI Link
if (ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'D', 'P')){ if (ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'D', 'P')){
@ -1426,7 +1285,7 @@ void FASTCALL SCSIDEV::CmdSetMcastAddr()
LOGTRACE("%s Set Multicast Address Command ", __PRETTY_FUNCTION__); LOGTRACE("%s Set Multicast Address Command ", __PRETTY_FUNCTION__);
DWORD lun = GetLun(); DWORD lun = GetLun();
if (ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'D', 'P')){ if (ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'D', 'P')){
LOGWARN("Received a SetMcastAddress command for a non-daynaport unit"); LOGWARN("Received a SetMcastAddress command for a non-daynaport unit");
@ -1463,7 +1322,7 @@ void FASTCALL SCSIDEV::CmdEnableInterface()
LOGTRACE("%s",__PRETTY_FUNCTION__); LOGTRACE("%s",__PRETTY_FUNCTION__);
DWORD lun = GetLun(); DWORD lun = GetLun();
// Error if not a DaynaPort SCSI Link // Error if not a DaynaPort SCSI Link
if (ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'D', 'P')){ if (ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'D', 'P')){

View File

@ -15,6 +15,7 @@
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#pragma once #pragma once
#include "controllers/sasidev_ctrl.h" #include "controllers/sasidev_ctrl.h"
#include <map>
//=========================================================================== //===========================================================================
// //
@ -38,79 +39,21 @@ public:
BYTE msb[256]; BYTE msb[256];
} scsi_t; } scsi_t;
// SCSI command name and pointer to implementation
typedef struct _command_t {
const char* name;
void FASTCALL (SCSIDEV::*execute)(void);
enum scsi_message_code : BYTE { _command_t(const char* _name, void FASTCALL (SCSIDEV::*_execute)(void)) : name(_name), execute(_execute) { };
eMsgCodeAbort = 0x06, } command_t;
eMsgCodeAbortTag = 0x0D,
eMsgCodeBusDeviceReset = 0x0C,
eMsgCodeClearQueue = 0x0E,
eMsgCodeCommandComplete = 0x00,
eMsgCodeDisconnect = 0x04,
eMsgCodeIdentify = 0x80,
eMsgCodeIgnoreWideResidue = 0x23, // (Two Bytes)
eMsgCodeInitiateRecovery = 0x0F,
eMsgCodeInitiatorDetectedError = 0x05,
eMsgCodeLinkedCommandComplete = 0x0A,
eMsgCodeLinkedCommandCompleteWithFlag = 0x0B,
eMsgCodeMessageParityError = 0x09,
eMsgCodeMessageReject = 0x07,
eMsgCodeNoOperation = 0x08,
eMsgCodeHeadOfQueueTag = 0x21,
eMsgCodeOrderedQueueTag = 0x22,
eMsgCodeSimpleQueueTag = 0x20,
eMsgCodeReleaseRecovery = 0x10,
eMsgCodeRestorePointers = 0x03,
eMsgCodeSaveDataPointer = 0x02,
eMsgCodeTerminateIOProcess = 0x11,
};
// Mapping of SCSI opcodes to command implementations
enum scsi_command : BYTE { std::map<BYTE, command_t*> scsi_commands;
eCmdTestUnitReady = 0x00,
eCmdRezero = 0x01,
eCmdRequestSense = 0x03,
eCmdFormat = 0x04,
eCmdReassign = 0x07,
eCmdRead6 = 0x08,
eCmdRetrieveStats = 0x09, // DaynaPort specific command
eCmdWrite6 = 0x0A,
eCmdSeek6 = 0x0B,
eCmdSetIfaceMode = 0x0C, // DaynaPort specific command
eCmdSetMcastAddr = 0x0D, // DaynaPort specific command
eCmdEnableInterface = 0x0E, // DaynaPort specific command
eCmdInquiry = 0x12,
eCmdModeSelect = 0x15,
eCmdReserve6 = 0x16,
eCmdRelease6 = 0x17,
eCmdModeSense = 0x1A,
eCmdStartStop = 0x1B,
eCmdRcvDiag = 0x1C,
eCmdSendDiag = 0x1D,
eCmdRemoval = 0x1E,
eCmdReadCapacity = 0x25,
eCmdRead10 = 0x28,
eCmdWrite10 = 0x2A,
eCmdSeek10 = 0x2B,
eCmdWriteAndVerify10 = 0x2E,
eCmdVerify = 0x2F,
eCmdSynchronizeCache = 0x35,
eCmdReadDefectData10 = 0x37,
eCmdReadToc = 0x43,
eCmdPlayAudio10 = 0x45,
eCmdPlayAudioMSF = 0x47,
eCmdPlayAudioTrack = 0x48,
eCmdModeSelect10 = 0x55,
eCmdReserve10 = 0x56,
eCmdRelease10 = 0x57,
eCmdModeSense10 = 0x5A,
eCmdInvalid = 0xC2, // (SASI only/Suppress warning when using SxSI)
eCmdSasiCmdAssign = 0x0e, // This isn't used by SCSI, and can probably be removed.
};
public: public:
// Basic Functions // Basic Functions
SCSIDEV(); SCSIDEV();
// Constructor ~SCSIDEV();
void FASTCALL Reset(); // Device Reset void FASTCALL Reset(); // Device Reset
@ -124,6 +67,8 @@ public:
BOOL FASTCALL IsSCSI() const {return TRUE;} // SCSI check BOOL FASTCALL IsSCSI() const {return TRUE;} // SCSI check
private: private:
void FASTCALL SetupCommand(BYTE, const char*, void FASTCALL (SCSIDEV::*)(void));
// Phase // Phase
void FASTCALL BusFree(); // Bus free phase void FASTCALL BusFree(); // Bus free phase
void FASTCALL Selection(); // Selection phase void FASTCALL Selection(); // Selection phase

View File

@ -35,6 +35,7 @@ CTapDriver::CTapDriver()
{ {
LOGTRACE("%s",__PRETTY_FUNCTION__); LOGTRACE("%s",__PRETTY_FUNCTION__);
// Initialization // Initialization
m_bTxValid = FALSE;
m_hTAP = -1; m_hTAP = -1;
memset(&m_MacAddr, 0, sizeof(m_MacAddr)); memset(&m_MacAddr, 0, sizeof(m_MacAddr));
m_pcap = NULL; m_pcap = NULL;