mirror of
https://github.com/akuker/RASCSI.git
synced 2024-12-21 08:29:59 +00:00
Cleaned up dependencies on controller manager (#964)
* Cleaned up dependencies on controller manager * Removed global fields * Simplified setting up RascsiResponse and RascsiExecutor * Got rid of remaining raw pointers * Use references instead of pointers * Improved encapsulation
This commit is contained in:
parent
921ba7d2ed
commit
c98c52ffb8
@ -117,7 +117,7 @@ bool AbstractController::AddDevice(shared_ptr<PrimaryDevice> device)
|
||||
}
|
||||
|
||||
luns[device->GetLun()] = device;
|
||||
device->SetController(this);
|
||||
device->SetController(shared_from_this());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "scsi.h"
|
||||
#include "hal/bus.h"
|
||||
#include "phase_handler.h"
|
||||
#include "controller_manager.h"
|
||||
#include <unordered_set>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
@ -23,7 +24,7 @@ using namespace std;
|
||||
|
||||
class PrimaryDevice;
|
||||
|
||||
class AbstractController : public PhaseHandler
|
||||
class AbstractController : public PhaseHandler, public enable_shared_from_this<AbstractController>
|
||||
{
|
||||
public:
|
||||
|
||||
@ -34,7 +35,8 @@ public:
|
||||
RESTART_PI
|
||||
};
|
||||
|
||||
AbstractController(shared_ptr<BUS> bus, int target_id, int max_luns) : target_id(target_id), bus(bus), max_luns(max_luns) {}
|
||||
AbstractController(shared_ptr<ControllerManager> controller_manager, int target_id, int max_luns)
|
||||
: controller_manager(controller_manager), target_id(target_id), max_luns(max_luns) {}
|
||||
~AbstractController() override = default;
|
||||
|
||||
virtual void Error(scsi_defs::sense_key, scsi_defs::asc = scsi_defs::asc::NO_ADDITIONAL_SENSE_INFORMATION,
|
||||
@ -82,7 +84,8 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
inline shared_ptr<BUS> GetBus() const { return bus; }
|
||||
shared_ptr<ControllerManager> GetControllerManager() const { return controller_manager.lock(); }
|
||||
inline BUS& GetBus() const { return controller_manager.lock()->GetBus(); }
|
||||
|
||||
scsi_defs::scsi_command GetOpcode() const { return static_cast<scsi_defs::scsi_command>(ctrl.cmd[0]); }
|
||||
int GetLun() const { return (ctrl.cmd[1] >> 5) & 0x07; }
|
||||
@ -116,13 +119,13 @@ private:
|
||||
|
||||
ctrl_t ctrl = {};
|
||||
|
||||
weak_ptr<ControllerManager> controller_manager;
|
||||
|
||||
// Logical units of this controller mapped to their LUN numbers
|
||||
unordered_map<int, shared_ptr<PrimaryDevice>> luns;
|
||||
|
||||
int target_id;
|
||||
|
||||
shared_ptr<BUS> bus;
|
||||
|
||||
int max_luns;
|
||||
|
||||
bool is_byte_transfer = false;
|
||||
|
@ -23,7 +23,7 @@ bool ControllerManager::AttachToScsiController(int id, shared_ptr<PrimaryDevice>
|
||||
|
||||
// If there is no LUN yet the first LUN must be LUN 0
|
||||
if (device->GetLun() == 0) {
|
||||
controller = make_shared<ScsiController>(bus, id);
|
||||
controller = make_shared<ScsiController>(shared_from_this(), id);
|
||||
|
||||
if (controller->AddDevice(device)) {
|
||||
controllers[id] = controller;
|
||||
@ -74,13 +74,6 @@ void ControllerManager::DeleteAllControllers()
|
||||
controllers.clear();
|
||||
}
|
||||
|
||||
void ControllerManager::ResetAllControllers() const
|
||||
{
|
||||
for (const auto& [id, controller] : controllers) {
|
||||
controller->Reset();
|
||||
}
|
||||
}
|
||||
|
||||
shared_ptr<PrimaryDevice> ControllerManager::GetDeviceByIdAndLun(int id, int lun) const
|
||||
{
|
||||
if (const auto& controller = FindController(id); controller != nullptr) {
|
||||
|
@ -21,26 +21,26 @@ class BUS;
|
||||
class AbstractController;
|
||||
class PrimaryDevice;
|
||||
|
||||
class ControllerManager
|
||||
class ControllerManager : public enable_shared_from_this<ControllerManager>
|
||||
{
|
||||
shared_ptr<BUS> bus;
|
||||
BUS& bus;
|
||||
|
||||
unordered_map<int, shared_ptr<AbstractController>> controllers;
|
||||
|
||||
public:
|
||||
|
||||
explicit ControllerManager(shared_ptr<BUS> bus) : bus(bus) {}
|
||||
explicit ControllerManager(BUS& bus) : bus(bus) {}
|
||||
~ControllerManager() = default;
|
||||
|
||||
// Maximum number of controller devices
|
||||
static const int DEVICE_MAX = 8;
|
||||
|
||||
inline BUS& GetBus() const { return bus; }
|
||||
bool AttachToScsiController(int, shared_ptr<PrimaryDevice>);
|
||||
bool DeleteController(shared_ptr<AbstractController>);
|
||||
shared_ptr<AbstractController> IdentifyController(int) const;
|
||||
shared_ptr<AbstractController> FindController(int) const;
|
||||
unordered_set<shared_ptr<PrimaryDevice>> GetAllDevices() const;
|
||||
void DeleteAllControllers();
|
||||
void ResetAllControllers() const;
|
||||
shared_ptr<PrimaryDevice> GetDeviceByIdAndLun(int, int) const;
|
||||
};
|
||||
|
@ -28,7 +28,8 @@
|
||||
|
||||
using namespace scsi_defs;
|
||||
|
||||
ScsiController::ScsiController(shared_ptr<BUS> bus, int target_id) : AbstractController(bus, target_id, LUN_MAX)
|
||||
ScsiController::ScsiController(shared_ptr<ControllerManager> controller_manager, int target_id)
|
||||
: AbstractController(controller_manager, target_id, LUN_MAX)
|
||||
{
|
||||
// The initial buffer size will default to either the default buffer size OR
|
||||
// the size of an Ethernet message, whichever is larger.
|
||||
@ -51,18 +52,14 @@ void ScsiController::Reset()
|
||||
|
||||
BUS::phase_t ScsiController::Process(int id)
|
||||
{
|
||||
// Get bus information
|
||||
GetBus()->Acquire();
|
||||
GetBus().Acquire();
|
||||
|
||||
// Check to see if the reset signal was asserted
|
||||
if (GetBus()->GetRST()) {
|
||||
if (GetBus().GetRST()) {
|
||||
LOGWARN("RESET signal received!")
|
||||
|
||||
// Reset the controller
|
||||
Reset();
|
||||
|
||||
// Reset the bus
|
||||
GetBus()->Reset();
|
||||
GetBus().Reset();
|
||||
|
||||
return GetPhase();
|
||||
}
|
||||
@ -84,7 +81,7 @@ BUS::phase_t ScsiController::Process(int id)
|
||||
LOGERROR("%s Unhandled SCSI error, resetting controller and bus and entering bus free phase", __PRETTY_FUNCTION__)
|
||||
|
||||
Reset();
|
||||
GetBus()->Reset();
|
||||
GetBus().Reset();
|
||||
|
||||
BusFree();
|
||||
}
|
||||
@ -99,11 +96,11 @@ void ScsiController::BusFree()
|
||||
|
||||
SetPhase(BUS::phase_t::busfree);
|
||||
|
||||
GetBus()->SetREQ(false);
|
||||
GetBus()->SetMSG(false);
|
||||
GetBus()->SetCD(false);
|
||||
GetBus()->SetIO(false);
|
||||
GetBus()->SetBSY(false);
|
||||
GetBus().SetREQ(false);
|
||||
GetBus().SetMSG(false);
|
||||
GetBus().SetCD(false);
|
||||
GetBus().SetIO(false);
|
||||
GetBus().SetBSY(false);
|
||||
|
||||
// Initialize status and message
|
||||
SetStatus(status::GOOD);
|
||||
@ -116,6 +113,13 @@ void ScsiController::BusFree()
|
||||
|
||||
SetByteTransfer(false);
|
||||
|
||||
if (shutdown_mode != rascsi_shutdown_mode::NONE) {
|
||||
// Prepare the shutdown by flushing all caches
|
||||
for (const auto& device : GetControllerManager()->GetAllDevices()) {
|
||||
device->FlushCache();
|
||||
}
|
||||
}
|
||||
|
||||
// When the bus is free RaSCSI or the Pi may be shut down.
|
||||
// This code has to be executed in the bus free phase and thus has to be located in the controller.
|
||||
switch(shutdown_mode) {
|
||||
@ -146,7 +150,7 @@ void ScsiController::BusFree()
|
||||
}
|
||||
|
||||
// Move to selection phase
|
||||
if (GetBus()->GetSEL() && !GetBus()->GetBSY()) {
|
||||
if (GetBus().GetSEL() && !GetBus().GetBSY()) {
|
||||
Selection();
|
||||
}
|
||||
}
|
||||
@ -155,7 +159,7 @@ void ScsiController::Selection()
|
||||
{
|
||||
if (!IsSelection()) {
|
||||
// A different device controller was selected
|
||||
if (int id = 1 << GetTargetId(); (static_cast<int>(GetBus()->GetDAT()) & id) == 0) {
|
||||
if (int id = 1 << GetTargetId(); (static_cast<int>(GetBus().GetDAT()) & id) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -169,14 +173,14 @@ void ScsiController::Selection()
|
||||
SetPhase(BUS::phase_t::selection);
|
||||
|
||||
// Raise BSY and respond
|
||||
GetBus()->SetBSY(true);
|
||||
GetBus().SetBSY(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// Selection completed
|
||||
if (!GetBus()->GetSEL() && GetBus()->GetBSY()) {
|
||||
if (!GetBus().GetSEL() && GetBus().GetBSY()) {
|
||||
// Message out phase if ATN=1, otherwise command phase
|
||||
if (GetBus()->GetATN()) {
|
||||
if (GetBus().GetATN()) {
|
||||
MsgOut();
|
||||
} else {
|
||||
Command();
|
||||
@ -191,11 +195,11 @@ void ScsiController::Command()
|
||||
|
||||
SetPhase(BUS::phase_t::command);
|
||||
|
||||
GetBus()->SetMSG(false);
|
||||
GetBus()->SetCD(true);
|
||||
GetBus()->SetIO(false);
|
||||
GetBus().SetMSG(false);
|
||||
GetBus().SetCD(true);
|
||||
GetBus().SetIO(false);
|
||||
|
||||
const int actual_count = GetBus()->CommandHandShake(GetBuffer().data());
|
||||
const int actual_count = GetBus().CommandHandShake(GetBuffer().data());
|
||||
const int command_byte_count = BUS::GetCommandByteCount(GetBuffer()[0]);
|
||||
|
||||
// If not able to receive all, move to the status phase
|
||||
@ -295,9 +299,9 @@ void ScsiController::Status()
|
||||
SetPhase(BUS::phase_t::status);
|
||||
|
||||
// Signal line operated by the target
|
||||
GetBus()->SetMSG(false);
|
||||
GetBus()->SetCD(true);
|
||||
GetBus()->SetIO(true);
|
||||
GetBus().SetMSG(false);
|
||||
GetBus().SetCD(true);
|
||||
GetBus().SetIO(true);
|
||||
|
||||
// Data transfer is 1 byte x 1 block
|
||||
ResetOffset();
|
||||
@ -318,9 +322,9 @@ void ScsiController::MsgIn()
|
||||
|
||||
SetPhase(BUS::phase_t::msgin);
|
||||
|
||||
GetBus()->SetMSG(true);
|
||||
GetBus()->SetCD(true);
|
||||
GetBus()->SetIO(true);
|
||||
GetBus().SetMSG(true);
|
||||
GetBus().SetCD(true);
|
||||
GetBus().SetIO(true);
|
||||
|
||||
ResetOffset();
|
||||
return;
|
||||
@ -345,9 +349,9 @@ void ScsiController::MsgOut()
|
||||
|
||||
SetPhase(BUS::phase_t::msgout);
|
||||
|
||||
GetBus()->SetMSG(true);
|
||||
GetBus()->SetCD(true);
|
||||
GetBus()->SetIO(false);
|
||||
GetBus().SetMSG(true);
|
||||
GetBus().SetCD(true);
|
||||
GetBus().SetIO(false);
|
||||
|
||||
// Data transfer is 1 byte x 1 block
|
||||
ResetOffset();
|
||||
@ -378,9 +382,9 @@ void ScsiController::DataIn()
|
||||
|
||||
SetPhase(BUS::phase_t::datain);
|
||||
|
||||
GetBus()->SetMSG(false);
|
||||
GetBus()->SetCD(false);
|
||||
GetBus()->SetIO(true);
|
||||
GetBus().SetMSG(false);
|
||||
GetBus().SetCD(false);
|
||||
GetBus().SetIO(true);
|
||||
|
||||
ResetOffset();
|
||||
|
||||
@ -409,9 +413,9 @@ void ScsiController::DataOut()
|
||||
SetPhase(BUS::phase_t::dataout);
|
||||
|
||||
// Signal line operated by the target
|
||||
GetBus()->SetMSG(false);
|
||||
GetBus()->SetCD(false);
|
||||
GetBus()->SetIO(false);
|
||||
GetBus().SetMSG(false);
|
||||
GetBus().SetCD(false);
|
||||
GetBus().SetIO(false);
|
||||
|
||||
ResetOffset();
|
||||
return;
|
||||
@ -423,12 +427,12 @@ void ScsiController::DataOut()
|
||||
void ScsiController::Error(sense_key sense_key, asc asc, status status)
|
||||
{
|
||||
// Get bus information
|
||||
GetBus()->Acquire();
|
||||
GetBus().Acquire();
|
||||
|
||||
// Reset check
|
||||
if (GetBus()->GetRST()) {
|
||||
if (GetBus().GetRST()) {
|
||||
Reset();
|
||||
GetBus()->Reset();
|
||||
GetBus().Reset();
|
||||
|
||||
return;
|
||||
}
|
||||
@ -472,8 +476,8 @@ void ScsiController::Error(sense_key sense_key, asc asc, status status)
|
||||
|
||||
void ScsiController::Send()
|
||||
{
|
||||
assert(!GetBus()->GetREQ());
|
||||
assert(GetBus()->GetIO());
|
||||
assert(!GetBus().GetREQ());
|
||||
assert(GetBus().GetIO());
|
||||
|
||||
if (HasValidLength()) {
|
||||
LOGTRACE("%s%s", __PRETTY_FUNCTION__, (" Sending handhake with offset " + to_string(GetOffset()) + ", length "
|
||||
@ -481,7 +485,7 @@ void ScsiController::Send()
|
||||
|
||||
// The delay should be taken from the respective LUN, but as there are no Daynaport drivers for
|
||||
// LUNs other than 0 this work-around works.
|
||||
if (const int len = GetBus()->SendHandShake(GetBuffer().data() + GetOffset(), GetLength(),
|
||||
if (const int len = GetBus().SendHandShake(GetBuffer().data() + GetOffset(), GetLength(),
|
||||
HasDeviceForLun(0) ? GetDeviceForLun(0)->GetSendDelay() : 0);
|
||||
len != static_cast<int>(GetLength())) {
|
||||
// If you cannot send all, move to status phase
|
||||
@ -568,15 +572,15 @@ void ScsiController::Receive()
|
||||
LOGTRACE("%s",__PRETTY_FUNCTION__)
|
||||
|
||||
// REQ is low
|
||||
assert(!GetBus()->GetREQ());
|
||||
assert(!GetBus()->GetIO());
|
||||
assert(!GetBus().GetREQ());
|
||||
assert(!GetBus().GetIO());
|
||||
|
||||
// Length != 0 if received
|
||||
if (HasValidLength()) {
|
||||
LOGTRACE("%s Length is %d bytes", __PRETTY_FUNCTION__, GetLength())
|
||||
|
||||
// If not able to receive all, move to status phase
|
||||
if (int len = GetBus()->ReceiveHandShake(GetBuffer().data() + GetOffset(), GetLength());
|
||||
if (int len = GetBus().ReceiveHandShake(GetBuffer().data() + GetOffset(), GetLength());
|
||||
len != static_cast<int>(GetLength())) {
|
||||
LOGERROR("%s Not able to receive %d bytes of data, only received %d",__PRETTY_FUNCTION__, GetLength(), len)
|
||||
Error(sense_key::ABORTED_COMMAND);
|
||||
@ -673,14 +677,14 @@ bool ScsiController::XferMsg(int msg)
|
||||
|
||||
void ScsiController::ReceiveBytes()
|
||||
{
|
||||
assert(!GetBus()->GetREQ());
|
||||
assert(!GetBus()->GetIO());
|
||||
assert(!GetBus().GetREQ());
|
||||
assert(!GetBus().GetIO());
|
||||
|
||||
if (HasValidLength()) {
|
||||
LOGTRACE("%s Length is %d bytes", __PRETTY_FUNCTION__, GetLength())
|
||||
|
||||
// If not able to receive all, move to status phase
|
||||
if (uint32_t len = GetBus()->ReceiveHandShake(GetBuffer().data() + GetOffset(), GetLength()); len != GetLength()) {
|
||||
if (uint32_t len = GetBus().ReceiveHandShake(GetBuffer().data() + GetOffset(), GetLength()); len != GetLength()) {
|
||||
LOGERROR("%s Not able to receive %d bytes of data, only received %d",
|
||||
__PRETTY_FUNCTION__, GetLength(), len)
|
||||
Error(sense_key::ABORTED_COMMAND);
|
||||
@ -1014,7 +1018,7 @@ void ScsiController::ParseMessage()
|
||||
void ScsiController::ProcessMessage()
|
||||
{
|
||||
// Continue message out phase as long as ATN keeps asserting
|
||||
if (GetBus()->GetATN()) {
|
||||
if (GetBus().GetATN()) {
|
||||
// Data transfer is 1 byte x 1 block
|
||||
ResetOffset();
|
||||
SetLength(1);
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "controller_manager.h"
|
||||
#include "abstract_controller.h"
|
||||
#include "scsi.h"
|
||||
#include <array>
|
||||
@ -53,7 +54,7 @@ public:
|
||||
// Maximum number of logical units
|
||||
static inline const int LUN_MAX = 32;
|
||||
|
||||
ScsiController(shared_ptr<BUS>, int);
|
||||
explicit ScsiController(shared_ptr<ControllerManager>, int);
|
||||
~ScsiController() override = default;
|
||||
|
||||
void Reset() override;
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "scsi_printer.h"
|
||||
#include "scsi_host_bridge.h"
|
||||
#include "scsi_daynaport.h"
|
||||
#include "rascsi_exceptions.h"
|
||||
#include "host_services.h"
|
||||
#include "rasutil.h"
|
||||
#include "device_factory.h"
|
||||
@ -78,8 +77,7 @@ PbDeviceType DeviceFactory::GetTypeForFile(const string& filename) const
|
||||
return UNDEFINED;
|
||||
}
|
||||
|
||||
shared_ptr<PrimaryDevice> DeviceFactory::CreateDevice(const ControllerManager& controller_manager, PbDeviceType type,
|
||||
int lun, const string& filename)
|
||||
shared_ptr<PrimaryDevice> DeviceFactory::CreateDevice(PbDeviceType type, int lun, const string& filename) const
|
||||
{
|
||||
// If no type was specified try to derive the device type from the filename
|
||||
if (type == UNDEFINED) {
|
||||
@ -95,7 +93,7 @@ shared_ptr<PrimaryDevice> DeviceFactory::CreateDevice(const ControllerManager& c
|
||||
if (const string ext = GetExtensionLowerCase(filename); ext == "hdn" || ext == "hdi" || ext == "nhd") {
|
||||
device = make_shared<SCSIHD_NEC>(lun);
|
||||
} else {
|
||||
device = make_shared<SCSIHD>(lun, sector_sizes[SCHD], false,
|
||||
device = make_shared<SCSIHD>(lun, sector_sizes.find(SCHD)->second, false,
|
||||
ext == "hd1" ? scsi_level::SCSI_1_CCS : scsi_level::SCSI_2);
|
||||
|
||||
// Some Apple tools require a particular drive identification
|
||||
@ -108,17 +106,17 @@ shared_ptr<PrimaryDevice> DeviceFactory::CreateDevice(const ControllerManager& c
|
||||
}
|
||||
|
||||
case SCRM:
|
||||
device = make_shared<SCSIHD>(lun, sector_sizes[SCRM], true);
|
||||
device = make_shared<SCSIHD>(lun, sector_sizes.find(SCRM)->second, true);
|
||||
device->SetProduct("SCSI HD (REM.)");
|
||||
break;
|
||||
|
||||
case SCMO:
|
||||
device = make_shared<SCSIMO>(lun, sector_sizes[SCMO]);
|
||||
device = make_shared<SCSIMO>(lun, sector_sizes.find(SCMO)->second);
|
||||
device->SetProduct("SCSI MO");
|
||||
break;
|
||||
|
||||
case SCCD:
|
||||
device = make_shared<SCSICD>(lun, sector_sizes[SCCD]);
|
||||
device = make_shared<SCSICD>(lun, sector_sizes.find(SCCD)->second);
|
||||
device->SetProduct("SCSI CD-ROM");
|
||||
break;
|
||||
|
||||
@ -126,7 +124,7 @@ shared_ptr<PrimaryDevice> DeviceFactory::CreateDevice(const ControllerManager& c
|
||||
device = make_shared<SCSIBR>(lun);
|
||||
// Since this is an emulation for a specific driver the product name has to be set accordingly
|
||||
device->SetProduct("RASCSI BRIDGE");
|
||||
device->SetDefaultParams(default_params[SCBR]);
|
||||
device->SetDefaultParams(default_params.find(SCBR)->second);
|
||||
break;
|
||||
|
||||
case SCDP:
|
||||
@ -135,11 +133,11 @@ shared_ptr<PrimaryDevice> DeviceFactory::CreateDevice(const ControllerManager& c
|
||||
device->SetVendor("Dayna");
|
||||
device->SetProduct("SCSI/Link");
|
||||
device->SetRevision("1.4a");
|
||||
device->SetDefaultParams(default_params[SCDP]);
|
||||
device->SetDefaultParams(default_params.find(SCDP)->second);
|
||||
break;
|
||||
|
||||
case SCHS:
|
||||
device = make_shared<HostServices>(lun, controller_manager);
|
||||
device = make_shared<HostServices>(lun);
|
||||
// Since this is an emulation for a specific device the full INQUIRY data have to be set accordingly
|
||||
device->SetVendor("RaSCSI");
|
||||
device->SetProduct("Host Services");
|
||||
@ -148,7 +146,7 @@ shared_ptr<PrimaryDevice> DeviceFactory::CreateDevice(const ControllerManager& c
|
||||
case SCLP:
|
||||
device = make_shared<SCSIPrinter>(lun);
|
||||
device->SetProduct("SCSI PRINTER");
|
||||
device->SetDefaultParams(default_params[SCLP]);
|
||||
device->SetDefaultParams(default_params.find(SCLP)->second);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -5,7 +5,7 @@
|
||||
//
|
||||
// Copyright (C) 2021-2022 Uwe Seimet
|
||||
//
|
||||
// The DeviceFactory singleton creates devices based on their type and the image file extension
|
||||
// The DeviceFactory creates devices based on their type and the image file extension
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@ -20,19 +20,18 @@
|
||||
using namespace std;
|
||||
using namespace rascsi_interface;
|
||||
|
||||
class ControllerManager;
|
||||
class PrimaryDevice;
|
||||
|
||||
class DeviceFactory
|
||||
{
|
||||
const string DEFAULT_IP = "10.10.20.1/24"; //NOSONAR This hardcoded IP address is safe
|
||||
const inline static string DEFAULT_IP = "10.10.20.1/24"; //NOSONAR This hardcoded IP address is safe
|
||||
|
||||
public:
|
||||
|
||||
DeviceFactory();
|
||||
~DeviceFactory() = default;
|
||||
|
||||
shared_ptr<PrimaryDevice> CreateDevice(const ControllerManager&, PbDeviceType, int, const string&);
|
||||
shared_ptr<PrimaryDevice> CreateDevice(PbDeviceType, int, const string&) const;
|
||||
PbDeviceType GetTypeForFile(const string&) const;
|
||||
const unordered_set<uint32_t>& GetSectorSizes(PbDeviceType type) const;
|
||||
const unordered_map<string, string>& GetDefaultParams(PbDeviceType type) const;
|
||||
|
@ -71,7 +71,7 @@ void Disk::Dispatch(scsi_command cmd)
|
||||
|
||||
SetMediumChanged(false);
|
||||
|
||||
controller->Error(sense_key::UNIT_ATTENTION, asc::NOT_READY_TO_READY_CHANGE);
|
||||
GetController()->Error(sense_key::UNIT_ATTENTION, asc::NOT_READY_TO_READY_CHANGE);
|
||||
}
|
||||
else {
|
||||
PrimaryDevice::Dispatch(cmd);
|
||||
@ -102,7 +102,7 @@ void Disk::FormatUnit()
|
||||
CheckReady();
|
||||
|
||||
// FMTDATA=1 is not supported (but OK if there is no DEFECT LIST)
|
||||
if ((controller->GetCmd(1) & 0x10) != 0 && controller->GetCmd(4) != 0) {
|
||||
if ((GetController()->GetCmd(1) & 0x10) != 0 && GetController()->GetCmd(4) != 0) {
|
||||
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
|
||||
}
|
||||
|
||||
@ -113,13 +113,13 @@ void Disk::Read(access_mode mode)
|
||||
{
|
||||
const auto& [valid, start, blocks] = CheckAndGetStartAndCount(mode);
|
||||
if (valid) {
|
||||
controller->SetBlocks(blocks);
|
||||
controller->SetLength(Read(controller->GetCmd(), controller->GetBuffer(), start));
|
||||
GetController()->SetBlocks(blocks);
|
||||
GetController()->SetLength(Read(GetController()->GetCmd(), GetController()->GetBuffer(), start));
|
||||
|
||||
LOGTRACE("%s ctrl.length is %d", __PRETTY_FUNCTION__, controller->GetLength())
|
||||
LOGTRACE("%s ctrl.length is %d", __PRETTY_FUNCTION__, GetController()->GetLength())
|
||||
|
||||
// Set next block
|
||||
controller->SetNext(start + 1);
|
||||
GetController()->SetNext(start + 1);
|
||||
|
||||
EnterDataInPhase();
|
||||
}
|
||||
@ -128,31 +128,31 @@ void Disk::Read(access_mode mode)
|
||||
}
|
||||
}
|
||||
|
||||
void Disk::ReadWriteLong10()
|
||||
void Disk::ReadWriteLong10() const
|
||||
{
|
||||
ValidateBlockAddress(RW10);
|
||||
|
||||
// Transfer lengths other than 0 are not supported, which is compliant with the SCSI standard
|
||||
if (GetInt16(controller->GetCmd(), 7) != 0) {
|
||||
if (GetInt16(GetController()->GetCmd(), 7) != 0) {
|
||||
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
|
||||
}
|
||||
|
||||
EnterStatusPhase();
|
||||
}
|
||||
|
||||
void Disk::ReadWriteLong16()
|
||||
void Disk::ReadWriteLong16() const
|
||||
{
|
||||
ValidateBlockAddress(RW16);
|
||||
|
||||
// Transfer lengths other than 0 are not supported, which is compliant with the SCSI standard
|
||||
if (GetInt16(controller->GetCmd(), 12) != 0) {
|
||||
if (GetInt16(GetController()->GetCmd(), 12) != 0) {
|
||||
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
|
||||
}
|
||||
|
||||
EnterStatusPhase();
|
||||
}
|
||||
|
||||
void Disk::Write(access_mode mode)
|
||||
void Disk::Write(access_mode mode) const
|
||||
{
|
||||
if (IsProtected()) {
|
||||
throw scsi_exception(sense_key::DATA_PROTECT, asc::WRITE_PROTECTED);
|
||||
@ -160,11 +160,11 @@ void Disk::Write(access_mode mode)
|
||||
|
||||
const auto& [valid, start, blocks] = CheckAndGetStartAndCount(mode);
|
||||
if (valid) {
|
||||
controller->SetBlocks(blocks);
|
||||
controller->SetLength(GetSectorSizeInBytes());
|
||||
GetController()->SetBlocks(blocks);
|
||||
GetController()->SetLength(GetSectorSizeInBytes());
|
||||
|
||||
// Set next block
|
||||
controller->SetNext(start + 1);
|
||||
GetController()->SetNext(start + 1);
|
||||
|
||||
EnterDataOutPhase();
|
||||
}
|
||||
@ -178,17 +178,17 @@ void Disk::Verify(access_mode mode)
|
||||
const auto& [valid, start, blocks] = CheckAndGetStartAndCount(mode);
|
||||
if (valid) {
|
||||
// if BytChk=0
|
||||
if ((controller->GetCmd(1) & 0x02) == 0) {
|
||||
if ((GetController()->GetCmd(1) & 0x02) == 0) {
|
||||
Seek();
|
||||
return;
|
||||
}
|
||||
|
||||
// Test reading
|
||||
controller->SetBlocks(blocks);
|
||||
controller->SetLength(Read(controller->GetCmd(), controller->GetBuffer(), start));
|
||||
GetController()->SetBlocks(blocks);
|
||||
GetController()->SetLength(Read(GetController()->GetCmd(), GetController()->GetBuffer(), start));
|
||||
|
||||
// Set next block
|
||||
controller->SetNext(start + 1);
|
||||
GetController()->SetNext(start + 1);
|
||||
|
||||
EnterDataOutPhase();
|
||||
}
|
||||
@ -199,8 +199,8 @@ void Disk::Verify(access_mode mode)
|
||||
|
||||
void Disk::StartStopUnit()
|
||||
{
|
||||
const bool start = controller->GetCmd(4) & 0x01;
|
||||
const bool load = controller->GetCmd(4) & 0x02;
|
||||
const bool start = GetController()->GetCmd(4) & 0x01;
|
||||
const bool load = GetController()->GetCmd(4) & 0x02;
|
||||
|
||||
if (load) {
|
||||
LOGTRACE(start ? "Loading medium" : "Ejecting medium")
|
||||
@ -236,7 +236,7 @@ void Disk::PreventAllowMediumRemoval()
|
||||
{
|
||||
CheckReady();
|
||||
|
||||
const bool lock = controller->GetCmd(4) & 0x01;
|
||||
const bool lock = GetController()->GetCmd(4) & 0x01;
|
||||
|
||||
LOGTRACE(lock ? "Locking medium" : "Unlocking medium")
|
||||
|
||||
@ -252,13 +252,14 @@ void Disk::SynchronizeCache()
|
||||
EnterStatusPhase();
|
||||
}
|
||||
|
||||
void Disk::ReadDefectData10()
|
||||
void Disk::ReadDefectData10() const
|
||||
{
|
||||
const size_t allocation_length = min(static_cast<size_t>(GetInt16(controller->GetCmd(), 7)), static_cast<size_t>(4));
|
||||
const size_t allocation_length = min(static_cast<size_t>(GetInt16(GetController()->GetCmd(), 7)),
|
||||
static_cast<size_t>(4));
|
||||
|
||||
// The defect list is empty
|
||||
fill_n(controller->GetBuffer().begin(), allocation_length, 0);
|
||||
controller->SetLength(static_cast<uint32_t>(allocation_length));
|
||||
fill_n(GetController()->GetBuffer().begin(), allocation_length, 0);
|
||||
GetController()->SetLength(static_cast<uint32_t>(allocation_length));
|
||||
|
||||
EnterDataInPhase();
|
||||
}
|
||||
@ -549,7 +550,7 @@ void Disk::ReadCapacity10()
|
||||
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::MEDIUM_NOT_PRESENT);
|
||||
}
|
||||
|
||||
vector<uint8_t>& buf = controller->GetBuffer();
|
||||
vector<uint8_t>& buf = GetController()->GetBuffer();
|
||||
|
||||
// Create end of logical block address (blocks-1)
|
||||
uint64_t capacity = GetBlockCount() - 1;
|
||||
@ -563,7 +564,7 @@ void Disk::ReadCapacity10()
|
||||
// Create block length (1 << size)
|
||||
SetInt32(buf, 4, 1 << size_shift_count);
|
||||
|
||||
controller->SetLength(8);
|
||||
GetController()->SetLength(8);
|
||||
|
||||
EnterDataInPhase();
|
||||
}
|
||||
@ -576,7 +577,7 @@ void Disk::ReadCapacity16()
|
||||
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::MEDIUM_NOT_PRESENT);
|
||||
}
|
||||
|
||||
vector<uint8_t>& buf = controller->GetBuffer();
|
||||
vector<uint8_t>& buf = GetController()->GetBuffer();
|
||||
|
||||
// Create end of logical block address (blocks-1)
|
||||
SetInt64(buf, 0, GetBlockCount() - 1);
|
||||
@ -589,7 +590,7 @@ void Disk::ReadCapacity16()
|
||||
// Logical blocks per physical block: not reported (1 or more)
|
||||
buf[13] = 0;
|
||||
|
||||
controller->SetLength(14);
|
||||
GetController()->SetLength(14);
|
||||
|
||||
EnterDataInPhase();
|
||||
}
|
||||
@ -597,7 +598,7 @@ void Disk::ReadCapacity16()
|
||||
void Disk::ReadCapacity16_ReadLong16()
|
||||
{
|
||||
// The service action determines the actual command
|
||||
switch (controller->GetCmd(1) & 0x1f) {
|
||||
switch (GetController()->GetCmd(1) & 0x1f) {
|
||||
case 0x10:
|
||||
ReadCapacity16();
|
||||
break;
|
||||
@ -614,7 +615,7 @@ void Disk::ReadCapacity16_ReadLong16()
|
||||
|
||||
void Disk::ValidateBlockAddress(access_mode mode) const
|
||||
{
|
||||
const uint64_t block = mode == RW16 ? GetInt64(controller->GetCmd(), 2) : GetInt32(controller->GetCmd(), 2);
|
||||
const uint64_t block = mode == RW16 ? GetInt64(GetController()->GetCmd(), 2) : GetInt32(GetController()->GetCmd(), 2);
|
||||
|
||||
if (block > GetBlockCount()) {
|
||||
LOGTRACE("%s", ("Capacity of " + to_string(GetBlockCount()) + " block(s) exceeded: Trying to access block "
|
||||
@ -629,21 +630,21 @@ tuple<bool, uint64_t, uint32_t> Disk::CheckAndGetStartAndCount(access_mode mode)
|
||||
uint32_t count;
|
||||
|
||||
if (mode == RW6 || mode == SEEK6) {
|
||||
start = GetInt24(controller->GetCmd(), 1);
|
||||
start = GetInt24(GetController()->GetCmd(), 1);
|
||||
|
||||
count = controller->GetCmd(4);
|
||||
count = GetController()->GetCmd(4);
|
||||
if (!count) {
|
||||
count= 0x100;
|
||||
}
|
||||
}
|
||||
else {
|
||||
start = mode == RW16 ? GetInt64(controller->GetCmd(), 2) : GetInt32(controller->GetCmd(), 2);
|
||||
start = mode == RW16 ? GetInt64(GetController()->GetCmd(), 2) : GetInt32(GetController()->GetCmd(), 2);
|
||||
|
||||
if (mode == RW16) {
|
||||
count = GetInt32(controller->GetCmd(), 10);
|
||||
count = GetInt32(GetController()->GetCmd(), 10);
|
||||
}
|
||||
else if (mode != SEEK6 && mode != SEEK10) {
|
||||
count = GetInt16(controller->GetCmd(), 7);
|
||||
count = GetInt16(GetController()->GetCmd(), 7);
|
||||
}
|
||||
else {
|
||||
count = 0;
|
||||
|
@ -67,7 +67,7 @@ private:
|
||||
void StartStopUnit();
|
||||
void PreventAllowMediumRemoval();
|
||||
void SynchronizeCache();
|
||||
void ReadDefectData10();
|
||||
void ReadDefectData10() const;
|
||||
virtual void Read6() { Read(RW6); }
|
||||
void Read10() override { Read(RW10); }
|
||||
void Read16() override { Read(RW16); }
|
||||
@ -83,10 +83,10 @@ private:
|
||||
void FormatUnit() override;
|
||||
void Seek6();
|
||||
void Read(access_mode);
|
||||
void Write(access_mode);
|
||||
void Write(access_mode) const;
|
||||
void Verify(access_mode);
|
||||
void ReadWriteLong10();
|
||||
void ReadWriteLong16();
|
||||
void ReadWriteLong10() const;
|
||||
void ReadWriteLong16() const;
|
||||
void ReadCapacity16_ReadLong16();
|
||||
|
||||
void ValidateBlockAddress(access_mode) const;
|
||||
|
@ -20,7 +20,6 @@
|
||||
// c) start && load (LOAD): Reboot the Raspberry Pi
|
||||
//
|
||||
|
||||
#include "controllers/controller_manager.h"
|
||||
#include "controllers/scsi_controller.h"
|
||||
#include "rascsi_exceptions.h"
|
||||
#include "scsi_command_util.h"
|
||||
@ -53,26 +52,21 @@ vector<uint8_t> HostServices::InquiryInternal() const
|
||||
return HandleInquiry(device_type::PROCESSOR, scsi_level::SPC_3, false);
|
||||
}
|
||||
|
||||
void HostServices::StartStopUnit()
|
||||
void HostServices::StartStopUnit() const
|
||||
{
|
||||
const bool start = controller->GetCmd(4) & 0x01;
|
||||
const bool load = controller->GetCmd(4) & 0x02;
|
||||
const bool start = GetController()->GetCmd(4) & 0x01;
|
||||
const bool load = GetController()->GetCmd(4) & 0x02;
|
||||
|
||||
if (!start) {
|
||||
// Flush any caches
|
||||
for (const auto& device : controller_manager.GetAllDevices()) {
|
||||
device->FlushCache();
|
||||
}
|
||||
|
||||
if (load) {
|
||||
controller->ScheduleShutdown(AbstractController::rascsi_shutdown_mode::STOP_PI);
|
||||
GetController()->ScheduleShutdown(AbstractController::rascsi_shutdown_mode::STOP_PI);
|
||||
}
|
||||
else {
|
||||
controller->ScheduleShutdown(AbstractController::rascsi_shutdown_mode::STOP_RASCSI);
|
||||
GetController()->ScheduleShutdown(AbstractController::rascsi_shutdown_mode::STOP_RASCSI);
|
||||
}
|
||||
}
|
||||
else if (load) {
|
||||
controller->ScheduleShutdown(AbstractController::rascsi_shutdown_mode::RESTART_PI);
|
||||
GetController()->ScheduleShutdown(AbstractController::rascsi_shutdown_mode::RESTART_PI);
|
||||
}
|
||||
else {
|
||||
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
|
||||
@ -92,7 +86,7 @@ int HostServices::ModeSense6(const vector<int>& cdb, vector<uint8_t>& buf) const
|
||||
fill_n(buf.begin(), length, 0);
|
||||
|
||||
// 4 bytes basic information
|
||||
int size = AddModePages(cdb, buf, 4, length, 255);
|
||||
const int size = AddModePages(cdb, buf, 4, length, 255);
|
||||
|
||||
buf[0] = (uint8_t)size;
|
||||
|
||||
@ -110,7 +104,7 @@ int HostServices::ModeSense10(const vector<int>& cdb, vector<uint8_t>& buf) cons
|
||||
fill_n(buf.begin(), length, 0);
|
||||
|
||||
// 8 bytes basic information
|
||||
int size = AddModePages(cdb, buf, 8, length, 65535);
|
||||
const int size = AddModePages(cdb, buf, 8, length, 65535);
|
||||
|
||||
SetInt16(buf, 0, size);
|
||||
|
||||
@ -126,7 +120,7 @@ void HostServices::SetUpModePages(map<int, vector<byte>>& pages, int page, bool
|
||||
|
||||
void HostServices::AddRealtimeClockPage(map<int, vector<byte>>& pages, bool changeable) const
|
||||
{
|
||||
vector<byte> buf(10);
|
||||
pages[32] = vector<byte>(10);
|
||||
|
||||
if (!changeable) {
|
||||
time_t t = time(nullptr);
|
||||
@ -144,8 +138,6 @@ void HostServices::AddRealtimeClockPage(map<int, vector<byte>>& pages, bool chan
|
||||
// Ignore leap second for simplicity
|
||||
datetime.second = (uint8_t)(localtime.tm_sec < 60 ? localtime.tm_sec : 59);
|
||||
|
||||
memcpy(&buf[2], &datetime, sizeof(datetime));
|
||||
memcpy(&pages[32][2], &datetime, sizeof(datetime));
|
||||
}
|
||||
|
||||
pages[32] = buf;
|
||||
}
|
||||
|
@ -15,14 +15,12 @@
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
class ControllerManager;
|
||||
|
||||
class HostServices: public ModePageDevice
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
HostServices(int lun, const ControllerManager& manager) : ModePageDevice(SCHS, lun), controller_manager(manager) {}
|
||||
explicit HostServices(int lun) : ModePageDevice(SCHS, lun) {}
|
||||
~HostServices() override = default;
|
||||
|
||||
bool Init(const unordered_map<string, string>&) override;
|
||||
@ -49,9 +47,7 @@ private:
|
||||
uint8_t second; // 0-59
|
||||
};
|
||||
|
||||
const ControllerManager& controller_manager;
|
||||
|
||||
void StartStopUnit();
|
||||
void StartStopUnit() const;
|
||||
int ModeSense6(const vector<int>&, vector<uint8_t>&) const override;
|
||||
int ModeSense10(const vector<int>&, vector<uint8_t>&) const override;
|
||||
|
||||
|
@ -96,16 +96,16 @@ int ModePageDevice::AddModePages(const vector<int>& cdb, vector<uint8_t>& buf, i
|
||||
return size + offset < length ? size + offset : length;
|
||||
}
|
||||
|
||||
void ModePageDevice::ModeSense6()
|
||||
void ModePageDevice::ModeSense6() const
|
||||
{
|
||||
controller->SetLength(ModeSense6(controller->GetCmd(), controller->GetBuffer()));
|
||||
GetController()->SetLength(ModeSense6(GetController()->GetCmd(), GetController()->GetBuffer()));
|
||||
|
||||
EnterDataInPhase();
|
||||
}
|
||||
|
||||
void ModePageDevice::ModeSense10()
|
||||
void ModePageDevice::ModeSense10() const
|
||||
{
|
||||
controller->SetLength(ModeSense10(controller->GetCmd(), controller->GetBuffer()));
|
||||
GetController()->SetLength(ModeSense10(GetController()->GetCmd(), GetController()->GetBuffer()));
|
||||
|
||||
EnterDataInPhase();
|
||||
}
|
||||
@ -116,25 +116,25 @@ void ModePageDevice::ModeSelect(scsi_command, const vector<int>&, const vector<u
|
||||
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_COMMAND_OPERATION_CODE);
|
||||
}
|
||||
|
||||
void ModePageDevice::ModeSelect6()
|
||||
void ModePageDevice::ModeSelect6() const
|
||||
{
|
||||
SaveParametersCheck(controller->GetCmd(4));
|
||||
SaveParametersCheck(GetController()->GetCmd(4));
|
||||
}
|
||||
|
||||
void ModePageDevice::ModeSelect10()
|
||||
void ModePageDevice::ModeSelect10() const
|
||||
{
|
||||
const auto length = min(controller->GetBuffer().size(), static_cast<size_t>(GetInt16(controller->GetCmd(), 7)));
|
||||
const auto length = min(GetController()->GetBuffer().size(), static_cast<size_t>(GetInt16(GetController()->GetCmd(), 7)));
|
||||
|
||||
SaveParametersCheck(static_cast<uint32_t>(length));
|
||||
}
|
||||
|
||||
void ModePageDevice::SaveParametersCheck(int length)
|
||||
void ModePageDevice::SaveParametersCheck(int length) const
|
||||
{
|
||||
if (!SupportsSaveParameters() && (controller->GetCmd(1) & 0x01)) {
|
||||
if (!SupportsSaveParameters() && (GetController()->GetCmd(1) & 0x01)) {
|
||||
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
|
||||
}
|
||||
|
||||
controller->SetLength(length);
|
||||
GetController()->SetLength(length);
|
||||
|
||||
EnterDataOutPhase();
|
||||
}
|
||||
|
@ -42,10 +42,10 @@ private:
|
||||
virtual int ModeSense6(const vector<int>&, vector<uint8_t>&) const = 0;
|
||||
virtual int ModeSense10(const vector<int>&, vector<uint8_t>&) const = 0;
|
||||
|
||||
void ModeSense6();
|
||||
void ModeSense10();
|
||||
void ModeSelect6();
|
||||
void ModeSelect10();
|
||||
void ModeSense6() const;
|
||||
void ModeSense10() const;
|
||||
void ModeSelect6() const;
|
||||
void ModeSelect10() const;
|
||||
|
||||
void SaveParametersCheck(int);
|
||||
void SaveParametersCheck(int) const;
|
||||
};
|
||||
|
@ -62,14 +62,14 @@ void PrimaryDevice::Reset()
|
||||
|
||||
int PrimaryDevice::GetId() const
|
||||
{
|
||||
if (controller == nullptr) {
|
||||
if (GetController() == nullptr) {
|
||||
LOGERROR("Device is missing its controller")
|
||||
}
|
||||
|
||||
return controller != nullptr ? controller->GetTargetId() : -1;
|
||||
return GetController() != nullptr ? GetController()->GetTargetId() : -1;
|
||||
}
|
||||
|
||||
void PrimaryDevice::SetController(AbstractController *c)
|
||||
void PrimaryDevice::SetController(shared_ptr<AbstractController> c)
|
||||
{
|
||||
controller = c;
|
||||
}
|
||||
@ -84,23 +84,23 @@ void PrimaryDevice::TestUnitReady()
|
||||
void PrimaryDevice::Inquiry()
|
||||
{
|
||||
// EVPD and page code check
|
||||
if ((controller->GetCmd(1) & 0x01) || controller->GetCmd(2)) {
|
||||
if ((GetController()->GetCmd(1) & 0x01) || GetController()->GetCmd(2)) {
|
||||
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
|
||||
}
|
||||
|
||||
vector<uint8_t> buf = InquiryInternal();
|
||||
|
||||
const size_t allocation_length = min(buf.size(), static_cast<size_t>(GetInt16(controller->GetCmd(), 3)));
|
||||
const size_t allocation_length = min(buf.size(), static_cast<size_t>(GetInt16(GetController()->GetCmd(), 3)));
|
||||
|
||||
memcpy(controller->GetBuffer().data(), buf.data(), allocation_length);
|
||||
controller->SetLength(static_cast<uint32_t>(allocation_length));
|
||||
memcpy(GetController()->GetBuffer().data(), buf.data(), allocation_length);
|
||||
GetController()->SetLength(static_cast<uint32_t>(allocation_length));
|
||||
|
||||
// Report if the device does not support the requested LUN
|
||||
if (int lun = controller->GetEffectiveLun(); !controller->HasDeviceForLun(lun)) {
|
||||
if (int lun = GetController()->GetEffectiveLun(); !GetController()->HasDeviceForLun(lun)) {
|
||||
LOGTRACE("Reporting LUN %d for device ID %d as not supported", lun, GetId())
|
||||
|
||||
// Signal that the requested LUN does not exist
|
||||
controller->GetBuffer().data()[0] = 0x7f;
|
||||
GetController()->GetBuffer().data()[0] = 0x7f;
|
||||
}
|
||||
|
||||
EnterDataInPhase();
|
||||
@ -109,18 +109,18 @@ void PrimaryDevice::Inquiry()
|
||||
void PrimaryDevice::ReportLuns()
|
||||
{
|
||||
// Only SELECT REPORT mode 0 is supported
|
||||
if (controller->GetCmd(2)) {
|
||||
if (GetController()->GetCmd(2)) {
|
||||
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
|
||||
}
|
||||
|
||||
const uint32_t allocation_length = GetInt32(controller->GetCmd(), 6);
|
||||
const uint32_t allocation_length = GetInt32(GetController()->GetCmd(), 6);
|
||||
|
||||
vector<uint8_t>& buf = controller->GetBuffer();
|
||||
vector<uint8_t>& buf = GetController()->GetBuffer();
|
||||
fill_n(buf.begin(), min(buf.size(), static_cast<size_t>(allocation_length)), 0);
|
||||
|
||||
uint32_t size = 0;
|
||||
for (int lun = 0; lun < controller->GetMaxLuns(); lun++) {
|
||||
if (controller->HasDeviceForLun(lun)) {
|
||||
for (int lun = 0; lun < GetController()->GetMaxLuns(); lun++) {
|
||||
if (GetController()->HasDeviceForLun(lun)) {
|
||||
size += 8;
|
||||
buf[size + 7] = (uint8_t)lun;
|
||||
}
|
||||
@ -130,35 +130,35 @@ void PrimaryDevice::ReportLuns()
|
||||
|
||||
size += 8;
|
||||
|
||||
controller->SetLength(min(allocation_length, size));
|
||||
GetController()->SetLength(min(allocation_length, size));
|
||||
|
||||
EnterDataInPhase();
|
||||
}
|
||||
|
||||
void PrimaryDevice::RequestSense()
|
||||
{
|
||||
int lun = controller->GetEffectiveLun();
|
||||
int lun = GetController()->GetEffectiveLun();
|
||||
|
||||
// Note: According to the SCSI specs the LUN handling for REQUEST SENSE non-existing LUNs do *not* result
|
||||
// in CHECK CONDITION. Only the Sense Key and ASC are set in order to signal the non-existing LUN.
|
||||
if (!controller->HasDeviceForLun(lun)) {
|
||||
if (!GetController()->HasDeviceForLun(lun)) {
|
||||
// LUN 0 can be assumed to be present (required to call RequestSense() below)
|
||||
assert(controller->HasDeviceForLun(0));
|
||||
assert(GetController()->HasDeviceForLun(0));
|
||||
|
||||
lun = 0;
|
||||
|
||||
// Do not raise an exception here because the rest of the code must be executed
|
||||
controller->Error(sense_key::ILLEGAL_REQUEST, asc::INVALID_LUN);
|
||||
GetController()->Error(sense_key::ILLEGAL_REQUEST, asc::INVALID_LUN);
|
||||
|
||||
controller->SetStatus(status::GOOD);
|
||||
GetController()->SetStatus(status::GOOD);
|
||||
}
|
||||
|
||||
vector<byte> buf = controller->GetDeviceForLun(lun)->HandleRequestSense();
|
||||
vector<byte> buf = GetController()->GetDeviceForLun(lun)->HandleRequestSense();
|
||||
|
||||
const size_t allocation_length = min(buf.size(), static_cast<size_t>(controller->GetCmd(4)));
|
||||
const size_t allocation_length = min(buf.size(), static_cast<size_t>(GetController()->GetCmd(4)));
|
||||
|
||||
memcpy(controller->GetBuffer().data(), buf.data(), allocation_length);
|
||||
controller->SetLength(static_cast<uint32_t>(allocation_length));
|
||||
memcpy(GetController()->GetBuffer().data(), buf.data(), allocation_length);
|
||||
GetController()->SetLength(static_cast<uint32_t>(allocation_length));
|
||||
|
||||
EnterDataInPhase();
|
||||
}
|
||||
@ -166,12 +166,12 @@ void PrimaryDevice::RequestSense()
|
||||
void PrimaryDevice::SendDiagnostic()
|
||||
{
|
||||
// Do not support PF bit
|
||||
if (controller->GetCmd(1) & 0x10) {
|
||||
if (GetController()->GetCmd(1) & 0x10) {
|
||||
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
|
||||
}
|
||||
|
||||
// Do not support parameter list
|
||||
if ((controller->GetCmd(3) != 0) || (controller->GetCmd(4) != 0)) {
|
||||
if ((GetController()->GetCmd(3) != 0) || (GetController()->GetCmd(4) != 0)) {
|
||||
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
|
||||
}
|
||||
|
||||
@ -246,7 +246,7 @@ vector<byte> PrimaryDevice::HandleRequestSense() const
|
||||
buf[12] = (byte)(GetStatusCode() >> 8);
|
||||
buf[13] = (byte)GetStatusCode();
|
||||
|
||||
LOGTRACE("%s Status $%02X, Sense Key $%02X, ASC $%02X",__PRETTY_FUNCTION__, static_cast<int>(controller->GetStatus()),
|
||||
LOGTRACE("%s Status $%02X, Sense Key $%02X, ASC $%02X",__PRETTY_FUNCTION__, static_cast<int>(GetController()->GetStatus()),
|
||||
static_cast<int>(buf[2]), static_cast<int>(buf[12]))
|
||||
|
||||
return buf;
|
||||
@ -261,7 +261,7 @@ bool PrimaryDevice::WriteByteSequence(vector<uint8_t>&, uint32_t)
|
||||
|
||||
void PrimaryDevice::ReserveUnit()
|
||||
{
|
||||
reserving_initiator = controller->GetInitiatorId();
|
||||
reserving_initiator = GetController()->GetInitiatorId();
|
||||
|
||||
if (reserving_initiator != -1) {
|
||||
LOGTRACE("Reserved device ID %d, LUN %d for initiator ID %d", GetId(), GetLun(), reserving_initiator)
|
||||
|
@ -37,7 +37,7 @@ public:
|
||||
|
||||
int GetId() const override;
|
||||
|
||||
void SetController(AbstractController *);
|
||||
void SetController(shared_ptr<AbstractController>);
|
||||
|
||||
virtual bool WriteByteSequence(vector<uint8_t>&, uint32_t);
|
||||
|
||||
@ -66,12 +66,11 @@ protected:
|
||||
void ReserveUnit() override;
|
||||
void ReleaseUnit() override;
|
||||
|
||||
void EnterStatusPhase() { controller->Status(); }
|
||||
void EnterDataInPhase() { controller->DataIn(); }
|
||||
void EnterDataOutPhase() { controller->DataOut(); }
|
||||
void EnterStatusPhase() const { controller.lock()->Status(); }
|
||||
void EnterDataInPhase() const { controller.lock()->DataIn(); }
|
||||
void EnterDataOutPhase() const { controller.lock()->DataOut(); }
|
||||
|
||||
// TODO Try to replace this raw pointer, maybe by a weak_ptr
|
||||
AbstractController *controller = nullptr;
|
||||
inline shared_ptr<AbstractController> GetController() const { return controller.lock(); }
|
||||
|
||||
private:
|
||||
|
||||
@ -84,6 +83,8 @@ private:
|
||||
|
||||
vector<byte> HandleRequestSense() const;
|
||||
|
||||
weak_ptr<AbstractController> controller;
|
||||
|
||||
unordered_map<scsi_command, operation> commands;
|
||||
|
||||
int send_delay = BUS::SEND_NO_DELAY;
|
||||
|
@ -265,7 +265,7 @@ bool SCSIDaynaPort::WriteBytes(const vector<int>& cdb, vector<uint8_t>& buf, uin
|
||||
LOGWARN("%s Unknown data format %02X", __PRETTY_FUNCTION__, data_format)
|
||||
}
|
||||
|
||||
controller->SetBlocks(0);
|
||||
GetController()->SetBlocks(0);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -302,65 +302,65 @@ void SCSIDaynaPort::TestUnitReady()
|
||||
void SCSIDaynaPort::Read6()
|
||||
{
|
||||
// Get record number and block number
|
||||
const uint32_t record = GetInt24(controller->GetCmd(), 1) & 0x1fffff;
|
||||
controller->SetBlocks(1);
|
||||
const uint32_t record = GetInt24(GetController()->GetCmd(), 1) & 0x1fffff;
|
||||
GetController()->SetBlocks(1);
|
||||
|
||||
// If any commands have a bogus control value, they were probably not
|
||||
// generated by the DaynaPort driver so ignore them
|
||||
if (controller->GetCmd(5) != 0xc0 && controller->GetCmd(5) != 0x80) {
|
||||
if (GetController()->GetCmd(5) != 0xc0 && GetController()->GetCmd(5) != 0x80) {
|
||||
LOGTRACE("%s Control value %d, (%04X), returning invalid CDB", __PRETTY_FUNCTION__,
|
||||
controller->GetCmd(5), controller->GetCmd(5))
|
||||
GetController()->GetCmd(5), GetController()->GetCmd(5))
|
||||
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
|
||||
}
|
||||
|
||||
LOGTRACE("%s READ(6) command record=%d blocks=%d", __PRETTY_FUNCTION__, record, controller->GetBlocks())
|
||||
LOGTRACE("%s READ(6) command record=%d blocks=%d", __PRETTY_FUNCTION__, record, GetController()->GetBlocks())
|
||||
|
||||
controller->SetLength(Read(controller->GetCmd(), controller->GetBuffer(), record));
|
||||
LOGTRACE("%s ctrl.length is %d", __PRETTY_FUNCTION__, controller->GetLength())
|
||||
GetController()->SetLength(Read(GetController()->GetCmd(), GetController()->GetBuffer(), record));
|
||||
LOGTRACE("%s ctrl.length is %d", __PRETTY_FUNCTION__, GetController()->GetLength())
|
||||
|
||||
// Set next block
|
||||
controller->SetNext(record + 1);
|
||||
GetController()->SetNext(record + 1);
|
||||
|
||||
EnterDataInPhase();
|
||||
}
|
||||
|
||||
void SCSIDaynaPort::Write6()
|
||||
void SCSIDaynaPort::Write6() const
|
||||
{
|
||||
// Ensure a sufficient buffer size (because it is not transfer for each block)
|
||||
controller->AllocateBuffer(DAYNAPORT_BUFFER_SIZE);
|
||||
GetController()->AllocateBuffer(DAYNAPORT_BUFFER_SIZE);
|
||||
|
||||
const int data_format = controller->GetCmd(5);
|
||||
const int data_format = GetController()->GetCmd(5);
|
||||
|
||||
if (data_format == 0x00) {
|
||||
controller->SetLength(GetInt16(controller->GetCmd(), 3));
|
||||
GetController()->SetLength(GetInt16(GetController()->GetCmd(), 3));
|
||||
}
|
||||
else if (data_format == 0x80) {
|
||||
controller->SetLength(GetInt16(controller->GetCmd(), 3) + 8);
|
||||
GetController()->SetLength(GetInt16(GetController()->GetCmd(), 3) + 8);
|
||||
}
|
||||
else {
|
||||
LOGWARN("%s Unknown data format $%02X", __PRETTY_FUNCTION__, data_format)
|
||||
}
|
||||
LOGTRACE("%s length: $%04X (%d) format: $%02X", __PRETTY_FUNCTION__, controller->GetLength(),
|
||||
controller->GetLength(), data_format)
|
||||
LOGTRACE("%s length: $%04X (%d) format: $%02X", __PRETTY_FUNCTION__, GetController()->GetLength(),
|
||||
GetController()->GetLength(), data_format)
|
||||
|
||||
if (controller->GetLength() <= 0) {
|
||||
if (GetController()->GetLength() <= 0) {
|
||||
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
|
||||
}
|
||||
|
||||
// Set next block
|
||||
controller->SetBlocks(1);
|
||||
controller->SetNext(1);
|
||||
GetController()->SetBlocks(1);
|
||||
GetController()->SetNext(1);
|
||||
|
||||
EnterDataOutPhase();
|
||||
}
|
||||
|
||||
void SCSIDaynaPort::RetrieveStatistics()
|
||||
void SCSIDaynaPort::RetrieveStatistics() const
|
||||
{
|
||||
controller->SetLength(RetrieveStats(controller->GetCmd(), controller->GetBuffer()));
|
||||
GetController()->SetLength(RetrieveStats(GetController()->GetCmd(), GetController()->GetBuffer()));
|
||||
|
||||
// Set next block
|
||||
controller->SetBlocks(1);
|
||||
controller->SetNext(1);
|
||||
GetController()->SetBlocks(1);
|
||||
GetController()->SetNext(1);
|
||||
|
||||
EnterDataInPhase();
|
||||
}
|
||||
@ -391,41 +391,41 @@ void SCSIDaynaPort::RetrieveStatistics()
|
||||
// value.
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
void SCSIDaynaPort::SetInterfaceMode()
|
||||
void SCSIDaynaPort::SetInterfaceMode() const
|
||||
{
|
||||
// Check whether this command is telling us to "Set Interface Mode" or "Set MAC Address"
|
||||
|
||||
controller->SetLength(RetrieveStats(controller->GetCmd(), controller->GetBuffer()));
|
||||
switch(controller->GetCmd(5)){
|
||||
GetController()->SetLength(RetrieveStats(GetController()->GetCmd(), GetController()->GetBuffer()));
|
||||
switch(GetController()->GetCmd(5)){
|
||||
case CMD_SCSILINK_SETMODE:
|
||||
// TODO Not implemented, do nothing
|
||||
EnterStatusPhase();
|
||||
break;
|
||||
|
||||
case CMD_SCSILINK_SETMAC:
|
||||
controller->SetLength(6);
|
||||
GetController()->SetLength(6);
|
||||
EnterDataOutPhase();
|
||||
break;
|
||||
|
||||
case CMD_SCSILINK_STATS:
|
||||
case CMD_SCSILINK_ENABLE:
|
||||
case CMD_SCSILINK_SET:
|
||||
LOGWARN("%s Unsupported SetInterface command received: %02X", __PRETTY_FUNCTION__, controller->GetCmd(5))
|
||||
LOGWARN("%s Unsupported SetInterface command received: %02X", __PRETTY_FUNCTION__, GetController()->GetCmd(5))
|
||||
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_COMMAND_OPERATION_CODE);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOGWARN("%s Unknown SetInterface command received: %02X", __PRETTY_FUNCTION__, controller->GetCmd(5))
|
||||
LOGWARN("%s Unknown SetInterface command received: %02X", __PRETTY_FUNCTION__, GetController()->GetCmd(5))
|
||||
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_COMMAND_OPERATION_CODE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SCSIDaynaPort::SetMcastAddr()
|
||||
void SCSIDaynaPort::SetMcastAddr() const
|
||||
{
|
||||
controller->SetLength(controller->GetCmd(4));
|
||||
if (controller->GetLength() == 0) {
|
||||
LOGWARN("%s Not supported SetMcastAddr Command %02X", __PRETTY_FUNCTION__, controller->GetCmd(2))
|
||||
GetController()->SetLength(GetController()->GetCmd(4));
|
||||
if (GetController()->GetLength() == 0) {
|
||||
LOGWARN("%s Not supported SetMcastAddr Command %02X", __PRETTY_FUNCTION__, GetController()->GetCmd(2))
|
||||
|
||||
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
|
||||
}
|
||||
@ -447,7 +447,7 @@ void SCSIDaynaPort::SetMcastAddr()
|
||||
//---------------------------------------------------------------------------
|
||||
void SCSIDaynaPort::EnableInterface()
|
||||
{
|
||||
if (controller->GetCmd(5) & 0x80) {
|
||||
if (GetController()->GetCmd(5) & 0x80) {
|
||||
if (!m_tap.Enable()) {
|
||||
LOGWARN("Unable to enable the DaynaPort Interface")
|
||||
|
||||
|
@ -59,10 +59,10 @@ public:
|
||||
|
||||
void TestUnitReady() override;
|
||||
void Read6();
|
||||
void Write6();
|
||||
void RetrieveStatistics();
|
||||
void SetInterfaceMode();
|
||||
void SetMcastAddr();
|
||||
void Write6() const;
|
||||
void RetrieveStatistics() const;
|
||||
void SetInterfaceMode() const;
|
||||
void SetMcastAddr() const;
|
||||
void EnableInterface();
|
||||
|
||||
static const int DAYNAPORT_BUFFER_SIZE = 0x1000000;
|
||||
|
@ -246,16 +246,16 @@ bool SCSIBR::WriteBytes(const vector<int>& cdb, vector<uint8_t>& buf, uint32_t)
|
||||
void SCSIBR::GetMessage10()
|
||||
{
|
||||
// Ensure a sufficient buffer size (because it is not a transfer for each block)
|
||||
controller->AllocateBuffer(0x1000000);
|
||||
GetController()->AllocateBuffer(0x1000000);
|
||||
|
||||
controller->SetLength(GetMessage10(controller->GetCmd(), controller->GetBuffer()));
|
||||
if (controller->GetLength() <= 0) {
|
||||
GetController()->SetLength(GetMessage10(GetController()->GetCmd(), GetController()->GetBuffer()));
|
||||
if (GetController()->GetLength() <= 0) {
|
||||
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
|
||||
}
|
||||
|
||||
// Set next block
|
||||
controller->SetBlocks(1);
|
||||
controller->SetNext(1);
|
||||
GetController()->SetBlocks(1);
|
||||
GetController()->SetNext(1);
|
||||
|
||||
EnterDataInPhase();
|
||||
}
|
||||
@ -267,19 +267,19 @@ void SCSIBR::GetMessage10()
|
||||
// This Send Message command is used by the X68000 host driver
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
void SCSIBR::SendMessage10()
|
||||
void SCSIBR::SendMessage10() const
|
||||
{
|
||||
controller->SetLength(GetInt24(controller->GetCmd(), 6));
|
||||
if (controller->GetLength() <= 0) {
|
||||
GetController()->SetLength(GetInt24(GetController()->GetCmd(), 6));
|
||||
if (GetController()->GetLength() <= 0) {
|
||||
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
|
||||
}
|
||||
|
||||
// Ensure a sufficient buffer size (because it is not a transfer for each block)
|
||||
controller->AllocateBuffer(0x1000000);
|
||||
GetController()->AllocateBuffer(0x1000000);
|
||||
|
||||
// Set next block
|
||||
controller->SetBlocks(1);
|
||||
controller->SetNext(1);
|
||||
GetController()->SetBlocks(1);
|
||||
GetController()->SetNext(1);
|
||||
|
||||
EnterDataOutPhase();
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ public:
|
||||
bool WriteBytes(const vector<int>&, vector<uint8_t>&, uint32_t) override;
|
||||
void TestUnitReady() override;
|
||||
void GetMessage10();
|
||||
void SendMessage10();
|
||||
void SendMessage10() const;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -84,19 +84,19 @@ vector<uint8_t> SCSIPrinter::InquiryInternal() const
|
||||
|
||||
void SCSIPrinter::Print()
|
||||
{
|
||||
const uint32_t length = GetInt24(controller->GetCmd(), 2);
|
||||
const uint32_t length = GetInt24(GetController()->GetCmd(), 2);
|
||||
|
||||
LOGTRACE("Receiving %d byte(s) to be printed", length)
|
||||
|
||||
if (length > controller->GetBuffer().size()) {
|
||||
LOGERROR("%s", ("Transfer buffer overflow: Buffer size is " + to_string(controller->GetBuffer().size()) +
|
||||
if (length > GetController()->GetBuffer().size()) {
|
||||
LOGERROR("%s", ("Transfer buffer overflow: Buffer size is " + to_string(GetController()->GetBuffer().size()) +
|
||||
" bytes, " + to_string(length) + " bytes expected").c_str())
|
||||
|
||||
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
|
||||
}
|
||||
|
||||
controller->SetLength(length);
|
||||
controller->SetByteTransfer(true);
|
||||
GetController()->SetLength(length);
|
||||
GetController()->SetByteTransfer(true);
|
||||
|
||||
EnterDataOutPhase();
|
||||
}
|
||||
|
@ -162,7 +162,7 @@ void SCSICD::CreateDataTrack()
|
||||
|
||||
void SCSICD::ReadToc()
|
||||
{
|
||||
controller->SetLength(ReadTocInternal(controller->GetCmd(), controller->GetBuffer()));
|
||||
GetController()->SetLength(ReadTocInternal(GetController()->GetCmd(), GetController()->GetBuffer()));
|
||||
|
||||
EnterDataInPhase();
|
||||
}
|
||||
|
@ -15,19 +15,15 @@
|
||||
#include "controllers/controller_manager.h"
|
||||
#include "controllers/scsi_controller.h"
|
||||
#include "devices/device_factory.h"
|
||||
#include "devices/disk.h"
|
||||
#include "devices/storage_device.h"
|
||||
#include "hal/gpiobus.h"
|
||||
#include "hal/gpiobus_factory.h"
|
||||
#include "hal/sbc_version.h"
|
||||
#include "hal/systimer.h"
|
||||
#include "rascsi_version.h"
|
||||
#include "rascsi_exceptions.h"
|
||||
#include "protobuf_serializer.h"
|
||||
#include "protobuf_util.h"
|
||||
#include "rascsi/rascsi_executor.h"
|
||||
#include "rascsi/rascsi_response.h"
|
||||
#include "rascsi/rascsi_image.h"
|
||||
#include "rascsi/rascsi_service.h"
|
||||
#include "rascsi/rascsi_core.h"
|
||||
#include "rasutil.h"
|
||||
#include "spdlog/sinks/stdout_color_sinks.h"
|
||||
@ -45,20 +41,6 @@ using namespace rascsi_interface;
|
||||
using namespace ras_util;
|
||||
using namespace protobuf_util;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Variable declarations
|
||||
// TODO Make these fields class fields
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
RascsiService service;
|
||||
shared_ptr<GPIOBUS> bus;
|
||||
DeviceFactory device_factory;
|
||||
shared_ptr<ControllerManager> controller_manager;
|
||||
RascsiImage rascsi_image;
|
||||
shared_ptr<RascsiResponse> rascsi_response;
|
||||
shared_ptr<RascsiExecutor> executor;
|
||||
|
||||
void Rascsi::Banner(const vector<char *>& args) const
|
||||
{
|
||||
cout << ras_util::Banner("Reloaded");
|
||||
@ -100,14 +82,15 @@ bool Rascsi::InitBus() const
|
||||
|
||||
bus->Reset();
|
||||
|
||||
controller_manager = make_shared<ControllerManager>(bus);
|
||||
rascsi_response = make_shared<RascsiResponse>(device_factory, *controller_manager, ScsiController::LUN_MAX);
|
||||
executor = make_shared<RascsiExecutor>(*rascsi_response, rascsi_image, device_factory, *controller_manager);
|
||||
auto b = bus;
|
||||
controller_manager = make_shared<ControllerManager>(*b);
|
||||
auto c = controller_manager;
|
||||
executor = make_shared<RascsiExecutor>(rascsi_image, *c);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Cleanup()
|
||||
void Rascsi::Cleanup()
|
||||
{
|
||||
executor->DetachAll();
|
||||
|
||||
@ -116,13 +99,6 @@ void Cleanup()
|
||||
bus->Cleanup();
|
||||
}
|
||||
|
||||
void Rascsi::Reset() const
|
||||
{
|
||||
controller_manager->ResetAllControllers();
|
||||
|
||||
bus->Reset();
|
||||
}
|
||||
|
||||
bool Rascsi::ReadAccessToken(const char *filename) const
|
||||
{
|
||||
struct stat st;
|
||||
@ -166,11 +142,9 @@ void Rascsi::LogDevices(string_view devices) const
|
||||
}
|
||||
}
|
||||
|
||||
void TerminationHandler(int signum)
|
||||
void Rascsi::TerminationHandler(int)
|
||||
{
|
||||
Cleanup();
|
||||
|
||||
exit(signum);
|
||||
}
|
||||
|
||||
bool Rascsi::ProcessId(const string& id_spec, int& id, int& unit) const
|
||||
@ -214,10 +188,11 @@ bool Rascsi::ParseArguments(const vector<char *>& args, int& port, optarg_queue_
|
||||
case 'F':
|
||||
case 'z':
|
||||
{
|
||||
string optarg_str = (optarg == nullptr) ? "" : string(optarg);
|
||||
post_process.emplace_back(opt ,optarg_str);
|
||||
const string optarg_str = optarg == nullptr ? "" : optarg;
|
||||
post_process.emplace_back(opt, optarg_str);
|
||||
continue;
|
||||
}
|
||||
|
||||
case 'b': {
|
||||
if (!GetAsInt(optarg, block_size)) {
|
||||
cerr << "Invalid block size " << optarg << endl;
|
||||
@ -348,6 +323,9 @@ bool Rascsi::CreateInitialDevices(const optarg_queue_type& optarg_queue) const
|
||||
case 1:
|
||||
// Encountered filename
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set up the device data
|
||||
@ -390,7 +368,7 @@ bool Rascsi::CreateInitialDevices(const optarg_queue_type& optarg_queue) const
|
||||
|
||||
// Display and log the device list
|
||||
PbServerInfo server_info;
|
||||
rascsi_response->GetDevices(server_info, rascsi_image.GetDefaultFolder());
|
||||
rascsi_response.GetDevices(controller_manager->GetAllDevices(), server_info, rascsi_image.GetDefaultFolder());
|
||||
const list<PbDevice>& devices = { server_info.devices_info().devices().begin(), server_info.devices_info().devices().end() };
|
||||
const string device_list = ListDevices(devices);
|
||||
LogDevices(device_list);
|
||||
@ -441,19 +419,20 @@ bool Rascsi::ExecuteCommand(const CommandContext& context, const PbCommand& comm
|
||||
}
|
||||
|
||||
case DEVICES_INFO: {
|
||||
rascsi_response->GetDevicesInfo(result, command, rascsi_image.GetDefaultFolder());
|
||||
rascsi_response.GetDevicesInfo(controller_manager->GetAllDevices(), result, command,
|
||||
rascsi_image.GetDefaultFolder());
|
||||
serializer.SerializeMessage(context.GetFd(), result);
|
||||
break;
|
||||
}
|
||||
|
||||
case DEVICE_TYPES_INFO: {
|
||||
result.set_allocated_device_types_info(rascsi_response->GetDeviceTypesInfo(result).release());
|
||||
result.set_allocated_device_types_info(rascsi_response.GetDeviceTypesInfo(result).release());
|
||||
serializer.SerializeMessage(context.GetFd(), result);
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVER_INFO: {
|
||||
result.set_allocated_server_info(rascsi_response->GetServerInfo(
|
||||
result.set_allocated_server_info(rascsi_response.GetServerInfo(controller_manager->GetAllDevices(),
|
||||
result, executor->GetReservedIds(), current_log_level, rascsi_image.GetDefaultFolder(),
|
||||
GetParam(command, "folder_pattern"), GetParam(command, "file_pattern"),
|
||||
rascsi_image.GetDepth()).release());
|
||||
@ -462,19 +441,19 @@ bool Rascsi::ExecuteCommand(const CommandContext& context, const PbCommand& comm
|
||||
}
|
||||
|
||||
case VERSION_INFO: {
|
||||
result.set_allocated_version_info(rascsi_response->GetVersionInfo(result).release());
|
||||
result.set_allocated_version_info(rascsi_response.GetVersionInfo(result).release());
|
||||
serializer.SerializeMessage(context.GetFd(), result);
|
||||
break;
|
||||
}
|
||||
|
||||
case LOG_LEVEL_INFO: {
|
||||
result.set_allocated_log_level_info(rascsi_response->GetLogLevelInfo(result, current_log_level).release());
|
||||
result.set_allocated_log_level_info(rascsi_response.GetLogLevelInfo(result, current_log_level).release());
|
||||
serializer.SerializeMessage(context.GetFd(), result);
|
||||
break;
|
||||
}
|
||||
|
||||
case DEFAULT_IMAGE_FILES_INFO: {
|
||||
result.set_allocated_image_files_info(rascsi_response->GetAvailableImages(result,
|
||||
result.set_allocated_image_files_info(rascsi_response.GetAvailableImages(result,
|
||||
rascsi_image.GetDefaultFolder(), GetParam(command, "folder_pattern"),
|
||||
GetParam(command, "file_pattern"), rascsi_image.GetDepth()).release());
|
||||
serializer.SerializeMessage(context.GetFd(), result);
|
||||
@ -487,7 +466,7 @@ bool Rascsi::ExecuteCommand(const CommandContext& context, const PbCommand& comm
|
||||
}
|
||||
else {
|
||||
auto image_file = make_unique<PbImageFile>();
|
||||
const bool status = rascsi_response->GetImageFile(*image_file.get(), rascsi_image.GetDefaultFolder(), filename);
|
||||
const bool status = rascsi_response.GetImageFile(*image_file.get(), rascsi_image.GetDefaultFolder(), filename);
|
||||
if (status) {
|
||||
result.set_status(true);
|
||||
result.set_allocated_image_file_info(image_file.get());
|
||||
@ -501,26 +480,26 @@ bool Rascsi::ExecuteCommand(const CommandContext& context, const PbCommand& comm
|
||||
}
|
||||
|
||||
case NETWORK_INTERFACES_INFO: {
|
||||
result.set_allocated_network_interfaces_info(rascsi_response->GetNetworkInterfacesInfo(result).release());
|
||||
result.set_allocated_network_interfaces_info(rascsi_response.GetNetworkInterfacesInfo(result).release());
|
||||
serializer.SerializeMessage(context.GetFd(), result);
|
||||
break;
|
||||
}
|
||||
|
||||
case MAPPING_INFO: {
|
||||
result.set_allocated_mapping_info(rascsi_response->GetMappingInfo(result).release());
|
||||
result.set_allocated_mapping_info(rascsi_response.GetMappingInfo(result).release());
|
||||
serializer.SerializeMessage(context.GetFd(), result);
|
||||
break;
|
||||
}
|
||||
|
||||
case OPERATION_INFO: {
|
||||
result.set_allocated_operation_info(rascsi_response->GetOperationInfo(result,
|
||||
result.set_allocated_operation_info(rascsi_response.GetOperationInfo(result,
|
||||
rascsi_image.GetDepth()).release());
|
||||
serializer.SerializeMessage(context.GetFd(), result);
|
||||
break;
|
||||
}
|
||||
|
||||
case RESERVED_IDS_INFO: {
|
||||
result.set_allocated_reserved_ids_info(rascsi_response->GetReservedIds(result,
|
||||
result.set_allocated_reserved_ids_info(rascsi_response.GetReservedIds(result,
|
||||
executor->GetReservedIds()).release());
|
||||
serializer.SerializeMessage(context.GetFd(), result);
|
||||
break;
|
||||
@ -552,15 +531,12 @@ int Rascsi::run(const vector<char *>& args) const
|
||||
{
|
||||
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
||||
|
||||
// added setvbuf to override stdout buffering, so logs are written immediately and not when the process exits.
|
||||
setvbuf(stdout, nullptr, _IONBF, 0);
|
||||
|
||||
Banner(args);
|
||||
|
||||
int port = DEFAULT_PORT;
|
||||
optarg_queue_type optarg_queue;
|
||||
if (!ParseArguments(args, port, optarg_queue)) {
|
||||
return -1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Note that current_log_level may have been modified by ParseArguments()
|
||||
@ -570,18 +546,18 @@ int Rascsi::run(const vector<char *>& args) const
|
||||
const auto logger = stdout_color_mt("rascsi stdout logger");
|
||||
|
||||
if (!InitBus()) {
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
if (!service.Init(&ExecuteCommand, port)) {
|
||||
return EPERM;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// We need to wait to create the devices until after the bus/controller/etc
|
||||
// objects have been created.
|
||||
if (!CreateInitialDevices(optarg_queue)) {
|
||||
Cleanup();
|
||||
return -1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (!service.Init(&ExecuteCommand, port)) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Signal handler to detach all devices on a KILL or TERM signal
|
||||
@ -592,9 +568,6 @@ int Rascsi::run(const vector<char *>& args) const
|
||||
sigaction(SIGINT, &termination_handler, nullptr);
|
||||
sigaction(SIGTERM, &termination_handler, nullptr);
|
||||
|
||||
// Reset
|
||||
Reset();
|
||||
|
||||
// Set the affinity to a specific processor core
|
||||
FixCpu(3);
|
||||
|
||||
@ -658,7 +631,7 @@ int Rascsi::run(const vector<char *>& args) const
|
||||
BUS::phase_t phase = BUS::phase_t::busfree;
|
||||
|
||||
// Identify the responsible controller
|
||||
shared_ptr<AbstractController> controller = controller_manager->IdentifyController(id_data);
|
||||
auto controller = controller_manager->IdentifyController(id_data);
|
||||
if (controller != nullptr) {
|
||||
initiator_id = controller->ExtractInitiatorId(id_data);
|
||||
|
||||
@ -702,5 +675,5 @@ int Rascsi::run(const vector<char *>& args) const
|
||||
active = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
@ -10,17 +10,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "rascsi/command_context.h"
|
||||
#include "rascsi/rascsi_service.h"
|
||||
#include "rascsi/rascsi_image.h"
|
||||
#include "rascsi/rascsi_response.h"
|
||||
#include "rascsi_interface.pb.h"
|
||||
#include <deque>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// TODO Only BUS should be known
|
||||
class GPIOBUS;
|
||||
class ControllerManager;
|
||||
class RascsiExecutor;
|
||||
|
||||
class Rascsi
|
||||
{
|
||||
using optarg_value_type = pair<int, string>;
|
||||
using optarg_queue_type = deque<optarg_value_type>;
|
||||
using optarg_queue_type = vector<pair<int, string>>;
|
||||
|
||||
static const int DEFAULT_PORT = 6868;
|
||||
static const char COMPONENT_SEPARATOR = ':';
|
||||
@ -36,16 +42,30 @@ private:
|
||||
|
||||
void Banner(const vector<char *>&) const;
|
||||
bool InitBus() const;
|
||||
void Reset() const;
|
||||
static void Cleanup();
|
||||
bool ReadAccessToken(const char *) const;
|
||||
void LogDevices(string_view) const;
|
||||
static void TerminationHandler(int);
|
||||
bool ProcessId(const string&, int&, int&) const;
|
||||
bool ParseArguments(const vector<char *>&, int&, optarg_queue_type&) const;
|
||||
bool CreateInitialDevices(const optarg_queue_type&) const;
|
||||
|
||||
// TODO Should not be static and should be moved to RascsiService
|
||||
static bool ExecuteCommand(const CommandContext&, const PbCommand&);
|
||||
|
||||
// TODO Get rid of static fields
|
||||
// TODO These fields should not be static
|
||||
|
||||
static inline RascsiService service;
|
||||
|
||||
static inline RascsiImage rascsi_image;
|
||||
|
||||
const static inline RascsiResponse rascsi_response;
|
||||
|
||||
static inline shared_ptr<GPIOBUS> bus;
|
||||
|
||||
static inline shared_ptr<ControllerManager> controller_manager;
|
||||
|
||||
static inline shared_ptr<RascsiExecutor> executor;
|
||||
|
||||
// Processing flag
|
||||
static inline volatile bool active;
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "devices/primary_device.h"
|
||||
#include "devices/disk.h"
|
||||
#include "rascsi_service.h"
|
||||
#include "rascsi_response.h"
|
||||
#include "rascsi_image.h"
|
||||
#include "rascsi_exceptions.h"
|
||||
#include "localizer.h"
|
||||
@ -157,7 +156,8 @@ bool RascsiExecutor::ProcessCmd(const CommandContext& context, const PbCommand&
|
||||
// A new command with an empty device list is required here in order to return data for all devices
|
||||
PbCommand cmd;
|
||||
PbResult result;
|
||||
rascsi_response.GetDevicesInfo(result, cmd, rascsi_image.GetDefaultFolder());
|
||||
rascsi_response.GetDevicesInfo(controller_manager.GetAllDevices(), result, cmd,
|
||||
rascsi_image.GetDefaultFolder());
|
||||
serializer.SerializeMessage(context.GetFd(), result);
|
||||
return true;
|
||||
}
|
||||
@ -668,7 +668,7 @@ bool RascsiExecutor::VerifyExistingIdAndLun(const CommandContext& context, int i
|
||||
shared_ptr<PrimaryDevice> RascsiExecutor::CreateDevice(const CommandContext& context, const PbDeviceType type,
|
||||
int lun, const string& filename) const
|
||||
{
|
||||
auto device = device_factory.CreateDevice(controller_manager, type, lun, filename);
|
||||
auto device = device_factory.CreateDevice(type, lun, filename);
|
||||
if (device == nullptr) {
|
||||
if (type == UNDEFINED) {
|
||||
context.ReturnLocalizedError(LocalizationKey::ERROR_MISSING_DEVICE_TYPE, filename);
|
||||
|
@ -9,9 +9,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "rascsi/rascsi_response.h"
|
||||
#include "protobuf_serializer.h"
|
||||
|
||||
class RascsiResponse;
|
||||
class RascsiImage;
|
||||
class DeviceFactory;
|
||||
class ControllerManager;
|
||||
@ -20,24 +20,10 @@ class CommandContext;
|
||||
|
||||
class RascsiExecutor
|
||||
{
|
||||
RascsiResponse& rascsi_response;
|
||||
|
||||
RascsiImage& rascsi_image;
|
||||
|
||||
DeviceFactory& device_factory;
|
||||
|
||||
ControllerManager& controller_manager;
|
||||
|
||||
ProtobufSerializer serializer;
|
||||
|
||||
unordered_set<int> reserved_ids;
|
||||
|
||||
public:
|
||||
|
||||
RascsiExecutor(RascsiResponse& rascsi_response, RascsiImage& rascsi_image, DeviceFactory& device_factory,
|
||||
ControllerManager& controller_manager)
|
||||
: rascsi_response(rascsi_response), rascsi_image(rascsi_image), device_factory(device_factory),
|
||||
controller_manager(controller_manager) {}
|
||||
RascsiExecutor(RascsiImage& rascsi_image, ControllerManager& controller_manager)
|
||||
: rascsi_image(rascsi_image), controller_manager(controller_manager) {}
|
||||
~RascsiExecutor() = default;
|
||||
|
||||
unordered_set<int> GetReservedIds() const { return reserved_ids; }
|
||||
@ -67,4 +53,17 @@ public:
|
||||
static bool ValidateIdAndLun(const CommandContext&, int, int);
|
||||
static bool SetProductData(const CommandContext&, const PbDeviceDefinition&, PrimaryDevice&);
|
||||
|
||||
private:
|
||||
|
||||
const RascsiResponse rascsi_response;
|
||||
|
||||
RascsiImage& rascsi_image;
|
||||
|
||||
ControllerManager& controller_manager;
|
||||
|
||||
const DeviceFactory device_factory;
|
||||
|
||||
const ProtobufSerializer serializer;
|
||||
|
||||
unordered_set<int> reserved_ids;
|
||||
};
|
||||
|
@ -8,7 +8,6 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "log.h"
|
||||
#include "controllers/controller_manager.h"
|
||||
#include "devices/disk.h"
|
||||
#include "devices/device_factory.h"
|
||||
#include "protobuf_util.h"
|
||||
@ -26,7 +25,8 @@ unique_ptr<PbDeviceProperties> RascsiResponse::GetDeviceProperties(const Device&
|
||||
{
|
||||
auto properties = make_unique<PbDeviceProperties>();
|
||||
|
||||
properties->set_luns(max_luns);
|
||||
// Currently there is only a SCSI controller, i.e. there can always be 32 LUNs
|
||||
properties->set_luns(32);
|
||||
properties->set_read_only(device.IsReadOnly());
|
||||
properties->set_protectable(device.IsProtectable());
|
||||
properties->set_stoppable(device.IsStoppable());
|
||||
@ -53,7 +53,7 @@ void RascsiResponse::GetDeviceTypeProperties(PbDeviceTypesInfo& device_types_inf
|
||||
{
|
||||
auto type_properties = device_types_info.add_properties();
|
||||
type_properties->set_type(type);
|
||||
const auto device = device_factory.CreateDevice(controller_manager, type, 0, "");
|
||||
const auto device = device_factory.CreateDevice(type, 0, "");
|
||||
type_properties->set_allocated_properties(GetDeviceProperties(*device).release());
|
||||
} //NOSONAR The allocated memory is managed by protobuf
|
||||
|
||||
@ -215,20 +215,20 @@ unique_ptr<PbReservedIdsInfo> RascsiResponse::GetReservedIds(PbResult& result, c
|
||||
return reserved_ids_info;
|
||||
}
|
||||
|
||||
void RascsiResponse::GetDevices(PbServerInfo& server_info, const string& default_folder) const
|
||||
void RascsiResponse::GetDevices(const unordered_set<shared_ptr<PrimaryDevice>>& devices, PbServerInfo& server_info,
|
||||
const string& default_folder) const
|
||||
{
|
||||
for (const auto& device : controller_manager.GetAllDevices()) {
|
||||
for (const auto& device : devices) {
|
||||
PbDevice *pb_device = server_info.mutable_devices_info()->add_devices();
|
||||
GetDevice(*device, *pb_device, default_folder);
|
||||
}
|
||||
}
|
||||
|
||||
void RascsiResponse::GetDevicesInfo(PbResult& result, const PbCommand& command, const string& default_folder) const
|
||||
void RascsiResponse::GetDevicesInfo(const unordered_set<shared_ptr<PrimaryDevice>>& devices, PbResult& result,
|
||||
const PbCommand& command, const string& default_folder) const
|
||||
{
|
||||
set<id_set> id_sets;
|
||||
|
||||
const auto& devices = controller_manager.GetAllDevices();
|
||||
|
||||
// If no device list was provided in the command get information on all devices
|
||||
if (!command.devices_size()) {
|
||||
for (const auto& device : devices) {
|
||||
@ -237,7 +237,7 @@ void RascsiResponse::GetDevicesInfo(PbResult& result, const PbCommand& command,
|
||||
}
|
||||
// Otherwise get information on the devices provided in the command
|
||||
else {
|
||||
id_sets = MatchDevices(result, command);
|
||||
id_sets = MatchDevices(devices, result, command);
|
||||
if (id_sets.empty()) {
|
||||
return;
|
||||
}
|
||||
@ -269,9 +269,9 @@ unique_ptr<PbDeviceTypesInfo> RascsiResponse::GetDeviceTypesInfo(PbResult& resul
|
||||
return device_types_info;
|
||||
}
|
||||
|
||||
unique_ptr<PbServerInfo> RascsiResponse::GetServerInfo(PbResult& result, const unordered_set<int>& reserved_ids,
|
||||
const string& current_log_level, const string& default_folder, const string& folder_pattern,
|
||||
const string& file_pattern, int scan_depth) const
|
||||
unique_ptr<PbServerInfo> RascsiResponse::GetServerInfo(const unordered_set<shared_ptr<PrimaryDevice>>& devices,
|
||||
PbResult& result, const unordered_set<int>& reserved_ids, const string& current_log_level,
|
||||
const string& default_folder, const string& folder_pattern, const string& file_pattern, int scan_depth) const
|
||||
{
|
||||
auto server_info = make_unique<PbServerInfo>();
|
||||
|
||||
@ -281,7 +281,7 @@ unique_ptr<PbServerInfo> RascsiResponse::GetServerInfo(PbResult& result, const u
|
||||
GetAvailableImages(result, *server_info, default_folder, folder_pattern, file_pattern, scan_depth);
|
||||
server_info->set_allocated_network_interfaces_info(GetNetworkInterfacesInfo(result).release());
|
||||
server_info->set_allocated_mapping_info(GetMappingInfo(result).release()); //NOSONAR The allocated memory is managed by protobuf
|
||||
GetDevices(*server_info, default_folder); //NOSONAR The allocated memory is managed by protobuf
|
||||
GetDevices(devices, *server_info, default_folder); //NOSONAR The allocated memory is managed by protobuf
|
||||
server_info->set_allocated_reserved_ids_info(GetReservedIds(result, reserved_ids).release());
|
||||
server_info->set_allocated_operation_info(GetOperationInfo(result, scan_depth).release()); //NOSONAR The allocated memory is managed by protobuf
|
||||
|
||||
@ -494,13 +494,14 @@ unique_ptr<PbOperationParameter> RascsiResponse::AddOperationParameter(PbOperati
|
||||
return parameter;
|
||||
}
|
||||
|
||||
set<id_set> RascsiResponse::MatchDevices(PbResult& result, const PbCommand& command) const
|
||||
set<id_set> RascsiResponse::MatchDevices(const unordered_set<shared_ptr<PrimaryDevice>>& devices, PbResult& result,
|
||||
const PbCommand& command) const
|
||||
{
|
||||
set<id_set> id_sets;
|
||||
|
||||
for (const auto& device : command.devices()) {
|
||||
bool has_device = false;
|
||||
for (const auto& d : controller_manager.GetAllDevices()) {
|
||||
for (const auto& d : devices) {
|
||||
if (d->GetId() == device.id() && d->GetLun() == device.unit()) {
|
||||
id_sets.insert(make_pair(device.id(), device.unit()));
|
||||
has_device = true;
|
||||
|
@ -9,6 +9,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "devices/device_factory.h"
|
||||
#include "devices/primary_device.h"
|
||||
#include "rascsi_interface.pb.h"
|
||||
#include <dirent.h>
|
||||
#include <array>
|
||||
@ -17,27 +19,24 @@
|
||||
using namespace std;
|
||||
using namespace rascsi_interface;
|
||||
|
||||
class DeviceFactory;
|
||||
class ControllerManager;
|
||||
class Device;
|
||||
|
||||
class RascsiResponse
|
||||
{
|
||||
using id_set = pair<int, int>;
|
||||
|
||||
public:
|
||||
|
||||
RascsiResponse(DeviceFactory& device_factory, const ControllerManager& controller_manager, int max_luns)
|
||||
: device_factory(device_factory), controller_manager(controller_manager), max_luns(max_luns) {}
|
||||
RascsiResponse() = default;
|
||||
~RascsiResponse() = default;
|
||||
|
||||
bool GetImageFile(PbImageFile&, const string&, const string&) const;
|
||||
unique_ptr<PbImageFilesInfo> GetAvailableImages(PbResult&, const string&, const string&, const string&, int) const;
|
||||
unique_ptr<PbReservedIdsInfo> GetReservedIds(PbResult&, const unordered_set<int>&) const;
|
||||
void GetDevices(PbServerInfo&, const string&) const;
|
||||
void GetDevicesInfo(PbResult&, const PbCommand&, const string&) const;
|
||||
void GetDevices(const unordered_set<shared_ptr<PrimaryDevice>>&, PbServerInfo&, const string&) const;
|
||||
void GetDevicesInfo(const unordered_set<shared_ptr<PrimaryDevice>>&, PbResult&, const PbCommand&, const string&) const;
|
||||
unique_ptr<PbDeviceTypesInfo> GetDeviceTypesInfo(PbResult&) const;
|
||||
unique_ptr<PbVersionInfo> GetVersionInfo(PbResult&) const;
|
||||
unique_ptr<PbServerInfo> GetServerInfo(PbResult&, const unordered_set<int>&, const string&, const string&, const string&,
|
||||
const string&, int) const;
|
||||
unique_ptr<PbServerInfo> GetServerInfo(const unordered_set<shared_ptr<PrimaryDevice>>&, PbResult&, const unordered_set<int>&,
|
||||
const string&, const string&, const string&, const string&, int) const;
|
||||
unique_ptr<PbNetworkInterfacesInfo> GetNetworkInterfacesInfo(PbResult&) const;
|
||||
unique_ptr<PbMappingInfo> GetMappingInfo(PbResult&) const;
|
||||
unique_ptr<PbLogLevelInfo> GetLogLevelInfo(PbResult&, const string&) const;
|
||||
@ -45,13 +44,9 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
DeviceFactory& device_factory;
|
||||
DeviceFactory device_factory;
|
||||
|
||||
const ControllerManager& controller_manager;
|
||||
|
||||
int max_luns;
|
||||
|
||||
const array<string, 6> log_levels = { "trace", "debug", "info", "warn", "err", "off" };
|
||||
const inline static array<string, 6> log_levels = { "trace", "debug", "info", "warn", "err", "off" };
|
||||
|
||||
unique_ptr<PbDeviceProperties> GetDeviceProperties(const Device&) const;
|
||||
void GetDevice(const Device&, PbDevice&, const string&) const;
|
||||
@ -62,7 +57,7 @@ private:
|
||||
unique_ptr<PbOperationMetaData> CreateOperation(PbOperationInfo&, const PbOperation&, const string&) const;
|
||||
unique_ptr<PbOperationParameter> AddOperationParameter(PbOperationMetaData&, const string&, const string&,
|
||||
const string& = "", bool = false) const;
|
||||
set<id_set> MatchDevices(PbResult&, const PbCommand&) const;
|
||||
set<id_set> MatchDevices(const unordered_set<shared_ptr<PrimaryDevice>>&, PbResult&, const PbCommand&) const;
|
||||
|
||||
static string GetNextImageFile(const dirent *, const string&);
|
||||
};
|
||||
|
@ -18,9 +18,12 @@
|
||||
#include <csignal>
|
||||
|
||||
using namespace rascsi_interface;
|
||||
using namespace ras_util;
|
||||
|
||||
void RascsiService::Cleanup() const
|
||||
{
|
||||
running = false;
|
||||
|
||||
if (service_socket != -1) {
|
||||
close(service_socket);
|
||||
}
|
||||
@ -76,7 +79,7 @@ void RascsiService::Execute() const
|
||||
#endif
|
||||
|
||||
// Set the affinity to a specific processor core
|
||||
ras_util::FixCpu(2);
|
||||
FixCpu(2);
|
||||
|
||||
// Wait for the execution to start
|
||||
const timespec ts = { .tv_sec = 0, .tv_nsec = 1000};
|
||||
|
@ -15,7 +15,9 @@ using namespace scsi_defs;
|
||||
|
||||
TEST(AbstractControllerTest, AllocateCmd)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
MockAbstractController controller(controller_manager, 0);
|
||||
|
||||
EXPECT_EQ(16, controller.GetCmd().size());
|
||||
controller.AllocateCmd(1234);
|
||||
@ -24,7 +26,9 @@ TEST(AbstractControllerTest, AllocateCmd)
|
||||
|
||||
TEST(AbstractControllerTest, AllocateBuffer)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
MockAbstractController controller(controller_manager, 0);
|
||||
|
||||
controller.AllocateBuffer(1);
|
||||
EXPECT_LE(1, controller.GetBuffer().size());
|
||||
@ -34,22 +38,26 @@ TEST(AbstractControllerTest, AllocateBuffer)
|
||||
|
||||
TEST(AbstractControllerTest, Reset)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto device = make_shared<MockPrimaryDevice>(0);
|
||||
|
||||
controller.AddDevice(device);
|
||||
controller->AddDevice(device);
|
||||
|
||||
controller.SetPhase(BUS::phase_t::status);
|
||||
EXPECT_EQ(BUS::phase_t::status, controller.GetPhase());
|
||||
controller.Reset();
|
||||
EXPECT_TRUE(controller.IsBusFree());
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(0, controller.GetLength());
|
||||
controller->SetPhase(BUS::phase_t::status);
|
||||
EXPECT_EQ(BUS::phase_t::status, controller->GetPhase());
|
||||
controller->Reset();
|
||||
EXPECT_TRUE(controller->IsBusFree());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
EXPECT_EQ(0, controller->GetLength());
|
||||
}
|
||||
|
||||
TEST(AbstractControllerTest, Next)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
MockAbstractController controller(controller_manager, 0);
|
||||
|
||||
controller.SetNext(0x1234);
|
||||
EXPECT_EQ(0x1234, controller.GetNext());
|
||||
@ -59,7 +67,9 @@ TEST(AbstractControllerTest, Next)
|
||||
|
||||
TEST(AbstractControllerTest, Message)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
MockAbstractController controller(controller_manager, 0);
|
||||
|
||||
controller.SetMessage(0x12);
|
||||
EXPECT_EQ(0x12, controller.GetMessage());
|
||||
@ -67,7 +77,9 @@ TEST(AbstractControllerTest, Message)
|
||||
|
||||
TEST(AbstractControllerTest, ByteTransfer)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
MockAbstractController controller(controller_manager, 0);
|
||||
|
||||
controller.SetByteTransfer(false);
|
||||
EXPECT_FALSE(controller.IsByteTransfer());
|
||||
@ -77,7 +89,9 @@ TEST(AbstractControllerTest, ByteTransfer)
|
||||
|
||||
TEST(AbstractControllerTest, BytesToTransfer)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
MockAbstractController controller(controller_manager, 0);
|
||||
|
||||
controller.SetBytesToTransfer(0x1234);
|
||||
EXPECT_EQ(0x1234, controller.GetBytesToTransfer());
|
||||
@ -87,14 +101,18 @@ TEST(AbstractControllerTest, BytesToTransfer)
|
||||
|
||||
TEST(AbstractControllerTest, GetMaxLuns)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
MockAbstractController controller(controller_manager, 0);
|
||||
|
||||
EXPECT_EQ(32, controller.GetMaxLuns());
|
||||
}
|
||||
|
||||
TEST(AbstractControllerTest, Status)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
MockAbstractController controller(controller_manager, 0);
|
||||
|
||||
controller.SetStatus(status::RESERVATION_CONFLICT);
|
||||
EXPECT_EQ(status::RESERVATION_CONFLICT, controller.GetStatus());
|
||||
@ -102,7 +120,9 @@ TEST(AbstractControllerTest, Status)
|
||||
|
||||
TEST(AbstractControllerTest, ProcessPhase)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
MockAbstractController controller(controller_manager, 0);
|
||||
|
||||
controller.SetPhase(BUS::phase_t::selection);
|
||||
EXPECT_CALL(controller, Selection);
|
||||
@ -152,25 +172,27 @@ TEST(AbstractControllerTest, DeviceLunLifeCycle)
|
||||
const int ID = 1;
|
||||
const int LUN = 4;
|
||||
|
||||
MockAbstractController controller(make_shared<MockBus>(), ID);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<NiceMock<MockAbstractController>>(controller_manager, ID);
|
||||
|
||||
auto device1 = make_shared<MockPrimaryDevice>(LUN);
|
||||
auto device2 = make_shared<MockPrimaryDevice>(32);
|
||||
auto device3 = make_shared<MockPrimaryDevice>(-1);
|
||||
|
||||
EXPECT_EQ(0, controller.GetLunCount());
|
||||
EXPECT_EQ(ID, controller.GetTargetId());
|
||||
EXPECT_TRUE(controller.AddDevice(device1));
|
||||
EXPECT_FALSE(controller.AddDevice(device2));
|
||||
EXPECT_FALSE(controller.AddDevice(device3));
|
||||
EXPECT_TRUE(controller.GetLunCount() > 0);
|
||||
EXPECT_TRUE(controller.HasDeviceForLun(LUN));
|
||||
EXPECT_FALSE(controller.HasDeviceForLun(0));
|
||||
EXPECT_NE(nullptr, controller.GetDeviceForLun(LUN));
|
||||
EXPECT_EQ(nullptr, controller.GetDeviceForLun(0));
|
||||
EXPECT_TRUE(controller.RemoveDevice(device1));
|
||||
EXPECT_EQ(0, controller.GetLunCount());
|
||||
EXPECT_FALSE(controller.RemoveDevice(device1));
|
||||
EXPECT_EQ(0, controller->GetLunCount());
|
||||
EXPECT_EQ(ID, controller->GetTargetId());
|
||||
EXPECT_TRUE(controller->AddDevice(device1));
|
||||
EXPECT_FALSE(controller->AddDevice(device2));
|
||||
EXPECT_FALSE(controller->AddDevice(device3));
|
||||
EXPECT_TRUE(controller->GetLunCount() > 0);
|
||||
EXPECT_TRUE(controller->HasDeviceForLun(LUN));
|
||||
EXPECT_FALSE(controller->HasDeviceForLun(0));
|
||||
EXPECT_NE(nullptr, controller->GetDeviceForLun(LUN));
|
||||
EXPECT_EQ(nullptr, controller->GetDeviceForLun(0));
|
||||
EXPECT_TRUE(controller->RemoveDevice(device1));
|
||||
EXPECT_EQ(0, controller->GetLunCount());
|
||||
EXPECT_FALSE(controller->RemoveDevice(device1));
|
||||
}
|
||||
|
||||
TEST(AbstractControllerTest, ExtractInitiatorId)
|
||||
@ -179,7 +201,9 @@ TEST(AbstractControllerTest, ExtractInitiatorId)
|
||||
const int INITIATOR_ID = 7;
|
||||
const int UNKNOWN_INITIATOR_ID = -1;
|
||||
|
||||
MockAbstractController controller(make_shared<MockBus>(), ID);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
MockAbstractController controller(controller_manager, ID);
|
||||
|
||||
EXPECT_EQ(INITIATOR_ID, controller.ExtractInitiatorId((1 << INITIATOR_ID) | ( 1 << ID)));
|
||||
EXPECT_EQ(UNKNOWN_INITIATOR_ID, controller.ExtractInitiatorId(1 << ID));
|
||||
@ -187,7 +211,9 @@ TEST(AbstractControllerTest, ExtractInitiatorId)
|
||||
|
||||
TEST(AbstractControllerTest, GetOpcode)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
MockAbstractController controller(controller_manager, 0);
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
|
||||
@ -199,7 +225,9 @@ TEST(AbstractControllerTest, GetLun)
|
||||
{
|
||||
const int LUN = 3;
|
||||
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
MockAbstractController controller(controller_manager, 0);
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
|
||||
@ -209,7 +237,9 @@ TEST(AbstractControllerTest, GetLun)
|
||||
|
||||
TEST(AbstractControllerTest, Blocks)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
MockAbstractController controller(controller_manager, 0);
|
||||
|
||||
controller.SetBlocks(1);
|
||||
EXPECT_EQ(1, controller.GetBlocks());
|
||||
@ -219,7 +249,9 @@ TEST(AbstractControllerTest, Blocks)
|
||||
|
||||
TEST(AbstractControllerTest, Length)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
MockAbstractController controller(controller_manager, 0);
|
||||
|
||||
EXPECT_FALSE(controller.HasValidLength());
|
||||
|
||||
@ -230,7 +262,9 @@ TEST(AbstractControllerTest, Length)
|
||||
|
||||
TEST(AbstractControllerTest, UpdateOffsetAndLength)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
MockAbstractController controller(controller_manager, 0);
|
||||
|
||||
EXPECT_FALSE(controller.HasValidLength());
|
||||
|
||||
@ -240,7 +274,9 @@ TEST(AbstractControllerTest, UpdateOffsetAndLength)
|
||||
|
||||
TEST(AbstractControllerTest, Offset)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
MockAbstractController controller(controller_manager, 0);
|
||||
|
||||
controller.ResetOffset();
|
||||
EXPECT_EQ(0, controller.GetOffset());
|
||||
|
@ -18,32 +18,32 @@ TEST(ControllerManagerTest, LifeCycle)
|
||||
const int LUN2 = 3;
|
||||
|
||||
auto bus = make_shared<MockBus>();
|
||||
ControllerManager controller_manager(bus);
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
DeviceFactory device_factory;
|
||||
|
||||
auto device = device_factory.CreateDevice(controller_manager, SCHS, -1, "");
|
||||
EXPECT_FALSE(controller_manager.AttachToScsiController(ID, device));
|
||||
auto device = device_factory.CreateDevice(SCHS, -1, "");
|
||||
EXPECT_FALSE(controller_manager->AttachToScsiController(ID, device));
|
||||
|
||||
device = device_factory.CreateDevice(controller_manager, SCHS, LUN1, "");
|
||||
EXPECT_TRUE(controller_manager.AttachToScsiController(ID, device));
|
||||
auto controller = controller_manager.FindController(ID);
|
||||
device = device_factory.CreateDevice(SCHS, LUN1, "");
|
||||
EXPECT_TRUE(controller_manager->AttachToScsiController(ID, device));
|
||||
auto controller = controller_manager->FindController(ID);
|
||||
EXPECT_NE(nullptr, controller);
|
||||
EXPECT_EQ(1, controller->GetLunCount());
|
||||
EXPECT_NE(nullptr, controller_manager.IdentifyController(1 << ID));
|
||||
EXPECT_EQ(nullptr, controller_manager.IdentifyController(0));
|
||||
EXPECT_EQ(nullptr, controller_manager.FindController(0));
|
||||
EXPECT_NE(nullptr, controller_manager.GetDeviceByIdAndLun(ID, LUN1));
|
||||
EXPECT_EQ(nullptr, controller_manager.GetDeviceByIdAndLun(0, 0));
|
||||
EXPECT_NE(nullptr, controller_manager->IdentifyController(1 << ID));
|
||||
EXPECT_EQ(nullptr, controller_manager->IdentifyController(0));
|
||||
EXPECT_EQ(nullptr, controller_manager->FindController(0));
|
||||
EXPECT_NE(nullptr, controller_manager->GetDeviceByIdAndLun(ID, LUN1));
|
||||
EXPECT_EQ(nullptr, controller_manager->GetDeviceByIdAndLun(0, 0));
|
||||
|
||||
device = device_factory.CreateDevice(controller_manager, SCHS, LUN2, "");
|
||||
EXPECT_TRUE(controller_manager.AttachToScsiController(ID, device));
|
||||
controller = controller_manager.FindController(ID);
|
||||
EXPECT_TRUE(controller_manager.DeleteController(controller));
|
||||
EXPECT_EQ(nullptr, controller_manager.FindController(ID));
|
||||
device = device_factory.CreateDevice(SCHS, LUN2, "");
|
||||
EXPECT_TRUE(controller_manager->AttachToScsiController(ID, device));
|
||||
controller = controller_manager->FindController(ID);
|
||||
EXPECT_TRUE(controller_manager->DeleteController(controller));
|
||||
EXPECT_EQ(nullptr, controller_manager->FindController(ID));
|
||||
|
||||
controller_manager.DeleteAllControllers();
|
||||
EXPECT_EQ(nullptr, controller_manager.FindController(ID));
|
||||
EXPECT_EQ(nullptr, controller_manager.GetDeviceByIdAndLun(ID, LUN1));
|
||||
controller_manager->DeleteAllControllers();
|
||||
EXPECT_EQ(nullptr, controller_manager->FindController(ID));
|
||||
EXPECT_EQ(nullptr, controller_manager->GetDeviceByIdAndLun(ID, LUN1));
|
||||
}
|
||||
|
||||
TEST(ControllerManagerTest, AttachToScsiController)
|
||||
@ -53,32 +53,14 @@ TEST(ControllerManagerTest, AttachToScsiController)
|
||||
const int LUN2 = 0;
|
||||
|
||||
auto bus = make_shared<MockBus>();
|
||||
ControllerManager controller_manager(bus);
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
DeviceFactory device_factory;
|
||||
|
||||
auto device1 = device_factory.CreateDevice(controller_manager, SCHS, LUN1, "");
|
||||
EXPECT_FALSE(controller_manager.AttachToScsiController(ID, device1)) << "LUN 0 is missing";
|
||||
auto device1 = device_factory.CreateDevice(SCHS, LUN1, "");
|
||||
EXPECT_FALSE(controller_manager->AttachToScsiController(ID, device1)) << "LUN 0 is missing";
|
||||
|
||||
auto device2 = device_factory.CreateDevice(controller_manager, SCLP, LUN2, "");
|
||||
EXPECT_TRUE(controller_manager.AttachToScsiController(ID, device2));
|
||||
EXPECT_TRUE(controller_manager.AttachToScsiController(ID, device1));
|
||||
EXPECT_FALSE(controller_manager.AttachToScsiController(ID, device1));
|
||||
}
|
||||
|
||||
TEST(ControllerManagerTest, ResetAllControllers)
|
||||
{
|
||||
const int ID = 2;
|
||||
|
||||
auto bus = make_shared<MockBus>();
|
||||
ControllerManager controller_manager(bus);
|
||||
DeviceFactory device_factory;
|
||||
|
||||
auto device = device_factory.CreateDevice(controller_manager, SCHS, 0, "");
|
||||
EXPECT_TRUE(controller_manager.AttachToScsiController(ID, device));
|
||||
auto controller = controller_manager.FindController(ID);
|
||||
EXPECT_NE(nullptr, controller);
|
||||
|
||||
controller->SetStatus(status::RESERVATION_CONFLICT);
|
||||
controller_manager.ResetAllControllers();
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
auto device2 = device_factory.CreateDevice(SCLP, LUN2, "");
|
||||
EXPECT_TRUE(controller_manager->AttachToScsiController(ID, device2));
|
||||
EXPECT_TRUE(controller_manager->AttachToScsiController(ID, device1));
|
||||
EXPECT_FALSE(controller_manager->AttachToScsiController(ID, device1));
|
||||
}
|
||||
|
@ -122,27 +122,24 @@ TEST(DeviceFactoryTest, GetDefaultParams)
|
||||
|
||||
TEST(DeviceFactoryTest, UnknownDeviceType)
|
||||
{
|
||||
auto bus = make_shared<MockBus>();
|
||||
DeviceFactory device_factory;
|
||||
ControllerManager controller_manager(bus);
|
||||
|
||||
auto device1 = device_factory.CreateDevice(controller_manager, UNDEFINED, 0, "test");
|
||||
auto device1 = device_factory.CreateDevice(UNDEFINED, 0, "test");
|
||||
EXPECT_EQ(nullptr, device1);
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
auto device2 = device_factory.CreateDevice(controller_manager, SAHD, 0, "test");
|
||||
auto device2 = device_factory.CreateDevice(SAHD, 0, "test");
|
||||
#pragma GCC diagnostic pop
|
||||
EXPECT_EQ(nullptr, device2);
|
||||
}
|
||||
|
||||
TEST(DeviceFactoryTest, SCHD_Device_Defaults)
|
||||
{
|
||||
auto bus = make_shared<MockBus>();
|
||||
DeviceFactory device_factory;
|
||||
ControllerManager controller_manager(bus);
|
||||
|
||||
auto device = device_factory.CreateDevice(controller_manager, UNDEFINED, 0, "test.hda");
|
||||
auto device = device_factory.CreateDevice(UNDEFINED, 0, "test.hda");
|
||||
|
||||
const unordered_map<string, string> params;
|
||||
device->Init(params);
|
||||
|
||||
@ -165,26 +162,23 @@ TEST(DeviceFactoryTest, SCHD_Device_Defaults)
|
||||
EXPECT_EQ(string(rascsi_get_version_string()).substr(0, 2) + string(rascsi_get_version_string()).substr(3, 2),
|
||||
device->GetRevision());
|
||||
|
||||
device = device_factory.CreateDevice(controller_manager, UNDEFINED, 0, "test.hds");
|
||||
device = device_factory.CreateDevice(UNDEFINED, 0, "test.hds");
|
||||
EXPECT_NE(nullptr, device);
|
||||
EXPECT_EQ(SCHD, device->GetType());
|
||||
|
||||
device = device_factory.CreateDevice(controller_manager, UNDEFINED, 0, "test.hdi");
|
||||
device = device_factory.CreateDevice(UNDEFINED, 0, "test.hdi");
|
||||
EXPECT_NE(nullptr, device);
|
||||
EXPECT_EQ(SCHD, device->GetType());
|
||||
|
||||
device = device_factory.CreateDevice(controller_manager, UNDEFINED, 0, "test.nhd");
|
||||
device = device_factory.CreateDevice(UNDEFINED, 0, "test.nhd");
|
||||
EXPECT_NE(nullptr, device);
|
||||
EXPECT_EQ(SCHD, device->GetType());
|
||||
}
|
||||
|
||||
void TestRemovableDrive(PbDeviceType type, const string& filename, const string& product)
|
||||
{
|
||||
auto bus = make_shared<MockBus>();
|
||||
DeviceFactory device_factory;
|
||||
ControllerManager controller_manager(bus);
|
||||
|
||||
auto device = device_factory.CreateDevice(controller_manager, UNDEFINED, 0, filename);
|
||||
auto device = device_factory.CreateDevice(UNDEFINED, 0, filename);
|
||||
const unordered_map<string, string> params;
|
||||
device->Init(params);
|
||||
|
||||
@ -221,11 +215,10 @@ TEST(DeviceFactoryTest, SCMO_Device_Defaults)
|
||||
|
||||
TEST(DeviceFactoryTest, SCCD_Device_Defaults)
|
||||
{
|
||||
auto bus = make_shared<MockBus>();
|
||||
DeviceFactory device_factory;
|
||||
ControllerManager controller_manager(bus);
|
||||
|
||||
auto device = device_factory.CreateDevice(controller_manager, UNDEFINED, 0, "test.iso");
|
||||
auto device = device_factory.CreateDevice(UNDEFINED, 0, "test.iso");
|
||||
|
||||
const unordered_map<string, string> params;
|
||||
device->Init(params);
|
||||
|
||||
@ -251,11 +244,10 @@ TEST(DeviceFactoryTest, SCCD_Device_Defaults)
|
||||
|
||||
TEST(DeviceFactoryTest, SCBR_Device_Defaults)
|
||||
{
|
||||
auto bus = make_shared<MockBus>();
|
||||
DeviceFactory device_factory;
|
||||
ControllerManager controller_manager(bus);
|
||||
|
||||
auto device = device_factory.CreateDevice(controller_manager, UNDEFINED, 0, "bridge");
|
||||
auto device = device_factory.CreateDevice(UNDEFINED, 0, "bridge");
|
||||
|
||||
const unordered_map<string, string> params;
|
||||
device->Init(params);
|
||||
|
||||
@ -281,11 +273,10 @@ TEST(DeviceFactoryTest, SCBR_Device_Defaults)
|
||||
|
||||
TEST(DeviceFactoryTest, SCDP_Device_Defaults)
|
||||
{
|
||||
auto bus = make_shared<MockBus>();
|
||||
DeviceFactory device_factory;
|
||||
ControllerManager controller_manager(bus);
|
||||
|
||||
auto device = device_factory.CreateDevice(controller_manager, UNDEFINED, 0, "daynaport");
|
||||
auto device = device_factory.CreateDevice(UNDEFINED, 0, "daynaport");
|
||||
|
||||
const unordered_map<string, string> params;
|
||||
device->Init(params);
|
||||
|
||||
@ -310,11 +301,10 @@ TEST(DeviceFactoryTest, SCDP_Device_Defaults)
|
||||
|
||||
TEST(DeviceFactoryTest, SCHS_Device_Defaults)
|
||||
{
|
||||
auto bus = make_shared<MockBus>();
|
||||
DeviceFactory device_factory;
|
||||
ControllerManager controller_manager(bus);
|
||||
|
||||
auto device = device_factory.CreateDevice(controller_manager, UNDEFINED, 0, "services");
|
||||
auto device = device_factory.CreateDevice(UNDEFINED, 0, "services");
|
||||
|
||||
const unordered_map<string, string> params;
|
||||
device->Init(params);
|
||||
|
||||
@ -340,11 +330,10 @@ TEST(DeviceFactoryTest, SCHS_Device_Defaults)
|
||||
|
||||
TEST(DeviceFactoryTest, SCLP_Device_Defaults)
|
||||
{
|
||||
auto bus = make_shared<MockBus>();
|
||||
DeviceFactory device_factory;
|
||||
ControllerManager controller_manager(bus);
|
||||
|
||||
auto device = device_factory.CreateDevice(controller_manager, UNDEFINED, 0, "printer");
|
||||
auto device = device_factory.CreateDevice(UNDEFINED, 0, "printer");
|
||||
|
||||
const unordered_map<string, string> params;
|
||||
device->Init(params);
|
||||
|
||||
|
@ -18,34 +18,38 @@ using namespace scsi_command_util;
|
||||
|
||||
TEST(DiskTest, Dispatch)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
const unordered_map<string, string> params;
|
||||
disk->Init(params);
|
||||
|
||||
controller.AddDevice(disk);
|
||||
controller->AddDevice(disk);
|
||||
|
||||
disk->SetRemovable(true);
|
||||
disk->SetMediumChanged(false);
|
||||
disk->SetReady(true);
|
||||
EXPECT_CALL(controller, Status);
|
||||
EXPECT_CALL(*controller, Status);
|
||||
disk->Dispatch(scsi_command::eCmdTestUnitReady);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
|
||||
disk->SetMediumChanged(true);
|
||||
EXPECT_CALL(controller, Error);
|
||||
EXPECT_CALL(*controller, Error);
|
||||
disk->Dispatch(scsi_command::eCmdTestUnitReady);
|
||||
EXPECT_FALSE(disk->IsMediumChanged());
|
||||
}
|
||||
|
||||
TEST(DiskTest, Rezero)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
const unordered_map<string, string> params;
|
||||
disk->Init(params);
|
||||
|
||||
controller.AddDevice(disk);
|
||||
controller->AddDevice(disk);
|
||||
|
||||
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdRezero); }, Throws<scsi_exception>(AllOf(
|
||||
Property(&scsi_exception::get_sense_key, sense_key::NOT_READY),
|
||||
@ -54,21 +58,23 @@ TEST(DiskTest, Rezero)
|
||||
|
||||
disk->SetReady(true);
|
||||
|
||||
EXPECT_CALL(controller, Status);
|
||||
EXPECT_CALL(*controller, Status);
|
||||
disk->Dispatch(scsi_command::eCmdRezero);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
}
|
||||
|
||||
TEST(DiskTest, FormatUnit)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
const unordered_map<string, string> params;
|
||||
disk->Init(params);
|
||||
|
||||
controller.AddDevice(disk);
|
||||
controller->AddDevice(disk);
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
auto& cmd = controller->GetCmd();
|
||||
|
||||
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdFormatUnit); }, Throws<scsi_exception>(AllOf(
|
||||
Property(&scsi_exception::get_sense_key, sense_key::NOT_READY),
|
||||
@ -77,9 +83,9 @@ TEST(DiskTest, FormatUnit)
|
||||
|
||||
disk->SetReady(true);
|
||||
|
||||
EXPECT_CALL(controller, Status);
|
||||
EXPECT_CALL(*controller, Status);
|
||||
disk->Dispatch(scsi_command::eCmdFormatUnit);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
|
||||
cmd[1] = 0x10;
|
||||
cmd[4] = 1;
|
||||
@ -90,12 +96,14 @@ TEST(DiskTest, FormatUnit)
|
||||
|
||||
TEST(DiskTest, ReassignBlocks)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
const unordered_map<string, string> params;
|
||||
disk->Init(params);
|
||||
|
||||
controller.AddDevice(disk);
|
||||
controller->AddDevice(disk);
|
||||
|
||||
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdReassignBlocks); }, Throws<scsi_exception>(AllOf(
|
||||
Property(&scsi_exception::get_sense_key, sense_key::NOT_READY),
|
||||
@ -104,21 +112,23 @@ TEST(DiskTest, ReassignBlocks)
|
||||
|
||||
disk->SetReady(true);
|
||||
|
||||
EXPECT_CALL(controller, Status);
|
||||
EXPECT_CALL(*controller, Status);
|
||||
disk->Dispatch(scsi_command::eCmdReassignBlocks);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
}
|
||||
|
||||
TEST(DiskTest, Seek6)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
const unordered_map<string, string> params;
|
||||
disk->Init(params);
|
||||
|
||||
controller.AddDevice(disk);
|
||||
controller->AddDevice(disk);
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
auto& cmd = controller->GetCmd();
|
||||
|
||||
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdSeek6); }, Throws<scsi_exception>(AllOf(
|
||||
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
|
||||
@ -135,21 +145,23 @@ TEST(DiskTest, Seek6)
|
||||
|
||||
disk->SetReady(true);
|
||||
|
||||
EXPECT_CALL(controller, Status);
|
||||
EXPECT_CALL(*controller, Status);
|
||||
disk->Dispatch(scsi_command::eCmdSeek6);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
}
|
||||
|
||||
TEST(DiskTest, Seek10)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
const unordered_map<string, string> params;
|
||||
disk->Init(params);
|
||||
|
||||
controller.AddDevice(disk);
|
||||
controller->AddDevice(disk);
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
auto& cmd = controller->GetCmd();
|
||||
|
||||
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdSeek10); }, Throws<scsi_exception>(AllOf(
|
||||
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
|
||||
@ -166,19 +178,21 @@ TEST(DiskTest, Seek10)
|
||||
|
||||
disk->SetReady(true);
|
||||
|
||||
EXPECT_CALL(controller, Status);
|
||||
EXPECT_CALL(*controller, Status);
|
||||
disk->Dispatch(scsi_command::eCmdSeek10);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
}
|
||||
|
||||
TEST(DiskTest, ReadCapacity10)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
const unordered_map<string, string> params;
|
||||
disk->Init(params);
|
||||
|
||||
controller.AddDevice(disk);
|
||||
controller->AddDevice(disk);
|
||||
|
||||
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdReadCapacity10); }, Throws<scsi_exception>(AllOf(
|
||||
Property(&scsi_exception::get_sense_key, sense_key::NOT_READY),
|
||||
@ -192,30 +206,32 @@ TEST(DiskTest, ReadCapacity10)
|
||||
<< "READ CAPACITY(10) must fail because the medium has no capacity";
|
||||
|
||||
disk->SetBlockCount(0x12345678);
|
||||
EXPECT_CALL(controller, DataIn);
|
||||
EXPECT_CALL(*controller, DataIn);
|
||||
disk->Dispatch(scsi_command::eCmdReadCapacity10);
|
||||
auto& buf = controller.GetBuffer();
|
||||
auto& buf = controller->GetBuffer();
|
||||
EXPECT_EQ(0x1234, GetInt16(buf, 0));
|
||||
EXPECT_EQ(0x5677, GetInt16(buf, 2));
|
||||
|
||||
disk->SetBlockCount(0x1234567887654321);
|
||||
EXPECT_CALL(controller, DataIn);
|
||||
EXPECT_CALL(*controller, DataIn);
|
||||
disk->Dispatch(scsi_command::eCmdReadCapacity10);
|
||||
buf = controller.GetBuffer();
|
||||
buf = controller->GetBuffer();
|
||||
EXPECT_EQ(0xffff, GetInt16(buf, 0));
|
||||
EXPECT_EQ(0xffff, GetInt16(buf, 2));
|
||||
}
|
||||
|
||||
TEST(DiskTest, ReadCapacity16)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
const unordered_map<string, string> params;
|
||||
disk->Init(params);
|
||||
|
||||
controller.AddDevice(disk);
|
||||
controller->AddDevice(disk);
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
auto& cmd = controller->GetCmd();
|
||||
|
||||
cmd[1] = 0x00;
|
||||
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdReadCapacity16_ReadLong16); }, Throws<scsi_exception>(AllOf(
|
||||
@ -238,9 +254,9 @@ TEST(DiskTest, ReadCapacity16)
|
||||
|
||||
disk->SetBlockCount(0x1234567887654321);
|
||||
disk->SetSectorSizeInBytes(1024);
|
||||
EXPECT_CALL(controller, DataIn);
|
||||
EXPECT_CALL(*controller, DataIn);
|
||||
disk->Dispatch(scsi_command::eCmdReadCapacity16_ReadLong16);
|
||||
const auto& buf = controller.GetBuffer();
|
||||
const auto& buf = controller->GetBuffer();
|
||||
EXPECT_EQ(0x1234, GetInt16(buf, 0));
|
||||
EXPECT_EQ(0x5678, GetInt16(buf, 2));
|
||||
EXPECT_EQ(0x8765, GetInt16(buf, 4));
|
||||
@ -251,12 +267,14 @@ TEST(DiskTest, ReadCapacity16)
|
||||
|
||||
TEST(DiskTest, Read6)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
const unordered_map<string, string> params;
|
||||
disk->Init(params);
|
||||
|
||||
controller.AddDevice(disk);
|
||||
controller->AddDevice(disk);
|
||||
|
||||
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdRead6); }, Throws<scsi_exception>(AllOf(
|
||||
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
|
||||
@ -268,12 +286,14 @@ TEST(DiskTest, Read6)
|
||||
|
||||
TEST(DiskTest, Read10)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
const unordered_map<string, string> params;
|
||||
disk->Init(params);
|
||||
|
||||
controller.AddDevice(disk);
|
||||
controller->AddDevice(disk);
|
||||
|
||||
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdRead10); }, Throws<scsi_exception>(AllOf(
|
||||
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
|
||||
@ -281,21 +301,23 @@ TEST(DiskTest, Read10)
|
||||
<< "READ(10) must fail for a medium with 0 blocks";
|
||||
|
||||
disk->SetBlockCount(1);
|
||||
EXPECT_CALL(controller, Status);
|
||||
EXPECT_CALL(*controller, Status);
|
||||
disk->Dispatch(scsi_command::eCmdRead10);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
|
||||
// Further testing requires filesystem access
|
||||
}
|
||||
|
||||
TEST(DiskTest, Read16)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
const unordered_map<string, string> params;
|
||||
disk->Init(params);
|
||||
|
||||
controller.AddDevice(disk);
|
||||
controller->AddDevice(disk);
|
||||
|
||||
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdRead16); }, Throws<scsi_exception>(AllOf(
|
||||
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
|
||||
@ -303,21 +325,23 @@ TEST(DiskTest, Read16)
|
||||
<< "READ(16) must fail for a medium with 0 blocks";
|
||||
|
||||
disk->SetBlockCount(1);
|
||||
EXPECT_CALL(controller, Status);
|
||||
EXPECT_CALL(*controller, Status);
|
||||
disk->Dispatch(scsi_command::eCmdRead16);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
|
||||
// Further testing requires filesystem access
|
||||
}
|
||||
|
||||
TEST(DiskTest, Write6)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
const unordered_map<string, string> params;
|
||||
disk->Init(params);
|
||||
|
||||
controller.AddDevice(disk);
|
||||
controller->AddDevice(disk);
|
||||
|
||||
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdWrite6); }, Throws<scsi_exception>(AllOf(
|
||||
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
|
||||
@ -337,12 +361,14 @@ TEST(DiskTest, Write6)
|
||||
|
||||
TEST(DiskTest, Write10)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
const unordered_map<string, string> params;
|
||||
disk->Init(params);
|
||||
|
||||
controller.AddDevice(disk);
|
||||
controller->AddDevice(disk);
|
||||
|
||||
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdWrite10); }, Throws<scsi_exception>(AllOf(
|
||||
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
|
||||
@ -350,21 +376,23 @@ TEST(DiskTest, Write10)
|
||||
<< "WRITE(10) must fail for a medium with 0 blocks";
|
||||
|
||||
disk->SetBlockCount(1);
|
||||
EXPECT_CALL(controller, Status);
|
||||
EXPECT_CALL(*controller, Status);
|
||||
disk->Dispatch(scsi_command::eCmdWrite10);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
|
||||
// Further testing requires filesystem access
|
||||
}
|
||||
|
||||
TEST(DiskTest, Write16)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
const unordered_map<string, string> params;
|
||||
disk->Init(params);
|
||||
|
||||
controller.AddDevice(disk);
|
||||
controller->AddDevice(disk);
|
||||
|
||||
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdWrite16); }, Throws<scsi_exception>(AllOf(
|
||||
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
|
||||
@ -372,21 +400,23 @@ TEST(DiskTest, Write16)
|
||||
<< "WRITE(16) must fail for a medium with 0 blocks";
|
||||
|
||||
disk->SetBlockCount(1);
|
||||
EXPECT_CALL(controller, Status);
|
||||
EXPECT_CALL(*controller, Status);
|
||||
disk->Dispatch(scsi_command::eCmdWrite16);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
|
||||
// Further testing requires filesystem access
|
||||
}
|
||||
|
||||
TEST(DiskTest, Verify10)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
const unordered_map<string, string> params;
|
||||
disk->Init(params);
|
||||
|
||||
controller.AddDevice(disk);
|
||||
controller->AddDevice(disk);
|
||||
|
||||
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdVerify10); }, Throws<scsi_exception>(AllOf(
|
||||
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
|
||||
@ -394,21 +424,23 @@ TEST(DiskTest, Verify10)
|
||||
<< "VERIFY(10) must fail for a medium with 0 blocks";
|
||||
|
||||
disk->SetBlockCount(1);
|
||||
EXPECT_CALL(controller, Status);
|
||||
EXPECT_CALL(*controller, Status);
|
||||
disk->Dispatch(scsi_command::eCmdVerify10);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
|
||||
// Further testing requires filesystem access
|
||||
}
|
||||
|
||||
TEST(DiskTest, Verify16)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
const unordered_map<string, string> params;
|
||||
disk->Init(params);
|
||||
|
||||
controller.AddDevice(disk);
|
||||
controller->AddDevice(disk);
|
||||
|
||||
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdVerify16); }, Throws<scsi_exception>(AllOf(
|
||||
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
|
||||
@ -416,27 +448,29 @@ TEST(DiskTest, Verify16)
|
||||
<< "VERIFY(16) must fail for a medium with 0 blocks";
|
||||
|
||||
disk->SetBlockCount(1);
|
||||
EXPECT_CALL(controller, Status);
|
||||
EXPECT_CALL(*controller, Status);
|
||||
disk->Dispatch(scsi_command::eCmdVerify16);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
|
||||
// Further testing requires filesystem access
|
||||
}
|
||||
|
||||
TEST(DiskTest, ReadLong10)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
const unordered_map<string, string> params;
|
||||
disk->Init(params);
|
||||
|
||||
controller.AddDevice(disk);
|
||||
controller->AddDevice(disk);
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
auto& cmd = controller->GetCmd();
|
||||
|
||||
EXPECT_CALL(controller, Status);
|
||||
EXPECT_CALL(*controller, Status);
|
||||
disk->Dispatch(scsi_command::eCmdReadLong10);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
|
||||
cmd[2] = 1;
|
||||
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdReadLong10); }, Throws<scsi_exception>(AllOf(
|
||||
@ -454,14 +488,16 @@ TEST(DiskTest, ReadLong10)
|
||||
|
||||
TEST(DiskTest, ReadLong16)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
const unordered_map<string, string> params;
|
||||
disk->Init(params);
|
||||
|
||||
controller.AddDevice(disk);
|
||||
controller->AddDevice(disk);
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
auto& cmd = controller->GetCmd();
|
||||
|
||||
// READ LONG(16), not READ CAPACITY(16)
|
||||
cmd[1] = 0x11;
|
||||
@ -472,9 +508,9 @@ TEST(DiskTest, ReadLong16)
|
||||
<< "READ LONG(16) must fail because the capacity is exceeded";
|
||||
cmd[2] = 0;
|
||||
|
||||
EXPECT_CALL(controller, Status);
|
||||
EXPECT_CALL(*controller, Status);
|
||||
disk->Dispatch(scsi_command::eCmdReadCapacity16_ReadLong16);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
|
||||
cmd[13] = 1;
|
||||
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdReadCapacity16_ReadLong16); }, Throws<scsi_exception>(AllOf(
|
||||
@ -485,18 +521,20 @@ TEST(DiskTest, ReadLong16)
|
||||
|
||||
TEST(DiskTest, WriteLong10)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
const unordered_map<string, string> params;
|
||||
disk->Init(params);
|
||||
|
||||
controller.AddDevice(disk);
|
||||
controller->AddDevice(disk);
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
auto& cmd = controller->GetCmd();
|
||||
|
||||
EXPECT_CALL(controller, Status);
|
||||
EXPECT_CALL(*controller, Status);
|
||||
disk->Dispatch(scsi_command::eCmdWriteLong10);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
|
||||
cmd[2] = 1;
|
||||
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdWriteLong10); }, Throws<scsi_exception>(AllOf(
|
||||
@ -514,14 +552,16 @@ TEST(DiskTest, WriteLong10)
|
||||
|
||||
TEST(DiskTest, WriteLong16)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
const unordered_map<string, string> params;
|
||||
disk->Init(params);
|
||||
|
||||
controller.AddDevice(disk);
|
||||
controller->AddDevice(disk);
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
auto& cmd = controller->GetCmd();
|
||||
|
||||
cmd[2] = 1;
|
||||
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdWriteLong16); }, Throws<scsi_exception>(AllOf(
|
||||
@ -530,9 +570,9 @@ TEST(DiskTest, WriteLong16)
|
||||
<< "WRITE LONG(16) must fail because the capacity is exceeded";
|
||||
cmd[2] = 0;
|
||||
|
||||
EXPECT_CALL(controller, Status);
|
||||
EXPECT_CALL(*controller, Status);
|
||||
disk->Dispatch(scsi_command::eCmdWriteLong16);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
|
||||
cmd[13] = 1;
|
||||
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdWriteLong16); }, Throws<scsi_exception>(AllOf(
|
||||
@ -543,33 +583,35 @@ TEST(DiskTest, WriteLong16)
|
||||
|
||||
TEST(DiskTest, StartStopUnit)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
const unordered_map<string, string> params;
|
||||
disk->Init(params);
|
||||
|
||||
disk->SetRemovable(true);
|
||||
|
||||
controller.AddDevice(disk);
|
||||
controller->AddDevice(disk);
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
auto& cmd = controller->GetCmd();
|
||||
|
||||
// Stop/Unload
|
||||
disk->SetReady(true);
|
||||
EXPECT_CALL(controller, Status);
|
||||
EXPECT_CALL(*controller, Status);
|
||||
EXPECT_CALL(*disk, FlushCache);
|
||||
disk->Dispatch(scsi_command::eCmdStartStop);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
EXPECT_TRUE(disk->IsStopped());
|
||||
|
||||
// Stop/Load
|
||||
cmd[4] = 0x02;
|
||||
disk->SetReady(true);
|
||||
disk->SetLocked(false);
|
||||
EXPECT_CALL(controller, Status);
|
||||
EXPECT_CALL(*controller, Status);
|
||||
EXPECT_CALL(*disk, FlushCache);
|
||||
disk->Dispatch(scsi_command::eCmdStartStop);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
|
||||
disk->SetReady(false);
|
||||
EXPECT_CALL(*disk, FlushCache).Times(0);
|
||||
@ -586,28 +628,30 @@ TEST(DiskTest, StartStopUnit)
|
||||
|
||||
// Start/Unload
|
||||
cmd[4] = 0x01;
|
||||
EXPECT_CALL(controller, Status);
|
||||
EXPECT_CALL(*controller, Status);
|
||||
disk->Dispatch(scsi_command::eCmdStartStop);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
EXPECT_FALSE(disk->IsStopped());
|
||||
|
||||
// Start/Load
|
||||
cmd[4] = 0x03;
|
||||
EXPECT_CALL(controller, Status);
|
||||
EXPECT_CALL(*controller, Status);
|
||||
disk->Dispatch(scsi_command::eCmdStartStop);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
}
|
||||
|
||||
TEST(DiskTest, PreventAllowMediumRemoval)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
const unordered_map<string, string> params;
|
||||
disk->Init(params);
|
||||
|
||||
controller.AddDevice(disk);
|
||||
controller->AddDevice(disk);
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
auto& cmd = controller->GetCmd();
|
||||
|
||||
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdPreventAllowMediumRemoval); }, Throws<scsi_exception>(AllOf(
|
||||
Property(&scsi_exception::get_sense_key, sense_key::NOT_READY),
|
||||
@ -616,15 +660,15 @@ TEST(DiskTest, PreventAllowMediumRemoval)
|
||||
|
||||
disk->SetReady(true);
|
||||
|
||||
EXPECT_CALL(controller, Status);
|
||||
EXPECT_CALL(*controller, Status);
|
||||
disk->Dispatch(scsi_command::eCmdPreventAllowMediumRemoval);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
EXPECT_FALSE(disk->IsLocked());
|
||||
|
||||
cmd[4] = 1;
|
||||
EXPECT_CALL(controller, Status);
|
||||
EXPECT_CALL(*controller, Status);
|
||||
disk->Dispatch(scsi_command::eCmdPreventAllowMediumRemoval);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
EXPECT_TRUE(disk->IsLocked());
|
||||
}
|
||||
|
||||
@ -657,9 +701,9 @@ TEST(DiskTest, Eject)
|
||||
EXPECT_TRUE(disk.Eject(true));
|
||||
}
|
||||
|
||||
void DiskTest_ValidateFormatPage(AbstractController& controller, int offset)
|
||||
void DiskTest_ValidateFormatPage(shared_ptr<AbstractController> controller, int offset)
|
||||
{
|
||||
const auto& buf = controller.GetBuffer();
|
||||
const auto& buf = controller->GetBuffer();
|
||||
EXPECT_EQ(0x08, buf[offset + 3]) << "Wrong number of trackes in one zone";
|
||||
EXPECT_EQ(25, GetInt16(buf, offset + 10)) << "Wrong number of sectors per track";
|
||||
EXPECT_EQ(1024, GetInt16(buf, offset + 12)) << "Wrong number of bytes per sector";
|
||||
@ -670,18 +714,18 @@ void DiskTest_ValidateFormatPage(AbstractController& controller, int offset)
|
||||
EXPECT_TRUE(buf[offset + 20] & 0x40) << "Wrong hard-sectored flag";
|
||||
}
|
||||
|
||||
void DiskTest_ValidateDrivePage(AbstractController& controller, int offset)
|
||||
void DiskTest_ValidateDrivePage(shared_ptr<AbstractController> controller, int offset)
|
||||
{
|
||||
const auto& buf = controller.GetBuffer();
|
||||
const auto& buf = controller->GetBuffer();
|
||||
EXPECT_EQ(0x17, buf[offset + 2]);
|
||||
EXPECT_EQ(0x4d3b, GetInt16(buf, offset + 3));
|
||||
EXPECT_EQ(8, buf[offset + 5]) << "Wrong number of heads";
|
||||
EXPECT_EQ(7200, GetInt16(buf, offset + 20)) << "Wrong medium rotation rate";
|
||||
}
|
||||
|
||||
void DiskTest_ValidateCachePage(AbstractController& controller, int offset)
|
||||
void DiskTest_ValidateCachePage(shared_ptr<AbstractController> controller, int offset)
|
||||
{
|
||||
const auto& buf = controller.GetBuffer();
|
||||
const auto& buf = controller->GetBuffer();
|
||||
EXPECT_EQ(0xffff, GetInt16(buf, offset + 4)) << "Wrong pre-fetch transfer length";
|
||||
EXPECT_EQ(0xffff, GetInt16(buf, offset + 8)) << "Wrong maximum pre-fetch";
|
||||
EXPECT_EQ(0xffff, GetInt16(buf, offset + 10)) << "Wrong maximum pre-fetch ceiling";
|
||||
@ -689,14 +733,16 @@ void DiskTest_ValidateCachePage(AbstractController& controller, int offset)
|
||||
|
||||
TEST(DiskTest, ModeSense6)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<NiceMock<MockAbstractController>>(controller_manager, 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
const unordered_map<string, string> params;
|
||||
disk->Init(params);
|
||||
|
||||
controller.AddDevice(disk);
|
||||
controller->AddDevice(disk);
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
auto& cmd = controller->GetCmd();
|
||||
|
||||
// Drive must be ready on order to return all data
|
||||
disk->SetReady(true);
|
||||
@ -705,18 +751,18 @@ TEST(DiskTest, ModeSense6)
|
||||
// ALLOCATION LENGTH
|
||||
cmd[4] = 255;
|
||||
disk->Dispatch(scsi_command::eCmdModeSense6);
|
||||
EXPECT_EQ(0x08, controller.GetBuffer()[3]) << "Wrong block descriptor length";
|
||||
EXPECT_EQ(0x08, controller->GetBuffer()[3]) << "Wrong block descriptor length";
|
||||
|
||||
// No block descriptor
|
||||
cmd[1] = 0x08;
|
||||
disk->Dispatch(scsi_command::eCmdModeSense6);
|
||||
EXPECT_EQ(0x00, controller.GetBuffer()[2]) << "Wrong device-specific parameter";
|
||||
EXPECT_EQ(0x00, controller->GetBuffer()[2]) << "Wrong device-specific parameter";
|
||||
|
||||
disk->SetReadOnly(false);
|
||||
disk->SetProtectable(true);
|
||||
disk->SetProtected(true);
|
||||
disk->Dispatch(scsi_command::eCmdModeSense6);
|
||||
const auto& buf = controller.GetBuffer();
|
||||
const auto& buf = controller->GetBuffer();
|
||||
EXPECT_EQ(0x80, buf[2]) << "Wrong device-specific parameter";
|
||||
|
||||
// Return block descriptor
|
||||
@ -742,14 +788,16 @@ TEST(DiskTest, ModeSense6)
|
||||
|
||||
TEST(DiskTest, ModeSense10)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<NiceMock<MockAbstractController>>(controller_manager, 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
const unordered_map<string, string> params;
|
||||
disk->Init(params);
|
||||
|
||||
controller.AddDevice(disk);
|
||||
controller->AddDevice(disk);
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
auto& cmd = controller->GetCmd();
|
||||
|
||||
// Drive must be ready on order to return all data
|
||||
disk->SetReady(true);
|
||||
@ -758,19 +806,19 @@ TEST(DiskTest, ModeSense10)
|
||||
// ALLOCATION LENGTH
|
||||
cmd[8] = 255;
|
||||
disk->Dispatch(scsi_command::eCmdModeSense10);
|
||||
EXPECT_EQ(0x08, controller.GetBuffer()[7]) << "Wrong block descriptor length";
|
||||
EXPECT_EQ(0x08, controller->GetBuffer()[7]) << "Wrong block descriptor length";
|
||||
|
||||
// No block descriptor
|
||||
cmd[1] = 0x08;
|
||||
disk->Dispatch(scsi_command::eCmdModeSense10);
|
||||
auto& buf = controller.GetBuffer();
|
||||
EXPECT_EQ(0x00, controller.GetBuffer()[3]) << "Wrong device-specific parameter";
|
||||
auto& buf = controller->GetBuffer();
|
||||
EXPECT_EQ(0x00, controller->GetBuffer()[3]) << "Wrong device-specific parameter";
|
||||
|
||||
disk->SetReadOnly(false);
|
||||
disk->SetProtectable(true);
|
||||
disk->SetProtected(true);
|
||||
disk->Dispatch(scsi_command::eCmdModeSense10);
|
||||
buf = controller.GetBuffer();
|
||||
buf = controller->GetBuffer();
|
||||
EXPECT_EQ(0x80, buf[3]) << "Wrong device-specific parameter";
|
||||
|
||||
// Return short block descriptor
|
||||
@ -778,7 +826,7 @@ TEST(DiskTest, ModeSense10)
|
||||
disk->SetBlockCount(0x1234);
|
||||
disk->SetSectorSizeInBytes(1024);
|
||||
disk->Dispatch(scsi_command::eCmdModeSense10);
|
||||
buf = controller.GetBuffer();
|
||||
buf = controller->GetBuffer();
|
||||
EXPECT_EQ(0x00, buf[4]) << "Wrong LONGLBA field";
|
||||
EXPECT_EQ(0x08, buf[7]) << "Wrong block descriptor length";
|
||||
EXPECT_EQ(0x00, GetInt16(buf, 8));
|
||||
@ -790,7 +838,7 @@ TEST(DiskTest, ModeSense10)
|
||||
cmd[1] = 0x10;
|
||||
disk->SetBlockCount((uint64_t)0xffffffff + 1);
|
||||
disk->Dispatch(scsi_command::eCmdModeSense10);
|
||||
buf = controller.GetBuffer();
|
||||
buf = controller->GetBuffer();
|
||||
EXPECT_EQ(0x01, buf[4]) << "Wrong LONGLBA field";
|
||||
EXPECT_EQ(0x10, buf[7]) << "Wrong block descriptor length";
|
||||
EXPECT_EQ(0x00, GetInt16(buf, 8));
|
||||
@ -821,36 +869,40 @@ TEST(DiskTest, ModeSense10)
|
||||
|
||||
TEST(DiskTest, SynchronizeCache)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
const unordered_map<string, string> params;
|
||||
disk->Init(params);
|
||||
|
||||
controller.AddDevice(disk);
|
||||
controller->AddDevice(disk);
|
||||
|
||||
EXPECT_CALL(*disk, FlushCache);
|
||||
EXPECT_CALL(controller, Status);
|
||||
EXPECT_CALL(*controller, Status);
|
||||
disk->Dispatch(scsi_command::eCmdSynchronizeCache10);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
|
||||
EXPECT_CALL(*disk, FlushCache);
|
||||
EXPECT_CALL(controller, Status);
|
||||
EXPECT_CALL(*controller, Status);
|
||||
disk->Dispatch(scsi_command::eCmdSynchronizeCache16);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
}
|
||||
|
||||
TEST(DiskTest, ReadDefectData)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
const unordered_map<string, string> params;
|
||||
disk->Init(params);
|
||||
|
||||
controller.AddDevice(disk);
|
||||
controller->AddDevice(disk);
|
||||
|
||||
EXPECT_CALL(controller, DataIn);
|
||||
EXPECT_CALL(*controller, DataIn);
|
||||
disk->Dispatch(scsi_command::eCmdReadDefectData10);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
}
|
||||
|
||||
TEST(DiskTest, SectorSize)
|
||||
|
@ -22,12 +22,14 @@ void HostServices_SetUpModePages(map<int, vector<byte>>& pages)
|
||||
|
||||
TEST(HostServicesTest, TestUnitReady)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto services = CreateDevice(SCHS, controller);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto services = CreateDevice(SCHS, *controller);
|
||||
|
||||
EXPECT_CALL(controller, Status());
|
||||
EXPECT_CALL(*controller, Status());
|
||||
services->Dispatch(scsi_command::eCmdTestUnitReady);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
}
|
||||
|
||||
TEST(HostServicesTest, Inquiry)
|
||||
@ -37,30 +39,32 @@ TEST(HostServicesTest, Inquiry)
|
||||
|
||||
TEST(HostServicesTest, StartStopUnit)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto services = CreateDevice(SCHS, controller);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto services = CreateDevice(SCHS, *controller);
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
auto& cmd = controller->GetCmd();
|
||||
|
||||
// STOP
|
||||
EXPECT_CALL(controller, ScheduleShutdown(AbstractController::rascsi_shutdown_mode::STOP_RASCSI));
|
||||
EXPECT_CALL(controller, Status());
|
||||
EXPECT_CALL(*controller, ScheduleShutdown(AbstractController::rascsi_shutdown_mode::STOP_RASCSI));
|
||||
EXPECT_CALL(*controller, Status());
|
||||
services->Dispatch(scsi_command::eCmdStartStop);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
|
||||
// LOAD
|
||||
cmd[4] = 0x02;
|
||||
EXPECT_CALL(controller, ScheduleShutdown(AbstractController::rascsi_shutdown_mode::STOP_PI));
|
||||
EXPECT_CALL(controller, Status());
|
||||
EXPECT_CALL(*controller, ScheduleShutdown(AbstractController::rascsi_shutdown_mode::STOP_PI));
|
||||
EXPECT_CALL(*controller, Status());
|
||||
services->Dispatch(scsi_command::eCmdStartStop);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
|
||||
// UNLOAD
|
||||
cmd[4] = 0x03;
|
||||
EXPECT_CALL(controller, ScheduleShutdown(AbstractController::rascsi_shutdown_mode::RESTART_PI));
|
||||
EXPECT_CALL(controller, Status());
|
||||
EXPECT_CALL(*controller, ScheduleShutdown(AbstractController::rascsi_shutdown_mode::RESTART_PI));
|
||||
EXPECT_CALL(*controller, Status());
|
||||
services->Dispatch(scsi_command::eCmdStartStop);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
|
||||
// START
|
||||
cmd[4] = 0x01;
|
||||
@ -71,12 +75,14 @@ TEST(HostServicesTest, StartStopUnit)
|
||||
|
||||
TEST(HostServicesTest, ModeSense6)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto services = CreateDevice(SCHS, controller);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto services = CreateDevice(SCHS, *controller);
|
||||
const unordered_map<string, string> params;
|
||||
services->Init(params);
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
auto& cmd = controller->GetCmd();
|
||||
|
||||
EXPECT_THAT([&] { services->Dispatch(scsi_command::eCmdModeSense6); }, Throws<scsi_exception>(AllOf(
|
||||
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
|
||||
@ -92,9 +98,9 @@ TEST(HostServicesTest, ModeSense6)
|
||||
cmd[1] = 0x08;
|
||||
// ALLOCATION LENGTH
|
||||
cmd[4] = 255;
|
||||
EXPECT_CALL(controller, DataIn());
|
||||
EXPECT_CALL(*controller, DataIn());
|
||||
services->Dispatch(scsi_command::eCmdModeSense6);
|
||||
vector<uint8_t>& buffer = controller.GetBuffer();
|
||||
vector<uint8_t>& buffer = controller->GetBuffer();
|
||||
// Major version 1
|
||||
EXPECT_EQ(0x01, buffer[6]);
|
||||
// Minor version 0
|
||||
@ -106,20 +112,22 @@ TEST(HostServicesTest, ModeSense6)
|
||||
|
||||
// ALLOCATION LENGTH
|
||||
cmd[4] = 2;
|
||||
EXPECT_CALL(controller, DataIn());
|
||||
EXPECT_CALL(*controller, DataIn());
|
||||
services->Dispatch(scsi_command::eCmdModeSense6);
|
||||
buffer = controller.GetBuffer();
|
||||
buffer = controller->GetBuffer();
|
||||
EXPECT_EQ(0x02, buffer[0]);
|
||||
}
|
||||
|
||||
TEST(HostServicesTest, ModeSense10)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto services = CreateDevice(SCHS, controller);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto services = CreateDevice(SCHS, *controller);
|
||||
const unordered_map<string, string> params;
|
||||
services->Init(params);
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
auto& cmd = controller->GetCmd();
|
||||
|
||||
EXPECT_THAT([&] { services->Dispatch(scsi_command::eCmdModeSense10); }, Throws<scsi_exception>(AllOf(
|
||||
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
|
||||
@ -135,9 +143,9 @@ TEST(HostServicesTest, ModeSense10)
|
||||
cmd[1] = 0x08;
|
||||
// ALLOCATION LENGTH
|
||||
cmd[8] = 255;
|
||||
EXPECT_CALL(controller, DataIn());
|
||||
EXPECT_CALL(*controller, DataIn());
|
||||
services->Dispatch(scsi_command::eCmdModeSense10);
|
||||
vector<uint8_t>& buffer = controller.GetBuffer();
|
||||
vector<uint8_t>& buffer = controller->GetBuffer();
|
||||
// Major version 1
|
||||
EXPECT_EQ(0x01, buffer[10]);
|
||||
// Minor version 0
|
||||
@ -149,16 +157,15 @@ TEST(HostServicesTest, ModeSense10)
|
||||
|
||||
// ALLOCATION LENGTH
|
||||
cmd[8] = 2;
|
||||
EXPECT_CALL(controller, DataIn());
|
||||
EXPECT_CALL(*controller, DataIn());
|
||||
services->Dispatch(scsi_command::eCmdModeSense10);
|
||||
buffer = controller.GetBuffer();
|
||||
buffer = controller->GetBuffer();
|
||||
EXPECT_EQ(0x02, buffer[1]);
|
||||
}
|
||||
|
||||
TEST(HostServicesTest, SetUpModePages)
|
||||
{
|
||||
ControllerManager controller_manager(make_shared<MockBus>());
|
||||
MockHostServices services(0, controller_manager);
|
||||
MockHostServices services(0);
|
||||
map<int, vector<byte>> pages;
|
||||
|
||||
// Non changeable
|
||||
|
@ -103,6 +103,7 @@ class MockAbstractController : public AbstractController //NOSONAR Having many f
|
||||
FRIEND_TEST(AbstractControllerTest, Length);
|
||||
FRIEND_TEST(AbstractControllerTest, UpdateOffsetAndLength);
|
||||
FRIEND_TEST(AbstractControllerTest, Offset);
|
||||
FRIEND_TEST(ScsiControllerTest, Selection);
|
||||
FRIEND_TEST(PrimaryDeviceTest, Inquiry);
|
||||
FRIEND_TEST(PrimaryDeviceTest, TestUnitReady);
|
||||
FRIEND_TEST(PrimaryDeviceTest, RequestSense);
|
||||
@ -153,14 +154,15 @@ public:
|
||||
MOCK_METHOD(void, MsgOut, (), ());
|
||||
MOCK_METHOD(void, ScheduleShutdown, (rascsi_shutdown_mode), (override));
|
||||
|
||||
explicit MockAbstractController(shared_ptr<MockBus> bus, int target_id) : AbstractController(bus, target_id, 32) {
|
||||
explicit MockAbstractController(shared_ptr<ControllerManager> controller_manager, int target_id)
|
||||
: AbstractController(controller_manager, target_id, 32) {
|
||||
AllocateBuffer(512);
|
||||
}
|
||||
~MockAbstractController() override = default;
|
||||
|
||||
// Permit access to all tests without the need for numerous FRIEND_TEST
|
||||
vector<int>& GetCmd() { return AbstractController::GetCmd(); } //NOSONAR Hides function on purpose
|
||||
shared_ptr<BUS> GetBus() { return AbstractController::GetBus(); } //NOSONAR Hides function on purpose
|
||||
BUS& GetBus() { return AbstractController::GetBus(); } //NOSONAR Hides function on purpose
|
||||
};
|
||||
|
||||
class MockScsiController : public ScsiController
|
||||
@ -184,9 +186,10 @@ public:
|
||||
MOCK_METHOD(void, Execute, (), ());
|
||||
|
||||
using ScsiController::ScsiController;
|
||||
explicit MockScsiController(shared_ptr<NiceMock<MockBus>> bus, int target_id) : ScsiController(bus, target_id) {}
|
||||
explicit MockScsiController(shared_ptr<MockBus> bus, int target_id) : ScsiController(bus, target_id) {}
|
||||
explicit MockScsiController(shared_ptr<MockBus> bus) : ScsiController(bus, 0) {}
|
||||
MockScsiController(shared_ptr<ControllerManager> controller_manager, int target_id)
|
||||
: ScsiController(controller_manager, target_id) {}
|
||||
explicit MockScsiController(shared_ptr<ControllerManager> controller_manager)
|
||||
: ScsiController(controller_manager, 0) {}
|
||||
~MockScsiController() override = default;
|
||||
|
||||
};
|
||||
|
@ -80,27 +80,31 @@ TEST(ModePageDeviceTest, AddVendorPage)
|
||||
|
||||
TEST(ModePageDeviceTest, ModeSense6)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto device = make_shared<NiceMock<MockModePageDevice>>();
|
||||
const unordered_map<string, string> params;
|
||||
device->Init(params);
|
||||
|
||||
controller.AddDevice(device);
|
||||
controller->AddDevice(device);
|
||||
|
||||
EXPECT_CALL(controller, DataIn());
|
||||
EXPECT_CALL(*controller, DataIn());
|
||||
device->Dispatch(scsi_command::eCmdModeSense6);
|
||||
}
|
||||
|
||||
TEST(ModePageDeviceTest, ModeSense10)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto device = make_shared<NiceMock<MockModePageDevice>>();
|
||||
const unordered_map<string, string> params;
|
||||
device->Init(params);
|
||||
|
||||
controller.AddDevice(device);
|
||||
controller->AddDevice(device);
|
||||
|
||||
EXPECT_CALL(controller, DataIn());
|
||||
EXPECT_CALL(*controller, DataIn());
|
||||
device->Dispatch(scsi_command::eCmdModeSense10);
|
||||
}
|
||||
|
||||
@ -122,16 +126,18 @@ TEST(ModePageDeviceTest, ModeSelect)
|
||||
|
||||
TEST(ModePageDeviceTest, ModeSelect6)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto device = make_shared<MockModePageDevice>();
|
||||
const unordered_map<string, string> params;
|
||||
device->Init(params);
|
||||
|
||||
controller.AddDevice(device);
|
||||
controller->AddDevice(device);
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
auto& cmd = controller->GetCmd();
|
||||
|
||||
EXPECT_CALL(controller, DataOut());
|
||||
EXPECT_CALL(*controller, DataOut());
|
||||
device->Dispatch(scsi_command::eCmdModeSelect6);
|
||||
|
||||
cmd[1] = 0x01;
|
||||
@ -143,16 +149,18 @@ TEST(ModePageDeviceTest, ModeSelect6)
|
||||
|
||||
TEST(ModePageDeviceTest, ModeSelect10)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto device = make_shared<MockModePageDevice>();
|
||||
const unordered_map<string, string> params;
|
||||
device->Init(params);
|
||||
|
||||
controller.AddDevice(device);
|
||||
controller->AddDevice(device);
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
auto& cmd = controller->GetCmd();
|
||||
|
||||
EXPECT_CALL(controller, DataOut());
|
||||
EXPECT_CALL(*controller, DataOut());
|
||||
device->Dispatch(scsi_command::eCmdModeSelect10);
|
||||
|
||||
cmd[1] = 0x01;
|
||||
|
@ -21,44 +21,50 @@ TEST(PrimaryDeviceTest, GetId)
|
||||
{
|
||||
const int ID = 5;
|
||||
|
||||
MockAbstractController controller(make_shared<MockBus>(), ID);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<NiceMock<MockAbstractController>>(controller_manager, ID);
|
||||
auto device = make_shared<MockPrimaryDevice>(0);
|
||||
const unordered_map<string, string> params;
|
||||
device->Init(params);
|
||||
|
||||
EXPECT_EQ(-1, device->GetId()) << "Device ID cannot be known without assignment to a controller";
|
||||
|
||||
controller.AddDevice(device);
|
||||
controller->AddDevice(device);
|
||||
EXPECT_EQ(ID, device->GetId());
|
||||
}
|
||||
|
||||
TEST(PrimaryDeviceTest, PhaseChange)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto device = make_shared<MockPrimaryDevice>(0);
|
||||
const unordered_map<string, string> params;
|
||||
device->Init(params);
|
||||
|
||||
controller.AddDevice(device);
|
||||
controller->AddDevice(device);
|
||||
|
||||
EXPECT_CALL(controller, Status);
|
||||
EXPECT_CALL(*controller, Status);
|
||||
device->EnterStatusPhase();
|
||||
|
||||
EXPECT_CALL(controller, DataIn);
|
||||
EXPECT_CALL(*controller, DataIn);
|
||||
device->EnterDataInPhase();
|
||||
|
||||
EXPECT_CALL(controller, DataOut);
|
||||
EXPECT_CALL(*controller, DataOut);
|
||||
device->EnterDataOutPhase();
|
||||
}
|
||||
|
||||
TEST(PrimaryDeviceTest, Reset)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<NiceMock<MockAbstractController>>(controller_manager, 0);
|
||||
auto device = make_shared<MockPrimaryDevice>(0);
|
||||
const unordered_map<string, string> params;
|
||||
device->Init(params);
|
||||
|
||||
controller.AddDevice(device);
|
||||
controller->AddDevice(device);
|
||||
|
||||
device->Dispatch(scsi_command::eCmdReserve6);
|
||||
EXPECT_FALSE(device->CheckReservation(1, scsi_command::eCmdTestUnitReady, false))
|
||||
@ -70,12 +76,14 @@ TEST(PrimaryDeviceTest, Reset)
|
||||
|
||||
TEST(PrimaryDeviceTest, CheckReservation)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<NiceMock<MockAbstractController>>(controller_manager, 0);
|
||||
auto device = make_shared<MockPrimaryDevice>(0);
|
||||
const unordered_map<string, string> params;
|
||||
device->Init(params);
|
||||
|
||||
controller.AddDevice(device);
|
||||
controller->AddDevice(device);
|
||||
|
||||
EXPECT_TRUE(device->CheckReservation(0, scsi_command::eCmdTestUnitReady, false))
|
||||
<< "Device must not be reserved for initiator ID 0";
|
||||
@ -102,12 +110,14 @@ TEST(PrimaryDeviceTest, CheckReservation)
|
||||
|
||||
TEST(PrimaryDeviceTest, ReserveReleaseUnit)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<NiceMock<MockAbstractController>>(controller_manager, 0);
|
||||
auto device = make_shared<MockPrimaryDevice>(0);
|
||||
const unordered_map<string, string> params;
|
||||
device->Init(params);
|
||||
|
||||
controller.AddDevice(device);
|
||||
controller->AddDevice(device);
|
||||
|
||||
device->Dispatch(scsi_command::eCmdReserve6);
|
||||
EXPECT_FALSE(device->CheckReservation(1, scsi_command::eCmdTestUnitReady, false))
|
||||
@ -117,7 +127,7 @@ TEST(PrimaryDeviceTest, ReserveReleaseUnit)
|
||||
EXPECT_TRUE(device->CheckReservation(1, scsi_command::eCmdTestUnitReady, false))
|
||||
<< "Device must not be reserved anymore for initiator ID 1";
|
||||
|
||||
ON_CALL(controller, GetInitiatorId).WillByDefault(Return(-1));
|
||||
ON_CALL(*controller, GetInitiatorId).WillByDefault(Return(-1));
|
||||
device->Dispatch(scsi_command::eCmdReserve6);
|
||||
EXPECT_FALSE(device->CheckReservation(1, scsi_command::eCmdTestUnitReady, false))
|
||||
<< "Device must be reserved for unknown initiator";
|
||||
@ -129,12 +139,14 @@ TEST(PrimaryDeviceTest, ReserveReleaseUnit)
|
||||
|
||||
TEST(PrimaryDeviceTest, DiscardReservation)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<NiceMock<MockAbstractController>>(controller_manager, 0);
|
||||
auto device = make_shared<MockPrimaryDevice>(0);
|
||||
const unordered_map<string, string> params;
|
||||
device->Init(params);
|
||||
|
||||
controller.AddDevice(device);
|
||||
controller->AddDevice(device);
|
||||
|
||||
device->Dispatch(scsi_command::eCmdReserve6);
|
||||
EXPECT_FALSE(device->CheckReservation(1, scsi_command::eCmdTestUnitReady, false))
|
||||
@ -146,56 +158,60 @@ TEST(PrimaryDeviceTest, DiscardReservation)
|
||||
|
||||
TEST(PrimaryDeviceTest, TestUnitReady)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto device = make_shared<MockPrimaryDevice>(0);
|
||||
const unordered_map<string, string> params;
|
||||
device->Init(params);
|
||||
|
||||
controller.AddDevice(device);
|
||||
controller->AddDevice(device);
|
||||
|
||||
device->SetReset(true);
|
||||
device->SetAttn(true);
|
||||
device->SetReady(false);
|
||||
EXPECT_CALL(controller, DataIn).Times(0);
|
||||
EXPECT_CALL(*controller, DataIn).Times(0);
|
||||
EXPECT_THAT([&] { device->Dispatch(scsi_command::eCmdTestUnitReady); }, Throws<scsi_exception>(AllOf(
|
||||
Property(&scsi_exception::get_sense_key, sense_key::UNIT_ATTENTION),
|
||||
Property(&scsi_exception::get_asc, asc::POWER_ON_OR_RESET))));
|
||||
|
||||
device->SetReset(false);
|
||||
EXPECT_CALL(controller, DataIn).Times(0);
|
||||
EXPECT_CALL(*controller, DataIn).Times(0);
|
||||
EXPECT_THAT([&] { device->Dispatch(scsi_command::eCmdTestUnitReady); }, Throws<scsi_exception>(AllOf(
|
||||
Property(&scsi_exception::get_sense_key, sense_key::UNIT_ATTENTION),
|
||||
Property(&scsi_exception::get_asc, asc::NOT_READY_TO_READY_CHANGE))));
|
||||
|
||||
device->SetReset(true);
|
||||
device->SetAttn(false);
|
||||
EXPECT_CALL(controller, DataIn).Times(0);
|
||||
EXPECT_CALL(*controller, DataIn).Times(0);
|
||||
EXPECT_THAT([&] { device->Dispatch(scsi_command::eCmdTestUnitReady); }, Throws<scsi_exception>(AllOf(
|
||||
Property(&scsi_exception::get_sense_key, sense_key::UNIT_ATTENTION),
|
||||
Property(&scsi_exception::get_asc, asc::POWER_ON_OR_RESET))));
|
||||
|
||||
device->SetReset(false);
|
||||
device->SetAttn(true);
|
||||
EXPECT_CALL(controller, DataIn).Times(0);
|
||||
EXPECT_CALL(*controller, DataIn).Times(0);
|
||||
EXPECT_THAT([&] { device->Dispatch(scsi_command::eCmdTestUnitReady); }, Throws<scsi_exception>(AllOf(
|
||||
Property(&scsi_exception::get_sense_key, sense_key::UNIT_ATTENTION),
|
||||
Property(&scsi_exception::get_asc, asc::NOT_READY_TO_READY_CHANGE))));
|
||||
|
||||
device->SetAttn(false);
|
||||
EXPECT_CALL(controller, DataIn).Times(0);
|
||||
EXPECT_CALL(*controller, DataIn).Times(0);
|
||||
EXPECT_THAT([&] { device->Dispatch(scsi_command::eCmdTestUnitReady); }, Throws<scsi_exception>(AllOf(
|
||||
Property(&scsi_exception::get_sense_key, sense_key::NOT_READY),
|
||||
Property(&scsi_exception::get_asc, asc::MEDIUM_NOT_PRESENT))));
|
||||
|
||||
device->SetReady(true);
|
||||
EXPECT_CALL(controller, Status);
|
||||
EXPECT_CALL(*controller, Status);
|
||||
device->Dispatch(scsi_command::eCmdTestUnitReady);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
}
|
||||
|
||||
TEST(PrimaryDeviceTest, Inquiry)
|
||||
{
|
||||
auto controller = make_shared<NiceMock<MockAbstractController>>(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<NiceMock<MockAbstractController>>(controller_manager, 0);
|
||||
auto device = make_shared<MockPrimaryDevice>(0);
|
||||
const unordered_map<string, string> params;
|
||||
device->Init(params);
|
||||
@ -266,14 +282,16 @@ TEST(PrimaryDeviceTest, Inquiry)
|
||||
|
||||
TEST(PrimaryDeviceTest, RequestSense)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<NiceMock<MockAbstractController>>(controller_manager, 0);
|
||||
auto device = make_shared<MockPrimaryDevice>(0);
|
||||
const unordered_map<string, string> params;
|
||||
device->Init(params);
|
||||
|
||||
controller.AddDevice(device);
|
||||
controller->AddDevice(device);
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
auto& cmd = controller->GetCmd();
|
||||
// ALLOCATION LENGTH
|
||||
cmd[4] = 255;
|
||||
|
||||
@ -283,25 +301,27 @@ TEST(PrimaryDeviceTest, RequestSense)
|
||||
Property(&scsi_exception::get_asc, asc::MEDIUM_NOT_PRESENT))));
|
||||
|
||||
device->SetReady(true);
|
||||
EXPECT_CALL(controller, DataIn);
|
||||
EXPECT_CALL(*controller, DataIn);
|
||||
device->Dispatch(scsi_command::eCmdRequestSense);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
}
|
||||
|
||||
TEST(PrimaryDeviceTest, SendDiagnostic)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto device = make_shared<MockPrimaryDevice>(0);
|
||||
const unordered_map<string, string> params;
|
||||
device->Init(params);
|
||||
|
||||
controller.AddDevice(device);
|
||||
controller->AddDevice(device);
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
auto& cmd = controller->GetCmd();
|
||||
|
||||
EXPECT_CALL(controller, Status);
|
||||
EXPECT_CALL(*controller, Status);
|
||||
device->Dispatch(scsi_command::eCmdSendDiagnostic);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
|
||||
cmd[1] = 0x10;
|
||||
EXPECT_THAT([&] { device->Dispatch(scsi_command::eCmdSendDiagnostic); }, Throws<scsi_exception>(AllOf(
|
||||
@ -328,25 +348,27 @@ TEST(PrimaryDeviceTest, ReportLuns)
|
||||
const int LUN1 = 1;
|
||||
const int LUN2 = 4;
|
||||
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto device1 = make_shared<MockPrimaryDevice>(LUN1);
|
||||
auto device2 = make_shared<MockPrimaryDevice>(LUN2);
|
||||
const unordered_map<string, string> params;
|
||||
device1->Init(params);
|
||||
device2->Init(params);
|
||||
|
||||
controller.AddDevice(device1);
|
||||
EXPECT_TRUE(controller.HasDeviceForLun(LUN1));
|
||||
controller.AddDevice(device2);
|
||||
EXPECT_TRUE(controller.HasDeviceForLun(LUN2));
|
||||
controller->AddDevice(device1);
|
||||
EXPECT_TRUE(controller->HasDeviceForLun(LUN1));
|
||||
controller->AddDevice(device2);
|
||||
EXPECT_TRUE(controller->HasDeviceForLun(LUN2));
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
auto& cmd = controller->GetCmd();
|
||||
// ALLOCATION LENGTH
|
||||
cmd[9] = 255;
|
||||
|
||||
EXPECT_CALL(controller, DataIn);
|
||||
EXPECT_CALL(*controller, DataIn);
|
||||
device1->Dispatch(scsi_command::eCmdReportLuns);
|
||||
const vector<uint8_t>& buffer = controller.GetBuffer();
|
||||
const vector<uint8_t>& buffer = controller->GetBuffer();
|
||||
EXPECT_EQ(0, GetInt16(buffer, 0)) << "Wrong data length";
|
||||
EXPECT_EQ(16, GetInt16(buffer, 2)) << "Wrong data length";
|
||||
EXPECT_EQ(0, GetInt16(buffer, 8)) << "Wrong LUN1 number";
|
||||
@ -367,12 +389,14 @@ TEST(PrimaryDeviceTest, ReportLuns)
|
||||
|
||||
TEST(PrimaryDeviceTest, Dispatch)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto device = make_shared<MockPrimaryDevice>(0);
|
||||
const unordered_map<string, string> params;
|
||||
device->Init(params);
|
||||
|
||||
controller.AddDevice(device);
|
||||
controller->AddDevice(device);
|
||||
|
||||
EXPECT_THROW(device->Dispatch(static_cast<scsi_command>(0x1f)), scsi_exception) << "Unknown command";
|
||||
}
|
||||
|
@ -40,12 +40,10 @@ TEST_F(RascsiExecutorTest, ProcessDeviceCmd)
|
||||
const int LUN = 0;
|
||||
|
||||
auto bus = make_shared<MockBus>();
|
||||
DeviceFactory device_factory;
|
||||
MockAbstractController controller(bus, ID);
|
||||
ControllerManager controller_manager(bus);
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
MockAbstractController controller(controller_manager, ID);
|
||||
RascsiImage rascsi_image;
|
||||
RascsiResponse rascsi_response(device_factory, controller_manager, 32);
|
||||
auto executor = make_shared<MockRascsiExecutor>(rascsi_response, rascsi_image, device_factory, controller_manager);
|
||||
auto executor = make_shared<MockRascsiExecutor>(rascsi_image, *controller_manager);
|
||||
PbDeviceDefinition definition;
|
||||
PbCommand command;
|
||||
MockCommandContext context;
|
||||
@ -68,19 +66,19 @@ TEST_F(RascsiExecutorTest, ProcessDeviceCmd)
|
||||
EXPECT_FALSE(executor->ProcessDeviceCmd(context, definition, command, true)) << "Operation for unknown device type must fail";
|
||||
|
||||
auto device1 = make_shared<MockPrimaryDevice>(LUN);
|
||||
EXPECT_TRUE(controller_manager.AttachToScsiController(ID, device1));
|
||||
EXPECT_TRUE(controller_manager->AttachToScsiController(ID, device1));
|
||||
|
||||
definition.set_type(SCHS);
|
||||
command.set_operation(INSERT);
|
||||
EXPECT_FALSE(executor->ProcessDeviceCmd(context, definition, command, true)) << "Operation unsupported by device must fail";
|
||||
controller_manager.DeleteAllControllers();
|
||||
controller_manager->DeleteAllControllers();
|
||||
definition.set_type(SCRM);
|
||||
|
||||
auto device2 = make_shared<MockSCSIHD_NEC>(LUN);
|
||||
device2->SetRemovable(true);
|
||||
device2->SetProtectable(true);
|
||||
device2->SetReady(true);
|
||||
EXPECT_TRUE(controller_manager.AttachToScsiController(ID, device2));
|
||||
EXPECT_TRUE(controller_manager->AttachToScsiController(ID, device2));
|
||||
|
||||
command.set_operation(ATTACH);
|
||||
EXPECT_FALSE(executor->ProcessDeviceCmd(context, definition, command, true)) << "ID and LUN already exist";
|
||||
@ -113,7 +111,7 @@ TEST_F(RascsiExecutorTest, ProcessDeviceCmd)
|
||||
command.set_operation(DETACH);
|
||||
EXPECT_TRUE(executor->ProcessDeviceCmd(context, definition, command, true));
|
||||
EXPECT_TRUE(executor->ProcessDeviceCmd(context, definition, command, false));
|
||||
EXPECT_TRUE(controller_manager.AttachToScsiController(ID, device2));
|
||||
EXPECT_TRUE(controller_manager->AttachToScsiController(ID, device2));
|
||||
|
||||
command.set_operation(CHECK_AUTHENTICATION);
|
||||
EXPECT_TRUE(executor->ProcessDeviceCmd(context, definition, command, true));
|
||||
@ -152,13 +150,11 @@ TEST_F(RascsiExecutorTest, ProcessDeviceCmd)
|
||||
|
||||
TEST_F(RascsiExecutorTest, ProcessCmd)
|
||||
{
|
||||
shared_ptr<MockBus> bus;
|
||||
DeviceFactory device_factory;
|
||||
MockAbstractController controller(bus, 0);
|
||||
ControllerManager controller_manager(bus);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
MockAbstractController controller(controller_manager, 0);
|
||||
RascsiImage rascsi_image;
|
||||
RascsiResponse rascsi_response(device_factory, controller_manager, 32);
|
||||
auto executor = make_shared<MockRascsiExecutor>(rascsi_response, rascsi_image, device_factory, controller_manager);
|
||||
auto executor = make_shared<MockRascsiExecutor>(rascsi_image, *controller_manager);
|
||||
PbCommand command1;
|
||||
PbCommand command2;
|
||||
MockCommandContext context;
|
||||
@ -219,11 +215,11 @@ TEST_F(RascsiExecutorTest, ProcessCmd)
|
||||
|
||||
TEST_F(RascsiExecutorTest, SetLogLevel)
|
||||
{
|
||||
DeviceFactory device_factory;
|
||||
ControllerManager controller_manager(make_shared<MockBus>());
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
MockAbstractController controller(controller_manager, 0);
|
||||
RascsiImage rascsi_image;
|
||||
RascsiResponse rascsi_response(device_factory, controller_manager, 32);
|
||||
RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager);
|
||||
RascsiExecutor executor(rascsi_image, *controller_manager);
|
||||
|
||||
EXPECT_TRUE(executor.SetLogLevel("trace"));
|
||||
EXPECT_TRUE(executor.SetLogLevel("debug"));
|
||||
@ -240,17 +236,17 @@ TEST_F(RascsiExecutorTest, Attach)
|
||||
const int LUN = 0;
|
||||
|
||||
DeviceFactory device_factory;
|
||||
ControllerManager controller_manager(make_shared<MockBus>());
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
RascsiImage rascsi_image;
|
||||
RascsiResponse rascsi_response(device_factory, controller_manager, 32);
|
||||
RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager);
|
||||
RascsiExecutor executor(rascsi_image, *controller_manager);
|
||||
PbDeviceDefinition definition;
|
||||
MockCommandContext context;
|
||||
|
||||
definition.set_unit(32);
|
||||
EXPECT_FALSE(executor.Attach(context, definition, false));
|
||||
|
||||
auto device = device_factory.CreateDevice(controller_manager, SCHD, LUN, "");
|
||||
auto device = device_factory.CreateDevice(SCHD, LUN, "");
|
||||
definition.set_id(ID);
|
||||
definition.set_unit(LUN);
|
||||
|
||||
@ -262,7 +258,7 @@ TEST_F(RascsiExecutorTest, Attach)
|
||||
|
||||
definition.set_type(PbDeviceType::SCHS);
|
||||
EXPECT_TRUE(executor.Attach(context, definition, false));
|
||||
controller_manager.DeleteAllControllers();
|
||||
controller_manager->DeleteAllControllers();
|
||||
|
||||
definition.set_type(PbDeviceType::SCHD);
|
||||
EXPECT_FALSE(executor.Attach(context, definition, false)) << "Drive without sectors not rejected";
|
||||
@ -290,7 +286,7 @@ TEST_F(RascsiExecutorTest, Attach)
|
||||
bool result = executor.Attach(context, definition, false);
|
||||
remove(filename);
|
||||
EXPECT_TRUE(result);
|
||||
controller_manager.DeleteAllControllers();
|
||||
controller_manager->DeleteAllControllers();
|
||||
|
||||
filename = CreateTempFile(513);
|
||||
SetParam(definition, "file", filename.c_str());
|
||||
@ -315,20 +311,20 @@ TEST_F(RascsiExecutorTest, Attach)
|
||||
remove(filename);
|
||||
EXPECT_TRUE(result);
|
||||
|
||||
controller_manager.DeleteAllControllers();
|
||||
controller_manager->DeleteAllControllers();
|
||||
}
|
||||
|
||||
TEST_F(RascsiExecutorTest, Insert)
|
||||
{
|
||||
DeviceFactory device_factory;
|
||||
ControllerManager controller_manager(make_shared<MockBus>());
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
RascsiImage rascsi_image;
|
||||
RascsiResponse rascsi_response(device_factory, controller_manager, 32);
|
||||
RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager);
|
||||
RascsiExecutor executor(rascsi_image, *controller_manager);
|
||||
PbDeviceDefinition definition;
|
||||
MockCommandContext context;
|
||||
|
||||
auto device = device_factory.CreateDevice(controller_manager, SCRM, 0, "test");
|
||||
auto device = device_factory.CreateDevice(SCRM, 0, "test");
|
||||
|
||||
device->SetRemoved(false);
|
||||
EXPECT_FALSE(executor.Insert(context, definition, device, false)) << "Medium is not removed";
|
||||
@ -381,23 +377,23 @@ TEST_F(RascsiExecutorTest, Detach)
|
||||
const int LUN2 = 1;
|
||||
|
||||
DeviceFactory device_factory;
|
||||
ControllerManager controller_manager(make_shared<MockBus>());
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
RascsiImage rascsi_image;
|
||||
RascsiResponse rascsi_response(device_factory, controller_manager, 32);
|
||||
RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager);
|
||||
RascsiExecutor executor(rascsi_image, *controller_manager);
|
||||
MockCommandContext context;
|
||||
|
||||
auto device1 = device_factory.CreateDevice(controller_manager, SCHS, LUN1, "");
|
||||
EXPECT_TRUE(controller_manager.AttachToScsiController(ID, device1));
|
||||
auto device2 = device_factory.CreateDevice(controller_manager, SCHS, LUN2, "");
|
||||
EXPECT_TRUE(controller_manager.AttachToScsiController(ID, device2));
|
||||
auto device1 = device_factory.CreateDevice(SCHS, LUN1, "");
|
||||
EXPECT_TRUE(controller_manager->AttachToScsiController(ID, device1));
|
||||
auto device2 = device_factory.CreateDevice(SCHS, LUN2, "");
|
||||
EXPECT_TRUE(controller_manager->AttachToScsiController(ID, device2));
|
||||
|
||||
auto d1 = controller_manager.GetDeviceByIdAndLun(ID, LUN1);
|
||||
auto d1 = controller_manager->GetDeviceByIdAndLun(ID, LUN1);
|
||||
EXPECT_FALSE(executor.Detach(context, d1, false)) << "LUNs > 0 have to be detached first";
|
||||
auto d2 = controller_manager.GetDeviceByIdAndLun(ID, LUN2);
|
||||
auto d2 = controller_manager->GetDeviceByIdAndLun(ID, LUN2);
|
||||
EXPECT_TRUE(executor.Detach(context, d2, false));
|
||||
EXPECT_TRUE(executor.Detach(context, d1, false));
|
||||
EXPECT_TRUE(controller_manager.GetAllDevices().empty());
|
||||
EXPECT_TRUE(controller_manager->GetAllDevices().empty());
|
||||
|
||||
EXPECT_FALSE(executor.Detach(context, d1, false));
|
||||
}
|
||||
@ -407,28 +403,27 @@ TEST_F(RascsiExecutorTest, DetachAll)
|
||||
const int ID = 4;
|
||||
|
||||
DeviceFactory device_factory;
|
||||
ControllerManager controller_manager(make_shared<MockBus>());
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
RascsiImage rascsi_image;
|
||||
RascsiResponse rascsi_response(device_factory, controller_manager, 32);
|
||||
RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager);
|
||||
RascsiExecutor executor(rascsi_image, *controller_manager);
|
||||
|
||||
auto device = device_factory.CreateDevice(controller_manager, SCHS, 0, "");
|
||||
EXPECT_TRUE(controller_manager.AttachToScsiController(ID, device));
|
||||
EXPECT_NE(nullptr, controller_manager.FindController(ID));
|
||||
EXPECT_FALSE(controller_manager.GetAllDevices().empty());
|
||||
auto device = device_factory.CreateDevice(SCHS, 0, "");
|
||||
EXPECT_TRUE(controller_manager->AttachToScsiController(ID, device));
|
||||
EXPECT_NE(nullptr, controller_manager->FindController(ID));
|
||||
EXPECT_FALSE(controller_manager->GetAllDevices().empty());
|
||||
|
||||
executor.DetachAll();
|
||||
EXPECT_EQ(nullptr, controller_manager.FindController(ID));
|
||||
EXPECT_TRUE(controller_manager.GetAllDevices().empty());
|
||||
EXPECT_EQ(nullptr, controller_manager->FindController(ID));
|
||||
EXPECT_TRUE(controller_manager->GetAllDevices().empty());
|
||||
}
|
||||
|
||||
TEST_F(RascsiExecutorTest, ShutDown)
|
||||
{
|
||||
DeviceFactory device_factory;
|
||||
ControllerManager controller_manager(make_shared<MockBus>());
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
RascsiImage rascsi_image;
|
||||
RascsiResponse rascsi_response(device_factory, controller_manager, 32);
|
||||
RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager);
|
||||
RascsiExecutor executor(rascsi_image, *controller_manager);
|
||||
MockCommandContext context;
|
||||
|
||||
EXPECT_FALSE(executor.ShutDown(context, ""));
|
||||
@ -441,10 +436,10 @@ TEST_F(RascsiExecutorTest, ShutDown)
|
||||
TEST_F(RascsiExecutorTest, SetReservedIds)
|
||||
{
|
||||
DeviceFactory device_factory;
|
||||
ControllerManager controller_manager(make_shared<MockBus>());
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
RascsiImage rascsi_image;
|
||||
RascsiResponse rascsi_response(device_factory, controller_manager, 32);
|
||||
RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager);
|
||||
RascsiExecutor executor(rascsi_image, *controller_manager);
|
||||
|
||||
string error = executor.SetReservedIds("xyz");
|
||||
EXPECT_FALSE(error.empty());
|
||||
@ -472,8 +467,8 @@ TEST_F(RascsiExecutorTest, SetReservedIds)
|
||||
EXPECT_NE(reserved_ids.end(), reserved_ids.find(5));
|
||||
EXPECT_NE(reserved_ids.end(), reserved_ids.find(7));
|
||||
|
||||
auto device = device_factory.CreateDevice(controller_manager, SCHS, 0, "");
|
||||
EXPECT_TRUE(controller_manager.AttachToScsiController(5, device));
|
||||
auto device = device_factory.CreateDevice(SCHS, 0, "");
|
||||
EXPECT_TRUE(controller_manager->AttachToScsiController(5, device));
|
||||
error = executor.SetReservedIds("5");
|
||||
EXPECT_FALSE(error.empty());
|
||||
}
|
||||
@ -481,14 +476,14 @@ TEST_F(RascsiExecutorTest, SetReservedIds)
|
||||
TEST_F(RascsiExecutorTest, ValidateImageFile)
|
||||
{
|
||||
DeviceFactory device_factory;
|
||||
ControllerManager controller_manager(make_shared<MockBus>());
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
RascsiImage rascsi_image;
|
||||
RascsiResponse rascsi_response(device_factory, controller_manager, 32);
|
||||
RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager);
|
||||
RascsiExecutor executor(rascsi_image, *controller_manager);
|
||||
MockCommandContext context;
|
||||
|
||||
string full_path;
|
||||
auto device = dynamic_pointer_cast<StorageDevice>(device_factory.CreateDevice(controller_manager, SCHD, 0, "test"));
|
||||
auto device = dynamic_pointer_cast<StorageDevice>(device_factory.CreateDevice(SCHD, 0, "test"));
|
||||
EXPECT_TRUE(executor.ValidateImageFile(context, *device, "", full_path));
|
||||
EXPECT_TRUE(full_path.empty());
|
||||
|
||||
@ -499,10 +494,10 @@ TEST_F(RascsiExecutorTest, ValidateImageFile)
|
||||
TEST_F(RascsiExecutorTest, ValidateLunSetup)
|
||||
{
|
||||
DeviceFactory device_factory;
|
||||
ControllerManager controller_manager(make_shared<MockBus>());
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
RascsiImage rascsi_image;
|
||||
RascsiResponse rascsi_response(device_factory, controller_manager, 32);
|
||||
RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager);
|
||||
RascsiExecutor executor(rascsi_image, *controller_manager);
|
||||
PbCommand command;
|
||||
|
||||
auto device1 = command.add_devices();
|
||||
@ -514,8 +509,8 @@ TEST_F(RascsiExecutorTest, ValidateLunSetup)
|
||||
error = executor.ValidateLunSetup(command);
|
||||
EXPECT_FALSE(error.empty());
|
||||
|
||||
auto device2 = device_factory.CreateDevice(controller_manager, SCHS, 0, "");
|
||||
EXPECT_TRUE(controller_manager.AttachToScsiController(0, device2));
|
||||
auto device2 = device_factory.CreateDevice(SCHS, 0, "");
|
||||
EXPECT_TRUE(controller_manager->AttachToScsiController(0, device2));
|
||||
error = executor.ValidateLunSetup(command);
|
||||
EXPECT_TRUE(error.empty());
|
||||
}
|
||||
@ -527,26 +522,25 @@ TEST_F(RascsiExecutorTest, VerifyExistingIdAndLun)
|
||||
const int LUN2 = 3;
|
||||
|
||||
DeviceFactory device_factory;
|
||||
ControllerManager controller_manager(make_shared<MockBus>());
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
RascsiImage rascsi_image;
|
||||
RascsiResponse rascsi_response(device_factory, controller_manager, 32);
|
||||
RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager);
|
||||
RascsiExecutor executor(rascsi_image, *controller_manager);
|
||||
MockCommandContext context;
|
||||
|
||||
EXPECT_FALSE(executor.VerifyExistingIdAndLun(context, ID, LUN1));
|
||||
auto device = device_factory.CreateDevice(controller_manager, SCHS, LUN1, "");
|
||||
EXPECT_TRUE(controller_manager.AttachToScsiController(ID, device));
|
||||
auto device = device_factory.CreateDevice(SCHS, LUN1, "");
|
||||
EXPECT_TRUE(controller_manager->AttachToScsiController(ID, device));
|
||||
EXPECT_TRUE(executor.VerifyExistingIdAndLun(context, ID, LUN1));
|
||||
EXPECT_FALSE(executor.VerifyExistingIdAndLun(context, ID, LUN2));
|
||||
}
|
||||
|
||||
TEST_F(RascsiExecutorTest, CreateDevice)
|
||||
{
|
||||
DeviceFactory device_factory;
|
||||
ControllerManager controller_manager(make_shared<MockBus>());
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
RascsiImage rascsi_image;
|
||||
RascsiResponse rascsi_response(device_factory, controller_manager, 32);
|
||||
RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager);
|
||||
RascsiExecutor executor(rascsi_image, *controller_manager);
|
||||
MockCommandContext context;
|
||||
|
||||
EXPECT_EQ(nullptr, executor.CreateDevice(context, UNDEFINED, 0, ""));
|
||||
@ -560,11 +554,10 @@ TEST_F(RascsiExecutorTest, CreateDevice)
|
||||
|
||||
TEST_F(RascsiExecutorTest, SetSectorSize)
|
||||
{
|
||||
DeviceFactory device_factory;
|
||||
ControllerManager controller_manager(make_shared<MockBus>());
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
RascsiImage rascsi_image;
|
||||
RascsiResponse rascsi_response(device_factory, controller_manager, 32);
|
||||
RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager);
|
||||
RascsiExecutor executor(rascsi_image, *controller_manager);
|
||||
MockCommandContext context;
|
||||
|
||||
unordered_set<uint32_t> sizes;
|
||||
@ -580,11 +573,10 @@ TEST_F(RascsiExecutorTest, SetSectorSize)
|
||||
|
||||
TEST_F(RascsiExecutorTest, ValidateOperationAgainstDevice)
|
||||
{
|
||||
DeviceFactory device_factory;
|
||||
ControllerManager controller_manager(make_shared<MockBus>());
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
RascsiImage rascsi_image;
|
||||
RascsiResponse rascsi_response(device_factory, controller_manager, 32);
|
||||
RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager);
|
||||
RascsiExecutor executor(rascsi_image, *controller_manager);
|
||||
MockCommandContext context;
|
||||
|
||||
auto device = make_shared<MockPrimaryDevice>(0);
|
||||
@ -634,11 +626,10 @@ TEST_F(RascsiExecutorTest, ValidateOperationAgainstDevice)
|
||||
|
||||
TEST_F(RascsiExecutorTest, ValidateIdAndLun)
|
||||
{
|
||||
DeviceFactory device_factory;
|
||||
ControllerManager controller_manager(make_shared<MockBus>());
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
RascsiImage rascsi_image;
|
||||
RascsiResponse rascsi_response(device_factory, controller_manager, 32);
|
||||
RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager);
|
||||
RascsiExecutor executor(rascsi_image, *controller_manager);
|
||||
MockCommandContext context;
|
||||
|
||||
EXPECT_FALSE(executor.ValidateIdAndLun(context, -1, 0));
|
||||
@ -651,11 +642,10 @@ TEST_F(RascsiExecutorTest, ValidateIdAndLun)
|
||||
|
||||
TEST_F(RascsiExecutorTest, SetProductData)
|
||||
{
|
||||
DeviceFactory device_factory;
|
||||
ControllerManager controller_manager(make_shared<MockBus>());
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
RascsiImage rascsi_image;
|
||||
RascsiResponse rascsi_response(device_factory, controller_manager, 32);
|
||||
RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager);
|
||||
RascsiExecutor executor(rascsi_image, *controller_manager);
|
||||
MockCommandContext context;
|
||||
PbDeviceDefinition definition;
|
||||
|
||||
|
@ -18,10 +18,7 @@ using namespace rascsi_interface;
|
||||
|
||||
TEST(RascsiResponseTest, Operation_Count)
|
||||
{
|
||||
auto bus = make_shared<MockBus>();
|
||||
ControllerManager controller_manager(bus);
|
||||
DeviceFactory device_factory;
|
||||
RascsiResponse response(device_factory, controller_manager, 32);
|
||||
RascsiResponse response;
|
||||
PbResult result;
|
||||
|
||||
const auto info = response.GetOperationInfo(result, 0);
|
||||
@ -31,17 +28,17 @@ TEST(RascsiResponseTest, Operation_Count)
|
||||
void TestNonDiskDevice(PbDeviceType type, int default_param_count)
|
||||
{
|
||||
auto bus = make_shared<MockBus>();
|
||||
ControllerManager controller_manager(bus);
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
DeviceFactory device_factory;
|
||||
RascsiResponse response(device_factory, controller_manager, 32);
|
||||
RascsiResponse response;
|
||||
|
||||
auto d = device_factory.CreateDevice(controller_manager, type, 0, "");
|
||||
auto d = device_factory.CreateDevice(type, 0, "");
|
||||
const unordered_map<string, string> params;
|
||||
d->Init(params);
|
||||
EXPECT_TRUE(controller_manager.AttachToScsiController(0, d));
|
||||
EXPECT_TRUE(controller_manager->AttachToScsiController(0, d));
|
||||
|
||||
PbServerInfo info;
|
||||
response.GetDevices(info, "image_folder");
|
||||
response.GetDevices(controller_manager->GetAllDevices(), info, "image_folder");
|
||||
|
||||
EXPECT_EQ(1, info.devices_info().devices().size());
|
||||
|
||||
@ -73,9 +70,7 @@ TEST(RascsiResponseTest, GetDevices)
|
||||
|
||||
TEST(RascsiResponseTest, GetImageFile)
|
||||
{
|
||||
ControllerManager controller_manager(make_shared<MockBus>());
|
||||
DeviceFactory device_factory;
|
||||
RascsiResponse response(device_factory, controller_manager, 32);
|
||||
RascsiResponse response;
|
||||
PbImageFile image_file;
|
||||
|
||||
EXPECT_FALSE(response.GetImageFile(image_file, "default_folder", ""));
|
||||
@ -88,10 +83,7 @@ TEST(RascsiResponseTest, GetImageFile)
|
||||
|
||||
TEST(RascsiResponseTest, GetReservedIds)
|
||||
{
|
||||
auto bus = make_shared<MockBus>();
|
||||
ControllerManager controller_manager(bus);
|
||||
DeviceFactory device_factory;
|
||||
RascsiResponse response(device_factory, controller_manager, 32);
|
||||
RascsiResponse response;
|
||||
unordered_set<int> ids;
|
||||
PbResult result;
|
||||
|
||||
@ -113,20 +105,20 @@ TEST(RascsiResponseTest, GetDevicesInfo)
|
||||
const int LUN2 = 5;
|
||||
const int LUN3 = 6;
|
||||
|
||||
ControllerManager controller_manager(make_shared<MockBus>());
|
||||
DeviceFactory device_factory;
|
||||
RascsiResponse response(device_factory, controller_manager, 32);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
RascsiResponse response;
|
||||
PbCommand command;
|
||||
PbResult result;
|
||||
|
||||
response.GetDevicesInfo(result, command, "");
|
||||
response.GetDevicesInfo(controller_manager->GetAllDevices(), result, command, "");
|
||||
EXPECT_TRUE(result.status());
|
||||
EXPECT_TRUE(result.devices_info().devices().empty());
|
||||
|
||||
auto device1 = make_shared<MockHostServices>(LUN1, controller_manager);
|
||||
EXPECT_TRUE(controller_manager.AttachToScsiController(ID, device1));
|
||||
auto device1 = make_shared<MockHostServices>(LUN1);
|
||||
EXPECT_TRUE(controller_manager->AttachToScsiController(ID, device1));
|
||||
|
||||
response.GetDevicesInfo(result, command, "");
|
||||
response.GetDevicesInfo(controller_manager->GetAllDevices(), result, command, "");
|
||||
EXPECT_TRUE(result.status());
|
||||
auto& devices1 = result.devices_info().devices();
|
||||
EXPECT_EQ(1, devices1.size());
|
||||
@ -135,9 +127,9 @@ TEST(RascsiResponseTest, GetDevicesInfo)
|
||||
EXPECT_EQ(LUN1, devices1[0].unit());
|
||||
|
||||
auto device2 = make_shared<MockSCSIHD_NEC>(LUN2);
|
||||
EXPECT_TRUE(controller_manager.AttachToScsiController(ID, device2));
|
||||
EXPECT_TRUE(controller_manager->AttachToScsiController(ID, device2));
|
||||
|
||||
response.GetDevicesInfo(result, command, "");
|
||||
response.GetDevicesInfo(controller_manager->GetAllDevices(), result, command, "");
|
||||
EXPECT_TRUE(result.status());
|
||||
auto& devices2 = result.devices_info().devices();
|
||||
EXPECT_EQ(2, devices2.size()) << "Data for all devices must be returned";
|
||||
@ -145,7 +137,7 @@ TEST(RascsiResponseTest, GetDevicesInfo)
|
||||
auto requested_device = command.add_devices();
|
||||
requested_device->set_id(ID);
|
||||
requested_device->set_unit(LUN1);
|
||||
response.GetDevicesInfo(result, command, "");
|
||||
response.GetDevicesInfo(controller_manager->GetAllDevices(), result, command, "");
|
||||
EXPECT_TRUE(result.status());
|
||||
auto& devices3 = result.devices_info().devices();
|
||||
EXPECT_EQ(1, devices3.size()) << "Only data for the specified ID and LUN must be returned";
|
||||
@ -155,15 +147,13 @@ TEST(RascsiResponseTest, GetDevicesInfo)
|
||||
|
||||
requested_device->set_id(ID);
|
||||
requested_device->set_unit(LUN3);
|
||||
response.GetDevicesInfo(result, command, "");
|
||||
response.GetDevicesInfo(controller_manager->GetAllDevices(), result, command, "");
|
||||
EXPECT_FALSE(result.status()) << "Only data for the specified ID and LUN must be returned";
|
||||
}
|
||||
|
||||
TEST(RascsiResponseTest, GetDeviceTypesInfo)
|
||||
{
|
||||
ControllerManager controller_manager(make_shared<MockBus>());
|
||||
DeviceFactory device_factory;
|
||||
RascsiResponse response(device_factory, controller_manager, 32);
|
||||
RascsiResponse response;
|
||||
PbResult result;
|
||||
|
||||
const auto& info = response.GetDeviceTypesInfo(result);
|
||||
@ -173,13 +163,14 @@ TEST(RascsiResponseTest, GetDeviceTypesInfo)
|
||||
|
||||
TEST(RascsiResponseTest, GetServerInfo)
|
||||
{
|
||||
ControllerManager controller_manager(make_shared<MockBus>());
|
||||
DeviceFactory device_factory;
|
||||
RascsiResponse response(device_factory, controller_manager, 32);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
RascsiResponse response;
|
||||
const unordered_set<shared_ptr<PrimaryDevice>> devices;
|
||||
const unordered_set<int> ids = { 1, 3 };
|
||||
PbResult result;
|
||||
|
||||
const auto& info = response.GetServerInfo(result, ids, "log_level", "default_folder", "", "", 1234);
|
||||
const auto& info = response.GetServerInfo(devices, result, ids, "log_level", "default_folder", "", "", 1234);
|
||||
EXPECT_TRUE(result.status());
|
||||
EXPECT_EQ(rascsi_major_version, info->version_info().major_version());
|
||||
EXPECT_EQ(rascsi_minor_version, info->version_info().minor_version());
|
||||
@ -192,9 +183,7 @@ TEST(RascsiResponseTest, GetServerInfo)
|
||||
|
||||
TEST(RascsiResponseTest, GetVersionInfo)
|
||||
{
|
||||
ControllerManager controller_manager(make_shared<MockBus>());
|
||||
DeviceFactory device_factory;
|
||||
RascsiResponse response(device_factory, controller_manager, 32);
|
||||
RascsiResponse response;
|
||||
PbResult result;
|
||||
|
||||
const auto& info = response.GetVersionInfo(result);
|
||||
@ -206,9 +195,7 @@ TEST(RascsiResponseTest, GetVersionInfo)
|
||||
|
||||
TEST(RascsiResponseTest, GetLogLevelInfo)
|
||||
{
|
||||
ControllerManager controller_manager(make_shared<MockBus>());
|
||||
DeviceFactory device_factory;
|
||||
RascsiResponse response(device_factory, controller_manager, 32);
|
||||
RascsiResponse response;
|
||||
PbResult result;
|
||||
|
||||
const auto& info = response.GetLogLevelInfo(result, "level");
|
||||
@ -219,9 +206,7 @@ TEST(RascsiResponseTest, GetLogLevelInfo)
|
||||
|
||||
TEST(RascsiResponseTest, GetNetworkInterfacesInfo)
|
||||
{
|
||||
ControllerManager controller_manager(make_shared<MockBus>());
|
||||
DeviceFactory device_factory;
|
||||
RascsiResponse response(device_factory, controller_manager, 32);
|
||||
RascsiResponse response;
|
||||
PbResult result;
|
||||
|
||||
const auto& info = response.GetNetworkInterfacesInfo(result);
|
||||
@ -231,9 +216,7 @@ TEST(RascsiResponseTest, GetNetworkInterfacesInfo)
|
||||
|
||||
TEST(RascsiResponseTest, GetMappingInfo)
|
||||
{
|
||||
ControllerManager controller_manager(make_shared<MockBus>());
|
||||
DeviceFactory device_factory;
|
||||
RascsiResponse response(device_factory, controller_manager, 32);
|
||||
RascsiResponse response;
|
||||
PbResult result;
|
||||
|
||||
const auto& info = response.GetMappingInfo(result);
|
||||
|
@ -18,7 +18,9 @@ TEST(ScsiControllerTest, GetInitiatorId)
|
||||
{
|
||||
const int ID = 2;
|
||||
|
||||
MockScsiController controller(make_shared<NiceMock<MockBus>>());
|
||||
auto bus = make_shared<NiceMock<MockBus>>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
MockScsiController controller(controller_manager, 0);
|
||||
|
||||
controller.Process(ID);
|
||||
EXPECT_EQ(ID, controller.GetInitiatorId());
|
||||
@ -29,7 +31,8 @@ TEST(ScsiControllerTest, GetInitiatorId)
|
||||
TEST(ScsiControllerTest, Process)
|
||||
{
|
||||
auto bus = make_shared<NiceMock<MockBus>>();
|
||||
MockScsiController controller(bus);
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
MockScsiController controller(controller_manager, 0);
|
||||
|
||||
controller.SetPhase(BUS::phase_t::reserved);
|
||||
ON_CALL(*bus, GetRST).WillByDefault(Return(true));
|
||||
@ -55,7 +58,9 @@ TEST(ScsiControllerTest, Process)
|
||||
|
||||
TEST(ScsiControllerTest, BusFree)
|
||||
{
|
||||
MockScsiController controller(make_shared<NiceMock<MockBus>>());
|
||||
auto bus = make_shared<NiceMock<MockBus>>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
MockScsiController controller(controller_manager, 0);
|
||||
|
||||
controller.SetPhase(BUS::phase_t::busfree);
|
||||
controller.BusFree();
|
||||
@ -87,63 +92,65 @@ TEST(ScsiControllerTest, BusFree)
|
||||
TEST(ScsiControllerTest, Selection)
|
||||
{
|
||||
auto bus = make_shared<NiceMock<MockBus>>();
|
||||
MockScsiController controller(bus, 0);
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockScsiController>(controller_manager, 0);
|
||||
|
||||
controller.SetPhase(BUS::phase_t::selection);
|
||||
controller->SetPhase(BUS::phase_t::selection);
|
||||
ON_CALL(*bus, GetSEL).WillByDefault(Return(true));
|
||||
ON_CALL(*bus, GetBSY).WillByDefault(Return(true));
|
||||
EXPECT_CALL(*bus, GetATN).Times(0);
|
||||
controller.Selection();
|
||||
EXPECT_EQ(BUS::phase_t::selection, controller.GetPhase());
|
||||
controller->Selection();
|
||||
EXPECT_EQ(BUS::phase_t::selection, controller->GetPhase());
|
||||
|
||||
ON_CALL(*bus, GetSEL).WillByDefault(Return(true));
|
||||
ON_CALL(*bus, GetBSY).WillByDefault(Return(false));
|
||||
EXPECT_CALL(*bus, GetATN).Times(0);
|
||||
EXPECT_CALL(controller, Status);
|
||||
controller.Selection();
|
||||
EXPECT_EQ(BUS::phase_t::selection, controller.GetPhase());
|
||||
EXPECT_CALL(*controller, Status);
|
||||
controller->Selection();
|
||||
EXPECT_EQ(BUS::phase_t::selection, controller->GetPhase());
|
||||
|
||||
ON_CALL(*bus, GetSEL).WillByDefault(Return(false));
|
||||
ON_CALL(*bus, GetBSY).WillByDefault(Return(false));
|
||||
EXPECT_CALL(*bus, GetATN).Times(0);
|
||||
controller.Selection();
|
||||
EXPECT_EQ(BUS::phase_t::selection, controller.GetPhase());
|
||||
controller->Selection();
|
||||
EXPECT_EQ(BUS::phase_t::selection, controller->GetPhase());
|
||||
|
||||
ON_CALL(*bus, GetSEL).WillByDefault(Return(false));
|
||||
ON_CALL(*bus, GetBSY).WillByDefault(Return(true));
|
||||
ON_CALL(*bus, GetATN).WillByDefault(Return(false));
|
||||
EXPECT_CALL(*bus, GetATN);
|
||||
controller.Selection();
|
||||
EXPECT_EQ(BUS::phase_t::command, controller.GetPhase());
|
||||
controller->Selection();
|
||||
EXPECT_EQ(BUS::phase_t::command, controller->GetPhase());
|
||||
|
||||
controller.SetPhase(BUS::phase_t::selection);
|
||||
controller->SetPhase(BUS::phase_t::selection);
|
||||
ON_CALL(*bus, GetSEL).WillByDefault(Return(false));
|
||||
ON_CALL(*bus, GetBSY).WillByDefault(Return(true));
|
||||
ON_CALL(*bus, GetATN).WillByDefault(Return(true));
|
||||
EXPECT_CALL(*bus, GetATN);
|
||||
controller.Selection();
|
||||
EXPECT_EQ(BUS::phase_t::msgout, controller.GetPhase());
|
||||
controller->Selection();
|
||||
EXPECT_EQ(BUS::phase_t::msgout, controller->GetPhase());
|
||||
|
||||
controller.SetPhase(BUS::phase_t::reserved);
|
||||
controller->SetPhase(BUS::phase_t::reserved);
|
||||
ON_CALL(*bus, GetDAT).WillByDefault(Return(0));
|
||||
controller.Selection();
|
||||
EXPECT_EQ(BUS::phase_t::reserved, controller.GetPhase());
|
||||
controller->Selection();
|
||||
EXPECT_EQ(BUS::phase_t::reserved, controller->GetPhase());
|
||||
|
||||
ON_CALL(*bus, GetDAT).WillByDefault(Return(1));
|
||||
controller.Selection();
|
||||
EXPECT_EQ(BUS::phase_t::reserved, controller.GetPhase()) << "There is no device that can be selected";
|
||||
controller->Selection();
|
||||
EXPECT_EQ(BUS::phase_t::reserved, controller->GetPhase()) << "There is no device that can be selected";
|
||||
|
||||
auto device = make_shared<MockPrimaryDevice>(0);
|
||||
controller.AddDevice(device);
|
||||
controller->AddDevice(device);
|
||||
EXPECT_CALL(*bus, SetBSY(true));
|
||||
controller.Selection();
|
||||
EXPECT_EQ(BUS::phase_t::selection, controller.GetPhase());
|
||||
controller->Selection();
|
||||
EXPECT_EQ(BUS::phase_t::selection, controller->GetPhase());
|
||||
}
|
||||
|
||||
TEST(ScsiControllerTest, Command)
|
||||
{
|
||||
auto bus = make_shared<NiceMock<MockBus>>();
|
||||
MockScsiController controller(bus, 0);
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
MockScsiController controller(controller_manager, 0);
|
||||
|
||||
controller.SetPhase(BUS::phase_t::command);
|
||||
EXPECT_CALL(controller, Status);
|
||||
@ -170,7 +177,8 @@ TEST(ScsiControllerTest, Command)
|
||||
TEST(ScsiControllerTest, MsgIn)
|
||||
{
|
||||
auto bus = make_shared<NiceMock<MockBus>>();
|
||||
MockScsiController controller(bus, 0);
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
MockScsiController controller(controller_manager, 0);
|
||||
|
||||
controller.SetPhase(BUS::phase_t::reserved);
|
||||
EXPECT_CALL(*bus, SetMSG(true));
|
||||
@ -185,7 +193,8 @@ TEST(ScsiControllerTest, MsgIn)
|
||||
TEST(ScsiControllerTest, MsgOut)
|
||||
{
|
||||
auto bus = make_shared<NiceMock<MockBus>>();
|
||||
MockScsiController controller(bus, 0);
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
MockScsiController controller(controller_manager, 0);
|
||||
|
||||
controller.SetPhase(BUS::phase_t::reserved);
|
||||
EXPECT_CALL(*bus, SetMSG(true));
|
||||
@ -200,7 +209,8 @@ TEST(ScsiControllerTest, MsgOut)
|
||||
TEST(ScsiControllerTest, DataIn)
|
||||
{
|
||||
auto bus = make_shared<NiceMock<MockBus>>();
|
||||
MockScsiController controller(bus, 0);
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
MockScsiController controller(controller_manager, 0);
|
||||
|
||||
controller.SetPhase(BUS::phase_t::reserved);
|
||||
controller.SetLength(0);
|
||||
@ -220,7 +230,8 @@ TEST(ScsiControllerTest, DataIn)
|
||||
TEST(ScsiControllerTest, DataOut)
|
||||
{
|
||||
auto bus = make_shared<NiceMock<MockBus>>();
|
||||
MockScsiController controller(bus, 0);
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
MockScsiController controller(controller_manager, 0);
|
||||
|
||||
controller.SetPhase(BUS::phase_t::reserved);
|
||||
controller.SetLength(0);
|
||||
@ -240,7 +251,8 @@ TEST(ScsiControllerTest, DataOut)
|
||||
TEST(ScsiControllerTest, Error)
|
||||
{
|
||||
auto bus = make_shared<NiceMock<MockBus>>();
|
||||
MockScsiController controller(bus, 0);
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
MockScsiController controller(controller_manager, 0);
|
||||
|
||||
ON_CALL(*bus, GetRST).WillByDefault(Return(true));
|
||||
controller.SetPhase(BUS::phase_t::reserved);
|
||||
@ -282,21 +294,23 @@ TEST(ScsiControllerTest, Error)
|
||||
|
||||
TEST(ScsiControllerTest, RequestSense)
|
||||
{
|
||||
MockScsiController controller(make_shared<NiceMock<MockBus>>());
|
||||
auto bus = make_shared<NiceMock<MockBus>>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockScsiController>(controller_manager, 0);
|
||||
auto device = make_shared<MockPrimaryDevice>(0);
|
||||
const unordered_map<string, string> params;
|
||||
device->Init(params);
|
||||
|
||||
controller.AddDevice(device);
|
||||
controller->AddDevice(device);
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
auto& cmd = controller->GetCmd();
|
||||
// ALLOCATION LENGTH
|
||||
cmd[4] = 255;
|
||||
// Non-existing LUN
|
||||
cmd[1] = 0x20;
|
||||
|
||||
device->SetReady(true);
|
||||
EXPECT_CALL(controller, Status);
|
||||
EXPECT_CALL(*controller, Status);
|
||||
device->Dispatch(scsi_command::eCmdRequestSense);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus()) << "Illegal CHECK CONDITION for non-existing LUN";
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus()) << "Wrong CHECK CONDITION for non-existing LUN";
|
||||
}
|
||||
|
@ -18,21 +18,25 @@ TEST(ScsiDaynaportTest, Inquiry)
|
||||
|
||||
TEST(ScsiDaynaportTest, TestUnitReady)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto daynaport = CreateDevice(SCDP, controller);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto daynaport = CreateDevice(SCDP, *controller);
|
||||
|
||||
EXPECT_CALL(controller, Status());
|
||||
EXPECT_CALL(*controller, Status());
|
||||
daynaport->Dispatch(scsi_command::eCmdTestUnitReady);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
}
|
||||
|
||||
TEST(ScsiDaynaportTest, Read)
|
||||
{
|
||||
vector<uint8_t> buf(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto daynaport = dynamic_pointer_cast<SCSIDaynaPort>(CreateDevice(SCDP, controller));
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto daynaport = dynamic_pointer_cast<SCSIDaynaPort>(CreateDevice(SCDP, *controller));
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
auto& cmd = controller->GetCmd();
|
||||
|
||||
// ALLOCATION LENGTH
|
||||
cmd[4] = 1;
|
||||
@ -42,10 +46,12 @@ TEST(ScsiDaynaportTest, Read)
|
||||
TEST(ScsiDaynaportTest, WriteBytes)
|
||||
{
|
||||
vector<uint8_t> buf(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto daynaport = dynamic_pointer_cast<SCSIDaynaPort>(CreateDevice(SCDP, controller));
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto daynaport = dynamic_pointer_cast<SCSIDaynaPort>(CreateDevice(SCDP, *controller));
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
auto& cmd = controller->GetCmd();
|
||||
|
||||
// Unknown data format
|
||||
cmd[5] = 0xff;
|
||||
@ -54,10 +60,12 @@ TEST(ScsiDaynaportTest, WriteBytes)
|
||||
|
||||
TEST(ScsiDaynaportTest, Read6)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto daynaport = CreateDevice(SCDP, controller);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto daynaport = CreateDevice(SCDP, *controller);
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
auto& cmd = controller->GetCmd();
|
||||
|
||||
cmd[5] = 0xff;
|
||||
EXPECT_THAT([&] { daynaport->Dispatch(scsi_command::eCmdRead6); }, Throws<scsi_exception>(AllOf(
|
||||
@ -68,10 +76,12 @@ TEST(ScsiDaynaportTest, Read6)
|
||||
|
||||
TEST(ScsiDaynaportTest, Write6)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto daynaport = CreateDevice(SCDP, controller);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto daynaport = CreateDevice(SCDP, *controller);
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
auto& cmd = controller->GetCmd();
|
||||
|
||||
cmd[5] = 0x00;
|
||||
EXPECT_THAT([&] { daynaport->Dispatch(scsi_command::eCmdWrite6); }, Throws<scsi_exception>(AllOf(
|
||||
@ -98,23 +108,27 @@ TEST(ScsiDaynaportTest, Write6)
|
||||
|
||||
TEST(ScsiDaynaportTest, TestRetrieveStats)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto daynaport = CreateDevice(SCDP, controller);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto daynaport = CreateDevice(SCDP, *controller);
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
auto& cmd = controller->GetCmd();
|
||||
|
||||
// ALLOCATION LENGTH
|
||||
cmd[4] = 255;
|
||||
EXPECT_CALL(controller, DataIn());
|
||||
EXPECT_CALL(*controller, DataIn());
|
||||
daynaport->Dispatch(scsi_command::eCmdRetrieveStats);
|
||||
}
|
||||
|
||||
TEST(ScsiDaynaportTest, SetInterfaceMode)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto daynaport = CreateDevice(SCDP, controller);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto daynaport = CreateDevice(SCDP, *controller);
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
auto& cmd = controller->GetCmd();
|
||||
|
||||
// Unknown interface command
|
||||
EXPECT_THAT([&] { daynaport->Dispatch(scsi_command::eCmdSetIfaceMode); }, Throws<scsi_exception>(AllOf(
|
||||
@ -123,12 +137,12 @@ TEST(ScsiDaynaportTest, SetInterfaceMode)
|
||||
|
||||
// Not implemented, do nothing
|
||||
cmd[5] = SCSIDaynaPort::CMD_SCSILINK_SETMODE;
|
||||
EXPECT_CALL(controller, Status());
|
||||
EXPECT_CALL(*controller, Status());
|
||||
daynaport->Dispatch(scsi_command::eCmdSetIfaceMode);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
|
||||
cmd[5] = SCSIDaynaPort::CMD_SCSILINK_SETMAC;
|
||||
EXPECT_CALL(controller, DataOut());
|
||||
EXPECT_CALL(*controller, DataOut());
|
||||
daynaport->Dispatch(scsi_command::eCmdSetIfaceMode);
|
||||
|
||||
// Not implemented
|
||||
@ -152,10 +166,12 @@ TEST(ScsiDaynaportTest, SetInterfaceMode)
|
||||
|
||||
TEST(ScsiDaynaportTest, SetMcastAddr)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto daynaport = CreateDevice(SCDP, controller);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto daynaport = CreateDevice(SCDP, *controller);
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
auto& cmd = controller->GetCmd();
|
||||
|
||||
EXPECT_THAT([&] { daynaport->Dispatch(scsi_command::eCmdSetMcastAddr); }, Throws<scsi_exception>(AllOf(
|
||||
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
|
||||
@ -163,16 +179,18 @@ TEST(ScsiDaynaportTest, SetMcastAddr)
|
||||
<< "Length of 0 is not supported";
|
||||
|
||||
cmd[4] = 1;
|
||||
EXPECT_CALL(controller, DataOut());
|
||||
EXPECT_CALL(*controller, DataOut());
|
||||
daynaport->Dispatch(scsi_command::eCmdSetMcastAddr);
|
||||
}
|
||||
|
||||
TEST(ScsiDaynaportTest, EnableInterface)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto daynaport = CreateDevice(SCDP, controller);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
auto daynaport = CreateDevice(SCDP, *controller);
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
auto& cmd = controller->GetCmd();
|
||||
|
||||
// Enable
|
||||
EXPECT_THAT([&] { daynaport->Dispatch(scsi_command::eCmdEnableInterface); }, Throws<scsi_exception>(AllOf(
|
||||
|
@ -16,8 +16,10 @@ using namespace std;
|
||||
|
||||
TEST(ScsiPrinterTest, Init)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto printer = CreateDevice(SCLP, controller);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<NiceMock<MockAbstractController>>(controller_manager, 0);
|
||||
auto printer = CreateDevice(SCLP, *controller);
|
||||
|
||||
unordered_map<string, string> params;
|
||||
EXPECT_TRUE(printer->Init(params));
|
||||
@ -31,12 +33,14 @@ TEST(ScsiPrinterTest, Init)
|
||||
|
||||
TEST(ScsiPrinterTest, TestUnitReady)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto printer = CreateDevice(SCLP, controller);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<NiceMock<MockAbstractController>>(controller_manager, 0);
|
||||
auto printer = CreateDevice(SCLP, *controller);
|
||||
|
||||
EXPECT_CALL(controller, Status());
|
||||
EXPECT_CALL(*controller, Status());
|
||||
printer->Dispatch(scsi_command::eCmdTestUnitReady);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
}
|
||||
|
||||
TEST(ScsiPrinterTest, Inquiry)
|
||||
@ -46,42 +50,50 @@ TEST(ScsiPrinterTest, Inquiry)
|
||||
|
||||
TEST(ScsiPrinterTest, ReserveUnit)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto printer = CreateDevice(SCLP, controller);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<NiceMock<MockAbstractController>>(controller_manager, 0);
|
||||
auto printer = CreateDevice(SCLP, *controller);
|
||||
|
||||
EXPECT_CALL(controller, Status()).Times(1);
|
||||
EXPECT_CALL(*controller, Status()).Times(1);
|
||||
printer->Dispatch(scsi_command::eCmdReserve6);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
}
|
||||
|
||||
TEST(ScsiPrinterTest, ReleaseUnit)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto printer = CreateDevice(SCLP, controller);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<NiceMock<MockAbstractController>>(controller_manager, 0);
|
||||
auto printer = CreateDevice(SCLP, *controller);
|
||||
|
||||
EXPECT_CALL(controller, Status()).Times(1);
|
||||
EXPECT_CALL(*controller, Status()).Times(1);
|
||||
printer->Dispatch(scsi_command::eCmdRelease6);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
}
|
||||
|
||||
TEST(ScsiPrinterTest, SendDiagnostic)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto printer = CreateDevice(SCLP, controller);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<NiceMock<MockAbstractController>>(controller_manager, 0);
|
||||
auto printer = CreateDevice(SCLP, *controller);
|
||||
|
||||
EXPECT_CALL(controller, Status()).Times(1);
|
||||
EXPECT_CALL(*controller, Status()).Times(1);
|
||||
printer->Dispatch(scsi_command::eCmdSendDiagnostic);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
}
|
||||
|
||||
TEST(ScsiPrinterTest, Print)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto printer = CreateDevice(SCLP, controller);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<NiceMock<MockAbstractController>>(controller_manager, 0);
|
||||
auto printer = CreateDevice(SCLP, *controller);
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
auto& cmd = controller->GetCmd();
|
||||
|
||||
EXPECT_CALL(controller, DataOut());
|
||||
EXPECT_CALL(*controller, DataOut());
|
||||
printer->Dispatch(scsi_command::eCmdPrint);
|
||||
|
||||
cmd[3] = 0xff;
|
||||
@ -94,18 +106,22 @@ TEST(ScsiPrinterTest, Print)
|
||||
|
||||
TEST(ScsiPrinterTest, StopPrint)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto printer = CreateDevice(SCLP, controller);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<NiceMock<MockAbstractController>>(controller_manager, 0);
|
||||
auto printer = CreateDevice(SCLP, *controller);
|
||||
|
||||
EXPECT_CALL(controller, Status());
|
||||
EXPECT_CALL(*controller, Status());
|
||||
printer->Dispatch(scsi_command::eCmdStopPrint);
|
||||
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
||||
EXPECT_EQ(status::GOOD, controller->GetStatus());
|
||||
}
|
||||
|
||||
TEST(ScsiPrinterTest, SynchronizeBuffer)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto printer = CreateDevice(SCLP, controller);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<NiceMock<MockAbstractController>>(controller_manager, 0);
|
||||
auto printer = CreateDevice(SCLP, *controller);
|
||||
|
||||
EXPECT_THAT([&] { printer->Dispatch(scsi_command::eCmdSynchronizeBuffer); }, Throws<scsi_exception>(AllOf(
|
||||
Property(&scsi_exception::get_sense_key, sense_key::ABORTED_COMMAND),
|
||||
@ -117,8 +133,10 @@ TEST(ScsiPrinterTest, SynchronizeBuffer)
|
||||
|
||||
TEST(ScsiPrinterTest, WriteByteSequence)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto printer = dynamic_pointer_cast<SCSIPrinter>(CreateDevice(SCLP, controller));
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<NiceMock<MockAbstractController>>(controller_manager, 0);
|
||||
auto printer = CreateDevice(SCLP, *controller);
|
||||
|
||||
vector<uint8_t> buf(1);
|
||||
EXPECT_TRUE(printer->WriteByteSequence(buf, buf.size()));
|
||||
|
@ -112,13 +112,15 @@ TEST(ScsiCdTest, Open)
|
||||
|
||||
TEST(ScsiCdTest, ReadToc)
|
||||
{
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<MockAbstractController>(controller_manager, 0);
|
||||
const unordered_set<uint32_t> sector_sizes;
|
||||
auto cd = make_shared<MockSCSICD>(0, sector_sizes);
|
||||
const unordered_map<string, string> params;
|
||||
cd->Init(params);
|
||||
|
||||
controller.AddDevice(cd);
|
||||
controller->AddDevice(cd);
|
||||
|
||||
EXPECT_THAT([&] { cd->Dispatch(scsi_command::eCmdReadToc); }, Throws<scsi_exception>(AllOf(
|
||||
Property(&scsi_exception::get_sense_key, sense_key::NOT_READY),
|
||||
|
@ -23,9 +23,8 @@ using namespace filesystem;
|
||||
shared_ptr<PrimaryDevice> CreateDevice(PbDeviceType type, MockAbstractController& controller, const string& extension)
|
||||
{
|
||||
DeviceFactory device_factory;
|
||||
auto controller_manager = make_shared<ControllerManager>(controller.GetBus());
|
||||
|
||||
auto device = device_factory.CreateDevice(*controller_manager, type, 0, extension);
|
||||
auto device = device_factory.CreateDevice(type, 0, extension);
|
||||
unordered_map<string, string> params;
|
||||
device->Init(params);
|
||||
|
||||
@ -37,16 +36,18 @@ shared_ptr<PrimaryDevice> CreateDevice(PbDeviceType type, MockAbstractController
|
||||
void TestInquiry(PbDeviceType type, device_type t, scsi_level l, const string& ident, int additional_length,
|
||||
bool removable, const string& extension)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto device = CreateDevice(type, controller, extension);
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller = make_shared<NiceMock<MockAbstractController>>(controller_manager, 0);
|
||||
auto device = CreateDevice(type, *controller, extension);
|
||||
|
||||
auto& cmd = controller.GetCmd();
|
||||
auto& cmd = controller->GetCmd();
|
||||
|
||||
// ALLOCATION LENGTH
|
||||
cmd[4] = 255;
|
||||
EXPECT_CALL(controller, DataIn());
|
||||
EXPECT_CALL(*controller, DataIn());
|
||||
device->Dispatch(scsi_command::eCmdInquiry);
|
||||
const vector<uint8_t>& buffer = controller.GetBuffer();
|
||||
const vector<uint8_t>& buffer = controller->GetBuffer();
|
||||
EXPECT_EQ(t, static_cast<device_type>(buffer[0]));
|
||||
EXPECT_EQ(removable ? 0x80: 0x00, buffer[1]);
|
||||
EXPECT_EQ(l, static_cast<scsi_level>(buffer[2]));
|
||||
|
Loading…
Reference in New Issue
Block a user