Moved commands from controller do disk

This commit is contained in:
Uwe Seimet 2021-08-22 11:46:03 +02:00
parent af13ce37bc
commit f1f2f4a84f
8 changed files with 156 additions and 182 deletions

View File

@ -1028,15 +1028,7 @@ void SASIDEV::CmdSeek6()
LOGTRACE("%s SEEK(6) Command ", __PRETTY_FUNCTION__);
// Command processing on drive
bool status = ctrl.device->Seek(ctrl.cmd);
if (!status) {
// Failure (Error)
Error();
return;
}
// status phase
Status();
ctrl.device->Seek6(this, &ctrl);
}
//---------------------------------------------------------------------------

View File

@ -179,6 +179,12 @@ public:
public:
void DataIn(); // Data in phase
void Status(); // Status phase
void MsgIn(); // Message in phase
void DataOut(); // Data out phase
virtual void Error(ERROR_CODES::sense_key sense_key = ERROR_CODES::sense_key::NO_SENSE,
ERROR_CODES::asc = ERROR_CODES::asc::NO_ADDITIONAL_SENSE_INFORMATION); // Common error handling
protected:
// Phase processing
@ -186,11 +192,6 @@ protected:
virtual void Selection(); // Selection phase
virtual void Command(); // Command phase
virtual void Execute(); // Execution phase
void Status(); // Status phase
void MsgIn(); // Message in phase
void DataOut(); // Data out phase
virtual void Error(ERROR_CODES::sense_key sense_key = ERROR_CODES::sense_key::NO_SENSE,
ERROR_CODES::asc = ERROR_CODES::asc::NO_ADDITIONAL_SENSE_INFORMATION); // Common error handling
// commands
void CmdTestUnitReady(); // TEST UNIT READY command

View File

