mirror of
https://github.com/akuker/RASCSI.git
synced 2024-12-24 12:30:20 +00:00
Moved Daynaport code to the Daynaport class
This commit is contained in:
parent
cdf9a6ad5b
commit
806e0e0f27
@ -48,12 +48,6 @@ SCSIDEV::SCSIDEV() : SASIDEV()
|
||||
SetUpControllerCommand(eCmdPlayAudioMSF, "CmdPlayAudioMSF", &SCSIDEV::CmdPlayAudioMSF);
|
||||
SetUpControllerCommand(eCmdPlayAudioTrack, "CmdPlayAudioTrack", &SCSIDEV::CmdPlayAudioTrack);
|
||||
SetUpControllerCommand(eCmdGetEventStatusNotification, "CmdGetEventStatusNotification", &SCSIDEV::CmdGetEventStatusNotification);
|
||||
|
||||
// DaynaPort specific. TODO Move to separate class
|
||||
SetUpControllerCommand(eCmdRetrieveStats, "CmdRetrieveStats", &SCSIDEV::CmdRetrieveStats);
|
||||
SetUpControllerCommand(eCmdSetIfaceMode, "CmdSetIfaceMode", &SCSIDEV::CmdSetIfaceMode);
|
||||
SetUpControllerCommand(eCmdSetMcastAddr, "CmdSetMcastAddr", &SCSIDEV::CmdSetMcastAddr);
|
||||
SetUpControllerCommand(eCmdEnableInterface, "CmdEnableInterface", &SCSIDEV::CmdEnableInterface);
|
||||
}
|
||||
|
||||
SCSIDEV::~SCSIDEV()
|
||||
@ -550,140 +544,6 @@ void SCSIDEV::CmdSendMessage10()
|
||||
DataOut();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Retrieve Statistics (09)
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
void SCSIDEV::CmdRetrieveStats()
|
||||
{
|
||||
// TODO Move Daynaport specific test
|
||||
// Error if not a DaynaPort SCSI Link
|
||||
if (!ctrl.device->IsDaynaPort()) {
|
||||
LOGWARN("Received a CmdRetrieveStats command for a non-daynaport unit %s", ctrl.device->GetType().c_str());
|
||||
Error(ERROR_CODES::sense_key::ILLEGAL_REQUEST, ERROR_CODES::asc::INVALID_COMMAND_OPERATION_CODE);
|
||||
return;
|
||||
}
|
||||
|
||||
// Process with drive
|
||||
SCSIDaynaPort *dayna_port = (SCSIDaynaPort*)ctrl.device;
|
||||
ctrl.length = dayna_port->RetrieveStats(ctrl.cmd, ctrl.buffer);
|
||||
|
||||
if (ctrl.length <= 0) {
|
||||
// Failure (Error)
|
||||
Error();
|
||||
return;
|
||||
}
|
||||
|
||||
// Set next block
|
||||
ctrl.blocks = 1;
|
||||
ctrl.next = 1;
|
||||
|
||||
// Data in phase
|
||||
DataIn();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Set Interface Mode (0c)
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
void SCSIDEV::CmdSetIfaceMode()
|
||||
{
|
||||
LOGTRACE("%s",__PRETTY_FUNCTION__);
|
||||
|
||||
// TODO Move DaynaPort specific test
|
||||
// Error if not a DaynaPort SCSI Link
|
||||
if (!ctrl.device->IsDaynaPort()) {
|
||||
LOGWARN("%s Received a CmdSetIfaceMode command for a non-daynaport unit %s", __PRETTY_FUNCTION__, ctrl.device->GetType().c_str());
|
||||
Error(ERROR_CODES::sense_key::ILLEGAL_REQUEST, ERROR_CODES::asc::INVALID_COMMAND_OPERATION_CODE);
|
||||
return;
|
||||
}
|
||||
|
||||
SCSIDaynaPort *dayna_port = (SCSIDaynaPort*)ctrl.device;
|
||||
|
||||
// Check whether this command is telling us to "Set Interface Mode" or "Set MAC Address"
|
||||
|
||||
ctrl.length = dayna_port->RetrieveStats(ctrl.cmd, ctrl.buffer);
|
||||
switch(ctrl.cmd[5]){
|
||||
case SCSIDaynaPort::CMD_SCSILINK_SETMODE:
|
||||
dayna_port->SetMode(ctrl.cmd, ctrl.buffer);
|
||||
Status();
|
||||
break;
|
||||
break;
|
||||
case SCSIDaynaPort::CMD_SCSILINK_SETMAC:
|
||||
ctrl.length = 6;
|
||||
// Write phase
|
||||
DataOut();
|
||||
break;
|
||||
default:
|
||||
LOGWARN("%s Unknown SetInterface command received: %02X", __PRETTY_FUNCTION__, (unsigned int)ctrl.cmd[5]);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Set the multicast address
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
void SCSIDEV::CmdSetMcastAddr()
|
||||
{
|
||||
LOGTRACE("%s Set Multicast Address Command ", __PRETTY_FUNCTION__);
|
||||
|
||||
// TODO Move DaynaPort specific test
|
||||
if (!ctrl.device->IsDaynaPort()) {
|
||||
LOGWARN("Received a SetMcastAddress command for a non-daynaport unit");
|
||||
Error(ERROR_CODES::sense_key::ILLEGAL_REQUEST, ERROR_CODES::asc::INVALID_COMMAND_OPERATION_CODE);
|
||||
return;
|
||||
}
|
||||
|
||||
// Command processing on drive
|
||||
ctrl.length = (DWORD)ctrl.cmd[4];
|
||||
|
||||
// ASSERT(ctrl.length >= 0);
|
||||
if (ctrl.length == 0) {
|
||||
LOGWARN("%s Not supported SetMcastAddr Command %02X", __PRETTY_FUNCTION__, (WORD)ctrl.cmd[2]);
|
||||
|
||||
// Failure (Error)
|
||||
Error();
|
||||
return;
|
||||
}
|
||||
|
||||
DataOut();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Enable/disable Interface (0e)
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
void SCSIDEV::CmdEnableInterface()
|
||||
{
|
||||
LOGTRACE("%s",__PRETTY_FUNCTION__);
|
||||
|
||||
// TODO Move DaynaPort specific test
|
||||
// Error if not a DaynaPort SCSI Link
|
||||
if (!ctrl.device->IsDaynaPort()) {
|
||||
LOGWARN("%s Received a CmdEnableInterface command for a non-daynaport unit %s", __PRETTY_FUNCTION__, ctrl.device->GetType().c_str());
|
||||
Error(ERROR_CODES::sense_key::ILLEGAL_REQUEST, ERROR_CODES::asc::INVALID_COMMAND_OPERATION_CODE);
|
||||
return;
|
||||
}
|
||||
|
||||
SCSIDaynaPort *dayna_port = (SCSIDaynaPort*)ctrl.device;
|
||||
|
||||
// Command processing on drive
|
||||
bool status = dayna_port->EnableInterface(ctrl.cmd);
|
||||
if (!status) {
|
||||
// Failure (Error)
|
||||
Error();
|
||||
return;
|
||||
}
|
||||
|
||||
// status phase
|
||||
Status();
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Data Transfer
|
||||
@ -708,6 +568,7 @@ void SCSIDEV::Send()
|
||||
s << __PRETTY_FUNCTION__ << " sending handhake with offset " << ctrl.offset << ", length " << ctrl.length;
|
||||
LOGTRACE("%s", s.str().c_str());
|
||||
|
||||
// TODO Get rid of Daynaport specific code
|
||||
// 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.
|
||||
|
@ -131,10 +131,6 @@ private:
|
||||
void CmdGetEventStatusNotification();
|
||||
void CmdModeSelect10(); // MODE SELECT(10) command
|
||||
void CmdModeSense10(); // MODE SENSE(10) command
|
||||
void CmdRetrieveStats(); // DaynaPort specific command
|
||||
void CmdSetIfaceMode(); // DaynaPort specific command
|
||||
void CmdSetMcastAddr(); // DaynaPort specific command
|
||||
void CmdEnableInterface(); // DaynaPort specific command
|
||||
// データ転送
|
||||
void Send(); // Send data
|
||||
void Receive(); // Receive data
|
||||
|
@ -1330,22 +1330,22 @@ Disk::~Disk()
|
||||
disk.dcache = NULL;
|
||||
}
|
||||
|
||||
for (auto const& command : disk_commands) {
|
||||
for (auto const& command : commands) {
|
||||
free(command.second);
|
||||
}
|
||||
}
|
||||
|
||||
void Disk::AddCommand(SCSIDEV::scsi_command opcode, const char* name, void (Disk::*execute)(SASIDEV *))
|
||||
{
|
||||
disk_commands[opcode] = new disk_command_t(name, execute);
|
||||
commands[opcode] = new command_t(name, execute);
|
||||
}
|
||||
|
||||
bool Disk::Dispatch(SCSIDEV *controller)
|
||||
{
|
||||
SASIDEV::ctrl_t *ctrl = controller->GetWorkAddr();
|
||||
|
||||
if (disk_commands.count(static_cast<SCSIDEV::scsi_command>(ctrl->cmd[0]))) {
|
||||
disk_command_t *command = disk_commands[static_cast<SCSIDEV::scsi_command>(ctrl->cmd[0])];
|
||||
if (commands.count(static_cast<SCSIDEV::scsi_command>(ctrl->cmd[0]))) {
|
||||
command_t *command = commands[static_cast<SCSIDEV::scsi_command>(ctrl->cmd[0])];
|
||||
|
||||
LOGDEBUG("++++ CMD ++++ %s received %s ($%02X)", __PRETTY_FUNCTION__, command->name, (unsigned int)ctrl->cmd[0]);
|
||||
|
||||
|
@ -140,13 +140,13 @@ protected:
|
||||
} disk_t;
|
||||
|
||||
private:
|
||||
typedef struct _disk_command_t {
|
||||
typedef struct _command_t {
|
||||
const char* name;
|
||||
void (Disk::*execute)(SASIDEV *);
|
||||
|
||||
_disk_command_t(const char* _name, void (Disk::*_execute)(SASIDEV *)) : name(_name), execute(_execute) { };
|
||||
} disk_command_t;
|
||||
std::map<SCSIDEV::scsi_command, disk_command_t*> disk_commands;
|
||||
_command_t(const char* _name, void (Disk::*_execute)(SASIDEV *)) : name(_name), execute(_execute) { };
|
||||
} command_t;
|
||||
std::map<SCSIDEV::scsi_command, command_t*> commands;
|
||||
|
||||
public:
|
||||
// Basic Functions
|
||||
@ -231,7 +231,7 @@ public:
|
||||
bool Format(const DWORD *cdb); // FORMAT UNIT command
|
||||
bool Reassign(const DWORD *cdb); // REASSIGN UNIT command
|
||||
|
||||
bool Dispatch(SCSIDEV *);
|
||||
virtual bool Dispatch(SCSIDEV *);
|
||||
|
||||
protected:
|
||||
// Internal processing
|
||||
|
@ -91,6 +91,10 @@ SCSIDaynaPort::SCSIDaynaPort() : Disk("SCDP")
|
||||
#endif // linux
|
||||
LOGTRACE("SCSIDaynaPort Constructor End");
|
||||
|
||||
AddCommand(SCSIDEV::eCmdRetrieveStats, "CmdRetrieveStats", &SCSIDaynaPort::CmdRetrieveStats);
|
||||
AddCommand(SCSIDEV::eCmdSetIfaceMode, "CmdSetIfaceMode", &SCSIDaynaPort::CmdSetIfaceMode);
|
||||
AddCommand(SCSIDEV::eCmdSetMcastAddr, "CmdSetMcastAddr", &SCSIDaynaPort::CmdSetMcastAddr);
|
||||
AddCommand(SCSIDEV::eCmdEnableInterface, "CmdEnableInterface", &SCSIDaynaPort::CmdEnableInterface);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
@ -106,6 +110,10 @@ SCSIDaynaPort::~SCSIDaynaPort()
|
||||
m_tap->Cleanup();
|
||||
delete m_tap;
|
||||
}
|
||||
|
||||
for (auto const& command : commands) {
|
||||
free(command.second);
|
||||
}
|
||||
}
|
||||
|
||||
void SCSIDaynaPort::Open(const Filepath& path, BOOL attn)
|
||||
@ -114,6 +122,28 @@ SCSIDaynaPort::~SCSIDaynaPort()
|
||||
m_tap->OpenDump(path);
|
||||
}
|
||||
|
||||
void SCSIDaynaPort::AddCommand(SCSIDEV::scsi_command opcode, const char* name, void (SCSIDaynaPort::*execute)(SASIDEV *))
|
||||
{
|
||||
commands[opcode] = new command_t(name, execute);
|
||||
}
|
||||
|
||||
bool SCSIDaynaPort::Dispatch(SCSIDEV *controller)
|
||||
{
|
||||
SASIDEV::ctrl_t *ctrl = controller->GetWorkAddr();
|
||||
|
||||
if (commands.count(static_cast<SCSIDEV::scsi_command>(ctrl->cmd[0]))) {
|
||||
command_t *command = commands[static_cast<SCSIDEV::scsi_command>(ctrl->cmd[0])];
|
||||
|
||||
LOGDEBUG("++++ CMD ++++ %s received %s ($%02X)", __PRETTY_FUNCTION__, command->name, (unsigned int)ctrl->cmd[0]);
|
||||
|
||||
(this->*command->execute)(controller);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return Disk::Dispatch(controller);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// INQUIRY
|
||||
@ -493,6 +523,90 @@ bool SCSIDaynaPort::TestUnitReady(const DWORD* /*cdb*/)
|
||||
return true;
|
||||
}
|
||||
|
||||
void SCSIDaynaPort::CmdRetrieveStats(SASIDEV *controller)
|
||||
{
|
||||
LOGTRACE("%s",__PRETTY_FUNCTION__);
|
||||
|
||||
SASIDEV::ctrl_t *ctrl = controller->GetWorkAddr();
|
||||
|
||||
ctrl->length = RetrieveStats(ctrl->cmd, ctrl->buffer);
|
||||
|
||||
if (ctrl->length <= 0) {
|
||||
// Failure (Error)
|
||||
controller->Error();
|
||||
return;
|
||||
}
|
||||
|
||||
// Set next block
|
||||
ctrl->blocks = 1;
|
||||
ctrl->next = 1;
|
||||
|
||||
// Data in phase
|
||||
controller->DataIn();
|
||||
}
|
||||
|
||||
void SCSIDaynaPort::CmdSetIfaceMode(SASIDEV *controller)
|
||||
{
|
||||
LOGTRACE("%s",__PRETTY_FUNCTION__);
|
||||
|
||||
SASIDEV::ctrl_t *ctrl = controller->GetWorkAddr();
|
||||
|
||||
// Check whether this command is telling us to "Set Interface Mode" or "Set MAC Address"
|
||||
|
||||
ctrl->length = RetrieveStats(ctrl->cmd, ctrl->buffer);
|
||||
switch(ctrl->cmd[5]){
|
||||
case SCSIDaynaPort::CMD_SCSILINK_SETMODE:
|
||||
SetMode(ctrl->cmd, ctrl->buffer);
|
||||
controller->Status();
|
||||
break;
|
||||
break;
|
||||
case SCSIDaynaPort::CMD_SCSILINK_SETMAC:
|
||||
ctrl->length = 6;
|
||||
// Write phase
|
||||
controller->DataOut();
|
||||
break;
|
||||
default:
|
||||
LOGWARN("%s Unknown SetInterface command received: %02X", __PRETTY_FUNCTION__, (unsigned int)ctrl->cmd[5]);
|
||||
}
|
||||
}
|
||||
|
||||
void SCSIDaynaPort::CmdSetMcastAddr(SASIDEV *controller)
|
||||
{
|
||||
LOGTRACE("%s Set Multicast Address Command ", __PRETTY_FUNCTION__);
|
||||
|
||||
SASIDEV::ctrl_t *ctrl = controller->GetWorkAddr();
|
||||
|
||||
ctrl->length = (DWORD)ctrl->cmd[4];
|
||||
|
||||
// ASSERT(ctrl.length >= 0);
|
||||
if (ctrl->length == 0) {
|
||||
LOGWARN("%s Not supported SetMcastAddr Command %02X", __PRETTY_FUNCTION__, (WORD)ctrl->cmd[2]);
|
||||
|
||||
// Failure (Error)
|
||||
controller->Error();
|
||||
return;
|
||||
}
|
||||
|
||||
controller->DataOut();
|
||||
}
|
||||
|
||||
void SCSIDaynaPort::CmdEnableInterface(SASIDEV *controller)
|
||||
{
|
||||
LOGTRACE("%s",__PRETTY_FUNCTION__);
|
||||
|
||||
SASIDEV::ctrl_t *ctrl = controller->GetWorkAddr();
|
||||
|
||||
bool status = EnableInterface(ctrl->cmd);
|
||||
if (!status) {
|
||||
// Failure (Error)
|
||||
controller->Error();
|
||||
return;
|
||||
}
|
||||
|
||||
// status phase
|
||||
controller->Status();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Set Mode - enable broadcast messages
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "os.h"
|
||||
#include "disk.h"
|
||||
#include "ctapdriver.h"
|
||||
#include <map>
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
@ -40,6 +41,16 @@
|
||||
//===========================================================================
|
||||
class SCSIDaynaPort: public Disk
|
||||
{
|
||||
|
||||
private:
|
||||
typedef struct _command_t {
|
||||
const char* name;
|
||||
void (SCSIDaynaPort::*execute)(SASIDEV *);
|
||||
|
||||
_command_t(const char* _name, void (SCSIDaynaPort::*_execute)(SASIDEV *)) : name(_name), execute(_execute) { };
|
||||
} command_t;
|
||||
std::map<SCSIDEV::scsi_command, command_t*> commands;
|
||||
|
||||
public:
|
||||
// Basic Functions
|
||||
SCSIDaynaPort();
|
||||
@ -70,6 +81,14 @@ public:
|
||||
// Set MAC address
|
||||
void SetMode(const DWORD *cdb, BYTE *buffer);
|
||||
// Set the mode: whether broadcast traffic is enabled or not
|
||||
|
||||
void CmdRetrieveStats(SASIDEV *);
|
||||
void CmdSetIfaceMode(SASIDEV *);
|
||||
void CmdSetMcastAddr(SASIDEV *);
|
||||
void CmdEnableInterface(SASIDEV *);
|
||||
|
||||
bool Dispatch(SCSIDEV *);
|
||||
|
||||
static const BYTE CMD_SCSILINK_STATS = 0x09;
|
||||
static const BYTE CMD_SCSILINK_ENABLE = 0x0E;
|
||||
static const BYTE CMD_SCSILINK_SET = 0x0C;
|
||||
@ -179,4 +198,7 @@ private:
|
||||
// MAC Address
|
||||
static const BYTE m_bcast_addr[6];
|
||||
static const BYTE m_apple_talk_addr[6];
|
||||
|
||||
private:
|
||||
void AddCommand(SCSIDEV::scsi_command, const char*, void (SCSIDaynaPort::*)(SASIDEV *));
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user