mirror of
https://github.com/akuker/RASCSI.git
synced 2025-02-27 00:29:40 +00:00
Inheritance hierarchy improvements, reduced dependencies to Disk class (#662)
* Fixed buster compile-time issue * Host services inherit from ModePageDevice * Call base class * Visibility update * Updated includes * Updated dispatcher * Added TODOs * Logging update * Code cleanup * Use namespace instead of class for ScsiDefs * Renaming * Cleanup * Use dispatcher template in order to remove duplicate code * Updated all dispatchers * Clean up commands * Removed duplicate code * Removed duplicate code * Updated template definition * Fixed typo * Fixed warning * Code cleanup * Device list must be static * Cleanup * Logging update * Added comments * Cleanup * Base class update * SCSIBR is not a subclass of Disk anymore, but of PrimaryDevice * Updated includes * Fixed compile-time issue on the Pi * Header file cleanup * Interface cleanup * Removed wrong override * include file cleanup * Removed obsolete usage of streams * Removed more stream usages * Stream usage cleanup * Include cleanup * Renaming * Include cleanup * Interface update
This commit is contained in:
parent
25b9b4ada2
commit
45cd5e58d1
@ -15,7 +15,7 @@
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
#include "../rascsi.h"
|
||||
#include "../config.h"
|
||||
#include "os.h"
|
||||
#include "scsi.h"
|
||||
#include "fileio.h"
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include "controllers/scsidev_ctrl.h"
|
||||
#include "gpiobus.h"
|
||||
#include "devices/scsi_daynaport.h"
|
||||
#include <sstream>
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
@ -239,7 +238,7 @@ void SCSIDEV::Execute()
|
||||
ctrl.execstart = SysTimer::GetTimerLow();
|
||||
|
||||
// Discard pending sense data from the previous command if the current command is not REQUEST SENSE
|
||||
if ((ScsiDefs::scsi_command)ctrl.cmd[0] != ScsiDefs::eCmdRequestSense) {
|
||||
if ((scsi_defs::scsi_command)ctrl.cmd[0] != scsi_defs::eCmdRequestSense) {
|
||||
ctrl.status = 0;
|
||||
}
|
||||
|
||||
@ -247,8 +246,8 @@ void SCSIDEV::Execute()
|
||||
|
||||
int lun = GetEffectiveLun();
|
||||
if (!ctrl.unit[lun]) {
|
||||
if ((ScsiDefs::scsi_command)ctrl.cmd[0] != ScsiDefs::eCmdInquiry &&
|
||||
(ScsiDefs::scsi_command)ctrl.cmd[0] != ScsiDefs::eCmdRequestSense) {
|
||||
if ((scsi_defs::scsi_command)ctrl.cmd[0] != scsi_defs::eCmdInquiry &&
|
||||
(scsi_defs::scsi_command)ctrl.cmd[0] != scsi_defs::eCmdRequestSense) {
|
||||
LOGDEBUG("Invalid LUN %d for ID %d", lun, GetSCSIID());
|
||||
|
||||
Error(ERROR_CODES::sense_key::ILLEGAL_REQUEST, ERROR_CODES::asc::INVALID_LUN);
|
||||
@ -266,7 +265,7 @@ void SCSIDEV::Execute()
|
||||
ctrl.device = ctrl.unit[lun];
|
||||
|
||||
// Discard pending sense data from the previous command if the current command is not REQUEST SENSE
|
||||
if ((ScsiDefs::scsi_command)ctrl.cmd[0] != ScsiDefs::eCmdRequestSense) {
|
||||
if ((scsi_defs::scsi_command)ctrl.cmd[0] != scsi_defs::eCmdRequestSense) {
|
||||
ctrl.device->SetStatusCode(0);
|
||||
}
|
||||
|
||||
@ -277,7 +276,7 @@ void SCSIDEV::Execute()
|
||||
}
|
||||
|
||||
// SCSI-2 p.104 4.4.3 Incorrect logical unit handling
|
||||
if ((ScsiDefs::scsi_command)ctrl.cmd[0] == ScsiDefs::eCmdInquiry && !ctrl.unit[lun]) {
|
||||
if ((scsi_defs::scsi_command)ctrl.cmd[0] == scsi_defs::eCmdInquiry && !ctrl.unit[lun]) {
|
||||
lun = GetEffectiveLun();
|
||||
|
||||
LOGTRACE("Reporting LUN %d for device ID %d as not supported", lun, ctrl.device->GetId());
|
||||
@ -381,9 +380,8 @@ void SCSIDEV::Send()
|
||||
|
||||
//if Length! = 0, send
|
||||
if (ctrl.length != 0) {
|
||||
ostringstream s;
|
||||
s << __PRETTY_FUNCTION__ << " sending handhake with offset " << ctrl.offset << ", length " << ctrl.length;
|
||||
LOGTRACE("%s", s.str().c_str());
|
||||
LOGTRACE("%s%s", __PRETTY_FUNCTION__, (" Sending handhake with offset " + to_string(ctrl.offset) + ", length "
|
||||
+ to_string(ctrl.length)).c_str());
|
||||
|
||||
// TODO Get rid of Daynaport specific code in this class
|
||||
// The Daynaport needs to have a delay after the size/flags field
|
||||
@ -420,9 +418,7 @@ void SCSIDEV::Send()
|
||||
if (ctrl.blocks != 0) {
|
||||
// set next buffer (set offset, length)
|
||||
result = XferIn(ctrl.buffer);
|
||||
ostringstream s;
|
||||
s << __PRETTY_FUNCTION__ << " Processing after data collection. Blocks: " << ctrl.blocks;
|
||||
LOGTRACE("%s", s.str().c_str());
|
||||
LOGTRACE("%s%s", __PRETTY_FUNCTION__, (" Processing after data collection. Blocks: " + to_string(ctrl.blocks)).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@ -434,9 +430,7 @@ void SCSIDEV::Send()
|
||||
|
||||
// Continue sending if block !=0
|
||||
if (ctrl.blocks != 0){
|
||||
ostringstream s;
|
||||
s << __PRETTY_FUNCTION__ << " Continuing to send. Blocks: " << ctrl.blocks;
|
||||
LOGTRACE("%s", s.str().c_str());
|
||||
LOGTRACE("%s%s", __PRETTY_FUNCTION__, (" Continuing to send. Blocks: " + to_string(ctrl.blocks)).c_str());
|
||||
ASSERT(ctrl.length > 0);
|
||||
ASSERT(ctrl.offset == 0);
|
||||
return;
|
||||
|
@ -8,17 +8,20 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
#include "rascsi_version.h"
|
||||
#include "os.h"
|
||||
#include "log.h"
|
||||
#include "exceptions.h"
|
||||
#include "device.h"
|
||||
|
||||
set<Device *> Device::devices;
|
||||
|
||||
Device::Device(const string& type)
|
||||
{
|
||||
assert(type.length() == 4);
|
||||
|
||||
devices.insert(this);
|
||||
|
||||
this->type = type;
|
||||
|
||||
vendor = DEFAULT_VENDOR;
|
||||
@ -48,6 +51,11 @@ Device::Device(const string& type)
|
||||
status_code = STATUS_NOERROR;
|
||||
}
|
||||
|
||||
Device::~Device()
|
||||
{
|
||||
devices.erase(this);
|
||||
}
|
||||
|
||||
void Device::Reset()
|
||||
{
|
||||
locked = false;
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
@ -104,10 +105,14 @@ private:
|
||||
// Sense Key, ASC and ASCQ
|
||||
int status_code;
|
||||
|
||||
protected:
|
||||
|
||||
static set<Device *> devices;
|
||||
|
||||
public:
|
||||
|
||||
Device(const string&);
|
||||
virtual ~Device() {};
|
||||
virtual ~Device();
|
||||
|
||||
// Override for device specific initializations, to be called after all device properties have been set
|
||||
virtual bool Init(const map<string, string>&) { return true; };
|
||||
|
@ -20,12 +20,11 @@
|
||||
#include "exceptions.h"
|
||||
#include "disk.h"
|
||||
#include "mode_page_device.h"
|
||||
#include <sstream>
|
||||
|
||||
Disk::Disk(const std::string id) : ModePageDevice(id), ScsiBlockCommands()
|
||||
using namespace scsi_defs;
|
||||
|
||||
Disk::Disk(const string& id) : ModePageDevice(id), ScsiBlockCommands()
|
||||
{
|
||||
disks.insert(this);
|
||||
|
||||
// Work initialization
|
||||
configured_sector_size = 0;
|
||||
disk.size = 0;
|
||||
@ -33,34 +32,34 @@ Disk::Disk(const std::string id) : ModePageDevice(id), ScsiBlockCommands()
|
||||
disk.dcache = NULL;
|
||||
disk.image_offset = 0;
|
||||
|
||||
AddCommand(ScsiDefs::eCmdRezero, "Rezero", &Disk::Rezero);
|
||||
AddCommand(ScsiDefs::eCmdFormat, "FormatUnit", &Disk::FormatUnit);
|
||||
AddCommand(ScsiDefs::eCmdReassign, "ReassignBlocks", &Disk::ReassignBlocks);
|
||||
AddCommand(ScsiDefs::eCmdRead6, "Read6", &Disk::Read6);
|
||||
AddCommand(ScsiDefs::eCmdWrite6, "Write6", &Disk::Write6);
|
||||
AddCommand(ScsiDefs::eCmdSeek6, "Seek6", &Disk::Seek6);
|
||||
AddCommand(ScsiDefs::eCmdReserve6, "Reserve6", &Disk::Reserve6);
|
||||
AddCommand(ScsiDefs::eCmdRelease6, "Release6", &Disk::Release6);
|
||||
AddCommand(ScsiDefs::eCmdStartStop, "StartStopUnit", &Disk::StartStopUnit);
|
||||
AddCommand(ScsiDefs::eCmdSendDiag, "SendDiagnostic", &Disk::SendDiagnostic);
|
||||
AddCommand(ScsiDefs::eCmdRemoval, "PreventAllowMediumRemoval", &Disk::PreventAllowMediumRemoval);
|
||||
AddCommand(ScsiDefs::eCmdReadCapacity10, "ReadCapacity10", &Disk::ReadCapacity10);
|
||||
AddCommand(ScsiDefs::eCmdRead10, "Read10", &Disk::Read10);
|
||||
AddCommand(ScsiDefs::eCmdWrite10, "Write10", &Disk::Write10);
|
||||
AddCommand(ScsiDefs::eCmdReadLong10, "ReadLong10", &Disk::ReadLong10);
|
||||
AddCommand(ScsiDefs::eCmdWriteLong10, "WriteLong10", &Disk::WriteLong10);
|
||||
AddCommand(ScsiDefs::eCmdWriteLong16, "WriteLong16", &Disk::WriteLong16);
|
||||
AddCommand(ScsiDefs::eCmdSeek10, "Seek10", &Disk::Seek10);
|
||||
AddCommand(ScsiDefs::eCmdVerify10, "Verify10", &Disk::Verify10);
|
||||
AddCommand(ScsiDefs::eCmdSynchronizeCache10, "SynchronizeCache10", &Disk::SynchronizeCache10);
|
||||
AddCommand(ScsiDefs::eCmdSynchronizeCache16, "SynchronizeCache16", &Disk::SynchronizeCache16);
|
||||
AddCommand(ScsiDefs::eCmdReadDefectData10, "ReadDefectData10", &Disk::ReadDefectData10);
|
||||
AddCommand(ScsiDefs::eCmdReserve10, "Reserve10", &Disk::Reserve10);
|
||||
AddCommand(ScsiDefs::eCmdRelease10, "Release10", &Disk::Release10);
|
||||
AddCommand(ScsiDefs::eCmdRead16, "Read16", &Disk::Read16);
|
||||
AddCommand(ScsiDefs::eCmdWrite16, "Write16", &Disk::Write16);
|
||||
AddCommand(ScsiDefs::eCmdVerify16, "Verify16", &Disk::Verify16);
|
||||
AddCommand(ScsiDefs::eCmdReadCapacity16_ReadLong16, "ReadCapacity16/ReadLong16", &Disk::ReadCapacity16_ReadLong16);
|
||||
dispatcher.AddCommand(eCmdRezero, "Rezero", &Disk::Rezero);
|
||||
dispatcher.AddCommand(eCmdFormat, "FormatUnit", &Disk::FormatUnit);
|
||||
dispatcher.AddCommand(eCmdReassign, "ReassignBlocks", &Disk::ReassignBlocks);
|
||||
dispatcher.AddCommand(eCmdRead6, "Read6", &Disk::Read6);
|
||||
dispatcher.AddCommand(eCmdWrite6, "Write6", &Disk::Write6);
|
||||
dispatcher.AddCommand(eCmdSeek6, "Seek6", &Disk::Seek6);
|
||||
dispatcher.AddCommand(eCmdReserve6, "Reserve6", &Disk::Reserve6);
|
||||
dispatcher.AddCommand(eCmdRelease6, "Release6", &Disk::Release6);
|
||||
dispatcher.AddCommand(eCmdStartStop, "StartStopUnit", &Disk::StartStopUnit);
|
||||
dispatcher.AddCommand(eCmdSendDiag, "SendDiagnostic", &Disk::SendDiagnostic);
|
||||
dispatcher.AddCommand(eCmdRemoval, "PreventAllowMediumRemoval", &Disk::PreventAllowMediumRemoval);
|
||||
dispatcher.AddCommand(eCmdReadCapacity10, "ReadCapacity10", &Disk::ReadCapacity10);
|
||||
dispatcher.AddCommand(eCmdRead10, "Read10", &Disk::Read10);
|
||||
dispatcher.AddCommand(eCmdWrite10, "Write10", &Disk::Write10);
|
||||
dispatcher.AddCommand(eCmdReadLong10, "ReadLong10", &Disk::ReadLong10);
|
||||
dispatcher.AddCommand(eCmdWriteLong10, "WriteLong10", &Disk::WriteLong10);
|
||||
dispatcher.AddCommand(eCmdWriteLong16, "WriteLong16", &Disk::WriteLong16);
|
||||
dispatcher.AddCommand(eCmdSeek10, "Seek10", &Disk::Seek10);
|
||||
dispatcher.AddCommand(eCmdVerify10, "Verify10", &Disk::Verify10);
|
||||
dispatcher.AddCommand(eCmdSynchronizeCache10, "SynchronizeCache10", &Disk::SynchronizeCache10);
|
||||
dispatcher.AddCommand(eCmdSynchronizeCache16, "SynchronizeCache16", &Disk::SynchronizeCache16);
|
||||
dispatcher.AddCommand(eCmdReadDefectData10, "ReadDefectData10", &Disk::ReadDefectData10);
|
||||
dispatcher.AddCommand(eCmdReserve10, "Reserve10", &Disk::Reserve10);
|
||||
dispatcher.AddCommand(eCmdRelease10, "Release10", &Disk::Release10);
|
||||
dispatcher.AddCommand(eCmdRead16, "Read16", &Disk::Read16);
|
||||
dispatcher.AddCommand(eCmdWrite16, "Write16", &Disk::Write16);
|
||||
dispatcher.AddCommand(eCmdVerify16, "Verify16", &Disk::Verify16);
|
||||
dispatcher.AddCommand(eCmdReadCapacity16_ReadLong16, "ReadCapacity16/ReadLong16", &Disk::ReadCapacity16_ReadLong16);
|
||||
}
|
||||
|
||||
Disk::~Disk()
|
||||
@ -78,37 +77,12 @@ Disk::~Disk()
|
||||
delete disk.dcache;
|
||||
disk.dcache = NULL;
|
||||
}
|
||||
|
||||
for (auto const& command : commands) {
|
||||
delete command.second;
|
||||
}
|
||||
|
||||
disks.erase(this);
|
||||
}
|
||||
|
||||
void Disk::AddCommand(ScsiDefs::scsi_command opcode, const char* name, void (Disk::*execute)(SASIDEV *))
|
||||
{
|
||||
commands[opcode] = new command_t(name, execute);
|
||||
}
|
||||
|
||||
bool Disk::Dispatch(SCSIDEV *controller)
|
||||
{
|
||||
ctrl = controller->GetCtrl();
|
||||
|
||||
if (commands.count(static_cast<ScsiDefs::scsi_command>(ctrl->cmd[0]))) {
|
||||
command_t *command = commands[static_cast<ScsiDefs::scsi_command>(ctrl->cmd[0])];
|
||||
|
||||
LOGDEBUG("%s Executing %s ($%02X)", __PRETTY_FUNCTION__, command->name, (unsigned int)ctrl->cmd[0]);
|
||||
|
||||
(this->*command->execute)(controller);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
LOGTRACE("%s Calling base class for dispatching $%02X", __PRETTY_FUNCTION__, (unsigned int)ctrl->cmd[0]);
|
||||
|
||||
// The base class handles the less specific commands
|
||||
return ModePageDevice::Dispatch(controller);
|
||||
// The superclass handles the less specific commands
|
||||
return dispatcher.Dispatch(this, controller) ? true : super::Dispatch(controller);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
@ -1276,9 +1250,8 @@ bool Disk::CheckBlockAddress(SASIDEV *controller, access_mode mode)
|
||||
|
||||
uint64_t capacity = GetBlockCount();
|
||||
if (block > capacity) {
|
||||
ostringstream s;
|
||||
s << "Capacity of " << capacity << " blocks exceeded: " << "Trying to access block " << block;
|
||||
LOGTRACE("%s", s.str().c_str());
|
||||
LOGTRACE("%s", ("Capacity of " + to_string(capacity) + " blocks exceeded: Trying to access block "
|
||||
+ to_string(block)).c_str());
|
||||
controller->Error(ERROR_CODES::sense_key::ILLEGAL_REQUEST, ERROR_CODES::asc::LBA_OUT_OF_RANGE);
|
||||
return false;
|
||||
}
|
||||
@ -1339,10 +1312,8 @@ bool Disk::GetStartAndCount(SASIDEV *controller, uint64_t& start, uint32_t& coun
|
||||
// Check capacity
|
||||
uint64_t capacity = GetBlockCount();
|
||||
if (start > capacity || start + count > capacity) {
|
||||
ostringstream s;
|
||||
s << "Capacity of " << capacity << " blocks exceeded: "
|
||||
<< "Trying to read block " << start << ", block count " << ctrl->blocks;
|
||||
LOGTRACE("%s", s.str().c_str());
|
||||
LOGTRACE("%s", ("Capacity of " + to_string(capacity) + " blocks exceeded: Trying to access block "
|
||||
+ to_string(start) + ", block count " + to_string(ctrl->blocks)).c_str());
|
||||
controller->Error(ERROR_CODES::sense_key::ILLEGAL_REQUEST, ERROR_CODES::asc::LBA_OUT_OF_RANGE);
|
||||
return false;
|
||||
}
|
||||
@ -1366,9 +1337,7 @@ void Disk::SetSectorSizeInBytes(uint32_t size, bool sasi)
|
||||
{
|
||||
set<uint32_t> sector_sizes = DeviceFactory::instance().GetSectorSizes(GetType());
|
||||
if (!sector_sizes.empty() && sector_sizes.find(size) == sector_sizes.end()) {
|
||||
stringstream error;
|
||||
error << "Invalid block size of " << size << " bytes";
|
||||
throw io_exception(error.str());
|
||||
throw io_exception("Invalid block size of " + to_string(size) + " bytes");
|
||||
}
|
||||
|
||||
switch (size) {
|
||||
|
@ -26,12 +26,13 @@
|
||||
#include "file_support.h"
|
||||
#include "filepath.h"
|
||||
#include "interfaces/scsi_block_commands.h"
|
||||
#include "interfaces/scsi_primary_commands.h"
|
||||
#include "mode_page_device.h"
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Disk : public ModePageDevice, ScsiBlockCommands
|
||||
{
|
||||
private:
|
||||
@ -52,18 +53,10 @@ private:
|
||||
off_t image_offset; // Offset to actual data
|
||||
} disk_t;
|
||||
|
||||
typedef struct _command_t {
|
||||
const char* name;
|
||||
void (Disk::*execute)(SASIDEV *);
|
||||
|
||||
_command_t(const char* _name, void (Disk::*_execute)(SASIDEV *)) : name(_name), execute(_execute) { };
|
||||
} command_t;
|
||||
std::map<ScsiDefs::scsi_command, command_t*> commands;
|
||||
|
||||
void AddCommand(ScsiDefs::scsi_command, const char*, void (Disk::*)(SASIDEV *));
|
||||
Dispatcher<Disk> dispatcher;
|
||||
|
||||
public:
|
||||
Disk(std::string);
|
||||
Disk(const string&);
|
||||
virtual ~Disk();
|
||||
|
||||
virtual bool Dispatch(SCSIDEV *) override;
|
||||
@ -76,13 +69,14 @@ public:
|
||||
bool Eject(bool) override;
|
||||
|
||||
private:
|
||||
typedef ModePageDevice super;
|
||||
|
||||
// Commands covered by the SCSI specification (see https://www.t10.org/drafts.htm)
|
||||
void StartStopUnit(SASIDEV *) override;
|
||||
void SendDiagnostic(SASIDEV *) override;
|
||||
void StartStopUnit(SASIDEV *);
|
||||
void SendDiagnostic(SASIDEV *);
|
||||
void PreventAllowMediumRemoval(SASIDEV *);
|
||||
void SynchronizeCache10(SASIDEV *) override;
|
||||
void SynchronizeCache16(SASIDEV *) override;
|
||||
void SynchronizeCache10(SASIDEV *);
|
||||
void SynchronizeCache16(SASIDEV *);
|
||||
void ReadDefectData10(SASIDEV *);
|
||||
virtual void Read6(SASIDEV *);
|
||||
void Read10(SASIDEV *) override;
|
||||
@ -90,12 +84,12 @@ private:
|
||||
virtual void Write6(SASIDEV *);
|
||||
void Write10(SASIDEV *) override;
|
||||
void Write16(SASIDEV *) override;
|
||||
void ReadLong10(SASIDEV *) override;
|
||||
void ReadLong16(SASIDEV *) override;
|
||||
void WriteLong10(SASIDEV *) override;
|
||||
void WriteLong16(SASIDEV *) override;
|
||||
void Verify10(SASIDEV *) override;
|
||||
void Verify16(SASIDEV *) override;
|
||||
void ReadLong10(SASIDEV *);
|
||||
void ReadLong16(SASIDEV *);
|
||||
void WriteLong10(SASIDEV *);
|
||||
void WriteLong16(SASIDEV *);
|
||||
void Verify10(SASIDEV *);
|
||||
void Verify16(SASIDEV *);
|
||||
void Seek(SASIDEV *);
|
||||
void Seek10(SASIDEV *);
|
||||
void ReadCapacity10(SASIDEV *) override;
|
||||
@ -110,7 +104,7 @@ public:
|
||||
// Commands covered by the SCSI specification (see https://www.t10.org/drafts.htm)
|
||||
void Rezero(SASIDEV *);
|
||||
void FormatUnit(SASIDEV *) override;
|
||||
void ReassignBlocks(SASIDEV *) override;
|
||||
void ReassignBlocks(SASIDEV *);
|
||||
void Seek6(SASIDEV *);
|
||||
|
||||
// Command helpers
|
||||
@ -154,8 +148,6 @@ protected:
|
||||
// Internal disk data
|
||||
disk_t disk;
|
||||
|
||||
set<Disk *> disks;
|
||||
|
||||
private:
|
||||
void Read(SASIDEV *, uint64_t);
|
||||
void Write(SASIDEV *, uint64_t);
|
||||
|
67
src/raspberrypi/devices/dispatcher.h
Normal file
67
src/raspberrypi/devices/dispatcher.h
Normal file
@ -0,0 +1,67 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Copyright (C) 2022 Uwe Seimet
|
||||
//
|
||||
// A template for dispatching SCSI commands
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "log.h"
|
||||
#include "scsi.h"
|
||||
#include <map>
|
||||
|
||||
class SASIDEV;
|
||||
class SCSIDEV;
|
||||
|
||||
using namespace std;
|
||||
using namespace scsi_defs;
|
||||
|
||||
template<class T>
|
||||
class Dispatcher
|
||||
{
|
||||
public:
|
||||
|
||||
Dispatcher() {}
|
||||
~Dispatcher()
|
||||
{
|
||||
for (auto const& command : commands) {
|
||||
delete command.second;
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct _command_t {
|
||||
const char* name;
|
||||
void (T::*execute)(SASIDEV *);
|
||||
|
||||
_command_t(const char* _name, void (T::*_execute)(SASIDEV *)) : name(_name), execute(_execute) { };
|
||||
} command_t;
|
||||
map<scsi_command, command_t*> commands;
|
||||
|
||||
void AddCommand(scsi_command opcode, const char* name, void (T::*execute)(SASIDEV *))
|
||||
{
|
||||
commands[opcode] = new command_t(name, execute);
|
||||
}
|
||||
|
||||
bool Dispatch(T *instance, SCSIDEV *controller)
|
||||
{
|
||||
SASIDEV::ctrl_t *ctrl = controller->GetCtrl();
|
||||
instance->SetCtrl(ctrl);
|
||||
|
||||
const auto& it = commands.find(static_cast<scsi_command>(ctrl->cmd[0]));
|
||||
if (it != commands.end()) {
|
||||
LOGDEBUG("%s Executing %s ($%02X)", __PRETTY_FUNCTION__, it->second->name, (unsigned int)ctrl->cmd[0]);
|
||||
|
||||
(instance->*it->second->execute)(controller);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Unknown command
|
||||
return false;
|
||||
}
|
||||
};
|
@ -30,24 +30,20 @@
|
||||
// b) !start && load (EJECT): Shut down the Raspberry Pi
|
||||
//
|
||||
|
||||
#include "controllers/scsidev_ctrl.h"
|
||||
#include "host_services.h"
|
||||
|
||||
using namespace scsi_defs;
|
||||
|
||||
HostServices::HostServices() : ModePageDevice("SCHS")
|
||||
{
|
||||
dispatcher.AddCommand(eCmdStartStop, "StartStopUnit", &HostServices::StartStopUnit);
|
||||
}
|
||||
|
||||
bool HostServices::Dispatch(SCSIDEV *controller)
|
||||
{
|
||||
unsigned int cmd = controller->GetCtrl()->cmd[0];
|
||||
|
||||
// Only certain commands are supported
|
||||
// TODO Do not inherit from Disk, mode page handling should be moved to ModePageDevice
|
||||
if (cmd == ScsiDefs::eCmdTestUnitReady || cmd == ScsiDefs::eCmdRequestSense
|
||||
|| cmd == ScsiDefs::eCmdInquiry || cmd == ScsiDefs::eCmdReportLuns
|
||||
|| cmd == ScsiDefs::eCmdModeSense6 || cmd == ScsiDefs::eCmdModeSense10
|
||||
|| cmd == ScsiDefs::eCmdStartStop) {
|
||||
LOGTRACE("%s Calling base class for dispatching $%02X", __PRETTY_FUNCTION__, cmd);
|
||||
|
||||
return Disk::Dispatch(controller);
|
||||
}
|
||||
|
||||
return false;
|
||||
// The superclass class handles the less specific commands
|
||||
return dispatcher.Dispatch(this, controller) ? true : super::Dispatch(controller);
|
||||
}
|
||||
|
||||
void HostServices::TestUnitReady(SASIDEV *controller)
|
||||
@ -58,28 +54,8 @@ void HostServices::TestUnitReady(SASIDEV *controller)
|
||||
|
||||
int HostServices::Inquiry(const DWORD *cdb, BYTE *buf)
|
||||
{
|
||||
int allocation_length = cdb[4] + (((DWORD)cdb[3]) << 8);
|
||||
if (allocation_length > 4) {
|
||||
if (allocation_length > 44) {
|
||||
allocation_length = 44;
|
||||
}
|
||||
|
||||
// Basic data
|
||||
// buf[0] ... Processor Device
|
||||
// buf[1] ... Not removable
|
||||
// buf[2] ... SCSI-2 compliant command system
|
||||
// buf[3] ... SCSI-2 compliant Inquiry response
|
||||
// buf[4] ... Inquiry additional data
|
||||
memset(buf, 0, allocation_length);
|
||||
buf[0] = 0x03;
|
||||
buf[2] = 0x01;
|
||||
buf[4] = 0x1F;
|
||||
|
||||
// Padded vendor, product, revision
|
||||
memcpy(&buf[8], GetPaddedName().c_str(), 28);
|
||||
}
|
||||
|
||||
return allocation_length;
|
||||
// Processor device, not removable
|
||||
return PrimaryDevice::Inquiry(3, false, cdb, buf);
|
||||
}
|
||||
|
||||
void HostServices::StartStopUnit(SASIDEV *controller)
|
||||
@ -88,10 +64,10 @@ void HostServices::StartStopUnit(SASIDEV *controller)
|
||||
bool load = ctrl->cmd[4] & 0x02;
|
||||
|
||||
if (!start) {
|
||||
// Delete all regular disk devices. This also flushes their caches.
|
||||
for (auto disk : disks) {
|
||||
if (disk && disk != this) {
|
||||
delete disk;
|
||||
// Delete all other devices. This will also flush any caches.
|
||||
for (const Device *device : devices) {
|
||||
if (device != this) {
|
||||
delete device;
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,7 +85,91 @@ void HostServices::StartStopUnit(SASIDEV *controller)
|
||||
controller->Error(ERROR_CODES::sense_key::ILLEGAL_REQUEST, ERROR_CODES::asc::INVALID_FIELD_IN_CDB);
|
||||
}
|
||||
|
||||
int HostServices::AddVendorPage(int page, bool, BYTE *buf)
|
||||
int HostServices::ModeSense6(const DWORD *cdb, BYTE *buf)
|
||||
{
|
||||
// Get length, clear buffer
|
||||
int length = (int)cdb[4];
|
||||
memset(buf, 0, length);
|
||||
|
||||
// Get page code (0x00 is valid from the beginning)
|
||||
int page = cdb[2] & 0x3f;
|
||||
bool valid = page == 0x00;
|
||||
|
||||
LOGTRACE("%s Requesting mode page $%02X", __PRETTY_FUNCTION__, page);
|
||||
|
||||
// Basic information
|
||||
int size = 4;
|
||||
|
||||
int ret = AddRealtimeClockPage(page, &buf[size]);
|
||||
if (ret > 0) {
|
||||
size += ret;
|
||||
valid = true;
|
||||
}
|
||||
|
||||
if (!valid) {
|
||||
LOGTRACE("%s Unsupported mode page $%02X", __PRETTY_FUNCTION__, page);
|
||||
SetStatusCode(STATUS_INVALIDCDB);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Do not return more than ALLOCATION LENGTH bytes
|
||||
if (size > length) {
|
||||
LOGTRACE("%s %d bytes available, %d bytes requested", __PRETTY_FUNCTION__, size, length);
|
||||
size = length;
|
||||
}
|
||||
|
||||
// Final setting of mode data length
|
||||
buf[0] = size;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int HostServices::ModeSense10(const DWORD *cdb, BYTE *buf)
|
||||
{
|
||||
// Get length, clear buffer
|
||||
int length = cdb[7];
|
||||
length <<= 8;
|
||||
length |= cdb[8];
|
||||
if (length > 0x800) {
|
||||
length = 0x800;
|
||||
}
|
||||
memset(buf, 0, length);
|
||||
|
||||
// Get page code (0x00 is valid from the beginning)
|
||||
int page = cdb[2] & 0x3f;
|
||||
bool valid = page == 0x00;
|
||||
|
||||
LOGTRACE("%s Requesting mode page $%02X", __PRETTY_FUNCTION__, page);
|
||||
|
||||
// Basic Information
|
||||
int size = 8;
|
||||
|
||||
int ret = AddRealtimeClockPage(page, &buf[size]);
|
||||
if (ret > 0) {
|
||||
size += ret;
|
||||
valid = true;
|
||||
}
|
||||
|
||||
if (!valid) {
|
||||
LOGTRACE("%s Unsupported mode page $%02X", __PRETTY_FUNCTION__, page);
|
||||
SetStatusCode(STATUS_INVALIDCDB);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Do not return more than ALLOCATION LENGTH bytes
|
||||
if (size > length) {
|
||||
LOGTRACE("%s %d bytes available, %d bytes requested", __PRETTY_FUNCTION__, size, length);
|
||||
size = length;
|
||||
}
|
||||
|
||||
// Final setting of mode data length
|
||||
buf[0] = size >> 8;
|
||||
buf[1] = size;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int HostServices::AddRealtimeClockPage(int page, BYTE *buf)
|
||||
{
|
||||
if (page == 0x20) {
|
||||
// Data structure version 1.0
|
||||
@ -131,4 +191,3 @@ int HostServices::AddVendorPage(int page, bool, BYTE *buf)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -5,21 +5,37 @@
|
||||
//
|
||||
// Copyright (C) 2022 Uwe Seimet
|
||||
//
|
||||
// RaSCSI Host Services with realtime clock and shutdown support
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
#include "disk.h"
|
||||
#include "mode_page_device.h"
|
||||
|
||||
class HostServices: public Disk
|
||||
using namespace std;
|
||||
|
||||
class HostServices: public ModePageDevice
|
||||
{
|
||||
|
||||
public:
|
||||
HostServices() : Disk("SCHS") {};
|
||||
~HostServices() {};
|
||||
|
||||
HostServices();
|
||||
~HostServices() {}
|
||||
|
||||
virtual bool Dispatch(SCSIDEV *) override;
|
||||
|
||||
int Inquiry(const DWORD *, BYTE *) override;
|
||||
void TestUnitReady(SASIDEV *) override;
|
||||
void StartStopUnit(SASIDEV *) override;
|
||||
int AddVendorPage(int, bool, BYTE *) override;
|
||||
void StartStopUnit(SASIDEV *);
|
||||
|
||||
int ModeSense6(const DWORD *, BYTE *);
|
||||
int ModeSense10(const DWORD *, BYTE *);
|
||||
|
||||
private:
|
||||
|
||||
typedef ModePageDevice super;
|
||||
|
||||
Dispatcher<HostServices> dispatcher;
|
||||
|
||||
int AddRealtimeClockPage(int, BYTE *);
|
||||
};
|
||||
|
@ -30,17 +30,4 @@ public:
|
||||
virtual void Read16(SASIDEV *) = 0;
|
||||
virtual void Write10(SASIDEV *) = 0;
|
||||
virtual void Write16(SASIDEV *) = 0;
|
||||
|
||||
// Implemented optional commands
|
||||
virtual void ReadLong10(SASIDEV *) = 0;
|
||||
virtual void WriteLong10(SASIDEV *) = 0;
|
||||
virtual void Verify10(SASIDEV *) = 0;
|
||||
virtual void ReadLong16(SASIDEV *) = 0;
|
||||
virtual void WriteLong16(SASIDEV *) = 0;
|
||||
virtual void Verify16(SASIDEV *) = 0;
|
||||
virtual void ReassignBlocks(SASIDEV *) = 0;
|
||||
virtual void SendDiagnostic(SASIDEV *) = 0;
|
||||
virtual void StartStopUnit(SASIDEV *) = 0;
|
||||
virtual void SynchronizeCache10(SASIDEV *) = 0;
|
||||
virtual void SynchronizeCache16(SASIDEV *) = 0;
|
||||
};
|
||||
|
@ -25,10 +25,6 @@ public:
|
||||
virtual void Inquiry(SASIDEV *) = 0;
|
||||
virtual void ReportLuns(SASIDEV *) = 0;
|
||||
|
||||
// Optional commands
|
||||
// Implemented for all RaSCSI device types
|
||||
virtual void RequestSense(SASIDEV *) = 0;
|
||||
virtual void ModeSense6(SASIDEV *) = 0;
|
||||
virtual void ModeSense10(SASIDEV *) = 0;
|
||||
virtual void ModeSelect6(SASIDEV *) = 0;
|
||||
virtual void ModeSelect10(SASIDEV *) = 0;
|
||||
};
|
||||
|
@ -14,36 +14,20 @@
|
||||
#include "mode_page_device.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace scsi_defs;
|
||||
|
||||
ModePageDevice::ModePageDevice(const string id) : PrimaryDevice(id)
|
||||
ModePageDevice::ModePageDevice(const string& id) : PrimaryDevice(id)
|
||||
{
|
||||
AddCommand(ScsiDefs::eCmdModeSense6, "ModeSense6", &ModePageDevice::ModeSense6);
|
||||
AddCommand(ScsiDefs::eCmdModeSense10, "ModeSense10", &ModePageDevice::ModeSense10);
|
||||
AddCommand(ScsiDefs::eCmdModeSelect6, "ModeSelect6", &ModePageDevice::ModeSelect6);
|
||||
AddCommand(ScsiDefs::eCmdModeSelect10, "ModeSelect10", &ModePageDevice::ModeSelect10);
|
||||
}
|
||||
|
||||
void ModePageDevice::AddCommand(ScsiDefs::scsi_command opcode, const char* name, void (ModePageDevice::*execute)(SASIDEV *))
|
||||
{
|
||||
commands[opcode] = new command_t(name, execute);
|
||||
dispatcher.AddCommand(eCmdModeSense6, "ModeSense6", &ModePageDevice::ModeSense6);
|
||||
dispatcher.AddCommand(eCmdModeSense10, "ModeSense10", &ModePageDevice::ModeSense10);
|
||||
dispatcher.AddCommand(eCmdModeSelect6, "ModeSelect6", &ModePageDevice::ModeSelect6);
|
||||
dispatcher.AddCommand(eCmdModeSelect10, "ModeSelect10", &ModePageDevice::ModeSelect10);
|
||||
}
|
||||
|
||||
bool ModePageDevice::Dispatch(SCSIDEV *controller)
|
||||
{
|
||||
ctrl = controller->GetCtrl();
|
||||
|
||||
if (commands.count(static_cast<ScsiDefs::scsi_command>(ctrl->cmd[0]))) {
|
||||
command_t *command = commands[static_cast<ScsiDefs::scsi_command>(ctrl->cmd[0])];
|
||||
|
||||
LOGDEBUG("%s Executing %s ($%02X)", __PRETTY_FUNCTION__, command->name, (unsigned int)ctrl->cmd[0]);
|
||||
|
||||
(this->*command->execute)(controller);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Unknown command
|
||||
return false;
|
||||
// The superclass class handles the less specific commands
|
||||
return dispatcher.Dispatch(this, controller) ? true : super::Dispatch(controller);
|
||||
}
|
||||
|
||||
void ModePageDevice::ModeSense6(SASIDEV *controller)
|
||||
|
@ -18,7 +18,7 @@ class ModePageDevice: public PrimaryDevice
|
||||
{
|
||||
public:
|
||||
|
||||
ModePageDevice(const string);
|
||||
ModePageDevice(const string&);
|
||||
virtual ~ModePageDevice() {}
|
||||
|
||||
virtual bool Dispatch(SCSIDEV *) override;
|
||||
@ -31,20 +31,14 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
typedef struct _command_t {
|
||||
const char* name;
|
||||
void (ModePageDevice::*execute)(SASIDEV *);
|
||||
typedef PrimaryDevice super;
|
||||
|
||||
_command_t(const char* _name, void (ModePageDevice::*_execute)(SASIDEV *)) : name(_name), execute(_execute) { };
|
||||
} command_t;
|
||||
std::map<ScsiDefs::scsi_command, command_t*> commands;
|
||||
Dispatcher<ModePageDevice> dispatcher;
|
||||
|
||||
void AddCommand(ScsiDefs::scsi_command, const char*, void (ModePageDevice::*)(SASIDEV *));
|
||||
|
||||
void ModeSense6(SASIDEV *) override;
|
||||
void ModeSense10(SASIDEV *) override;
|
||||
void ModeSelect6(SASIDEV *) override;
|
||||
void ModeSelect10(SASIDEV *) override;
|
||||
void ModeSense6(SASIDEV *);
|
||||
void ModeSense10(SASIDEV *);
|
||||
void ModeSelect6(SASIDEV *);
|
||||
void ModeSelect10(SASIDEV *);
|
||||
|
||||
int ModeSelectCheck(const DWORD *, int);
|
||||
int ModeSelectCheck6(const DWORD *);
|
||||
|
@ -9,44 +9,28 @@
|
||||
|
||||
#include "log.h"
|
||||
#include "controllers/scsidev_ctrl.h"
|
||||
#include "dispatcher.h"
|
||||
#include "primary_device.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace scsi_defs;
|
||||
|
||||
PrimaryDevice::PrimaryDevice(const string id) : ScsiPrimaryCommands(), Device(id)
|
||||
PrimaryDevice::PrimaryDevice(const string& id) : ScsiPrimaryCommands(), Device(id)
|
||||
{
|
||||
ctrl = NULL;
|
||||
|
||||
// Mandatory SCSI primary commands
|
||||
AddCommand(ScsiDefs::eCmdTestUnitReady, "TestUnitReady", &PrimaryDevice::TestUnitReady);
|
||||
AddCommand(ScsiDefs::eCmdInquiry, "Inquiry", &PrimaryDevice::Inquiry);
|
||||
AddCommand(ScsiDefs::eCmdReportLuns, "ReportLuns", &PrimaryDevice::ReportLuns);
|
||||
dispatcher.AddCommand(eCmdTestUnitReady, "TestUnitReady", &PrimaryDevice::TestUnitReady);
|
||||
dispatcher.AddCommand(eCmdInquiry, "Inquiry", &PrimaryDevice::Inquiry);
|
||||
dispatcher.AddCommand(eCmdReportLuns, "ReportLuns", &PrimaryDevice::ReportLuns);
|
||||
|
||||
// Optional commands used by all RaSCSI devices
|
||||
AddCommand(ScsiDefs::eCmdRequestSense, "RequestSense", &PrimaryDevice::RequestSense);
|
||||
}
|
||||
|
||||
void PrimaryDevice::AddCommand(ScsiDefs::scsi_command opcode, const char* name, void (PrimaryDevice::*execute)(SASIDEV *))
|
||||
{
|
||||
commands[opcode] = new command_t(name, execute);
|
||||
dispatcher.AddCommand(eCmdRequestSense, "RequestSense", &PrimaryDevice::RequestSense);
|
||||
}
|
||||
|
||||
bool PrimaryDevice::Dispatch(SCSIDEV *controller)
|
||||
{
|
||||
ctrl = controller->GetCtrl();
|
||||
|
||||
if (commands.count(static_cast<ScsiDefs::scsi_command>(ctrl->cmd[0]))) {
|
||||
command_t *command = commands[static_cast<ScsiDefs::scsi_command>(ctrl->cmd[0])];
|
||||
|
||||
LOGDEBUG("%s Executing %s ($%02X)", __PRETTY_FUNCTION__, command->name, (unsigned int)ctrl->cmd[0]);
|
||||
|
||||
(this->*command->execute)(controller);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Unknown command
|
||||
return false;
|
||||
return dispatcher.Dispatch(this, controller);
|
||||
}
|
||||
|
||||
void PrimaryDevice::TestUnitReady(SASIDEV *controller)
|
||||
@ -90,7 +74,7 @@ void PrimaryDevice::Inquiry(SASIDEV *controller)
|
||||
|
||||
// Report if the device does not support the requested LUN
|
||||
if (!ctrl->unit[lun]) {
|
||||
LOGDEBUG("Reporting LUN %d for device ID %d as not supported", lun, ctrl->device->GetId());
|
||||
LOGTRACE("Reporting LUN %d for device ID %d as not supported", lun, ctrl->device->GetId());
|
||||
|
||||
ctrl->buffer[0] |= 0x7f;
|
||||
}
|
||||
@ -183,6 +167,33 @@ bool PrimaryDevice::CheckReady()
|
||||
return true;
|
||||
}
|
||||
|
||||
int PrimaryDevice::Inquiry(int type, bool is_removable, const DWORD *cdb, BYTE *buf)
|
||||
{
|
||||
int allocation_length = cdb[4] + (((DWORD)cdb[3]) << 8);
|
||||
if (allocation_length > 4) {
|
||||
if (allocation_length > 44) {
|
||||
allocation_length = 44;
|
||||
}
|
||||
|
||||
// Basic data
|
||||
// buf[0] ... SCSI Device type
|
||||
// buf[1] ... Bit 7: Removable/not removable
|
||||
// buf[2] ... SCSI-2 compliant command system
|
||||
// buf[3] ... SCSI-2 compliant Inquiry response
|
||||
// buf[4] ... Inquiry additional data
|
||||
memset(buf, 0, allocation_length);
|
||||
buf[0] = type;
|
||||
buf[1] = is_removable ? 0x80 : 0x00;
|
||||
buf[2] = 0x01;
|
||||
buf[4] = 0x1F;
|
||||
|
||||
// Padded vendor, product, revision
|
||||
memcpy(&buf[8], GetPaddedName().c_str(), 28);
|
||||
}
|
||||
|
||||
return allocation_length;
|
||||
}
|
||||
|
||||
int PrimaryDevice::RequestSense(const DWORD *cdb, BYTE *buf)
|
||||
{
|
||||
ASSERT(cdb);
|
||||
|
@ -11,11 +11,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "controllers/sasidev_ctrl.h"
|
||||
#include "controllers/scsidev_ctrl.h"
|
||||
#include "interfaces/scsi_primary_commands.h"
|
||||
#include "device.h"
|
||||
#include "dispatcher.h"
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -23,33 +23,29 @@ class PrimaryDevice: public Device, virtual public ScsiPrimaryCommands
|
||||
{
|
||||
public:
|
||||
|
||||
PrimaryDevice(const string);
|
||||
PrimaryDevice(const string&);
|
||||
virtual ~PrimaryDevice() {}
|
||||
|
||||
virtual bool Dispatch(SCSIDEV *) override;
|
||||
virtual bool Dispatch(SCSIDEV *);
|
||||
|
||||
void TestUnitReady(SASIDEV *);
|
||||
void RequestSense(SASIDEV *);
|
||||
|
||||
void SetCtrl(SASIDEV::ctrl_t *ctrl) { this->ctrl = ctrl; }
|
||||
|
||||
bool CheckReady();
|
||||
virtual int Inquiry(const DWORD *, BYTE *) = 0;
|
||||
virtual int RequestSense(const DWORD *, BYTE *);
|
||||
|
||||
protected:
|
||||
|
||||
int Inquiry(int, bool, const DWORD *, BYTE *);
|
||||
|
||||
SASIDEV::ctrl_t *ctrl;
|
||||
|
||||
private:
|
||||
|
||||
typedef struct _command_t {
|
||||
const char* name;
|
||||
void (PrimaryDevice::*execute)(SASIDEV *);
|
||||
|
||||
_command_t(const char* _name, void (PrimaryDevice::*_execute)(SASIDEV *)) : name(_name), execute(_execute) { };
|
||||
} command_t;
|
||||
std::map<ScsiDefs::scsi_command, command_t*> commands;
|
||||
|
||||
void AddCommand(ScsiDefs::scsi_command, const char*, void (PrimaryDevice::*)(SASIDEV *));
|
||||
Dispatcher<PrimaryDevice> dispatcher;
|
||||
|
||||
void Inquiry(SASIDEV *);
|
||||
void ReportLuns(SASIDEV *);
|
||||
|
@ -13,11 +13,11 @@
|
||||
// [ SASI hard disk ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "sasihd.h"
|
||||
#include "fileio.h"
|
||||
#include "exceptions.h"
|
||||
#include <sstream>
|
||||
#include "../rascsi.h"
|
||||
#include "../config.h"
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
|
@ -28,23 +28,25 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "scsi_daynaport.h"
|
||||
#include <sstream>
|
||||
|
||||
using namespace scsi_defs;
|
||||
|
||||
const BYTE SCSIDaynaPort::m_bcast_addr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
const BYTE SCSIDaynaPort::m_apple_talk_addr[6] = { 0x09, 0x00, 0x07, 0xff, 0xff, 0xff };
|
||||
|
||||
// TODO Disk should not be the superclass
|
||||
SCSIDaynaPort::SCSIDaynaPort() : Disk("SCDP")
|
||||
{
|
||||
m_tap = NULL;
|
||||
m_bTapEnable = false;
|
||||
|
||||
AddCommand(ScsiDefs::eCmdTestUnitReady, "TestUnitReady", &SCSIDaynaPort::TestUnitReady);
|
||||
AddCommand(ScsiDefs::eCmdRead6, "Read6", &SCSIDaynaPort::Read6);
|
||||
AddCommand(ScsiDefs::eCmdWrite6, "Write6", &SCSIDaynaPort::Write6);
|
||||
AddCommand(ScsiDefs::eCmdRetrieveStats, "RetrieveStats", &SCSIDaynaPort::RetrieveStatistics);
|
||||
AddCommand(ScsiDefs::eCmdSetIfaceMode, "SetIfaceMode", &SCSIDaynaPort::SetInterfaceMode);
|
||||
AddCommand(ScsiDefs::eCmdSetMcastAddr, "SetMcastAddr", &SCSIDaynaPort::SetMcastAddr);
|
||||
AddCommand(ScsiDefs::eCmdEnableInterface, "EnableInterface", &SCSIDaynaPort::EnableInterface);
|
||||
dispatcher.AddCommand(eCmdTestUnitReady, "TestUnitReady", &SCSIDaynaPort::TestUnitReady);
|
||||
dispatcher.AddCommand(eCmdRead6, "Read6", &SCSIDaynaPort::Read6);
|
||||
dispatcher.AddCommand(eCmdWrite6, "Write6", &SCSIDaynaPort::Write6);
|
||||
dispatcher.AddCommand(eCmdRetrieveStats, "RetrieveStats", &SCSIDaynaPort::RetrieveStatistics);
|
||||
dispatcher.AddCommand(eCmdSetIfaceMode, "SetIfaceMode", &SCSIDaynaPort::SetInterfaceMode);
|
||||
dispatcher.AddCommand(eCmdSetMcastAddr, "SetMcastAddr", &SCSIDaynaPort::SetMcastAddr);
|
||||
dispatcher.AddCommand(eCmdEnableInterface, "EnableInterface", &SCSIDaynaPort::EnableInterface);
|
||||
}
|
||||
|
||||
SCSIDaynaPort::~SCSIDaynaPort()
|
||||
@ -54,35 +56,12 @@ SCSIDaynaPort::~SCSIDaynaPort()
|
||||
m_tap->Cleanup();
|
||||
delete m_tap;
|
||||
}
|
||||
|
||||
for (auto const& command : commands) {
|
||||
delete command.second;
|
||||
}
|
||||
}
|
||||
|
||||
void SCSIDaynaPort::AddCommand(ScsiDefs::scsi_command opcode, const char* name, void (SCSIDaynaPort::*execute)(SASIDEV *))
|
||||
{
|
||||
commands[opcode] = new command_t(name, execute);
|
||||
}
|
||||
|
||||
bool SCSIDaynaPort::Dispatch(SCSIDEV *controller)
|
||||
{
|
||||
ctrl = controller->GetCtrl();
|
||||
|
||||
if (commands.count(static_cast<ScsiDefs::scsi_command>(ctrl->cmd[0]))) {
|
||||
command_t *command = commands[static_cast<ScsiDefs::scsi_command>(ctrl->cmd[0])];
|
||||
|
||||
LOGDEBUG("%s Executing %s ($%02X)", __PRETTY_FUNCTION__, command->name, (unsigned int)ctrl->cmd[0]);
|
||||
|
||||
(this->*command->execute)(controller);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
LOGTRACE("%s Calling base class for dispatching $%02X", __PRETTY_FUNCTION__, (unsigned int)ctrl->cmd[0]);
|
||||
|
||||
// The base class handles the less specific commands
|
||||
return Disk::Dispatch(controller);
|
||||
// The superclass class handles the less specific commands
|
||||
return dispatcher.Dispatch(this, controller) ? true : super::Dispatch(controller);
|
||||
}
|
||||
|
||||
bool SCSIDaynaPort::Init(const map<string, string>& params)
|
||||
@ -133,36 +112,10 @@ void SCSIDaynaPort::Open(const Filepath& path)
|
||||
m_tap->OpenDump(path);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// INQUIRY
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
int SCSIDaynaPort::Inquiry(const DWORD *cdb, BYTE *buf)
|
||||
{
|
||||
int allocation_length = cdb[4] + (((DWORD)cdb[3]) << 8);
|
||||
if (allocation_length > 4) {
|
||||
if (allocation_length > 44) {
|
||||
allocation_length = 44;
|
||||
}
|
||||
|
||||
// Basic data
|
||||
// buf[0] ... Processor Device
|
||||
// buf[1] ... Not removable
|
||||
// buf[2] ... SCSI-2 compliant command system
|
||||
// buf[3] ... SCSI-2 compliant Inquiry response
|
||||
// buf[4] ... Inquiry additional data
|
||||
// http://www.bitsavers.org/pdf/apple/scsi/dayna/daynaPORT/pocket_scsiLINK/pocketscsilink_inq.png
|
||||
memset(buf, 0, allocation_length);
|
||||
buf[0] = 0x03;
|
||||
buf[2] = 0x01;
|
||||
buf[4] = 0x1F;
|
||||
|
||||
// Padded vendor, product, revision
|
||||
memcpy(&buf[8], GetPaddedName().c_str(), 28);
|
||||
}
|
||||
|
||||
return allocation_length;
|
||||
// Processor device, not removable
|
||||
return PrimaryDevice::Inquiry(3, false, cdb, buf);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
@ -201,10 +154,6 @@ int SCSIDaynaPort::Read(const DWORD *cdb, BYTE *buf, uint64_t block)
|
||||
int rx_packet_size = 0;
|
||||
scsi_resp_read_t *response = (scsi_resp_read_t*)buf;
|
||||
|
||||
ostringstream s;
|
||||
s << __PRETTY_FUNCTION__ << " reading DaynaPort block " << block;
|
||||
LOGTRACE("%s", s.str().c_str());
|
||||
|
||||
int requested_length = cdb[4];
|
||||
LOGTRACE("%s Read maximum length %d, (%04X)", __PRETTY_FUNCTION__, requested_length, requested_length);
|
||||
|
||||
|
@ -42,19 +42,6 @@
|
||||
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<ScsiDefs::scsi_command, command_t*> commands;
|
||||
|
||||
SASIDEV::ctrl_t *ctrl;
|
||||
|
||||
void AddCommand(ScsiDefs::scsi_command, const char*, void (SCSIDaynaPort::*)(SASIDEV *));
|
||||
|
||||
public:
|
||||
SCSIDaynaPort();
|
||||
~SCSIDaynaPort();
|
||||
@ -103,6 +90,10 @@ public:
|
||||
static const DWORD DAYNAPORT_READ_HEADER_SZ = 2 + 4;
|
||||
|
||||
private:
|
||||
typedef Disk super;
|
||||
|
||||
Dispatcher<SCSIDaynaPort> dispatcher;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
BYTE operation_code;
|
||||
BYTE misc_cdb_information;
|
||||
|
@ -16,17 +16,19 @@
|
||||
// work with the Sharp X68000 operating system.
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "controllers/scsidev_ctrl.h"
|
||||
#include "scsi_host_bridge.h"
|
||||
#include "ctapdriver.h"
|
||||
#include "cfilesystem.h"
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
using namespace scsi_defs;
|
||||
|
||||
SCSIBR::SCSIBR() : Disk("SCBR")
|
||||
SCSIBR::SCSIBR() : PrimaryDevice("SCBR")
|
||||
{
|
||||
tap = NULL;
|
||||
m_bTapEnable = false;
|
||||
packet_enable = false;
|
||||
|
||||
fsoptlen = 0;
|
||||
fsoutlen = 0;
|
||||
@ -37,9 +39,9 @@ SCSIBR::SCSIBR() : Disk("SCBR")
|
||||
fs = new CFileSys();
|
||||
fs->Reset();
|
||||
|
||||
AddCommand(ScsiDefs::eCmdTestUnitReady, "TestUnitReady", &SCSIBR::TestUnitReady);
|
||||
AddCommand(ScsiDefs::eCmdRead6, "GetMessage10", &SCSIBR::GetMessage10);
|
||||
AddCommand(ScsiDefs::eCmdWrite6, "SendMessage10", &SCSIBR::SendMessage10);
|
||||
dispatcher.AddCommand(eCmdTestUnitReady, "TestUnitReady", &SCSIBR::TestUnitReady);
|
||||
dispatcher.AddCommand(eCmdRead6, "GetMessage10", &SCSIBR::GetMessage10);
|
||||
dispatcher.AddCommand(eCmdWrite6, "SendMessage10", &SCSIBR::SendMessage10);
|
||||
}
|
||||
|
||||
SCSIBR::~SCSIBR()
|
||||
@ -55,10 +57,6 @@ SCSIBR::~SCSIBR()
|
||||
fs->Reset();
|
||||
delete fs;
|
||||
}
|
||||
|
||||
for (auto const& command : commands) {
|
||||
delete command.second;
|
||||
}
|
||||
}
|
||||
|
||||
bool SCSIBR::Init(const map<string, string>& params)
|
||||
@ -96,29 +94,10 @@ bool SCSIBR::Init(const map<string, string>& params)
|
||||
#endif
|
||||
}
|
||||
|
||||
void SCSIBR::AddCommand(ScsiDefs::scsi_command opcode, const char* name, void (SCSIBR::*execute)(SASIDEV *))
|
||||
{
|
||||
commands[opcode] = new command_t(name, execute);
|
||||
}
|
||||
|
||||
bool SCSIBR::Dispatch(SCSIDEV *controller)
|
||||
{
|
||||
ctrl = controller->GetCtrl();
|
||||
|
||||
if (commands.count(static_cast<ScsiDefs::scsi_command>(ctrl->cmd[0]))) {
|
||||
command_t *command = commands[static_cast<ScsiDefs::scsi_command>(ctrl->cmd[0])];
|
||||
|
||||
LOGDEBUG("%s Executing %s ($%02X)", __PRETTY_FUNCTION__, command->name, (unsigned int)ctrl->cmd[0]);
|
||||
|
||||
(this->*command->execute)(controller);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
LOGTRACE("%s Calling base class for dispatching $%02X", __PRETTY_FUNCTION__, (unsigned int)ctrl->cmd[0]);
|
||||
|
||||
// The base class handles the less specific commands
|
||||
return Disk::Dispatch(controller);
|
||||
// The superclass class handles the less specific commands
|
||||
return dispatcher.Dispatch(this, controller) ? true : super::Dispatch(controller);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
@ -128,14 +107,10 @@ bool SCSIBR::Dispatch(SCSIDEV *controller)
|
||||
//---------------------------------------------------------------------------
|
||||
int SCSIBR::Inquiry(const DWORD *cdb, BYTE *buf)
|
||||
{
|
||||
ASSERT(cdb);
|
||||
ASSERT(buf);
|
||||
ASSERT(cdb[0] == 0x12);
|
||||
|
||||
// EVPD check
|
||||
if (cdb[1] & 0x01) {
|
||||
SetStatusCode(STATUS_INVALIDCDB);
|
||||
return FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Basic data
|
||||
@ -175,15 +150,9 @@ int SCSIBR::Inquiry(const DWORD *cdb, BYTE *buf)
|
||||
return size;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// TEST UNIT READY
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
void SCSIBR::TestUnitReady(SASIDEV *controller)
|
||||
{
|
||||
// TEST UNIT READY Success
|
||||
|
||||
// Always successful
|
||||
controller->Status();}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -18,7 +18,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "os.h"
|
||||
#include "disk.h"
|
||||
#include "primary_device.h"
|
||||
#include <string>
|
||||
|
||||
//===========================================================================
|
||||
@ -29,22 +29,9 @@
|
||||
class CTapDriver;
|
||||
class CFileSys;
|
||||
|
||||
class SCSIBR : public Disk
|
||||
class SCSIBR : public PrimaryDevice
|
||||
{
|
||||
|
||||
private:
|
||||
typedef struct _command_t {
|
||||
const char* name;
|
||||
void (SCSIBR::*execute)(SASIDEV *);
|
||||
|
||||
_command_t(const char* _name, void (SCSIBR::*_execute)(SASIDEV *)) : name(_name), execute(_execute) { };
|
||||
} command_t;
|
||||
std::map<ScsiDefs::scsi_command, command_t*> commands;
|
||||
|
||||
SASIDEV::ctrl_t *ctrl;
|
||||
|
||||
void AddCommand(ScsiDefs::scsi_command, const char*, void (SCSIBR::*)(SASIDEV *));
|
||||
|
||||
public:
|
||||
SCSIBR();
|
||||
~SCSIBR();
|
||||
@ -61,6 +48,10 @@ public:
|
||||
void SendMessage10(SASIDEV *);
|
||||
|
||||
private:
|
||||
typedef PrimaryDevice super;
|
||||
|
||||
Dispatcher<SCSIBR> dispatcher;
|
||||
|
||||
int GetMacAddr(BYTE *buf); // Get MAC address
|
||||
void SetMacAddr(BYTE *buf); // Set MAC address
|
||||
void ReceivePacket(); // Receive a packet
|
||||
|
@ -10,14 +10,15 @@
|
||||
// Licensed under the BSD 3-Clause License.
|
||||
// See LICENSE file in the project root folder.
|
||||
//
|
||||
// [ SCSI CD-ROM for Apple Macintosh ]
|
||||
// [ SCSI CD-ROM ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "scsicd.h"
|
||||
#include "fileio.h"
|
||||
#include "exceptions.h"
|
||||
#include <sstream>
|
||||
|
||||
using namespace scsi_defs;
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
@ -240,8 +241,8 @@ SCSICD::SCSICD() : Disk("SCCD"), ScsiMmcCommands(), FileSupport()
|
||||
dataindex = -1;
|
||||
audioindex = -1;
|
||||
|
||||
AddCommand(ScsiDefs::eCmdReadToc, "ReadToc", &SCSICD::ReadToc);
|
||||
AddCommand(ScsiDefs::eCmdGetEventStatusNotification, "GetEventStatusNotification", &SCSICD::GetEventStatusNotification);
|
||||
dispatcher.AddCommand(eCmdReadToc, "ReadToc", &SCSICD::ReadToc);
|
||||
dispatcher.AddCommand(eCmdGetEventStatusNotification, "GetEventStatusNotification", &SCSICD::GetEventStatusNotification);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
@ -253,35 +254,12 @@ SCSICD::~SCSICD()
|
||||
{
|
||||
// Clear track
|
||||
ClearTrack();
|
||||
|
||||
for (auto const& command : commands) {
|
||||
delete command.second;
|
||||
}
|
||||
}
|
||||
|
||||
void SCSICD::AddCommand(ScsiDefs::scsi_command opcode, const char* name, void (SCSICD::*execute)(SASIDEV *))
|
||||
{
|
||||
commands[opcode] = new command_t(name, execute);
|
||||
}
|
||||
|
||||
bool SCSICD::Dispatch(SCSIDEV *controller)
|
||||
{
|
||||
ctrl = controller->GetCtrl();
|
||||
|
||||
if (commands.count(static_cast<ScsiDefs::scsi_command>(ctrl->cmd[0]))) {
|
||||
command_t *command = commands[static_cast<ScsiDefs::scsi_command>(ctrl->cmd[0])];
|
||||
|
||||
LOGDEBUG("%s Executing %s ($%02X)", __PRETTY_FUNCTION__, command->name, (unsigned int)ctrl->cmd[0]);
|
||||
|
||||
(this->*command->execute)(controller);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
LOGTRACE("%s Calling base class for dispatching $%02X", __PRETTY_FUNCTION__, (unsigned int)ctrl->cmd[0]);
|
||||
|
||||
// The base class handles the less specific commands
|
||||
return Disk::Dispatch(controller);
|
||||
// The superclass class handles the less specific commands
|
||||
return dispatcher.Dispatch(this, controller) ? true : super::Dispatch(controller);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
@ -421,9 +399,8 @@ void SCSICD::OpenIso(const Filepath& path)
|
||||
if (rawfile) {
|
||||
// Size must be a multiple of 2536
|
||||
if (size % 2536) {
|
||||
stringstream error;
|
||||
error << "Raw ISO CD-ROM file size must be a multiple of 2536 bytes but is " << size << " bytes";
|
||||
throw io_exception(error.str());
|
||||
throw io_exception("Raw ISO CD-ROM file size must be a multiple of 2536 bytes but is "
|
||||
+ to_string(size) + " bytes");
|
||||
}
|
||||
|
||||
// Set the number of blocks
|
||||
@ -499,13 +476,10 @@ void SCSICD::ReadToc(SASIDEV *controller)
|
||||
//---------------------------------------------------------------------------
|
||||
int SCSICD::Inquiry(const DWORD *cdb, BYTE *buf)
|
||||
{
|
||||
ASSERT(cdb);
|
||||
ASSERT(buf);
|
||||
|
||||
// EVPD check
|
||||
if (cdb[1] & 0x01) {
|
||||
SetStatusCode(STATUS_INVALIDCDB);
|
||||
return FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Basic data
|
||||
|
@ -71,25 +71,12 @@ private:
|
||||
//===========================================================================
|
||||
class SCSICD : public Disk, public ScsiMmcCommands, public FileSupport
|
||||
{
|
||||
private:
|
||||
typedef struct _command_t {
|
||||
const char* name;
|
||||
void (SCSICD::*execute)(SASIDEV *);
|
||||
|
||||
_command_t(const char* _name, void (SCSICD::*_execute)(SASIDEV *)) : name(_name), execute(_execute) { };
|
||||
} command_t;
|
||||
std::map<ScsiDefs::scsi_command, command_t*> commands;
|
||||
|
||||
SASIDEV::ctrl_t *ctrl;
|
||||
|
||||
void AddCommand(ScsiDefs::scsi_command, const char*, void (SCSICD::*)(SASIDEV *));
|
||||
|
||||
public:
|
||||
enum {
|
||||
TrackMax = 96 // Maximum number of tracks
|
||||
};
|
||||
|
||||
public:
|
||||
SCSICD();
|
||||
~SCSICD();
|
||||
|
||||
@ -103,6 +90,10 @@ public:
|
||||
int ReadToc(const DWORD *cdb, BYTE *buf); // READ TOC command
|
||||
|
||||
private:
|
||||
typedef Disk super;
|
||||
|
||||
Dispatcher<SCSICD> dispatcher;
|
||||
|
||||
// Open
|
||||
void OpenCue(const Filepath& path); // Open(CUE)
|
||||
void OpenIso(const Filepath& path); // Open(ISO)
|
||||
|
@ -119,9 +119,6 @@ void SCSIHD::Open(const Filepath& path)
|
||||
//---------------------------------------------------------------------------
|
||||
int SCSIHD::Inquiry(const DWORD *cdb, BYTE *buf)
|
||||
{
|
||||
ASSERT(cdb);
|
||||
ASSERT(buf);
|
||||
|
||||
// EVPD check
|
||||
if (cdb[1] & 0x01) {
|
||||
SetStatusCode(STATUS_INVALIDCDB);
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
#include "fileio.h"
|
||||
#include "exceptions.h"
|
||||
#include <sstream>
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
|
@ -11,7 +11,8 @@
|
||||
#include "os.h"
|
||||
#include "filepath.h"
|
||||
#include "fileio.h"
|
||||
#include "rascsi.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
|
@ -10,8 +10,8 @@
|
||||
|
||||
#include "os.h"
|
||||
#include "filepath.h"
|
||||
#include "config.h"
|
||||
#include "fileio.h"
|
||||
#include "rascsi.h"
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
|
@ -16,8 +16,9 @@
|
||||
|
||||
#include "os.h"
|
||||
#include "gpiobus.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "log.h"
|
||||
#include "rascsi.h"
|
||||
|
||||
#ifdef __linux__
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -12,7 +12,7 @@
|
||||
#if !defined(gpiobus_h)
|
||||
#define gpiobus_h
|
||||
|
||||
#include "rascsi.h"
|
||||
#include "config.h"
|
||||
#include "scsi.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -10,7 +10,6 @@
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "rascsi.h"
|
||||
#include "os.h"
|
||||
#include "controllers/sasidev_ctrl.h"
|
||||
#include "devices/device_factory.h"
|
||||
@ -34,6 +33,7 @@
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "config.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace spdlog;
|
||||
@ -520,17 +520,17 @@ string SetReservedIds(const string& ids)
|
||||
reserved_ids = reserved;
|
||||
|
||||
if (!reserved_ids.empty()) {
|
||||
ostringstream s;
|
||||
string s;
|
||||
bool isFirst = true;
|
||||
for (auto const& reserved_id : reserved_ids) {
|
||||
if (!isFirst) {
|
||||
s << ", ";
|
||||
s += ", ";
|
||||
}
|
||||
isFirst = false;
|
||||
s << reserved_id;
|
||||
s += to_string(reserved_id);
|
||||
}
|
||||
|
||||
LOGINFO("Reserved ID(s) set to %s", s.str().c_str());
|
||||
LOGINFO("Reserved ID(s) set to %s", s.c_str());
|
||||
}
|
||||
else {
|
||||
LOGINFO("Cleared reserved IDs");
|
||||
@ -580,15 +580,14 @@ bool Attach(const CommandContext& context, const PbDeviceDefinition& pb_device,
|
||||
if (unit >= supported_luns) {
|
||||
delete device;
|
||||
|
||||
ostringstream error;
|
||||
error << "Invalid unit " << unit << " for device type " << PbDeviceType_Name(type);
|
||||
string error = "Invalid unit " + to_string(unit) + " for device type " + PbDeviceType_Name(type);
|
||||
if (supported_luns == 1) {
|
||||
error << " (0)";
|
||||
error += " (0)";
|
||||
}
|
||||
else {
|
||||
error << " (0-" << (supported_luns -1) << ")";
|
||||
error += " (0-" + to_string(supported_luns -1) + ")";
|
||||
}
|
||||
return ReturnStatus(context, false, error.str());
|
||||
return ReturnStatus(context, false, error);
|
||||
}
|
||||
|
||||
// If no filename was provided the medium is considered removed
|
||||
@ -709,16 +708,15 @@ bool Attach(const CommandContext& context, const PbDeviceDefinition& pb_device,
|
||||
|
||||
// Re-map the controller
|
||||
if (MapController(map)) {
|
||||
ostringstream msg;
|
||||
msg << "Attached ";
|
||||
string msg = "Attached ";
|
||||
if (device->IsReadOnly()) {
|
||||
msg << "read-only ";
|
||||
msg += "read-only ";
|
||||
}
|
||||
else if (device->IsProtectable() && device->IsProtected()) {
|
||||
msg << "protected ";
|
||||
msg += "protected ";
|
||||
}
|
||||
msg << device->GetType() << " device, ID " << id << ", unit " << unit;
|
||||
LOGINFO("%s", msg.str().c_str());
|
||||
msg += device->GetType() + " device, ID " + to_string(id) + ", unit " + to_string(unit);
|
||||
LOGINFO("%s", msg.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -840,8 +838,6 @@ void TerminationHandler(int signum)
|
||||
|
||||
bool ProcessCmd(const CommandContext& context, const PbDeviceDefinition& pb_device, const PbCommand& command, bool dryRun)
|
||||
{
|
||||
ostringstream error;
|
||||
|
||||
const int id = pb_device.id();
|
||||
const int unit = pb_device.unit();
|
||||
const PbDeviceType type = pb_device.type();
|
||||
|
@ -70,7 +70,7 @@ void RascsiResponse::GetAllDeviceTypeProperties(PbDeviceTypesInfo& device_types_
|
||||
int ordinal = 1;
|
||||
while (PbDeviceType_IsValid(ordinal)) {
|
||||
PbDeviceType type = UNDEFINED;
|
||||
PbDeviceType_Parse(PbDeviceType_Name(ordinal), &type);
|
||||
PbDeviceType_Parse(PbDeviceType_Name((PbDeviceType)ordinal), &type);
|
||||
GetDeviceTypeProperties(device_types_info, type);
|
||||
ordinal++;
|
||||
}
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "rasutil.h"
|
||||
#include "rasctl_commands.h"
|
||||
#include "rascsi_interface.pb.h"
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
|
||||
@ -66,9 +65,8 @@ void RasctlCommands::SendCommand()
|
||||
memcpy(&server.sin_addr.s_addr, host->h_addr, host->h_length);
|
||||
|
||||
if (connect(fd, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) < 0) {
|
||||
ostringstream error;
|
||||
error << "Can't connect to rascsi process on host '" << hostname << "', port " << port;
|
||||
throw io_exception(error.str());
|
||||
throw io_exception("Can't connect to rascsi process on host '" + hostname + "', port "
|
||||
+ to_string(port));
|
||||
}
|
||||
|
||||
if (write(fd, "RASCSI", 6) != 6) {
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include "fileio.h"
|
||||
#include "filepath.h"
|
||||
#include "gpiobus.h"
|
||||
#include "rascsi.h"
|
||||
#include "rascsi_version.h"
|
||||
|
||||
#define BUFSIZE 1024 * 64 // Maybe around 64KB?
|
||||
|
@ -154,8 +154,7 @@ private:
|
||||
static const char* phase_str_table[];
|
||||
};
|
||||
|
||||
class ScsiDefs {
|
||||
public:
|
||||
namespace scsi_defs {
|
||||
enum scsi_command : int {
|
||||
eCmdTestUnitReady = 0x00,
|
||||
eCmdRezero = 0x01,
|
||||
|
Loading…
x
Reference in New Issue
Block a user