@ -49,11 +49,11 @@ SCSIDEV::SCSIDEV() : SASIDEV()
SetUpControllerCommand(eCmdReassign, "CmdReassign", &SCSIDEV::CmdReassign);
SetUpControllerCommand(eCmdRead6, "CmdRead6", &SCSIDEV::CmdRead6);
SetUpControllerCommand(eCmdWrite6, "CmdWrite6", &SCSIDEV::CmdWrite6);
SetUpControllerCommand(eCmdSeek6, "CmdSeek6", &SCSIDEV::CmdSeek6);
SetUpDeviceCommand(eCmdSeek6, "CmdSeek6", &Disk::Seek6);
SetUpControllerCommand(eCmdInquiry, "CmdInquiry", &SCSIDEV::CmdInquiry);
SetUpControllerCommand(eCmdModeSelect, "CmdModeSelect", &SCSIDEV::CmdModeSelect);
SetUpControllerCommand(eCmdReserve6, "CmdReserve6", &SCSIDEV::CmdReserve6);
SetUpControllerCommand(eCmdRelease6, "CmdRelease6", &SCSIDEV::CmdRelease6);
SetUpDeviceCommand(eCmdReserve6, "CmdReserve6", &Disk::Reserve6);
SetUpDeviceCommand(eCmdRelease6, "CmdRelease6", &Disk::Release6);
SetUpControllerCommand(eCmdModeSense, "CmdModeSense", &SCSIDEV::CmdModeSense);
SetUpControllerCommand(eCmdStartStop, "CmdStartStop", &SCSIDEV::CmdStartStop);
SetUpControllerCommand(eCmdSendDiag, "CmdSendDiag", &SCSIDEV::CmdSendDiag);
@ -62,19 +62,19 @@ SCSIDEV::SCSIDEV() : SASIDEV()
SetUpControllerCommand(eCmdRead10, "CmdRead10", &SCSIDEV::CmdRead10);
SetUpControllerCommand(eCmdWrite10, "CmdWrite10", &SCSIDEV::CmdWrite10);
SetUpControllerCommand(eCmdVerify10, "CmdVerify10", &SCSIDEV::CmdWrite10);
SetUpControllerCommand(eCmdSeek10, "CmdSeek10", &SCSIDEV::CmdSeek10);
SetUpDeviceCommand(eCmdSeek10, "CmdSeek10", &Disk::Seek10);
SetUpControllerCommand(eCmdVerify, "CmdVerify", &SCSIDEV::CmdVerify);
SetUpControllerCommand(eCmdSynchronizeCache, "CmdSynchronizeCache", &SCSIDEV::CmdSynchronizeCache);
SetUpControllerCommand(eCmdReadDefectData10, "CmdReadDefectData10", &SCSIDEV::CmdReadDefectData10);
SetUpControllerCommand(eCmdModeSelect10, "CmdModeSelect10", &SCSIDEV::CmdModeSelect10);
SetUpControllerCommand(eCmdReserve10, "CmdReserve10", &SCSIDEV::CmdReserve10);
SetUpControllerCommand(eCmdRelease10, "CmdRelease10", &SCSIDEV::CmdRelease10);
SetUpDeviceCommand(eCmdReserve10, "CmdReserve10", &Disk::Reserve10);
SetUpDeviceCommand(eCmdRelease10, "CmdRelease10", &Disk::Release10);
SetUpControllerCommand(eCmdModeSense10, "CmdModeSense10", &SCSIDEV::CmdModeSense10);
SetUpControllerCommand(eCmdRead16, "CmdRead16", &SCSIDEV::CmdRead16);
SetUpControllerCommand(eCmdWrite16, "CmdWrite16", &SCSIDEV::CmdWrite16);
SetUpControllerCommand(eCmdVerify16, "CmdVerify16", &SCSIDEV::CmdWrite16);
SetUpDeviceCommand(eCmdReadCapacity16, "CmdReadCapacity16", &Disk::ReadCapacity16);
SetUpControllerCommand(eCmdReportLuns, "CmdReportLuns", &SCSIDEV::CmdReportLuns);
SetUpDeviceCommand(eCmdReportLuns, "CmdReportLuns", &Disk::ReportLuns);
// MMC specific. TODO Move to separate class
SetUpControllerCommand(eCmdReadToc, "CmdReadToc", &SCSIDEV::CmdReadToc);
@ -106,7 +106,7 @@ void SCSIDEV::SetUpControllerCommand(scsi_command opcode, const char* name, void
controller_commands[opcode] = new controller_command_t(name, execute);
}
void SCSIDEV::SetUpDeviceCommand(scsi_command opcode, const char* name, void (Disk::*execute)(SCSIDEV *, SASIDEV::ctrl_t *))
void SCSIDEV::SetUpDeviceCommand(scsi_command opcode, const char* name, void (Disk::*execute)(SASIDEV *, SASIDEV::ctrl_t *))
{
device_commands[opcode] = new device_command_t(name, execute);
}
@ -501,78 +501,6 @@ void SCSIDEV::CmdModeSelect()
DataOut();
}
//---------------------------------------------------------------------------
//
// RESERVE(6)
//
// The reserve/release commands are only used in multi-initiator
// environments. RaSCSI doesn't support this use case. However, some old
// versions of Solaris will issue the reserve/release commands. We will
// just respond with an OK status.
//
//---------------------------------------------------------------------------
void SCSIDEV::CmdReserve6()
{
LOGTRACE( "%s Reserve(6) Command", __PRETTY_FUNCTION__);
// status phase
Status();
}
//---------------------------------------------------------------------------
//
// RESERVE(10)
//
// The reserve/release commands are only used in multi-initiator
// environments. RaSCSI doesn't support this use case. However, some old
// versions of Solaris will issue the reserve/release commands. We will
// just respond with an OK status.
//
//---------------------------------------------------------------------------
void SCSIDEV::CmdReserve10()
{
LOGTRACE( "%s Reserve(10) Command", __PRETTY_FUNCTION__);
// status phase
Status();
}
//---------------------------------------------------------------------------
//
// RELEASE(6)
//
// The reserve/release commands are only used in multi-initiator
// environments. RaSCSI doesn't support this use case. However, some old
// versions of Solaris will issue the reserve/release commands. We will
// just respond with an OK status.
//
//---------------------------------------------------------------------------
void SCSIDEV::CmdRelease6()
{
LOGTRACE( "%s Release(6) Command", __PRETTY_FUNCTION__);
// status phase
Status();
}
//---------------------------------------------------------------------------
//
// RELEASE(10)
//
// The reserve/release commands are only used in multi-initiator
// environments. RaSCSI doesn't support this use case. However, some old
// versions of Solaris will issue the reserve/release commands. We will
// just respond with an OK status.
//
//---------------------------------------------------------------------------
void SCSIDEV::CmdRelease10()
{
LOGTRACE( "%s Release(10) Command", __PRETTY_FUNCTION__);
// status phase
Status();
}
//---------------------------------------------------------------------------
//
// MODE SENSE
@ -808,27 +736,6 @@ void SCSIDEV::CmdWrite16()
DataOut();
}
//---------------------------------------------------------------------------
//
// SEEK(10)
//
//---------------------------------------------------------------------------
void SCSIDEV::CmdSeek10()
{
LOGTRACE( "%s SEEK(10) Command ", __PRETTY_FUNCTION__);
// Command processing on drive
bool status = ctrl.device->Seek(ctrl.cmd);
if (!status) {
// Failure (Error)
Error();
return;
}
// status phase
Status();
}
//---------------------------------------------------------------------------
//
// VERIFY
@ -845,15 +752,7 @@ void SCSIDEV::CmdVerify()
// if BytChk=0
if ((ctrl.cmd[1] & 0x02) == 0) {
// Command processing on drive
bool status = ctrl.device->Seek(ctrl.cmd);
if (!status) {
// Failure (Error)
Error();
return;
}
// status phase
Status();
ctrl.device->Seek(this, &ctrl);
return;
}
@ -872,26 +771,6 @@ void SCSIDEV::CmdVerify()
DataOut();
}
//---------------------------------------------------------------------------
//
// REPORT LUNS
//
//---------------------------------------------------------------------------
void SCSIDEV::CmdReportLuns()
{
int length = ctrl.device->ReportLuns(ctrl.cmd, ctrl.buffer);
if (length <= 0) {
// Failure (Error)
Error();
return;
}
ctrl.length = length;
// Data in phase
DataIn();
}
//---------------------------------------------------------------------------
//
// SYNCHRONIZE CACHE

View File

@ -50,9 +50,9 @@ public:
typedef struct _device_command_t {
const char* name;
void (Disk::*execute)(SCSIDEV *, SASIDEV::ctrl_t *);
void (Disk::*execute)(SASIDEV *, SASIDEV::ctrl_t *);
_device_command_t(const char* _name, void (Disk::*_execute)(SCSIDEV *, SASIDEV::ctrl_t *)) : name(_name), execute(_execute) { };
_device_command_t(const char* _name, void (Disk::*_execute)(SASIDEV *, SASIDEV::ctrl_t *)) : name(_name), execute(_execute) { };
} device_command_t;
std::map<scsi_command, device_command_t*> device_commands;
@ -77,7 +77,7 @@ public:
private:
void SetUpControllerCommand(scsi_command, const char*, void (SCSIDEV::*)(void));
void SetUpDeviceCommand(scsi_command, const char*, void (Disk::*)(SCSIDEV *, SASIDEV::ctrl_t *));
void SetUpDeviceCommand(scsi_command, const char*, void (Disk::*)(SASIDEV *, SASIDEV::ctrl_t *));
// Phase
void BusFree(); // Bus free phase
@ -88,17 +88,12 @@ private:
// commands
void CmdInquiry(); // INQUIRY command
void CmdModeSelect(); // MODE SELECT command
void CmdReserve6(); // RESERVE(6) command
void CmdReserve10(); // RESERVE(10) command
void CmdRelease6(); // RELEASE(6) command
void CmdRelease10(); // RELEASE(10) command
void CmdModeSense(); // MODE SENSE command
void CmdStartStop(); // START STOP UNIT command
void CmdSendDiag(); // SEND DIAGNOSTIC command
void CmdRemoval(); // PREVENT/ALLOW MEDIUM REMOVAL command
void CmdRead10(); // READ(10) command
void CmdWrite10(); // WRITE(10) command
void CmdSeek10(); // SEEK(10) command
void CmdVerify(); // VERIFY command
void CmdSynchronizeCache(); // SYNCHRONIZE CACHE command
void CmdReadDefectData10(); // READ DEFECT DATA(10) command
@ -111,7 +106,6 @@ private:
void CmdModeSense10(); // MODE SENSE(10) command
void CmdRead16(); // READ(16) command
void CmdWrite16(); // WRITE(16) command
void CmdReportLuns(); // REPORT LUNS command
void CmdGetMessage10(); // GET MESSAGE(10) command
void CmdSendMessage10(); // SEND MESSAGE(10) command
void CmdRetrieveStats(); // DaynaPort specific command

View File

@ -12,7 +12,6 @@
#pragma once
#include "controllers/sasidev_ctrl.h"
#include "controllers/scsidev_ctrl.h"
#include "primary_device.h"
class BlockDevice : public PrimaryDevice
@ -23,26 +22,26 @@ public:
virtual ~BlockDevice() {};
// Mandatory commands
virtual bool TestUnitReady(const DWORD *cdb) = 0;
virtual int Inquiry(const DWORD *cdb, BYTE *buf) = 0;
virtual int ReportLuns(const DWORD *cdb, BYTE *buf) = 0;
virtual bool TestUnitReady(const DWORD *cdb) override = 0;
virtual int Inquiry(const DWORD *cdb, BYTE *buf) override = 0;
virtual void ReportLuns(SASIDEV *, SASIDEV::ctrl_t *) override = 0;
virtual bool Format(const DWORD *cdb) = 0;
// READ(6), READ(10)
virtual int Read(const DWORD *cdb, BYTE *buf, DWORD block) = 0;
// WRITE(6), WRITE(10)
virtual bool Write(const DWORD *cdb, const BYTE *buf, DWORD block) = 0;
virtual void ReadCapacity10(SCSIDEV *, SASIDEV::ctrl_t *) = 0;
virtual void ReadCapacity16(SCSIDEV *, SASIDEV::ctrl_t *) = 0;
virtual void ReadCapacity10(SASIDEV *, SASIDEV::ctrl_t *) = 0;
virtual void ReadCapacity16(SASIDEV *, SASIDEV::ctrl_t *) = 0;
// TODO Uncomment as soon as there is a clean separation between controllers and devices
//virtual int Read16(const DWORD *cdb, BYTE *buf, DWORD block) = 0;
//virtual int Write16(const DWORD *cdb, BYTE *buf, DWORD block) = 0;
//virtual int Verify16(const DWORD *cdb, BYTE *buf, DWORD block) = 0;
// Implemented optional commands
virtual int RequestSense(const DWORD *cdb, BYTE *buf) = 0;
virtual int ModeSense(const DWORD *cdb, BYTE *buf) = 0;
virtual int ModeSense10(const DWORD *cdb, BYTE *buf) = 0;
virtual bool ModeSelect(const DWORD *cdb, const BYTE *buf, int length) = 0;
virtual int RequestSense(const DWORD *cdb, BYTE *buf) override = 0;
virtual int ModeSense(const DWORD *cdb, BYTE *buf) override = 0;
virtual int ModeSense10(const DWORD *cdb, BYTE *buf) override = 0;
virtual bool ModeSelect(const DWORD *cdb, const BYTE *buf, int length) override = 0;
// TODO Add the other optional commands currently implemented
};

View File

@ -1661,16 +1661,41 @@ bool Disk::Write(const DWORD *cdb, const BYTE *buf, DWORD block)
return true;
}
//---------------------------------------------------------------------------
//
// SEEK
// *Does not check LBA (SASI IOCS)
//
//---------------------------------------------------------------------------
bool Disk::Seek(const DWORD* /*cdb*/)
void Disk::Seek(SASIDEV *controller, SASIDEV::ctrl_t *)
{
// Status check
return CheckReady();
if (!CheckReady()) {
controller->Error();
return;
}
// status phase
controller->Status();
}
//---------------------------------------------------------------------------
//
// SEEK(6)
// Does not check LBA (SASI IOCS)
//
//---------------------------------------------------------------------------
void Disk::Seek6(SASIDEV *controller, SASIDEV::ctrl_t *ctrl)
{
LOGTRACE( "%s SEEK(6) Command ", __PRETTY_FUNCTION__);
Seek(controller, ctrl);
}
//---------------------------------------------------------------------------
//
// SEEK(10)
//
//---------------------------------------------------------------------------
void Disk::Seek10(SASIDEV *controller, SASIDEV::ctrl_t *ctrl)
{
LOGTRACE( "%s SEEK(10) Command ", __PRETTY_FUNCTION__);
Seek(controller, ctrl);
}
//---------------------------------------------------------------------------
@ -1776,7 +1801,7 @@ bool Disk::Removal(const DWORD *cdb)
// READ CAPACITY
//
//---------------------------------------------------------------------------
void Disk::ReadCapacity10(SCSIDEV *controller, SASIDEV::ctrl_t *ctrl)
void Disk::ReadCapacity10(SASIDEV *controller, SASIDEV::ctrl_t *ctrl)
{
LOGTRACE( "%s READ CAPACITY(10) Command ", __PRETTY_FUNCTION__);
@ -1822,7 +1847,7 @@ void Disk::ReadCapacity10(SCSIDEV *controller, SASIDEV::ctrl_t *ctrl)
controller->DataIn();
}
void Disk::ReadCapacity16(SCSIDEV *controller, SASIDEV::ctrl_t *ctrl)
void Disk::ReadCapacity16(SASIDEV *controller, SASIDEV::ctrl_t *ctrl)
{
LOGTRACE( "%s READ CAPACITY(16) Command ", __PRETTY_FUNCTION__);
@ -1877,8 +1902,10 @@ void Disk::ReadCapacity16(SCSIDEV *controller, SASIDEV::ctrl_t *ctrl)
// REPORT LUNS
//
//---------------------------------------------------------------------------
int Disk::ReportLuns(const DWORD* /*cdb*/, BYTE *buf)
void Disk::ReportLuns(SASIDEV *controller, SASIDEV::ctrl_t *ctrl)
{
BYTE *buf = ctrl->buffer;
ASSERT(buf);
// Buffer clear
@ -1886,7 +1913,8 @@ int Disk::ReportLuns(const DWORD* /*cdb*/, BYTE *buf)
// Status check
if (!CheckReady()) {
return 0;
controller->Error();
return;
}
// LUN list length
@ -1894,7 +1922,10 @@ int Disk::ReportLuns(const DWORD* /*cdb*/, BYTE *buf)
// As long as there is no proper support for more than one SCSI LUN no other fields must be set => 1 LUN
return 16;
ctrl->length = 16;
// Data in phase
controller->DataIn();
}
//---------------------------------------------------------------------------
@ -1934,6 +1965,78 @@ bool Disk::Verify(const DWORD *cdb)
return true;
}
//---------------------------------------------------------------------------
//
// RESERVE(6)
//
// The reserve/release commands are only used in multi-initiator
// environments. RaSCSI doesn't support this use case. However, some old
// versions of Solaris will issue the reserve/release commands. We will
// just respond with an OK status.
//
//---------------------------------------------------------------------------
void Disk::Reserve6(SASIDEV *controller, SASIDEV::ctrl_t *)
{
LOGTRACE( "%s Reserve(6) Command", __PRETTY_FUNCTION__);
// status phase
controller->Status();
}
//---------------------------------------------------------------------------
//
// RESERVE(10)
//
// The reserve/release commands are only used in multi-initiator
// environments. RaSCSI doesn't support this use case. However, some old
// versions of Solaris will issue the reserve/release commands. We will
// just respond with an OK status.
//
//---------------------------------------------------------------------------
void Disk::Reserve10(SASIDEV *controller, SASIDEV::ctrl_t *)
{
LOGTRACE( "%s Reserve(10) Command", __PRETTY_FUNCTION__);
// status phase
controller->Status();
}
//---------------------------------------------------------------------------
//
// RELEASE(6)
//
// The reserve/release commands are only used in multi-initiator
// environments. RaSCSI doesn't support this use case. However, some old
// versions of Solaris will issue the reserve/release commands. We will
// just respond with an OK status.
//
//---------------------------------------------------------------------------
void Disk::Release6(SASIDEV *controller, SASIDEV::ctrl_t *)
{
LOGTRACE( "%s Release(6) Command", __PRETTY_FUNCTION__);
// status phase
controller->Status();
}
//---------------------------------------------------------------------------
//
// RELEASE(10)
//
// The reserve/release commands are only used in multi-initiator
// environments. RaSCSI doesn't support this use case. However, some old
// versions of Solaris will issue the reserve/release commands. We will
// just respond with an OK status.
//
//---------------------------------------------------------------------------
void Disk::Release10(SASIDEV *controller, SASIDEV::ctrl_t *)
{
LOGTRACE( "%s Release(10) Command", __PRETTY_FUNCTION__);
// status phase
controller->Status();
}
//---------------------------------------------------------------------------
//
// READ TOC

View File

@ -21,7 +21,6 @@
#include "log.h"
#include "scsi.h"
#include "controllers/sasidev_ctrl.h"
#include "controllers/scsidev_ctrl.h"
#include "block_device.h"
#include "file_support.h"
#include "filepath.h"
@ -166,15 +165,21 @@ public:
virtual int Read(const DWORD *cdb, BYTE *buf, DWORD block) override; // READ command
virtual int WriteCheck(DWORD block); // WRITE check
virtual bool Write(const DWORD *cdb, const BYTE *buf, DWORD block) override; // WRITE command
bool Seek(const DWORD *cdb); // SEEK command
void Seek(SASIDEV *, SASIDEV::ctrl_t *);
void Seek6(SASIDEV *, SASIDEV::ctrl_t *);
void Seek10(SASIDEV *, SASIDEV::ctrl_t *);
bool Assign(const DWORD *cdb); // ASSIGN command
bool Specify(const DWORD *cdb); // SPECIFY command
bool StartStop(const DWORD *cdb); // START STOP UNIT command
bool SendDiag(const DWORD *cdb); // SEND DIAGNOSTIC command
bool Removal(const DWORD *cdb); // PREVENT/ALLOW MEDIUM REMOVAL command
void ReadCapacity10(SCSIDEV *, SASIDEV::ctrl_t *) override; // READ CAPACITY(10) command
void ReadCapacity16(SCSIDEV *, SASIDEV::ctrl_t *) override; // READ CAPACITY(16) command
int ReportLuns(const DWORD *cdb, BYTE *buf); // REPORT LUNS command
void ReadCapacity10(SASIDEV *, SASIDEV::ctrl_t *) override; // READ CAPACITY(10) command
void ReadCapacity16(SASIDEV *, SASIDEV::ctrl_t *) override; // READ CAPACITY(16) command
void ReportLuns(SASIDEV *, SASIDEV::ctrl_t *) override;
void Reserve6(SASIDEV *, SASIDEV::ctrl_t *);
void Reserve10(SASIDEV *, SASIDEV::ctrl_t *);
void Release6(SASIDEV *, SASIDEV::ctrl_t *);
void Release10(SASIDEV *, SASIDEV::ctrl_t *);
int GetSectorSize() const;
void SetSectorSize(int);
bool IsSectorSizeConfigurable() const;

View File

@ -11,6 +11,7 @@
#pragma once
#include "controllers/sasidev_ctrl.h"
#include "device.h"
class PrimaryDevice : public Device
@ -23,7 +24,7 @@ public:
// Mandatory commands
virtual bool TestUnitReady(const DWORD *cdb) = 0;
virtual int Inquiry(const DWORD *cdb, BYTE *buf) = 0;
virtual int ReportLuns(const DWORD *cdb, BYTE *buf) = 0;
virtual void ReportLuns(SASIDEV *, SASIDEV::ctrl_t *) = 0;
// Implemented optional commands
virtual int RequestSense(const DWORD *cdb, BYTE *buf) = 0;