Merge branch 'develop' into feature_bpi3

This commit is contained in:
Tony Kuker 2022-11-02 09:11:48 -05:00
commit 4b7b8eec92
103 changed files with 2141 additions and 1556 deletions

8
.gitignore vendored
View File

@ -7,7 +7,6 @@ core
__pycache__
current
rascsi_interface_pb2.py
src/raspberrypi/hfdisk/
*~
messages.pot
messages.mo
@ -27,3 +26,10 @@ s.sh
# temporary kicad files
*-backups
# VSCode temp file
settings.json
# submodules
hfdisk*
mac-hard-disk-drivers

View File

@ -9,8 +9,8 @@
#pragma once
#include "os.h"
#include "scsi.h"
#include <cstdint>
#include <array>
#include <unordered_map>
#include "hal/board_type.h"
@ -87,14 +87,14 @@ public:
virtual bool GetREQ() const = 0;
virtual void SetREQ(bool ast) = 0;
virtual BYTE GetDAT() = 0;
virtual void SetDAT(BYTE dat) = 0;
virtual uint8_t GetDAT() = 0;
virtual void SetDAT(uint8_t dat) = 0;
virtual bool GetDP() const = 0; // Get parity signal
virtual uint32_t Acquire() = 0;
virtual int CommandHandShake(BYTE *buf) = 0;
virtual int ReceiveHandShake(BYTE *buf, int count) = 0;
virtual int SendHandShake(BYTE *buf, int count, int delay_after_bytes) = 0;
virtual int CommandHandShake(uint8_t *buf) = 0;
virtual int ReceiveHandShake(uint8_t *buf, int count) = 0;
virtual int SendHandShake(uint8_t *buf, int count, int delay_after_bytes) = 0;
virtual bool GetSignal(board_type::pi_physical_pin_e pin) const = 0;
// Get SCSI input signal value

View File

@ -121,16 +121,11 @@ bool AbstractController::AddDevice(shared_ptr<PrimaryDevice> device)
return true;
}
bool AbstractController::RemoveDevice(const shared_ptr<PrimaryDevice> device)
bool AbstractController::RemoveDevice(shared_ptr<PrimaryDevice> device)
{
const size_t count = luns.erase(device->GetLun());
assert (count == 1);
device->SetController(nullptr);
if (count == 1) {
device->SetController(nullptr);
}
return count == 1;
return luns.erase(device->GetLun()) == 1;
}
bool AbstractController::HasDeviceForLun(int lun) const

View File

@ -25,12 +25,6 @@ class PrimaryDevice;
class AbstractController : public PhaseHandler
{
friend class PrimaryDevice;
friend class ScsiController;
// Logical units of this controller mapped to their LUN numbers
unordered_map<int, shared_ptr<PrimaryDevice>> luns;
public:
enum class rascsi_shutdown_mode {
@ -40,21 +34,6 @@ public:
RESTART_PI
};
using ctrl_t = struct _ctrl_t {
// Command data, dynamically resized if required
vector<int> cmd = vector<int>(16);
scsi_defs::status status; // Status data
int message; // Message data
// Transfer
vector<BYTE> buffer; // Transfer data buffer
uint32_t blocks; // Number of transfer blocks
uint64_t next; // Next record
uint32_t offset; // Transfer offset
uint32_t length; // Transfer remaining length
};
AbstractController(shared_ptr<BUS> bus, int target_id, int max_luns) : target_id(target_id), bus(bus), max_luns(max_luns) {}
~AbstractController() override = default;
@ -70,42 +49,76 @@ public:
int GetTargetId() const { return target_id; }
int GetMaxLuns() const { return max_luns; }
int GetLunCount() const { return (int)luns.size(); }
int GetLunCount() const { return static_cast<int>(luns.size()); }
unordered_set<shared_ptr<PrimaryDevice>> GetDevices() const;
shared_ptr<PrimaryDevice> GetDeviceForLun(int) const;
bool AddDevice(shared_ptr<PrimaryDevice>);
bool RemoveDevice(const shared_ptr<PrimaryDevice>);
bool RemoveDevice(shared_ptr<PrimaryDevice>);
bool HasDeviceForLun(int) const;
int ExtractInitiatorId(int) const;
// TODO These should probably be extracted into a new TransferHandler class
void AllocateBuffer(size_t);
vector<BYTE>& GetBuffer() { return ctrl.buffer; }
vector<uint8_t>& GetBuffer() { return ctrl.buffer; }
scsi_defs::status GetStatus() const { return ctrl.status; }
void SetStatus(scsi_defs::status s) { ctrl.status = s; }
uint32_t GetLength() const { return ctrl.length; }
void SetLength(uint32_t l) { ctrl.length = l; }
uint32_t GetBlocks() const { return ctrl.blocks; }
void SetBlocks(uint32_t b) { ctrl.blocks = b; }
void DecrementBlocks() { --ctrl.blocks; }
uint64_t GetNext() const { return ctrl.next; }
void SetNext(uint64_t n) { ctrl.next = n; }
void IncrementNext() { ++ctrl.next; }
int GetMessage() const { return ctrl.message; }
void SetMessage(int m) { ctrl.message = m; }
vector<int>& GetCmd() { return ctrl.cmd; }
int GetCmd(int index) const { return ctrl.cmd[index]; }
bool IsByteTransfer() const { return is_byte_transfer; }
void SetByteTransfer(bool);
uint32_t GetBytesToTransfer() const { return bytes_to_transfer; }
void SetBytesToTransfer(uint32_t b) { bytes_to_transfer = b; }
protected:
inline shared_ptr<BUS> GetBus() const { return bus; }
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; }
void ProcessPhase();
vector<int>& GetCmd() { return ctrl.cmd; }
void AllocateCmd(size_t);
// TODO These should probably be extracted into a new TransferHandler class
bool HasValidLength() const { return ctrl.length != 0; }
int GetOffset() const { return ctrl.offset; }
void ResetOffset() { ctrl.offset = 0; }
void SetLength(uint32_t l) { ctrl.length = l; }
void UpdateOffsetAndLength() { ctrl.offset += ctrl.length; ctrl.length = 0; }
private:
using ctrl_t = struct _ctrl_t {
// Command data, dynamically resized if required
vector<int> cmd = vector<int>(16);
scsi_defs::status status; // Status data
int message; // Message data
// Transfer
vector<uint8_t> buffer; // Transfer data buffer
uint32_t blocks; // Number of transfer blocks
uint64_t next; // Next record
uint32_t offset; // Transfer offset
uint32_t length; // Transfer remaining length
};
ctrl_t ctrl = {};
// Logical units of this controller mapped to their LUN numbers
unordered_map<int, shared_ptr<PrimaryDevice>> luns;
int target_id;
shared_ptr<BUS> bus;
@ -114,7 +127,4 @@ private:
bool is_byte_transfer = false;
uint32_t bytes_to_transfer = 0;
ctrl_t ctrl = {};
ctrl_t* GetCtrl() { return &ctrl; }
};

View File

@ -23,13 +23,13 @@ class PrimaryDevice;
class ControllerManager
{
std::shared_ptr<BUS> bus;
shared_ptr<BUS> bus;
unordered_map<int, shared_ptr<AbstractController>> controllers;
public:
explicit ControllerManager(std::shared_ptr<BUS> bus) : bus(bus) {}
explicit ControllerManager(shared_ptr<BUS> bus) : bus(bus) {}
~ControllerManager() = default;
// Maximum number of controller devices

View File

@ -16,8 +16,9 @@
#include "hal/gpiobus.h"
#include "hal/systimer.h"
#include "rascsi_exceptions.h"
#include "devices/scsi_host_bridge.h"
#include "devices/scsi_daynaport.h"
#include "devices/interfaces/byte_writer.h"
#include "devices/mode_page_device.h"
#include "devices/disk.h"
#include "scsi_controller.h"
#include <sstream>
#include <iomanip>
@ -27,8 +28,6 @@
using namespace scsi_defs;
const int ScsiController::LUN_MAX = 32;
ScsiController::ScsiController(shared_ptr<BUS> bus, int target_id) : AbstractController(bus, target_id, LUN_MAX)
{
// The initial buffer size will default to either the default buffer size OR
@ -53,17 +52,17 @@ void ScsiController::Reset()
BUS::phase_t ScsiController::Process(int id)
{
// Get bus information
bus->Acquire();
GetBus()->Acquire();
// Check to see if the reset signal was asserted
if (bus->GetRST()) {
if (GetBus()->GetRST()) {
LOGWARN("RESET signal received!")
// Reset the controller
Reset();
// Reset the bus
bus->Reset();
GetBus()->Reset();
return GetPhase();
}
@ -85,7 +84,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();
bus->Reset();
GetBus()->Reset();
BusFree();
}
@ -100,15 +99,15 @@ void ScsiController::BusFree()
SetPhase(BUS::phase_t::busfree);
bus->SetREQ(false);
bus->SetMSG(false);
bus->SetCD(false);
bus->SetIO(false);
bus->SetBSY(false);
GetBus()->SetREQ(false);
GetBus()->SetMSG(false);
GetBus()->SetCD(false);
GetBus()->SetIO(false);
GetBus()->SetBSY(false);
// Initialize status and message
SetStatus(status::GOOD);
ctrl.message = 0x00;
SetMessage(0x00);
// Initialize ATN message reception status
scsi.atnmsg = false;
@ -147,7 +146,7 @@ void ScsiController::BusFree()
}
// Move to selection phase
if (bus->GetSEL() && !bus->GetBSY()) {
if (GetBus()->GetSEL() && !GetBus()->GetBSY()) {
Selection();
}
}
@ -156,7 +155,7 @@ void ScsiController::Selection()
{
if (!IsSelection()) {
// A different device controller was selected
if (int id = 1 << GetTargetId(); ((int)bus->GetDAT() & id) == 0) {
if (int id = 1 << GetTargetId(); (static_cast<int>(GetBus()->GetDAT()) & id) == 0) {
return;
}
@ -170,14 +169,14 @@ void ScsiController::Selection()
SetPhase(BUS::phase_t::selection);
// Raise BSY and respond
bus->SetBSY(true);
GetBus()->SetBSY(true);
return;
}
// Selection completed
if (!bus->GetSEL() && bus->GetBSY()) {
if (!GetBus()->GetSEL() && GetBus()->GetBSY()) {
// Message out phase if ATN=1, otherwise command phase
if (bus->GetATN()) {
if (GetBus()->GetATN()) {
MsgOut();
} else {
Command();
@ -192,11 +191,12 @@ void ScsiController::Command()
SetPhase(BUS::phase_t::command);
bus->SetMSG(false);
bus->SetCD(true);
bus->SetIO(false);
GetBus()->SetMSG(false);
GetBus()->SetCD(true);
GetBus()->SetIO(false);
const int actual_count = bus->CommandHandShake(GetBuffer().data());
const int actual_count = GetBus()->CommandHandShake(GetBuffer().data());
// TODO Try to move GetCommandByteCount() to BUS, so that the controller does not need to know GPIOBUS
const int command_byte_count = GPIOBUS::GetCommandByteCount(GetBuffer()[0]);
// If not able to receive all, move to the status phase
@ -212,8 +212,8 @@ void ScsiController::Command()
// Command data transfer
stringstream s;
for (int i = 0; i < command_byte_count; i++) {
ctrl.cmd[i] = GetBuffer()[i];
s << setfill('0') << setw(2) << hex << ctrl.cmd[i];
GetCmd()[i] = GetBuffer()[i];
s << setfill('0') << setw(2) << hex << GetCmd(i);
}
LOGTRACE("%s CDB=$%s",__PRETTY_FUNCTION__, s.str().c_str())
@ -225,11 +225,11 @@ void ScsiController::Command()
void ScsiController::Execute()
{
LOGDEBUG("++++ CMD ++++ %s Executing command $%02X", __PRETTY_FUNCTION__, (int)GetOpcode())
LOGDEBUG("++++ CMD ++++ %s Executing command $%02X", __PRETTY_FUNCTION__, static_cast<int>(GetOpcode()))
// Initialization for data transfer
ResetOffset();
ctrl.blocks = 1;
SetBlocks(1);
execstart = SysTimer::GetTimerLow();
// Discard pending sense data from the previous command if the current command is not REQUEST SENSE
@ -267,13 +267,13 @@ void ScsiController::Execute()
device->SetStatusCode(0);
}
if (!device->CheckReservation(initiator_id, GetOpcode(), ctrl.cmd[4] & 0x01)) {
if (!device->CheckReservation(initiator_id, GetOpcode(), GetCmd(4) & 0x01)) {
Error(sense_key::ABORTED_COMMAND, asc::NO_ADDITIONAL_SENSE_INFORMATION, status::RESERVATION_CONFLICT);
}
else {
try {
if (!device->Dispatch(GetOpcode())) {
LOGTRACE("ID %d LUN %d received unsupported command: $%02X", GetTargetId(), lun, (int)GetOpcode())
LOGTRACE("ID %d LUN %d received unsupported command: $%02X", GetTargetId(), lun, static_cast<int>(GetOpcode()))
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_COMMAND_OPERATION_CODE);
}
@ -305,20 +305,20 @@ void ScsiController::Status()
SysTimer::SleepUsec(5);
}
LOGTRACE("%s Status Phase, status is $%02X",__PRETTY_FUNCTION__, (int)GetStatus())
LOGTRACE("%s Status Phase, status is $%02X",__PRETTY_FUNCTION__, static_cast<int>(GetStatus()))
SetPhase(BUS::phase_t::status);
// Signal line operated by the target
bus->SetMSG(false);
bus->SetCD(true);
bus->SetIO(true);
GetBus()->SetMSG(false);
GetBus()->SetCD(true);
GetBus()->SetIO(true);
// Data transfer is 1 byte x 1 block
ResetOffset();
SetLength(1);
ctrl.blocks = 1;
GetBuffer()[0] = (BYTE)GetStatus();
SetBlocks(1);
GetBuffer()[0] = (uint8_t)GetStatus();
return;
}
@ -333,9 +333,9 @@ void ScsiController::MsgIn()
SetPhase(BUS::phase_t::msgin);
bus->SetMSG(true);
bus->SetCD(true);
bus->SetIO(true);
GetBus()->SetMSG(true);
GetBus()->SetCD(true);
GetBus()->SetIO(true);
ResetOffset();
return;
@ -360,14 +360,14 @@ void ScsiController::MsgOut()
SetPhase(BUS::phase_t::msgout);
bus->SetMSG(true);
bus->SetCD(true);
bus->SetIO(false);
GetBus()->SetMSG(true);
GetBus()->SetCD(true);
GetBus()->SetIO(false);
// Data transfer is 1 byte x 1 block
ResetOffset();
SetLength(1);
ctrl.blocks = 1;
SetBlocks(1);
return;
}
@ -393,9 +393,9 @@ void ScsiController::DataIn()
SetPhase(BUS::phase_t::datain);
bus->SetMSG(false);
bus->SetCD(false);
bus->SetIO(true);
GetBus()->SetMSG(false);
GetBus()->SetCD(false);
GetBus()->SetIO(true);
ResetOffset();
@ -424,9 +424,9 @@ void ScsiController::DataOut()
SetPhase(BUS::phase_t::dataout);
// Signal line operated by the target
bus->SetMSG(false);
bus->SetCD(false);
bus->SetIO(false);
GetBus()->SetMSG(false);
GetBus()->SetCD(false);
GetBus()->SetIO(false);
ResetOffset();
return;
@ -438,12 +438,12 @@ void ScsiController::DataOut()
void ScsiController::Error(sense_key sense_key, asc asc, status status)
{
// Get bus information
bus->Acquire();
GetBus()->Acquire();
// Reset check
if (bus->GetRST()) {
if (GetBus()->GetRST()) {
Reset();
bus->Reset();
GetBus()->Reset();
return;
}
@ -460,7 +460,7 @@ void ScsiController::Error(sense_key sense_key, asc asc, status status)
LOGERROR("No LUN 0 for device %d", GetTargetId())
SetStatus(status);
ctrl.message = 0x00;
SetMessage(0x00);
Status();
@ -471,14 +471,14 @@ void ScsiController::Error(sense_key sense_key, asc asc, status status)
}
if (sense_key != sense_key::NO_SENSE || asc != asc::NO_ADDITIONAL_SENSE_INFORMATION) {
LOGDEBUG("Error status: Sense Key $%02X, ASC $%02X", (int)sense_key, (int)asc)
LOGDEBUG("Error status: Sense Key $%02X, ASC $%02X", static_cast<int>(sense_key), static_cast<int>(asc))
// Set Sense Key and ASC for a subsequent REQUEST SENSE
GetDeviceForLun(lun)->SetStatusCode(((int)sense_key << 16) | ((int)asc << 8));
GetDeviceForLun(lun)->SetStatusCode((static_cast<int>(sense_key) << 16) | (static_cast<int>(asc) << 8));
}
SetStatus(status);
ctrl.message = 0x00;
SetMessage(0x00);
LOGTRACE("%s Error (to status phase)", __PRETTY_FUNCTION__)
@ -487,18 +487,18 @@ void ScsiController::Error(sense_key sense_key, asc asc, status status)
void ScsiController::Send()
{
assert(!bus->GetREQ());
assert(bus->GetIO());
assert(!GetBus()->GetREQ());
assert(GetBus()->GetIO());
if (HasValidLength()) {
LOGTRACE("%s%s", __PRETTY_FUNCTION__, (" Sending handhake with offset " + to_string(GetOffset()) + ", length "
+ to_string(ctrl.length)).c_str())
+ to_string(GetLength())).c_str())
// TODO The delay has to be taken from ctrl.unit[lun], but as there are currently no Daynaport drivers for
// LUNs other than 0 this work-around works.
if (const int len = bus->SendHandShake(GetBuffer().data() + ctrl.offset, ctrl.length,
if (const int len = GetBus()->SendHandShake(GetBuffer().data() + GetOffset(), GetLength(),
HasDeviceForLun(0) ? GetDeviceForLun(0)->GetSendDelay() : 0);
len != (int)ctrl.length) {
len != static_cast<int>(GetLength())) {
// If you cannot send all, move to status phase
Error(sense_key::ABORTED_COMMAND);
return;
@ -510,14 +510,14 @@ void ScsiController::Send()
}
// Block subtraction, result initialization
ctrl.blocks--;
DecrementBlocks();
bool result = true;
// Processing after data collection (read/data-in only)
if (IsDataIn() && ctrl.blocks != 0) {
if (IsDataIn() && GetBlocks() != 0) {
// set next buffer (set offset, length)
result = XferIn(GetBuffer());
LOGTRACE("%s%s", __PRETTY_FUNCTION__, (" Processing after data collection. Blocks: " + to_string(ctrl.blocks)).c_str())
LOGTRACE("%s%s", __PRETTY_FUNCTION__, (" Processing after data collection. Blocks: " + to_string(GetBlocks())).c_str())
}
// If result FALSE, move to status phase
@ -527,10 +527,10 @@ void ScsiController::Send()
}
// Continue sending if block !=0
if (ctrl.blocks != 0){
LOGTRACE("%s%s", __PRETTY_FUNCTION__, (" Continuing to send. Blocks: " + to_string(ctrl.blocks)).c_str())
if (GetBlocks() != 0){
LOGTRACE("%s%s", __PRETTY_FUNCTION__, (" Continuing to send. Blocks: " + to_string(GetBlocks())).c_str())
assert(HasValidLength());
assert(ctrl.offset == 0);
assert(GetOffset() == 0);
return;
}
@ -562,8 +562,8 @@ void ScsiController::Send()
case BUS::phase_t::status:
// Message in phase
SetLength(1);
ctrl.blocks = 1;
GetBuffer()[0] = (BYTE)ctrl.message;
SetBlocks(1);
GetBuffer()[0] = (uint8_t)GetMessage();
MsgIn();
break;
@ -583,17 +583,17 @@ void ScsiController::Receive()
LOGTRACE("%s",__PRETTY_FUNCTION__)
// REQ is low
assert(!bus->GetREQ());
assert(!bus->GetIO());
assert(!GetBus()->GetREQ());
assert(!GetBus()->GetIO());
// Length != 0 if received
if (HasValidLength()) {
LOGTRACE("%s Length is %d bytes", __PRETTY_FUNCTION__, ctrl.length)
LOGTRACE("%s Length is %d bytes", __PRETTY_FUNCTION__, GetLength())
// If not able to receive all, move to status phase
if (int len = bus->ReceiveHandShake(GetBuffer().data() + GetOffset(), ctrl.length);
len != (int)ctrl.length) {
LOGERROR("%s Not able to receive %d bytes of data, only received %d",__PRETTY_FUNCTION__, ctrl.length, len)
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);
return;
}
@ -604,14 +604,14 @@ void ScsiController::Receive()
}
// Block subtraction, result initialization
ctrl.blocks--;
DecrementBlocks();
bool result = true;
// Processing after receiving data (by phase)
LOGTRACE("%s Phase: %s",__PRETTY_FUNCTION__, BUS::GetPhaseStrRaw(GetPhase()))
switch (GetPhase()) {
case BUS::phase_t::dataout:
if (ctrl.blocks == 0) {
if (GetBlocks() == 0) {
// End with this buffer
result = XferOut(false);
} else {
@ -621,15 +621,15 @@ void ScsiController::Receive()
break;
case BUS::phase_t::msgout:
ctrl.message = GetBuffer()[0];
if (!XferMsg(ctrl.message)) {
SetMessage(GetBuffer()[0]);
if (!XferMsg(GetMessage())) {
// Immediately free the bus if message output fails
BusFree();
return;
}
// Clear message data in preparation for message-in
ctrl.message = 0x00;
SetMessage(0x00);
break;
default:
@ -637,16 +637,15 @@ void ScsiController::Receive()
}
// If result FALSE, move to status phase
// TODO Check whether we can raise scsi_exception here in order to simplify the error handling
if (!result) {
Error(sense_key::ABORTED_COMMAND);
return;
}
// Continue to receive if block !=0
if (ctrl.blocks != 0) {
// Continue to receive if block != 0
if (GetBlocks() != 0) {
assert(HasValidLength());
assert(ctrl.offset == 0);
assert(GetOffset() == 0);
return;
}
@ -679,7 +678,7 @@ bool ScsiController::XferMsg(int msg)
// Save message out data
if (scsi.atnmsg) {
scsi.msb[scsi.msc] = (BYTE)msg;
scsi.msb[scsi.msc] = (uint8_t)msg;
scsi.msc++;
scsi.msc %= 256;
}
@ -689,22 +688,21 @@ bool ScsiController::XferMsg(int msg)
void ScsiController::ReceiveBytes()
{
assert(!bus->GetREQ());
assert(!bus->GetIO());
assert(!GetBus()->GetREQ());
assert(!GetBus()->GetIO());
if (HasValidLength()) {
LOGTRACE("%s Length is %d bytes", __PRETTY_FUNCTION__, ctrl.length)
LOGTRACE("%s Length is %d bytes", __PRETTY_FUNCTION__, GetLength())
// If not able to receive all, move to status phase
if (uint32_t len = bus->ReceiveHandShake(GetBuffer().data() + GetOffset(), ctrl.length);
len != ctrl.length) {
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__, ctrl.length, len)
__PRETTY_FUNCTION__, GetLength(), len)
Error(sense_key::ABORTED_COMMAND);
return;
}
bytes_to_transfer = ctrl.length;
SetBytesToTransfer(GetLength());
UpdateOffsetAndLength();
@ -722,15 +720,15 @@ void ScsiController::ReceiveBytes()
break;
case BUS::phase_t::msgout:
ctrl.message = GetBuffer()[0];
if (!XferMsg(ctrl.message)) {
SetMessage(GetBuffer()[0]);
if (!XferMsg(GetMessage())) {
// Immediately free the bus if message output fails
BusFree();
return;
}
// Clear message data in preparation for message-in
ctrl.message = 0x00;
SetMessage(0x00);
break;
default:
@ -771,11 +769,11 @@ bool ScsiController::XferOut(bool cont)
return XferOutBlockOriented(cont);
}
const uint32_t length = bytes_to_transfer;
const uint32_t count = GetBytesToTransfer();
SetByteTransfer(false);
auto device = GetDeviceForLun(GetEffectiveLun());
return device != nullptr ? device->WriteByteSequence(GetBuffer(), length) : false;
return device != nullptr ? device->WriteByteSequence(GetBuffer(), count) : false;
}
void ScsiController::DataOutNonBlockOriented()
@ -795,10 +793,9 @@ void ScsiController::DataOutNonBlockOriented()
case scsi_command::eCmdModeSelect6:
case scsi_command::eCmdModeSelect10: {
// TODO Try to get rid of this cast
if (auto device = dynamic_pointer_cast<ModePageDevice>(GetDeviceForLun(GetEffectiveLun()));
device != nullptr) {
device->ModeSelect(GetOpcode(), ctrl.cmd, GetBuffer(), GetOffset());
device->ModeSelect(GetOpcode(), GetCmd(), GetBuffer(), GetOffset());
}
else {
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_COMMAND_OPERATION_CODE);
@ -811,7 +808,7 @@ void ScsiController::DataOutNonBlockOriented()
break;
default:
LOGWARN("Unexpected Data Out phase for command $%02X", (int)GetOpcode())
LOGWARN("Unexpected Data Out phase for command $%02X", static_cast<int>(GetOpcode()))
break;
}
}
@ -822,11 +819,11 @@ void ScsiController::DataOutNonBlockOriented()
// *Reset offset and length
//
//---------------------------------------------------------------------------
bool ScsiController::XferIn(vector<BYTE>& buf)
bool ScsiController::XferIn(vector<uint8_t>& buf)
{
assert(IsDataIn());
LOGTRACE("%s command=%02X", __PRETTY_FUNCTION__, (int)GetOpcode())
LOGTRACE("%s command=%02X", __PRETTY_FUNCTION__, static_cast<int>(GetOpcode()))
int lun = GetEffectiveLun();
if (!HasDeviceForLun(lun)) {
@ -840,14 +837,14 @@ bool ScsiController::XferIn(vector<BYTE>& buf)
case scsi_command::eCmdRead16:
// Read from disk
try {
SetLength(dynamic_pointer_cast<Disk>(GetDeviceForLun(lun))->Read(ctrl.cmd, buf, ctrl.next));
SetLength(dynamic_pointer_cast<Disk>(GetDeviceForLun(lun))->Read(GetCmd(), buf, GetNext()));
}
catch(const scsi_exception&) {
// If there is an error, go to the status phase
return false;
}
ctrl.next++;
IncrementNext();
// If things are normal, work setting
ResetOffset();
@ -867,26 +864,33 @@ bool ScsiController::XferIn(vector<BYTE>& buf)
// Data transfer OUT
// *If cont=true, reset the offset and length
//
// TODO Try to use less casts
//
//---------------------------------------------------------------------------
bool ScsiController::XferOutBlockOriented(bool cont)
{
auto disk = dynamic_pointer_cast<Disk>(GetDeviceForLun(GetEffectiveLun()));
if (disk == nullptr) {
return false;
}
auto device = GetDeviceForLun(GetEffectiveLun());
// Limited to write commands
switch (GetOpcode()) {
case scsi_command::eCmdModeSelect6:
case scsi_command::eCmdModeSelect10:
{
auto mode_page_device = dynamic_pointer_cast<ModePageDevice>(device);
if (mode_page_device == nullptr) {
return false;
}
try {
disk->ModeSelect(GetOpcode(), ctrl.cmd, GetBuffer(), GetOffset());
mode_page_device->ModeSelect(GetOpcode(), GetCmd(), GetBuffer(), GetOffset());
}
catch(const scsi_exception& e) {
Error(e.get_sense_key(), e.get_asc());
return false;
}
break;
}
case scsi_command::eCmdWrite6:
case scsi_command::eCmdWrite10:
@ -895,11 +899,9 @@ bool ScsiController::XferOutBlockOriented(bool cont)
case scsi_command::eCmdVerify10:
case scsi_command::eCmdVerify16:
{
// Special case Write function for bridge
// TODO This class must not know about SCSIBR
if (auto bridge = dynamic_pointer_cast<SCSIBR>(disk); bridge) {
if (!bridge->WriteBytes(ctrl.cmd, GetBuffer(), ctrl.length)) {
// Write failed
// Special case for SCBR and SCDP
if (auto byte_writer = dynamic_pointer_cast<ByteWriter>(device); byte_writer) {
if (!byte_writer->WriteBytes(GetCmd(), GetBuffer(), GetLength())) {
return false;
}
@ -907,38 +909,31 @@ bool ScsiController::XferOutBlockOriented(bool cont)
break;
}
// Special case Write function for DaynaPort
// TODO This class must not know about DaynaPort
if (auto daynaport = dynamic_pointer_cast<SCSIDaynaPort>(disk); daynaport) {
daynaport->WriteBytes(ctrl.cmd, GetBuffer(), 0);
ResetOffset();
ctrl.blocks = 0;
break;
auto disk = dynamic_pointer_cast<Disk>(device);
if (disk == nullptr) {
return false;
}
try {
disk->Write(ctrl.cmd, GetBuffer(), ctrl.next - 1);
disk->Write(GetCmd(), GetBuffer(), GetNext() - 1);
}
catch(const scsi_exception& e) {
Error(e.get_sense_key(), e.get_asc());
// Write failed
return false;
}
// If you do not need the next block, end here
ctrl.next++;
IncrementNext();
if (!cont) {
break;
}
// Check the next block
try {
SetLength(disk->WriteCheck(ctrl.next - 1));
SetLength(disk->WriteCheck(GetNext() - 1));
}
catch(const scsi_exception&) {
// Cannot write
return false;
}
@ -951,7 +946,7 @@ bool ScsiController::XferOutBlockOriented(bool cont)
break;
default:
LOGWARN("Received an unexpected command ($%02X) in %s", (int)GetOpcode(), __PRETTY_FUNCTION__)
LOGWARN("Received an unexpected command ($%02X) in %s", static_cast<int>(GetOpcode()), __PRETTY_FUNCTION__)
break;
}
@ -965,8 +960,8 @@ void ScsiController::ProcessCommand()
stringstream s;
s << setfill('0') << setw(2) << hex;
for (uint32_t i = 0; i < len; i++) {
ctrl.cmd[i] = GetBuffer()[i];
s << ctrl.cmd[i];
GetCmd()[i] = GetBuffer()[i];
s << GetCmd(i);
}
LOGTRACE("%s CDB=$%s",__PRETTY_FUNCTION__, s.str().c_str())
@ -977,7 +972,7 @@ void ScsiController::ParseMessage()
{
int i = 0;
while (i < scsi.msc) {
const BYTE message_type = scsi.msb[i];
const uint8_t message_type = scsi.msb[i];
if (message_type == 0x06) {
LOGTRACE("Received ABORT message")
@ -996,7 +991,7 @@ void ScsiController::ParseMessage()
}
if (message_type >= 0x80) {
identified_lun = (int)message_type & 0x1F;
identified_lun = static_cast<int>(message_type) & 0x1F;
LOGTRACE("Received IDENTIFY message for LUN %d", identified_lun)
}
@ -1006,7 +1001,7 @@ void ScsiController::ParseMessage()
// Check only when synchronous transfer is possible
if (!scsi.syncenable || scsi.msb[i + 2] != 0x01) {
SetLength(1);
ctrl.blocks = 1;
SetBlocks(1);
GetBuffer()[0] = 0x07;
MsgIn();
return;
@ -1024,7 +1019,7 @@ void ScsiController::ParseMessage()
// STDR response message generation
SetLength(5);
ctrl.blocks = 1;
SetBlocks(1);
GetBuffer()[0] = 0x01;
GetBuffer()[1] = 0x03;
GetBuffer()[2] = 0x01;
@ -1042,11 +1037,11 @@ void ScsiController::ParseMessage()
void ScsiController::ProcessMessage()
{
// Continue message out phase as long as ATN keeps asserting
if (bus->GetATN()) {
if (GetBus()->GetATN()) {
// Data transfer is 1 byte x 1 block
ResetOffset();
SetLength(1);
ctrl.blocks = 1;
SetBlocks(1);
return;
}

View File

@ -15,7 +15,6 @@
#pragma once
#include "abstract_controller.h"
#include "os.h"
#include "scsi.h"
#include <array>
@ -30,7 +29,7 @@ class ScsiController : public AbstractController
static const int MAX_SYNC_PERIOD = 50;
// REQ/ACK offset(limited to 16)
static const BYTE MAX_SYNC_OFFSET = 16;
static const uint8_t MAX_SYNC_OFFSET = 16;
static const int UNKNOWN_INITIATOR_ID = -1;
@ -39,20 +38,20 @@ class ScsiController : public AbstractController
using scsi_t = struct _scsi_t {
// Synchronous transfer
bool syncenable; // Synchronous transfer possible
BYTE syncperiod = MAX_SYNC_PERIOD; // Synchronous transfer period
BYTE syncoffset; // Synchronous transfer offset
uint8_t syncperiod = MAX_SYNC_PERIOD; // Synchronous transfer period
uint8_t syncoffset; // Synchronous transfer offset
int syncack; // Number of synchronous transfer ACKs
// ATN message
bool atnmsg;
int msc;
std::array<BYTE, 256> msb;
std::array<uint8_t, 256> msb;
};
public:
// Maximum number of logical units
static const int LUN_MAX;
static inline const int LUN_MAX = 32;
ScsiController(shared_ptr<BUS>, int);
~ScsiController() override = default;
@ -98,7 +97,7 @@ private:
// Data transfer
void Send();
bool XferMsg(int);
bool XferIn(vector<BYTE>&);
bool XferIn(vector<uint8_t>&);
bool XferOut(bool);
bool XferOutBlockOriented(bool);
void ReceiveBytes();

View File

@ -17,7 +17,6 @@
//
//---------------------------------------------------------------------------
#include "os.h"
#include "log.h"
#include "cfilesystem.h"
#include <dirent.h>
@ -107,12 +106,12 @@ static char* U2S(const char *utf8)
/// A 66 byte buffer is required for writing.
//
//---------------------------------------------------------------------------
void Human68k::namests_t::GetCopyPath(BYTE* szPath) const
void Human68k::namests_t::GetCopyPath(uint8_t* szPath) const
{
assert(szPath);
BYTE* p = szPath;
for (BYTE c : path) {
uint8_t* p = szPath;
for (uint8_t c : path) {
if (c == '\0')
break;
if (c == 0x09) {
@ -132,16 +131,16 @@ void Human68k::namests_t::GetCopyPath(BYTE* szPath) const
/// A 23 byte buffer is required for writing.
//
//---------------------------------------------------------------------------
void Human68k::namests_t::GetCopyFilename(BYTE* szFilename) const
void Human68k::namests_t::GetCopyFilename(uint8_t* szFilename) const
{
assert(szFilename);
size_t i;
BYTE* p = szFilename;
uint8_t* p = szFilename;
// Transfer the base file name
for (i = 0; i < 8; i++) {
BYTE c = name[i];
uint8_t c = name[i];
if (c == ' ') {
// Check that the file name continues after a space is detected
/// TODO: Should change this function to be compatible with 8+3 chars and TwentyOne
@ -165,7 +164,7 @@ void Human68k::namests_t::GetCopyFilename(BYTE* szFilename) const
if (i >= 8) {
// Transfer the extraneous part
for (i = 0; i < 10; i++) {
const BYTE c = add[i];
const uint8_t c = add[i];
if (c == '\0')
break;
*p++ = c;
@ -177,7 +176,7 @@ void Human68k::namests_t::GetCopyFilename(BYTE* szFilename) const
if (ext[0] != ' ' || ext[1] != ' ' || ext[2] != ' ') {
*p++ = '.';
for (i = 0; i < 3; i++) {
const BYTE c = ext[i];
const uint8_t c = ext[i];
if (c == ' ') {
// Check that the file extension continues after a space is detected
/// TODO: Should change this function to be compatible with 8+3 chars and TwentyOne
@ -290,7 +289,7 @@ bool CHostDrv::isMediaOffline() const
// Get media bytes
//
//---------------------------------------------------------------------------
BYTE CHostDrv::GetMediaByte() const
uint8_t CHostDrv::GetMediaByte() const
{
return Human68k::MEDIA_REMOTE;
}
@ -474,7 +473,7 @@ void CHostDrv::CleanCache() const
/// Update the cache for the specified path
//
//---------------------------------------------------------------------------
void CHostDrv::CleanCache(const BYTE* szHumanPath)
void CHostDrv::CleanCache(const uint8_t* szHumanPath)
{
assert(szHumanPath);
@ -490,7 +489,7 @@ void CHostDrv::CleanCache(const BYTE* szHumanPath)
/// Update the cache below and including the specified path
//
//---------------------------------------------------------------------------
void CHostDrv::CleanCacheChild(const BYTE* szHumanPath) const
void CHostDrv::CleanCacheChild(const uint8_t* szHumanPath) const
{
assert(szHumanPath);
@ -507,7 +506,7 @@ void CHostDrv::CleanCacheChild(const BYTE* szHumanPath) const
/// Delete the cache for the specified path
//
//---------------------------------------------------------------------------
void CHostDrv::DeleteCache(const BYTE* szHumanPath)
void CHostDrv::DeleteCache(const uint8_t* szHumanPath)
{
auto p = FindCache(szHumanPath);
if (p) {
@ -526,7 +525,7 @@ void CHostDrv::DeleteCache(const BYTE* szHumanPath)
/// Make sure to lock from the top.
//
//---------------------------------------------------------------------------
CHostPath* CHostDrv::FindCache(const BYTE* szHuman)
CHostPath* CHostDrv::FindCache(const uint8_t* szHuman)
{
assert(szHuman);
@ -602,7 +601,7 @@ CHostPath* CHostDrv::MakeCache(CHostFiles* pFiles)
assert(m_szBase);
assert(strlen(m_szBase) < FILEPATH_MAX);
BYTE szHumanPath[HUMAN68K_PATH_MAX]; // Path names are entered in order from the route
uint8_t szHumanPath[HUMAN68K_PATH_MAX]; // Path names are entered in order from the route
szHumanPath[0] = '\0';
size_t nHumanPath = 0;
@ -611,7 +610,7 @@ CHostPath* CHostDrv::MakeCache(CHostFiles* pFiles)
size_t nHostPath = strlen(szHostPath);
CHostPath* pPath;
const BYTE* p = pFiles->GetHumanPath();
const uint8_t* p = pFiles->GetHumanPath();
for (;;) {
// Add path separators
if (nHumanPath + 1 >= HUMAN68K_PATH_MAX)
@ -624,7 +623,7 @@ CHostPath* CHostDrv::MakeCache(CHostFiles* pFiles)
szHostPath[nHostPath] = '\0';
// Insert one file
BYTE szHumanFilename[24]; // File name part
uint8_t szHumanFilename[24]; // File name part
p = SeparateCopyFilename(p, szHumanFilename);
if (p == nullptr)
return nullptr; // Error: Failed to read file name
@ -767,13 +766,13 @@ void CHostFilename::SetHost(const TCHAR* szHost)
/// Copy the Human68k file name elements
//
//---------------------------------------------------------------------------
BYTE* CHostFilename::CopyName(BYTE* pWrite, const BYTE* pFirst, const BYTE* pLast) // static
uint8_t* CHostFilename::CopyName(uint8_t* pWrite, const uint8_t* pFirst, const uint8_t* pLast) // static
{
assert(pWrite);
assert(pFirst);
assert(pLast);
for (const BYTE* p = pFirst; p < pLast; p++) {
for (const uint8_t* p = pFirst; p < pLast; p++) {
*pWrite++ = *p;
}
@ -812,42 +811,42 @@ void CHostFilename::ConvertHuman(int nCount)
nMax = 8;
// Preparations to adjust the base name segment
BYTE szNumber[8];
BYTE* pNumber = nullptr;
uint8_t szNumber[8];
uint8_t* pNumber = nullptr;
if (nCount >= 0) {
pNumber = &szNumber[8];
for (uint32_t i = 0; i < 5; i++) { // Max 5+1 digits (always leave the first 2 bytes of the base name)
int n = nCount % 36;
nMax--;
pNumber--;
*pNumber = (BYTE)(n + (n < 10 ? '0' : 'A' - 10));
*pNumber = (uint8_t)(n + (n < 10 ? '0' : 'A' - 10));
nCount /= 36;
if (nCount == 0)
break;
}
nMax--;
pNumber--;
auto c = (BYTE)((nOption >> 24) & 0x7F);
auto c = (uint8_t)((nOption >> 24) & 0x7F);
if (c == 0)
c = XM6_HOST_FILENAME_MARK;
*pNumber = c;
}
// Char conversion
BYTE szHuman[FILEPATH_MAX];
const BYTE* pFirst = szHuman;
BYTE* pLast;
BYTE* pExt = nullptr;
uint8_t szHuman[FILEPATH_MAX];
const uint8_t* pFirst = szHuman;
uint8_t* pLast;
uint8_t* pExt = nullptr;
{
char szHost[FILEPATH_MAX];
strcpy(szHost, m_szHost);
auto pRead = (const BYTE*)szHost;
BYTE* pWrite = szHuman;
auto pRead = (const uint8_t*)szHost;
uint8_t* pWrite = szHuman;
const auto pPeriod = SeparateExt(pRead);
for (bool bFirst = true;; bFirst = false) {
BYTE c = *pRead++;
uint8_t c = *pRead++;
switch (c) {
case ' ':
if (nOption & WINDRV_OPT_REDUCED_SPACE)
@ -938,11 +937,11 @@ void CHostFilename::ConvertHuman(int nCount)
// The above example becomes "This.Long.Filename.txt" after conversion
// Evaluate first char
const BYTE* pCut = pFirst;
const BYTE* pStop = pExt - nMax; // Allow for up to 17 bytes for extension (leave base name)
const uint8_t* pCut = pFirst;
const uint8_t* pStop = pExt - nMax; // Allow for up to 17 bytes for extension (leave base name)
if (pFirst < pExt) {
pCut++; // 1 byte always uses the base name
BYTE c = *pFirst;
uint8_t c = *pFirst;
if ((0x80 <= c && c <= 0x9F) || 0xE0 <= c) { // Specifically 0x81~0x9F 0xE0~0xEF
pCut++; // Base name. At least 2 bytes.
pStop++; // File extension. Max 16 bytes.
@ -952,15 +951,15 @@ void CHostFilename::ConvertHuman(int nCount)
pStop = pFirst;
// Evaluate base name
pCut = (const BYTE*)strchr((const char*)pCut, '.'); // The 2nd byte of Shift-JIS is always 0x40 or higher, so this is ok
pCut = (const uint8_t*)strchr((const char*)pCut, '.'); // The 2nd byte of Shift-JIS is always 0x40 or higher, so this is ok
if (pCut == nullptr)
pCut = pLast;
if ((size_t)(pCut - pFirst) > nMax)
pCut = pFirst + nMax; // Execute Shift-JIS 2 byte evaluation/adjustment later. Not allowed to do it here.
// Evaluate extension
const BYTE* pSecond = pExt;
const BYTE* p;
const uint8_t* pSecond = pExt;
const uint8_t* p;
for (p = pExt - 1; pStop < p; p--) {
if (*p == '.')
pSecond = p; // The 2nd byte of Shift-JIS is always 0x40 or higher, so this is ok
@ -972,7 +971,7 @@ void CHostFilename::ConvertHuman(int nCount)
pCut = pFirst + nMax - nExt;
// If in the middle of a 2 byte char, shorten even further
for (p = pFirst; p < pCut; p++) {
BYTE c = *p;
uint8_t c = *p;
if ((0x80 <= c && c <= 0x9F) || 0xE0 <= c) { // Specifically 0x81~0x9F 0xE0~0xEF
p++;
if (p >= pCut) {
@ -983,7 +982,7 @@ void CHostFilename::ConvertHuman(int nCount)
}
// Joining the name
BYTE* pWrite = m_szHuman;
uint8_t* pWrite = m_szHuman;
pWrite = CopyName(pWrite, pFirst, pCut); // Transfer the base name
if (pNumber)
pWrite = CopyName(pWrite, pNumber, &szNumber[8]); // Transfer the adjustment char
@ -1019,7 +1018,7 @@ void CHostFilename::ConvertHuman(int nCount)
/// Duplicates the file name segment data, then executes the correspoding initialization with ConvertHuman().
//
//---------------------------------------------------------------------------
void CHostFilename::CopyHuman(const BYTE* szHuman)
void CHostFilename::CopyHuman(const uint8_t* szHuman)
{
assert(szHuman);
assert(strlen((const char*)szHuman) < 23);
@ -1040,7 +1039,7 @@ void CHostFilename::CopyHuman(const BYTE* szHuman)
void CHostFilename::SetEntryName()
{
// Set file name
const BYTE* p = m_szHuman;
const uint8_t* p = m_szHuman;
size_t i;
for (i = 0; i < 8; i++) {
if (p < m_pszHumanExt)
@ -1059,7 +1058,7 @@ void CHostFilename::SetEntryName()
if (*p == '.')
p++;
for (i = 0; i < 3; i++) {
BYTE c = *p;
uint8_t c = *p;
if (c)
p++;
m_dirHuman.ext[i] = c;
@ -1083,7 +1082,7 @@ bool CHostFilename::isReduce() const
//---------------------------------------------------------------------------
int CHostFilename::CheckAttribute(uint32_t nHumanAttribute) const
{
BYTE nAttribute = m_dirHuman.attr;
uint8_t nAttribute = m_dirHuman.attr;
if ((nAttribute & (Human68k::AT_ARCHIVE | Human68k::AT_DIRECTORY | Human68k::AT_VOLUME)) == 0)
nAttribute |= Human68k::AT_ARCHIVE;
@ -1095,15 +1094,15 @@ int CHostFilename::CheckAttribute(uint32_t nHumanAttribute) const
/// Split the extension from Human68k file name
//
//---------------------------------------------------------------------------
const BYTE* CHostFilename::SeparateExt(const BYTE* szHuman) // static
const uint8_t* CHostFilename::SeparateExt(const uint8_t* szHuman) // static
{
// Obtain the file name length
const size_t nLength = strlen((const char*)szHuman);
const BYTE* pFirst = szHuman;
const BYTE* pLast = pFirst + nLength;
const uint8_t* pFirst = szHuman;
const uint8_t* pLast = pFirst + nLength;
// Confirm the position of the Human68k extension
auto pExt = (const BYTE*)strrchr((const char*)pFirst, '.'); // The 2nd byte of Shift-JIS is always 0x40 or higher, so this is ok
auto pExt = (const uint8_t*)strrchr((const char*)pFirst, '.'); // The 2nd byte of Shift-JIS is always 0x40 or higher, so this is ok
if (pExt == nullptr)
pExt = pLast;
// Special handling of the pattern where the file name is 20~22 chars, and the 19th char is '.' or ends with '.'
@ -1186,7 +1185,7 @@ void CHostPath::Clean()
/// Specify Human68k side names directly
//
//---------------------------------------------------------------------------
void CHostPath::SetHuman(const BYTE* szHuman)
void CHostPath::SetHuman(const uint8_t* szHuman)
{
assert(szHuman);
assert(strlen((const char*)szHuman) < HUMAN68K_PATH_MAX);
@ -1212,7 +1211,7 @@ void CHostPath::SetHost(const TCHAR* szHost)
/// Compare arrays (supports wildcards)
//
//---------------------------------------------------------------------------
int CHostPath::Compare(const BYTE* pFirst, const BYTE* pLast, const BYTE* pBufFirst, const BYTE* pBufLast)
int CHostPath::Compare(const uint8_t* pFirst, const uint8_t* pLast, const uint8_t* pBufFirst, const uint8_t* pBufLast)
{
assert(pFirst);
assert(pLast);
@ -1222,10 +1221,10 @@ int CHostPath::Compare(const BYTE* pFirst, const BYTE* pLast, const BYTE* pBufFi
// Compare chars
bool bSkip0 = false;
bool bSkip1 = false;
for (const BYTE* p = pFirst; p < pLast; p++) {
for (const uint8_t* p = pFirst; p < pLast; p++) {
// Read 1 char
BYTE c = *p;
BYTE d = '\0';
uint8_t c = *p;
uint8_t d = '\0';
if (pBufFirst < pBufLast)
d = *pBufFirst++;
@ -1289,7 +1288,7 @@ int CHostPath::Compare(const BYTE* pFirst, const BYTE* pLast, const BYTE* pBufFi
/// Compare Human68k side name
//
//---------------------------------------------------------------------------
bool CHostPath::isSameHuman(const BYTE* szHuman) const
bool CHostPath::isSameHuman(const uint8_t* szHuman) const
{
assert(szHuman);
@ -1305,7 +1304,7 @@ bool CHostPath::isSameHuman(const BYTE* szHuman) const
return Compare(m_szHuman, m_szHuman + nLength, szHuman, szHuman + n) == 0;
}
bool CHostPath::isSameChild(const BYTE* szHuman) const
bool CHostPath::isSameChild(const uint8_t* szHuman) const
{
assert(szHuman);
@ -1330,14 +1329,14 @@ bool CHostPath::isSameChild(const BYTE* szHuman) const
/// Make sure to lock from the top.
//
//---------------------------------------------------------------------------
const CHostFilename* CHostPath::FindFilename(const BYTE* szHuman, uint32_t nHumanAttribute) const
const CHostFilename* CHostPath::FindFilename(const uint8_t* szHuman, uint32_t nHumanAttribute) const
{
assert(szHuman);
// Calulate number of chars
const BYTE* pFirst = szHuman;
const uint8_t* pFirst = szHuman;
size_t nLength = strlen((const char*)pFirst);
const BYTE* pLast = pFirst + nLength;
const uint8_t* pLast = pFirst + nLength;
// Find something that matches perfectly with either of the stored file names
const ring_t* p = (ring_t*)m_cRing.Next();
@ -1345,8 +1344,8 @@ const CHostFilename* CHostPath::FindFilename(const BYTE* szHuman, uint32_t nHuma
if (p->f.CheckAttribute(nHumanAttribute) == 0)
continue;
// Calulate number of chars
const BYTE* pBufFirst = p->f.GetHuman();
const BYTE* pBufLast = p->f.GetHumanLast();
const uint8_t* pBufFirst = p->f.GetHuman();
const uint8_t* pBufLast = p->f.GetHumanLast();
// Check number of chars
if (size_t nBufLength = pBufLast - pBufFirst; nLength != nBufLength)
continue;
@ -1367,15 +1366,15 @@ const CHostFilename* CHostPath::FindFilename(const BYTE* szHuman, uint32_t nHuma
/// Make sure to lock from the top.
//
//---------------------------------------------------------------------------
const CHostFilename* CHostPath::FindFilenameWildcard(const BYTE* szHuman, uint32_t nHumanAttribute, find_t* pFind) const
const CHostFilename* CHostPath::FindFilenameWildcard(const uint8_t* szHuman, uint32_t nHumanAttribute, find_t* pFind) const
{
assert(szHuman);
assert(pFind);
// Split the base file name and Human68k file extension
const BYTE* pFirst = szHuman;
const BYTE* pLast = pFirst + strlen((const char*)pFirst);
const BYTE* pExt = CHostFilename::SeparateExt(pFirst);
const uint8_t* pFirst = szHuman;
const uint8_t* pLast = pFirst + strlen((const char*)pFirst);
const uint8_t* pExt = CHostFilename::SeparateExt(pFirst);
// Move to the start position
auto p = (const ring_t*)m_cRing.Next();
@ -1416,9 +1415,9 @@ const CHostFilename* CHostPath::FindFilenameWildcard(const BYTE* szHuman, uint32
continue;
// Split the base file name and Human68k file extension
const BYTE* pBufFirst = p->f.GetHuman();
const BYTE* pBufLast = p->f.GetHumanLast();
const BYTE* pBufExt = p->f.GetHumanExt();
const uint8_t* pBufFirst = p->f.GetHuman();
const uint8_t* pBufLast = p->f.GetHumanLast();
const uint8_t* pBufExt = p->f.GetHumanExt();
// Compare base file name
if (Compare(pFirst, pExt, pBufFirst, pBufExt))
@ -1575,7 +1574,7 @@ void CHostPath::Refresh()
if (stat(S2U(szPath), &sb))
continue;
BYTE nHumanAttribute = Human68k::AT_ARCHIVE;
uint8_t nHumanAttribute = Human68k::AT_ARCHIVE;
if (S_ISDIR(sb.st_mode))
nHumanAttribute = Human68k::AT_DIRECTORY;
if ((sb.st_mode & 0200) == 0)
@ -1772,7 +1771,7 @@ void CHostEntry::CleanCache(uint32_t nUnit) const
/// Update the cache for the specified path
//
//---------------------------------------------------------------------------
void CHostEntry::CleanCache(uint32_t nUnit, const BYTE* szHumanPath) const
void CHostEntry::CleanCache(uint32_t nUnit, const uint8_t* szHumanPath) const
{
assert(szHumanPath);
assert(nUnit < DRIVE_MAX);
@ -1786,7 +1785,7 @@ void CHostEntry::CleanCache(uint32_t nUnit, const BYTE* szHumanPath) const
/// Update all cache for the specified path and below
//
//---------------------------------------------------------------------------
void CHostEntry::CleanCacheChild(uint32_t nUnit, const BYTE* szHumanPath) const
void CHostEntry::CleanCacheChild(uint32_t nUnit, const uint8_t* szHumanPath) const
{
assert(szHumanPath);
assert(nUnit < DRIVE_MAX);
@ -1800,7 +1799,7 @@ void CHostEntry::CleanCacheChild(uint32_t nUnit, const BYTE* szHumanPath) const
/// Delete cache for the specified path
//
//---------------------------------------------------------------------------
void CHostEntry::DeleteCache(uint32_t nUnit, const BYTE* szHumanPath) const
void CHostEntry::DeleteCache(uint32_t nUnit, const uint8_t* szHumanPath) const
{
assert(szHumanPath);
assert(nUnit < DRIVE_MAX);
@ -1880,7 +1879,7 @@ bool CHostEntry::isMediaOffline(uint32_t nUnit) const
/// Get media byte
//
//---------------------------------------------------------------------------
BYTE CHostEntry::GetMediaByte(uint32_t nUnit) const
uint8_t CHostEntry::GetMediaByte(uint32_t nUnit) const
{
assert(nUnit < DRIVE_MAX);
assert(m_pDrv[nUnit]);
@ -1990,15 +1989,15 @@ bool CHostEntry::GetCapacityCache(uint32_t nUnit, Human68k::capacity_t* pCapacit
/// If the array ends with a '/' treat it as an empty array and don't trow an error.
//
//---------------------------------------------------------------------------
const BYTE* CHostDrv::SeparateCopyFilename(const BYTE* szHuman, BYTE* szBuffer) // static
const uint8_t* CHostDrv::SeparateCopyFilename(const uint8_t* szHuman, uint8_t* szBuffer) // static
{
assert(szHuman);
assert(szBuffer);
const size_t nMax = 22;
const BYTE* p = szHuman;
const uint8_t* p = szHuman;
BYTE c = *p++; // Read
uint8_t c = *p++; // Read
if (c != '/' && c != '\\')
return nullptr; // Error: Invalid path name
@ -2263,7 +2262,7 @@ void CHostFcb::SetFilename(const TCHAR* szFilename)
strcpy(m_szFilename, szFilename);
}
void CHostFcb::SetHumanPath(const BYTE* szHumanPath)
void CHostFcb::SetHumanPath(const uint8_t* szHumanPath)
{
assert(szHumanPath);
assert(strlen((const char*)szHumanPath) < HUMAN68K_PATH_MAX);
@ -2327,12 +2326,12 @@ bool CHostFcb::Open()
/// Return -1 if error is thrown.
//
//---------------------------------------------------------------------------
uint32_t CHostFcb::Read(BYTE* pBuffer, uint32_t nSize)
uint32_t CHostFcb::Read(uint8_t* pBuffer, uint32_t nSize)
{
assert(pBuffer);
assert(m_pFile);
size_t nResult = fread(pBuffer, sizeof(BYTE), nSize, m_pFile);
size_t nResult = fread(pBuffer, sizeof(uint8_t), nSize, m_pFile);
if (ferror(m_pFile))
nResult = (size_t)-1;
@ -2347,12 +2346,12 @@ uint32_t CHostFcb::Read(BYTE* pBuffer, uint32_t nSize)
/// Return -1 if error is thrown.
//
//---------------------------------------------------------------------------
uint32_t CHostFcb::Write(const BYTE* pBuffer, uint32_t nSize)
uint32_t CHostFcb::Write(const uint8_t* pBuffer, uint32_t nSize)
{
assert(pBuffer);
assert(m_pFile);
size_t nResult = fwrite(pBuffer, sizeof(BYTE), nSize, m_pFile);
size_t nResult = fwrite(pBuffer, sizeof(uint8_t), nSize, m_pFile);
if (ferror(m_pFile))
nResult = (size_t)-1;
@ -2752,7 +2751,7 @@ int CFileSys::RemoveDir(uint32_t nUnit, const Human68k::namests_t* pNamests) con
return FS_DIRNOTFND;
// Delete cache
BYTE szHuman[HUMAN68K_PATH_MAX + 24];
uint8_t szHuman[HUMAN68K_PATH_MAX + 24];
assert(strlen((const char*)f.GetHumanPath()) +
strlen((const char*)f.GetHumanFilename()) < HUMAN68K_PATH_MAX + 24);
strcpy((char*)szHuman, (const char*)f.GetHumanPath());
@ -3006,7 +3005,7 @@ int CFileSys::Files(uint32_t nUnit, uint32_t nKey, const Human68k::namests_t* pN
}
// Store search results
pFiles->attr = (BYTE)pHostFiles->GetAttribute();
pFiles->attr = (uint8_t)pHostFiles->GetAttribute();
pFiles->date = pHostFiles->GetDate();
pFiles->time = pHostFiles->GetTime();
pFiles->size = pHostFiles->GetSize();
@ -3054,7 +3053,7 @@ int CFileSys::NFiles(uint32_t nUnit, uint32_t nKey, Human68k::files_t* pFiles)
assert(pFiles->offset == 0);
// Store search results
pFiles->attr = (BYTE)pHostFiles->GetAttribute();
pFiles->attr = (uint8_t)pHostFiles->GetAttribute();
pFiles->date = pHostFiles->GetDate();
pFiles->time = pHostFiles->GetTime();
pFiles->size = pHostFiles->GetSize();
@ -3245,7 +3244,7 @@ int CFileSys::Close(uint32_t nUnit, uint32_t nKey, const Human68k::fcb_t* /* pFc
/// Clean exit when 0 bytes are read.
//
//---------------------------------------------------------------------------
int CFileSys::Read(uint32_t nKey, Human68k::fcb_t* pFcb, BYTE* pBuffer, uint32_t nSize)
int CFileSys::Read(uint32_t nKey, Human68k::fcb_t* pFcb, uint8_t* pBuffer, uint32_t nSize)
{
assert(nKey);
assert(pFcb);
@ -3284,7 +3283,7 @@ int CFileSys::Read(uint32_t nKey, Human68k::fcb_t* pFcb, BYTE* pBuffer, uint32_t
/// Truncate file if 0 bytes are written.
//
//---------------------------------------------------------------------------
int CFileSys::Write(uint32_t nKey, Human68k::fcb_t* pFcb, const BYTE* pBuffer, uint32_t nSize)
int CFileSys::Write(uint32_t nKey, Human68k::fcb_t* pFcb, const uint8_t* pBuffer, uint32_t nSize)
{
assert(nKey);
assert(pFcb);
@ -3462,7 +3461,7 @@ int CFileSys::CtrlDrive(uint32_t nUnit, Human68k::ctrldrive_t* pCtrlDrive) const
switch (pCtrlDrive->status) {
case 0: // Inspect status
case 9: // Inspect status 2
pCtrlDrive->status = (BYTE)m_cEntry.GetStatus(nUnit);
pCtrlDrive->status = (uint8_t)m_cEntry.GetStatus(nUnit);
return pCtrlDrive->status;
case 1: // Eject
@ -3501,7 +3500,7 @@ int CFileSys::GetDPB(uint32_t nUnit, Human68k::dpb_t* pDpb) const
return FS_FATAL_INVALIDUNIT;
Human68k::capacity_t cap;
BYTE media = Human68k::MEDIA_REMOTE;
uint8_t media = Human68k::MEDIA_REMOTE;
if (nUnit < m_nUnits) {
media = m_cEntry.GetMediaByte(nUnit);
@ -3549,11 +3548,11 @@ int CFileSys::GetDPB(uint32_t nUnit, Human68k::dpb_t* pDpb) const
// Set DPB
pDpb->sector_size = cap.bytes; // Bytes per sector
pDpb->cluster_size =
(BYTE)(cap.sectors - 1); // Sectors per cluster - 1
pDpb->shift = (BYTE)nShift; // Number of cluster → sector shifts
(uint8_t)(cap.sectors - 1); // Sectors per cluster - 1
pDpb->shift = (uint8_t)nShift; // Number of cluster → sector shifts
pDpb->fat_sector = (uint16_t)nFat; // First FAT sector number
pDpb->fat_max = 1; // Number of FAT memory spaces
pDpb->fat_size = (BYTE)cap.sectors; // Number of sectors controlled by FAT (excluding copies)
pDpb->fat_size = (uint8_t)cap.sectors; // Number of sectors controlled by FAT (excluding copies)
pDpb->file_max =
(uint16_t)(cap.sectors * cap.bytes / 0x20); // Number of files in the root directory
pDpb->data_sector = (uint16_t)nData; // First sector number of data memory
@ -3572,7 +3571,7 @@ int CFileSys::GetDPB(uint32_t nUnit, Human68k::dpb_t* pDpb) const
/// Buffer size is hard coded to $200 byte.
//
//---------------------------------------------------------------------------
int CFileSys::DiskRead(uint32_t nUnit, BYTE* pBuffer, uint32_t nSector, uint32_t nSize)
int CFileSys::DiskRead(uint32_t nUnit, uint8_t* pBuffer, uint32_t nSector, uint32_t nSize)
{
assert(pBuffer);
@ -3828,14 +3827,14 @@ void CFileSys::InitOption(const Human68k::argument_t* pArgument)
// Initialize number of drives
m_nDrives = 0;
const BYTE* pp = pArgument->buf;
const uint8_t* pp = pArgument->buf;
pp += strlen((const char*)pp) + 1;
uint32_t nOption = m_nOptionDefault;
for (;;) {
assert(pp < pArgument->buf + sizeof(*pArgument));
const BYTE* p = pp;
BYTE c = *p++;
const uint8_t* p = pp;
uint8_t c = *p++;
if (c == '\0')
break;

View File

@ -106,48 +106,48 @@ namespace Human68k {
const static int MEDIA_REMOTE = 0xF3; ///< Remote drive
struct namests_t {
BYTE wildcard; ///< Wildcard character length
BYTE drive; ///< Drive number
BYTE path[65]; ///< Path (subdirectory +/)
BYTE name[8]; ///< File name (PADDING 0x20)
BYTE ext[3]; ///< Extension (PADDING 0x20)
BYTE add[10]; ///< File name addition (PADDING 0x00)
uint8_t wildcard; ///< Wildcard character length
uint8_t drive; ///< Drive number
uint8_t path[65]; ///< Path (subdirectory +/)
uint8_t name[8]; ///< File name (PADDING 0x20)
uint8_t ext[3]; ///< Extension (PADDING 0x20)
uint8_t add[10]; ///< File name addition (PADDING 0x00)
void GetCopyPath(BYTE* szPath) const;
void GetCopyFilename(BYTE* szFilename) const;
void GetCopyPath(uint8_t* szPath) const;
void GetCopyFilename(uint8_t* szFilename) const;
};
struct files_t {
BYTE fatr; ///< + 0 search attribute; read-only
// BYTE drive; ///< + 1 drive number; read-only
uint8_t fatr; ///< + 0 search attribute; read-only
// uint8_t drive; ///< + 1 drive number; read-only
uint32_t sector; ///< + 2 directory sector; DOS _FILES first address substitute
// uint16_t cluster; ///< + 6 directory cluster; details unknown (unused)
uint16_t offset; ///< + 8 directory entry; write-only
// BYTE name[8]; ///< +10 working file name; write-only (unused)
// BYTE ext[3]; ///< +18 working extension; write-only (unused)
BYTE attr; ///< +21 file attribute; write-only
// uint8_t name[8]; ///< +10 working file name; write-only (unused)
// uint8_t ext[3]; ///< +18 working extension; write-only (unused)
uint8_t attr; ///< +21 file attribute; write-only
uint16_t time; ///< +22 last change time of day; write-only
uint16_t date; ///< +24 last change date; write-only
uint32_t size; ///< +26 file size; write-only
BYTE full[23]; ///< +30 full name; write-only
uint8_t full[23]; ///< +30 full name; write-only
};
struct fcb_t {
// BYTE pad00[6]; ///< + 0~+ 5 (unused)
// uint8_t pad00[6]; ///< + 0~+ 5 (unused)
uint32_t fileptr; ///< + 6~+ 9 file pointer
// BYTE pad01[4]; ///< +10~+13 (unused)
// uint8_t pad01[4]; ///< +10~+13 (unused)
uint16_t mode; ///< +14~+15 open mode
// BYTE pad02[16]; ///< +16~+31 (unused)
// uint8_t pad02[16]; ///< +16~+31 (unused)
// uint32_t zero; ///< +32~+35 zeros are written when opened (unused)
// BYTE name[8]; ///< +36~+43 file name (PADDING 0x20) (unused)
// BYTE ext[3]; ///< +44~+46 extension (PADDING 0x20) (unused)
BYTE attr; ///< +47 file attribute
// BYTE add[10]; ///< +48~+57 file name addition (PADDING 0x00) (unused)
// uint8_t name[8]; ///< +36~+43 file name (PADDING 0x20) (unused)
// uint8_t ext[3]; ///< +44~+46 extension (PADDING 0x20) (unused)
uint8_t attr; ///< +47 file attribute
// uint8_t add[10]; ///< +48~+57 file name addition (PADDING 0x00) (unused)
uint16_t time; ///< +58~+59 last change time of day
uint16_t date; ///< +60~+61 last change date
// uint16_t cluster; ///< +62~+63 cluster number (unused)
uint32_t size; ///< +64~+67 file size
// BYTE pad03[28]; ///< +68~+95 FAT cache (unused)
// uint8_t pad03[28]; ///< +68~+95 FAT cache (unused)
};
struct capacity_t {
@ -158,32 +158,32 @@ namespace Human68k {
};
struct ctrldrive_t {
BYTE status; ///< +13 status
BYTE pad[3]; ///< Padding
uint8_t status; ///< +13 status
uint8_t pad[3]; ///< Padding
};
struct dpb_t {
uint16_t sector_size; ///< + 0 Number of bytes in one sector
BYTE cluster_size; ///< + 2 Number sectors in one cluster -1
BYTE shift; ///< + 3 Number of cluster→sector shifts
uint8_t cluster_size; ///< + 2 Number sectors in one cluster -1
uint8_t shift; ///< + 3 Number of cluster→sector shifts
uint16_t fat_sector; ///< + 4 FAT first sector number
BYTE fat_max; ///< + 6 FAT storage quantity
BYTE fat_size; ///< + 7 FAT controlled sector number (excluding duplicates)
uint8_t fat_max; ///< + 6 FAT storage quantity
uint8_t fat_size; ///< + 7 FAT controlled sector number (excluding duplicates)
uint16_t file_max; ///< + 8 Number of files in the root directory
uint16_t data_sector; ///< +10 First sector number of data storage
uint16_t cluster_max; ///< +12 Total number of clusters +1
uint16_t root_sector; ///< +14 First sector number of root directory
// uint32_t driverentry; ///< +16 Device driver pointer (unused)
BYTE media; ///< +20 Media identifier
// BYTE flag; ///< +21 Flag used by DPB (unused)
uint8_t media; ///< +20 Media identifier
// uint8_t flag; ///< +21 Flag used by DPB (unused)
};
/// Directory entry struct
struct dirent_t {
BYTE name[8]; ///< + 0 File name (PADDING 0x20)
BYTE ext[3]; ///< + 8 Extension (PADDING 0x20)
BYTE attr; ///< +11 File attribute
BYTE add[10]; ///< +12 File name addition (PADDING 0x00)
uint8_t name[8]; ///< + 0 File name (PADDING 0x20)
uint8_t ext[3]; ///< + 8 Extension (PADDING 0x20)
uint8_t attr; ///< +11 File attribute
uint8_t add[10]; ///< +12 File name addition (PADDING 0x00)
uint16_t time; ///< +22 Last change time of day
uint16_t date; ///< +24 Last change date
uint16_t cluster; ///< +26 Cluster number
@ -192,7 +192,7 @@ namespace Human68k {
/// IOCTRL parameter union
union ioctrl_t {
BYTE buffer[8]; ///< Access in byte units
uint8_t buffer[8]; ///< Access in byte units
uint32_t param; ///< Parameter (First 4 bytes)
uint16_t media; ///< Media byte (First 2 bytes)
};
@ -203,7 +203,7 @@ namespace Human68k {
so setting to a length longer than HUMAN68K_PATH_MAX
*/
struct argument_t {
BYTE buf[256]; ///< Command line argument
uint8_t buf[256]; ///< Command line argument
};
}
@ -423,15 +423,15 @@ public:
void SetHost(const TCHAR* szHost); ///< Set the name of the host
const TCHAR* GetHost() const { return m_szHost; } ///< Get the name of the host
void ConvertHuman(int nCount = -1); ///< Convert the Human68k name
void CopyHuman(const BYTE* szHuman); ///< Copy the Human68k name
void CopyHuman(const uint8_t* szHuman); ///< Copy the Human68k name
bool isReduce() const; ///< Inspect if the Human68k name is generated
bool isCorrect() const { return m_bCorrect; } ///< Inspect if the Human68k file name adhers to naming rules
const BYTE* GetHuman() const { return m_szHuman; } ///< Get Human68k file name
const BYTE* GetHumanLast() const
const uint8_t* GetHuman() const { return m_szHuman; } ///< Get Human68k file name
const uint8_t* GetHumanLast() const
{ return m_pszHumanLast; } ///< Get Human68k file name
const BYTE* GetHumanExt() const { return m_pszHumanExt; }///< Get Human68k file name
const uint8_t* GetHumanExt() const { return m_pszHumanExt; }///< Get Human68k file name
void SetEntryName(); ///< Set Human68k directory entry
void SetEntryAttribute(BYTE nHumanAttribute)
void SetEntryAttribute(uint8_t nHumanAttribute)
{ m_dirHuman.attr = nHumanAttribute; } ///< Set Human68k directory entry
void SetEntrySize(uint32_t nHumanSize)
{ m_dirHuman.size = nHumanSize; } ///< Set Human68k directory entry
@ -449,16 +449,16 @@ public:
///< Determine Human68k directory entry match
// Path name operations
static const BYTE* SeparateExt(const BYTE* szHuman); ///< Extract extension from Human68k file name
static const uint8_t* SeparateExt(const uint8_t* szHuman); ///< Extract extension from Human68k file name
private:
static BYTE* CopyName(BYTE* pWrite, const BYTE* pFirst, const BYTE* pLast);
static uint8_t* CopyName(uint8_t* pWrite, const uint8_t* pFirst, const uint8_t* pLast);
///< Copy Human68k file name elements
const BYTE* m_pszHumanLast = nullptr; ///< Last position of the Human68k internal name of the relevant entry
const BYTE* m_pszHumanExt = nullptr; ///< Position of the extension of the Human68k internal name of the relevant entry
const uint8_t* m_pszHumanLast = nullptr; ///< Last position of the Human68k internal name of the relevant entry
const uint8_t* m_pszHumanExt = nullptr; ///< Position of the extension of the Human68k internal name of the relevant entry
bool m_bCorrect = false; ///< TRUE if the relevant entry of the Human68k internal name is correct
BYTE m_szHuman[24]; ///< Human68k internal name of the relevant entry
uint8_t m_szHuman[24]; ///< Human68k internal name of the relevant entry
Human68k::dirent_t m_dirHuman; ///< All information for the Human68k relevant entry
TCHAR m_szHost[FILEPATH_MAX]; ///< The host name of the relevant entry (variable length)
};
@ -510,14 +510,14 @@ public:
void Clean(); ///< Initialialize for reuse
void SetHuman(const BYTE* szHuman); ///< Directly specify the name on the Human68k side
void SetHuman(const uint8_t* szHuman); ///< Directly specify the name on the Human68k side
void SetHost(const TCHAR* szHost); ///< Directly specify the name on the host side
bool isSameHuman(const BYTE* szHuman) const; ///< Compare the name on the Human68k side
bool isSameChild(const BYTE* szHuman) const; ///< Compare the name on the Human68k side
bool isSameHuman(const uint8_t* szHuman) const; ///< Compare the name on the Human68k side
bool isSameChild(const uint8_t* szHuman) const; ///< Compare the name on the Human68k side
const TCHAR* GetHost() const { return m_szHost; } ///< Obtain the name on the host side
const CHostFilename* FindFilename(const BYTE* szHuman, uint32_t nHumanAttribute = Human68k::AT_ALL) const;
const CHostFilename* FindFilename(const uint8_t* szHuman, uint32_t nHumanAttribute = Human68k::AT_ALL) const;
///< Find file name
const CHostFilename* FindFilenameWildcard(const BYTE* szHuman, uint32_t nHumanAttribute, find_t* pFind) const;
const CHostFilename* FindFilenameWildcard(const uint8_t* szHuman, uint32_t nHumanAttribute, find_t* pFind) const;
///< Find file name (with support for wildcards)
bool isRefresh() const; ///< Check that the file change has been done
void Refresh(); ///< Refresh file
@ -531,14 +531,14 @@ public:
private:
static ring_t* Alloc(size_t nLength); ///< Allocate memory for the file name
static void Free(ring_t* pRing); ///< Release memory for the file name
static int Compare(const BYTE* pFirst, const BYTE* pLast, const BYTE* pBufFirst, const BYTE* pBufLast);
static int Compare(const uint8_t* pFirst, const uint8_t* pLast, const uint8_t* pBufFirst, const uint8_t* pBufLast);
///< Compare string (with support for wildcards)
CRing m_cRing; ///< For CHostFilename linking
time_t m_tBackup = 0; ///< For time stamp restoration
bool m_bRefresh = true; ///< Refresh flag
uint32_t m_nId = 0; ///< Unique ID (When the value has changed, it means an update has been made)
BYTE m_szHuman[HUMAN68K_PATH_MAX]; ///< The internal Human68k name for the relevant entry
uint8_t m_szHuman[HUMAN68K_PATH_MAX]; ///< The internal Human68k name for the relevant entry
TCHAR m_szHost[FILEPATH_MAX]; ///< The host side name for the relevant entry
static uint32_t g_nId; ///< Counter for the unique ID generation
@ -595,9 +595,9 @@ public:
uint16_t GetDate() const { return m_dirHuman.date; } ///< Get Human68k date
uint16_t GetTime() const { return m_dirHuman.time; } ///< Get Human68k time
uint32_t GetSize() const { return m_dirHuman.size; } ///< Get Human68k file size
const BYTE* GetHumanFilename() const { return m_szHumanFilename; }///< Get Human68k file name
const BYTE* GetHumanResult() const { return m_szHumanResult; } ///< Get Human68k file name search results
const BYTE* GetHumanPath() const { return m_szHumanPath; } ///< Get Human68k path name
const uint8_t* GetHumanFilename() const { return m_szHumanFilename; }///< Get Human68k file name
const uint8_t* GetHumanResult() const { return m_szHumanResult; } ///< Get Human68k file name search results
const uint8_t* GetHumanPath() const { return m_szHumanPath; } ///< Get Human68k path name
private:
uint32_t m_nKey = 0; ///< FILES buffer address for Human68k; 0 is unused
@ -605,9 +605,9 @@ private:
uint32_t m_nHumanAttribute = 0; ///< Human68k search attribute
CHostPath::find_t m_findNext = {}; ///< Next search location data
Human68k::dirent_t m_dirHuman = {}; ///< Search results: Human68k file data
BYTE m_szHumanFilename[24] = {}; ///< Human68k file name
BYTE m_szHumanResult[24] = {}; ///< Search results: Human68k file name
BYTE m_szHumanPath[HUMAN68K_PATH_MAX] = {}; ///< Human68k path name
uint8_t m_szHumanFilename[24] = {}; ///< Human68k file name
uint8_t m_szHumanResult[24] = {}; ///< Search results: Human68k file name
uint8_t m_szHumanPath[HUMAN68K_PATH_MAX] = {}; ///< Human68k path name
TCHAR m_szHostResult[FILEPATH_MAX] = {}; ///< Search results: host's full path name
};
@ -657,13 +657,13 @@ public:
bool isUpdate() const { return m_bUpdate; } ///< Get update state
bool SetMode(uint32_t nHumanMode); ///< Set file open mode
void SetFilename(const TCHAR* szFilename); ///< Set file name
void SetHumanPath(const BYTE* szHumanPath); ///< Set Human68k path name
const BYTE* GetHumanPath() const { return m_szHumanPath; } ///< Get Human68k path name
void SetHumanPath(const uint8_t* szHumanPath); ///< Set Human68k path name
const uint8_t* GetHumanPath() const { return m_szHumanPath; } ///< Get Human68k path name
bool Create(uint32_t nHumanAttribute, bool bForce); ///< Create file
bool Open(); ///< Open file
uint32_t Read(BYTE* pBuffer, uint32_t nSize); ///< Read file
uint32_t Write(const BYTE* pBuffer, uint32_t nSize); ///< Write file
uint32_t Read(uint8_t* pBuffer, uint32_t nSize); ///< Read file
uint32_t Write(const uint8_t* pBuffer, uint32_t nSize); ///< Write file
bool Truncate() const; ///< Truncate file
uint32_t Seek(uint32_t nOffset, Human68k::seek_t nHumanSeek); ///< Seek file
bool TimeStamp(uint32_t nHumanTime) const; ///< Set file time stamp
@ -675,7 +675,7 @@ private:
FILE* m_pFile = nullptr; ///< Host side file object
const char* m_pszMode = nullptr; ///< Host side file open mode
bool m_bFlag = false; ///< Host side file open flag
BYTE m_szHumanPath[HUMAN68K_PATH_MAX] = {}; ///< Human68k path name
uint8_t m_szHumanPath[HUMAN68K_PATH_MAX] = {}; ///< Human68k path name
TCHAR m_szFilename[FILEPATH_MAX] = {}; ///< Host side file name
};
@ -726,7 +726,7 @@ public:
bool isWriteProtect() const { return m_bWriteProtect; }
bool isEnable() const { return m_bEnable; } ///< Is it accessible?
bool isMediaOffline() const;
BYTE GetMediaByte() const;
uint8_t GetMediaByte() const;
uint32_t GetStatus() const;
void SetEnable(bool); ///< Set media status
bool CheckMedia(); ///< Check if media was changed
@ -739,17 +739,17 @@ public:
// Cache operations
void CleanCache() const; ///< Update all cache
void CleanCache(const BYTE* szHumanPath); ///< Update cache for the specified path
void CleanCacheChild(const BYTE* szHumanPath) const; ///< Update all cache below the specified path
void DeleteCache(const BYTE* szHumanPath); ///< Delete the cache for the specified path
CHostPath* FindCache(const BYTE* szHuman); ///< Inspect if the specified path is cached
void CleanCache(const uint8_t* szHumanPath); ///< Update cache for the specified path
void CleanCacheChild(const uint8_t* szHumanPath) const; ///< Update all cache below the specified path
void DeleteCache(const uint8_t* szHumanPath); ///< Delete the cache for the specified path
CHostPath* FindCache(const uint8_t* szHuman); ///< Inspect if the specified path is cached
CHostPath* CopyCache(CHostFiles* pFiles); ///< Acquire the host side name on the basis of cache information
CHostPath* MakeCache(CHostFiles* pFiles); ///< Get all required data to construct a host side name
bool Find(CHostFiles* pFiles); ///< Find host side name (path + file name (can be abbreviated) + attribute)
private:
// Path name operations
static const BYTE* SeparateCopyFilename(const BYTE* szHuman, BYTE* szBuffer);
static const uint8_t* SeparateCopyFilename(const uint8_t* szHuman, uint8_t* szBuffer);
///< Split and copy the first element of the Human68k full path name
/// For memory management
@ -791,9 +791,9 @@ public:
// Cache operations
void CleanCache() const; ///< Update all cache
void CleanCache(uint32_t nUnit) const; ///< Update cache for the specified unit
void CleanCache(uint32_t nUnit, const BYTE* szHumanPath) const; ///< Update cache for the specified path
void CleanCacheChild(uint32_t nUnit, const BYTE* szHumanPath) const; ///< Update cache below the specified path
void DeleteCache(uint32_t nUnit, const BYTE* szHumanPath) const; ///< Delete cache for the specified path
void CleanCache(uint32_t nUnit, const uint8_t* szHumanPath) const; ///< Update cache for the specified path
void CleanCacheChild(uint32_t nUnit, const uint8_t* szHumanPath) const; ///< Update cache below the specified path
void DeleteCache(uint32_t nUnit, const uint8_t* szHumanPath) const; ///< Delete cache for the specified path
bool Find(uint32_t nUnit, CHostFiles* pFiles) const; ///< Find host side name (path + file name (can be abbreviated) + attribute)
void ShellNotify(uint32_t nEvent, const TCHAR* szPath); ///< Notify status change in the host side file system
@ -802,7 +802,7 @@ public:
bool isWriteProtect(uint32_t nUnit) const;
bool isEnable(uint32_t nUnit) const; ///< Is it accessible?
bool isMediaOffline(uint32_t nUnit) const;
BYTE GetMediaByte(uint32_t nUnit) const;
uint8_t GetMediaByte(uint32_t nUnit) const;
uint32_t GetStatus(uint32_t nUnit) const; ///< Get drive status
bool CheckMedia(uint32_t nUnit) const; ///< Media change check
void Eject(uint32_t nUnit) const;
@ -875,9 +875,9 @@ public:
int Open(uint32_t nUnit, uint32_t nKey, const Human68k::namests_t* pNamests, Human68k::fcb_t* pFcb);
///< $4A - Open file
int Close(uint32_t nUnit, uint32_t nKey, const Human68k::fcb_t* pFcb); ///< $4B - Close file
int Read(uint32_t nKey, Human68k::fcb_t* pFcb, BYTE* pAddress, uint32_t nSize);
int Read(uint32_t nKey, Human68k::fcb_t* pFcb, uint8_t* pAddress, uint32_t nSize);
///< $4C - Read file
int Write(uint32_t nKey, Human68k::fcb_t* pFcb, const BYTE* pAddress, uint32_t nSize);
int Write(uint32_t nKey, Human68k::fcb_t* pFcb, const uint8_t* pAddress, uint32_t nSize);
///< $4D - Write file
int Seek(uint32_t nKey, Human68k::fcb_t* pFcb, uint32_t nSeek, int nOffset); ///< $4E - Seek file
uint32_t TimeStamp(uint32_t nUnit, uint32_t nKey, Human68k::fcb_t* pFcb, uint32_t nHumanTime);
@ -885,7 +885,7 @@ public:
int GetCapacity(uint32_t nUnit, Human68k::capacity_t* pCapacity) const; ///< $50 - Get capacity
int CtrlDrive(uint32_t nUnit, Human68k::ctrldrive_t* pCtrlDrive) const; ///< $51 - Inspect / control drive status
int GetDPB(uint32_t nUnit, Human68k::dpb_t* pDpb) const; ///< $52 - Get DPB
int DiskRead(uint32_t nUnit, BYTE* pBuffer, uint32_t nSector, uint32_t nSize); ///< $53 - Read sectors
int DiskRead(uint32_t nUnit, uint8_t* pBuffer, uint32_t nSector, uint32_t nSize); ///< $53 - Read sectors
int DiskWrite(uint32_t nUnit) const; ///< $54 - Write sectors
int Ioctrl(uint32_t nUnit, uint32_t nFunction, Human68k::ioctrl_t* pIoctrl); ///< $55 - IOCTRL
int Flush(uint32_t nUnit) const; ///< $56 - Flush

View File

@ -12,7 +12,6 @@
#include <unistd.h>
#include <poll.h>
#include <arpa/inet.h>
#include "os.h"
#include "ctapdriver.h"
#include "log.h"
#include "rasutil.h"
@ -411,12 +410,12 @@ void CTapDriver::Flush()
{
LOGTRACE("%s", __PRETTY_FUNCTION__)
while (PendingPackets()) {
array<BYTE, ETH_FRAME_LEN> m_garbage_buffer;
array<uint8_t, ETH_FRAME_LEN> m_garbage_buffer;
(void)Receive(m_garbage_buffer.data());
}
}
void CTapDriver::GetMacAddr(BYTE *mac) const
void CTapDriver::GetMacAddr(uint8_t *mac) const
{
assert(mac);
@ -447,19 +446,19 @@ bool CTapDriver::PendingPackets() const
}
// See https://stackoverflow.com/questions/21001659/crc32-algorithm-implementation-in-c-without-a-look-up-table-and-with-a-public-li
uint32_t CTapDriver::Crc32(const BYTE *buf, int length) {
uint32_t CTapDriver::Crc32(const uint8_t *buf, int length) {
uint32_t crc = 0xffffffff;
for (int i = 0; i < length; i++) {
crc ^= buf[i];
for (int j = 0; j < 8; j++) {
const uint32_t mask = -((int)crc & 1);
const uint32_t mask = -(static_cast<int>(crc) & 1);
crc = (crc >> 1) ^ (0xEDB88320 & mask);
}
}
return ~crc;
}
int CTapDriver::Receive(BYTE *buf)
int CTapDriver::Receive(uint8_t *buf)
{
assert(m_hTAP != -1);
@ -469,8 +468,8 @@ int CTapDriver::Receive(BYTE *buf)
}
// Receive
auto dwReceived = (uint32_t)read(m_hTAP, buf, ETH_FRAME_LEN);
if (dwReceived == (uint32_t)-1) {
auto dwReceived = static_cast<uint32_t>(read(m_hTAP, buf, ETH_FRAME_LEN));
if (dwReceived == static_cast<uint32_t>(-1)) {
LOGWARN("%s Error occured while receiving a packet", __PRETTY_FUNCTION__)
return 0;
}
@ -482,10 +481,10 @@ int CTapDriver::Receive(BYTE *buf)
// need it.
const int crc = Crc32(buf, dwReceived);
buf[dwReceived + 0] = (BYTE)((crc >> 0) & 0xFF);
buf[dwReceived + 1] = (BYTE)((crc >> 8) & 0xFF);
buf[dwReceived + 2] = (BYTE)((crc >> 16) & 0xFF);
buf[dwReceived + 3] = (BYTE)((crc >> 24) & 0xFF);
buf[dwReceived + 0] = (uint8_t)((crc >> 0) & 0xFF);
buf[dwReceived + 1] = (uint8_t)((crc >> 8) & 0xFF);
buf[dwReceived + 2] = (uint8_t)((crc >> 16) & 0xFF);
buf[dwReceived + 3] = (uint8_t)((crc >> 24) & 0xFF);
LOGDEBUG("%s CRC is %08X - %02X %02X %02X %02X\n", __PRETTY_FUNCTION__, crc, buf[dwReceived+0], buf[dwReceived+1], buf[dwReceived+2], buf[dwReceived+3])
@ -508,7 +507,7 @@ int CTapDriver::Receive(BYTE *buf)
return dwReceived;
}
int CTapDriver::Send(const BYTE *buf, int len)
int CTapDriver::Send(const uint8_t *buf, int len)
{
assert(m_hTAP != -1);
@ -524,5 +523,5 @@ int CTapDriver::Send(const BYTE *buf, int len)
}
// Start sending
return (int)write(m_hTAP, buf, len);
return static_cast<int>(write(m_hTAP, buf, len));
}

View File

@ -14,7 +14,7 @@
#include <pcap/pcap.h>
#include <net/ethernet.h>
#include <unordered_map>
#include <list>
#include <vector>
#include <string>
#include <array>
@ -33,15 +33,15 @@ public:
bool Init(const unordered_map<string, string>&);
void OpenDump(const string& path); // Capture packets
void GetMacAddr(BYTE *mac) const;
int Receive(BYTE *buf);
int Send(const BYTE *buf, int len);
void GetMacAddr(uint8_t *mac) const;
int Receive(uint8_t *buf);
int Send(const uint8_t *buf, int len);
bool PendingPackets() const; // Check if there are IP packets available
bool Enable() const; // Enable the ras0 interface
bool Disable() const; // Disable the ras0 interface
void Flush(); // Purge all of the packets that are waiting to be processed
static uint32_t Crc32(const BYTE *, int);
static uint32_t Crc32(const uint8_t *, int);
private:
array<byte, 6> m_MacAddr; // MAC Address
@ -52,7 +52,7 @@ private:
pcap_dumper_t *m_pcap_dumper = nullptr;
// Prioritized comma-separated list of interfaces to create the bridge for
list<string> interfaces;
vector<string> interfaces;
string inet;
};

View File

@ -169,9 +169,9 @@ const unordered_map<string, string>& DeviceFactory::GetDefaultParams(PbDeviceTyp
return it != default_params.end() ? it->second : empty_map;
}
list<string> DeviceFactory::GetNetworkInterfaces() const
vector<string> DeviceFactory::GetNetworkInterfaces() const
{
list<string> network_interfaces;
vector<string> network_interfaces;
#ifdef __linux__
ifaddrs *addrs;

View File

@ -12,7 +12,7 @@
#pragma once
#include <string>
#include <list>
#include <vector>
#include <unordered_set>
#include <unordered_map>
#include "rascsi_interface.pb.h"
@ -36,7 +36,7 @@ public:
PbDeviceType GetTypeForFile(const string&) const;
const unordered_set<uint32_t>& GetSectorSizes(PbDeviceType type) const;
const unordered_map<string, string>& GetDefaultParams(PbDeviceType type) const;
list<string> GetNetworkInterfaces() const;
vector<string> GetNetworkInterfaces() const;
const unordered_map<string, PbDeviceType>& GetExtensionMapping() const { return extension_mapping; }
private:

View File

@ -78,13 +78,13 @@ bool Disk::Dispatch(scsi_command cmd)
void Disk::SetUpCache(off_t image_offset, bool raw)
{
cache = make_unique<DiskCache>(GetFilename(), size_shift_count, (uint32_t)GetBlockCount(), image_offset);
cache = make_unique<DiskCache>(GetFilename(), size_shift_count, static_cast<uint32_t>(GetBlockCount()), image_offset);
cache->SetRawMode(raw);
}
void Disk::ResizeCache(const string& path, bool raw)
{
cache.reset(new DiskCache(path, size_shift_count, (uint32_t)GetBlockCount()));
cache.reset(new DiskCache(path, size_shift_count, static_cast<uint32_t>(GetBlockCount())));
cache->SetRawMode(raw);
}
@ -100,7 +100,7 @@ void Disk::FormatUnit()
CheckReady();
// FMTDATA=1 is not supported (but OK if there is no DEFECT LIST)
if ((ctrl->cmd[1] & 0x10) != 0 && ctrl->cmd[4] != 0) {
if ((controller->GetCmd(1) & 0x10) != 0 && controller->GetCmd(4) != 0) {
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
}
@ -109,12 +109,15 @@ void Disk::FormatUnit()
void Disk::Read(access_mode mode)
{
if (uint64_t start; CheckAndGetStartAndCount(start, ctrl->blocks, mode)) {
ctrl->length = Read(ctrl->cmd, controller->GetBuffer(), start);
uint64_t start;
uint32_t blocks;
if (CheckAndGetStartAndCount(start, blocks, mode)) {
controller->SetBlocks(blocks);
controller->SetLength(Read(controller->GetCmd(), controller->GetBuffer(), start));
LOGTRACE("%s ctrl.length is %d", __PRETTY_FUNCTION__, controller->GetLength())
// Set next block
ctrl->next = start + 1;
controller->SetNext(start + 1);
EnterDataInPhase();
}
@ -126,7 +129,7 @@ void Disk::Read(access_mode mode)
void Disk::ReadWriteLong10()
{
// Transfer lengths other than 0 are not supported, which is compliant with the SCSI standard
if (GetInt16(ctrl->cmd, 7) != 0) {
if (GetInt16(controller->GetCmd(), 7) != 0) {
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
}
@ -138,7 +141,7 @@ void Disk::ReadWriteLong10()
void Disk::ReadWriteLong16()
{
// Transfer lengths other than 0 are not supported, which is compliant with the SCSI standard
if (GetInt16(ctrl->cmd, 12) != 0) {
if (GetInt16(controller->GetCmd(), 12) != 0) {
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
}
@ -149,11 +152,14 @@ void Disk::ReadWriteLong16()
void Disk::Write(access_mode mode)
{
if (uint64_t start; CheckAndGetStartAndCount(start, ctrl->blocks, mode)) {
ctrl->length = WriteCheck(start);
uint64_t start;
uint32_t blocks;
if (CheckAndGetStartAndCount(start, blocks, mode)) {
controller->SetBlocks(blocks);
controller->SetLength(WriteCheck(start));
// Set next block
ctrl->next = start + 1;
controller->SetNext(start + 1);
EnterDataOutPhase();
}
@ -164,18 +170,21 @@ void Disk::Write(access_mode mode)
void Disk::Verify(access_mode mode)
{
if (uint64_t start; CheckAndGetStartAndCount(start, ctrl->blocks, mode)) {
uint64_t start;
uint32_t blocks;
if (CheckAndGetStartAndCount(start, blocks, mode)) {
// if BytChk=0
if ((ctrl->cmd[1] & 0x02) == 0) {
if ((controller->GetCmd(1) & 0x02) == 0) {
Seek();
return;
}
// Test reading
ctrl->length = Read(ctrl->cmd, controller->GetBuffer(), start);
controller->SetBlocks(blocks);
controller->SetLength(Read(controller->GetCmd(), controller->GetBuffer(), start));
// Set next block
ctrl->next = start + 1;
controller->SetNext(start + 1);
EnterDataOutPhase();
}
@ -186,8 +195,8 @@ void Disk::Verify(access_mode mode)
void Disk::StartStopUnit()
{
const bool start = ctrl->cmd[4] & 0x01;
const bool load = ctrl->cmd[4] & 0x02;
const bool start = controller->GetCmd(4) & 0x01;
const bool load = controller->GetCmd(4) & 0x02;
if (load) {
LOGTRACE(start ? "Loading medium" : "Ejecting medium")
@ -223,7 +232,7 @@ void Disk::PreventAllowMediumRemoval()
{
CheckReady();
const bool lock = ctrl->cmd[4] & 0x01;
const bool lock = controller->GetCmd(4) & 0x01;
LOGTRACE(lock ? "Locking medium" : "Unlocking medium")
@ -241,11 +250,11 @@ void Disk::SynchronizeCache()
void Disk::ReadDefectData10()
{
const size_t allocation_length = min((size_t)GetInt16(ctrl->cmd, 7), (size_t)4);
const size_t allocation_length = min(static_cast<size_t>(GetInt16(controller->GetCmd(), 7)), static_cast<size_t>(4));
// The defect list is empty
fill_n(controller->GetBuffer().begin(), allocation_length, 0);
ctrl->length = (int)allocation_length;
controller->SetLength(static_cast<uint32_t>(allocation_length));
EnterDataInPhase();
}
@ -264,10 +273,10 @@ bool Disk::Eject(bool force)
return status;
}
int Disk::ModeSense6(const vector<int>& cdb, vector<BYTE>& buf) const
int Disk::ModeSense6(const vector<int>& cdb, vector<uint8_t>& buf) const
{
// Get length, clear buffer
const auto length = (int)min(buf.size(), (size_t)cdb[4]);
const auto length = static_cast<int>(min(buf.size(), static_cast<size_t>(cdb[4])));
fill_n(buf.begin(), length, 0);
// DEVICE SPECIFIC PARAMETER
@ -286,7 +295,7 @@ int Disk::ModeSense6(const vector<int>& cdb, vector<BYTE>& buf) const
// Only if ready
if (IsReady()) {
// Short LBA mode parameter block descriptor (number of blocks and block length)
SetInt32(buf, 4, (uint32_t)GetBlockCount());
SetInt32(buf, 4, static_cast<uint32_t>(GetBlockCount()));
SetInt32(buf, 8, GetSectorSizeInBytes());
}
@ -295,15 +304,15 @@ int Disk::ModeSense6(const vector<int>& cdb, vector<BYTE>& buf) const
size = AddModePages(cdb, buf, size, length, 255);
buf[0] = (BYTE)size;
buf[0] = (uint8_t)size;
return size;
}
int Disk::ModeSense10(const vector<int>& cdb, vector<BYTE>& buf) const
int Disk::ModeSense10(const vector<int>& cdb, vector<uint8_t>& buf) const
{
// Get length, clear buffer
const auto length = (int)min(buf.size(), (size_t)GetInt16(cdb, 7));
const auto length = static_cast<int>(min(buf.size(), static_cast<size_t>(GetInt16(cdb, 7))));
fill_n(buf.begin(), length, 0);
// DEVICE SPECIFIC PARAMETER
@ -325,7 +334,7 @@ int Disk::ModeSense10(const vector<int>& cdb, vector<BYTE>& buf) const
buf[7] = 0x08;
// Short LBA mode parameter block descriptor (number of blocks and block length)
SetInt32(buf, 8, (uint32_t)disk_blocks);
SetInt32(buf, 8, static_cast<uint32_t>(disk_blocks));
SetInt32(buf, 12, disk_size);
size = 16;
@ -443,7 +452,7 @@ void Disk::AddDrivePage(map<int, vector<byte>>& pages, bool changeable) const
uint64_t cylinders = GetBlockCount();
cylinders >>= 3;
cylinders /= 25;
SetInt32(buf, 0x01, (uint32_t)cylinders);
SetInt32(buf, 0x01, static_cast<uint32_t>(cylinders));
// Fix the head at 8
buf[0x05] = (byte)0x8;
@ -480,7 +489,7 @@ void Disk::AddCachePage(map<int, vector<byte>>& pages, bool changeable) const
pages[8] = buf;
}
int Disk::Read(const vector<int>&, vector<BYTE>& buf, uint64_t block)
int Disk::Read(const vector<int>&, vector<uint8_t>& buf, uint64_t block)
{
LOGTRACE("%s", __PRETTY_FUNCTION__)
@ -492,7 +501,7 @@ int Disk::Read(const vector<int>&, vector<BYTE>& buf, uint64_t block)
}
// leave it to the cache
if (!cache->ReadSector(buf, (uint32_t)block)) {
if (!cache->ReadSector(buf, static_cast<uint32_t>(block))) {
throw scsi_exception(sense_key::MEDIUM_ERROR, asc::READ_FAULT);
}
@ -516,7 +525,7 @@ int Disk::WriteCheck(uint64_t block)
return GetSectorSizeInBytes();
}
void Disk::Write(const vector<int>&, const vector<BYTE>& buf, uint64_t block)
void Disk::Write(const vector<int>&, const vector<uint8_t>& buf, uint64_t block)
{
LOGTRACE("%s", __PRETTY_FUNCTION__)
@ -533,7 +542,7 @@ void Disk::Write(const vector<int>&, const vector<BYTE>& buf, uint64_t block)
}
// Leave it to the cache
if (!cache->WriteSector(buf, (uint32_t)block)) {
if (!cache->WriteSector(buf, static_cast<uint32_t>(block))) {
throw scsi_exception(sense_key::MEDIUM_ERROR, asc::WRITE_FAULT);
}
}
@ -547,7 +556,8 @@ void Disk::Seek()
void Disk::Seek6()
{
if (uint64_t start; CheckAndGetStartAndCount(start, ctrl->blocks, SEEK6)) {
uint64_t start;
if (uint32_t blocks; CheckAndGetStartAndCount(start, blocks, SEEK6)) {
CheckReady();
}
@ -556,7 +566,8 @@ void Disk::Seek6()
void Disk::Seek10()
{
if (uint64_t start; CheckAndGetStartAndCount(start, ctrl->blocks, SEEK10)) {
uint64_t start;
if (uint32_t blocks; CheckAndGetStartAndCount(start, blocks, SEEK10)) {
CheckReady();
}
@ -571,7 +582,7 @@ void Disk::ReadCapacity10()
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::MEDIUM_NOT_PRESENT);
}
vector<BYTE>& buf = controller->GetBuffer();
vector<uint8_t>& buf = controller->GetBuffer();
// Create end of logical block address (blocks-1)
uint64_t capacity = GetBlockCount() - 1;
@ -580,13 +591,13 @@ void Disk::ReadCapacity10()
if (capacity > 4294967295) {
capacity = -1;
}
SetInt32(buf, 0, (uint32_t)capacity);
SetInt32(buf, 0, static_cast<uint32_t>(capacity));
// Create block length (1 << size)
SetInt32(buf, 4, 1 << size_shift_count);
// the size
ctrl->length = 8;
controller->SetLength(8);
EnterDataInPhase();
}
@ -599,7 +610,7 @@ void Disk::ReadCapacity16()
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::MEDIUM_NOT_PRESENT);
}
vector<BYTE>& buf = controller->GetBuffer();
vector<uint8_t>& buf = controller->GetBuffer();
// Create end of logical block address (blocks-1)
SetInt64(buf, 0, GetBlockCount() - 1);
@ -613,7 +624,7 @@ void Disk::ReadCapacity16()
buf[13] = 0;
// the size
ctrl->length = 14;
controller->SetLength(14);
EnterDataInPhase();
}
@ -621,7 +632,7 @@ void Disk::ReadCapacity16()
void Disk::ReadCapacity16_ReadLong16()
{
// The service action determines the actual command
switch (ctrl->cmd[1] & 0x1f) {
switch (controller->GetCmd(1) & 0x1f) {
case 0x10:
ReadCapacity16();
break;
@ -644,7 +655,7 @@ void Disk::ReadCapacity16_ReadLong16()
void Disk::ValidateBlockAddress(access_mode mode) const
{
const uint64_t block = mode == RW16 ? GetInt64(ctrl->cmd, 2) : GetInt32(ctrl->cmd, 2);
const uint64_t block = mode == RW16 ? GetInt64(controller->GetCmd(), 2) : GetInt32(controller->GetCmd(), 2);
if (block > GetBlockCount()) {
LOGTRACE("%s", ("Capacity of " + to_string(GetBlockCount()) + " block(s) exceeded: Trying to access block "
@ -656,28 +667,29 @@ void Disk::ValidateBlockAddress(access_mode mode) const
bool Disk::CheckAndGetStartAndCount(uint64_t& start, uint32_t& count, access_mode mode) const
{
if (mode == RW6 || mode == SEEK6) {
start = GetInt24(ctrl->cmd, 1);
start = GetInt24(controller->GetCmd(), 1);
count = ctrl->cmd[4];
count = controller->GetCmd(4);
if (!count) {
count= 0x100;
}
}
else {
start = mode == RW16 ? GetInt64(ctrl->cmd, 2) : GetInt32(ctrl->cmd, 2);
start = mode == RW16 ? GetInt64(controller->GetCmd(), 2) : GetInt32(controller->GetCmd(), 2);
if (mode == RW16) {
count = GetInt32(ctrl->cmd, 10);
count = GetInt32(controller->GetCmd(), 10);
}
else if (mode != SEEK6 && mode != SEEK10) {
count = GetInt16(ctrl->cmd, 7);
count = GetInt16(controller->GetCmd(), 7);
}
else {
count = 0;
}
}
LOGTRACE("%s READ/WRITE/VERIFY/SEEK command record=$%08X blocks=%d", __PRETTY_FUNCTION__, (uint32_t)start, count)
LOGTRACE("%s READ/WRITE/VERIFY/SEEK command record=$%08X blocks=%d", __PRETTY_FUNCTION__,
static_cast<uint32_t>(start), count)
// Check capacity
if (uint64_t capacity = GetBlockCount(); !capacity || start > capacity || start + count > capacity) {

View File

@ -53,9 +53,9 @@ public:
// Command helpers
virtual int WriteCheck(uint64_t);
virtual void Write(const vector<int>&, const vector<BYTE>&, uint64_t);
virtual void Write(const vector<int>&, const vector<uint8_t>&, uint64_t);
virtual int Read(const vector<int>&, vector<BYTE>& , uint64_t);
virtual int Read(const vector<int>&, vector<uint8_t>& , uint64_t);
uint32_t GetSectorSizeInBytes() const;
bool IsSectorSizeConfigurable() const { return !sector_sizes.empty(); }
@ -95,8 +95,8 @@ private:
void ValidateBlockAddress(access_mode) const;
bool CheckAndGetStartAndCount(uint64_t&, uint32_t&, access_mode) const;
int ModeSense6(const vector<int>&, vector<BYTE>&) const override;
int ModeSense10(const vector<int>&, vector<BYTE>&) const override;
int ModeSense6(const vector<int>&, vector<uint8_t>&) const override;
int ModeSense10(const vector<int>&, vector<uint8_t>&) const override;
static const unordered_map<uint32_t, uint32_t> shift_counts;

View File

@ -14,11 +14,11 @@
//
//---------------------------------------------------------------------------
#include "os.h"
#include "disk_track.h"
#include "disk_cache.h"
#include <cstdlib>
#include <cassert>
#include <algorithm>
DiskCache::DiskCache(const string& path, int size, uint32_t blocks, off_t imgoff)
: sec_path(path), sec_size(size), sec_blocks(blocks), imgoffset(imgoff)
@ -29,15 +29,9 @@ DiskCache::DiskCache(const string& path, int size, uint32_t blocks, off_t imgoff
bool DiskCache::Save() const
{
// Save track
for (const cache_t& c : cache) {
// Save if this is a valid track
if (c.disktrk && !c.disktrk->Save(sec_path)) {
return false;
}
}
return true;
// Save valid tracks
return none_of(cache.begin(), cache.end(), [this](const cache_t& c)
{ return c.disktrk != nullptr && !c.disktrk->Save(sec_path); });
}
shared_ptr<DiskTrack> DiskCache::GetTrack(uint32_t block)
@ -52,7 +46,7 @@ shared_ptr<DiskTrack> DiskCache::GetTrack(uint32_t block)
return Assign(track);
}
bool DiskCache::ReadSector(vector<BYTE>& buf, uint32_t block)
bool DiskCache::ReadSector(vector<uint8_t>& buf, uint32_t block)
{
shared_ptr<DiskTrack> disktrk = GetTrack(block);
if (disktrk == nullptr) {
@ -63,7 +57,7 @@ bool DiskCache::ReadSector(vector<BYTE>& buf, uint32_t block)
return disktrk->ReadSector(buf, block & 0xff);
}
bool DiskCache::WriteSector(const vector<BYTE>& buf, uint32_t block)
bool DiskCache::WriteSector(const vector<uint8_t>& buf, uint32_t block)
{
shared_ptr<DiskTrack> disktrk = GetTrack(block);
if (disktrk == nullptr) {
@ -97,7 +91,7 @@ shared_ptr<DiskTrack> DiskCache::Assign(int track)
for (size_t i = 0; i < cache.size(); i++) {
if (cache[i].disktrk == nullptr) {
// Try loading
if (Load((int)i, track, nullptr)) {
if (Load(static_cast<int>(i), track, nullptr)) {
// Success loading
cache[i].serial = serial;
return cache[i].disktrk;
@ -134,7 +128,7 @@ shared_ptr<DiskTrack> DiskCache::Assign(int track)
shared_ptr<DiskTrack> disktrk = cache[c].disktrk;
cache[c].disktrk.reset();
if (Load((int)c, track, disktrk)) {
if (Load(static_cast<int>(c), track, disktrk)) {
// Successful loading
cache[c].serial = serial;
return cache[c].disktrk;
@ -151,7 +145,7 @@ shared_ptr<DiskTrack> DiskCache::Assign(int track)
//---------------------------------------------------------------------------
bool DiskCache::Load(int index, int track, shared_ptr<DiskTrack> disktrk)
{
assert(index >= 0 && index < (int)cache.size());
assert(index >= 0 && index < static_cast<int>(cache.size()));
assert(track >= 0);
assert(cache[index].disktrk == nullptr);

View File

@ -41,8 +41,8 @@ public:
// Access
bool Save() const; // Save and release all
bool ReadSector(vector<BYTE>&, uint32_t); // Sector Read
bool WriteSector(const vector<BYTE>&, uint32_t); // Sector Write
bool ReadSector(vector<uint8_t>&, uint32_t); // Sector Read
bool WriteSector(const vector<uint8_t>&, uint32_t); // Sector Write
private:

View File

@ -85,7 +85,7 @@ bool DiskTrack::Load(const string& path)
}
// Reallocate if the buffer length is different
if (dt.length != (uint32_t)length) {
if (dt.length != static_cast<uint32_t>(length)) {
free(dt.buffer);
if (posix_memalign((void **)&dt.buffer, 512, ((length + 511) / 512) * 512)) {
LOGWARN("%s posix_memalign failed", __PRETTY_FUNCTION__)
@ -215,7 +215,7 @@ bool DiskTrack::Save(const string& path)
return true;
}
bool DiskTrack::ReadSector(vector<BYTE>& buf, int sec) const
bool DiskTrack::ReadSector(vector<uint8_t>& buf, int sec) const
{
assert(sec >= 0 && sec < 0x100);
@ -240,7 +240,7 @@ bool DiskTrack::ReadSector(vector<BYTE>& buf, int sec) const
return true;
}
bool DiskTrack::WriteSector(const vector<BYTE>& buf, int sec)
bool DiskTrack::WriteSector(const vector<uint8_t>& buf, int sec)
{
assert((sec >= 0) && (sec < 0x100));
assert(!dt.raw);

View File

@ -15,7 +15,6 @@
#pragma once
#include "os.h"
#include <cstdlib>
#include <vector>
#include <string>
@ -29,7 +28,7 @@ class DiskTrack
int size; // Sector Size (8=256, 9=512, 10=1024, 11=2048, 12=4096)
int sectors; // Number of sectors(<0x100)
uint32_t length; // Data buffer length
BYTE *buffer; // Data buffer
uint8_t *buffer; // Data buffer
bool init; // Is it initilized?
bool changed; // Changed flag
vector<bool> changemap; // Changed map
@ -53,8 +52,8 @@ private:
bool Save(const string& path);
// Read / Write
bool ReadSector(vector<BYTE>&, int) const; // Sector Read
bool WriteSector(const vector<BYTE>& buf, int); // Sector Write
bool ReadSector(vector<uint8_t>&, int) const; // Sector Read
bool WriteSector(const vector<uint8_t>& buf, int); // Sector Write
int GetTrack() const { return dt.track; } // Get track
};

View File

@ -39,7 +39,7 @@ public:
commands[opcode] = make_unique<command_t>(name, execute);
}
bool Dispatch(T *instance, scsi_command cmd)
bool Dispatch(T *instance, scsi_command cmd) const
{
if (const auto& it = commands.find(cmd); it != commands.end()) {
LOGDEBUG("%s Executing %s ($%02X)", __PRETTY_FUNCTION__, it->second->name, (int)cmd)

View File

@ -59,8 +59,8 @@ vector<byte> HostServices::InquiryInternal() const
void HostServices::StartStopUnit()
{
const bool start = ctrl->cmd[4] & 0x01;
const bool load = ctrl->cmd[4] & 0x02;
const bool start = controller->GetCmd(4) & 0x01;
const bool load = controller->GetCmd(4) & 0x02;
if (!start) {
// Flush any caches
@ -85,32 +85,32 @@ void HostServices::StartStopUnit()
EnterStatusPhase();
}
int HostServices::ModeSense6(const vector<int>& cdb, vector<BYTE>& buf) const
int HostServices::ModeSense6(const vector<int>& cdb, vector<uint8_t>& buf) const
{
// Block descriptors cannot be returned
if (!(cdb[1] & 0x08)) {
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
}
const auto length = (int)min(buf.size(), (size_t)cdb[4]);
const auto length = static_cast<int>(min(buf.size(), static_cast<size_t>(cdb[4])));
fill_n(buf.begin(), length, 0);
// 4 bytes basic information
int size = AddModePages(cdb, buf, 4, length, 255);
buf[0] = (BYTE)size;
buf[0] = (uint8_t)size;
return size;
}
int HostServices::ModeSense10(const vector<int>& cdb, vector<BYTE>& buf) const
int HostServices::ModeSense10(const vector<int>& cdb, vector<uint8_t>& buf) const
{
// Block descriptors cannot be returned
if (!(cdb[1] & 0x08)) {
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
}
const auto length = (int)min(buf.size(), (size_t)GetInt16(cdb, 7));
const auto length = static_cast<int>(min(buf.size(), static_cast<size_t>(GetInt16(cdb, 7))));
fill_n(buf.begin(), length, 0);
// 8 bytes basic information

View File

@ -56,8 +56,8 @@ private:
const ControllerManager& controller_manager;
void StartStopUnit();
int ModeSense6(const vector<int>&, vector<BYTE>&) const override;
int ModeSense10(const vector<int>&, vector<BYTE>&) const override;
int ModeSense6(const vector<int>&, vector<uint8_t>&) const override;
int ModeSense10(const vector<int>&, vector<uint8_t>&) const override;
void AddRealtimeClockPage(map<int, vector<byte>>&, bool) const;
};

View File

@ -0,0 +1,27 @@
//---------------------------------------------------------------------------
//
// SCSI Target Emulator RaSCSI Reloaded
// for Raspberry Pi
//
// Copyright (C) 2022 Uwe Seimet
//
// Abstraction for the DaynaPort and the host bridge, which both have methods for writing byte sequences
//
//---------------------------------------------------------------------------
#pragma once
#include <vector>
using namespace std;
class ByteWriter
{
public:
ByteWriter() = default;
virtual ~ByteWriter() = default;
virtual bool WriteBytes(const vector<int>&, vector<uint8_t>&, uint32_t) = 0;
};

View File

@ -34,7 +34,7 @@ bool ModePageDevice::Dispatch(scsi_command cmd)
return dispatcher.Dispatch(this, cmd) ? true : super::Dispatch(cmd);
}
int ModePageDevice::AddModePages(const vector<int>& cdb, vector<BYTE>& buf, int offset, int length, int max_size) const
int ModePageDevice::AddModePages(const vector<int>& cdb, vector<uint8_t>& buf, int offset, int length, int max_size) const
{
int max_length = length - offset;
if (max_length < 0) {
@ -88,11 +88,11 @@ int ModePageDevice::AddModePages(const vector<int>& cdb, vector<BYTE>& buf, int
result[off + 1] = (byte)(page0.size() - 2);
}
if ((int)result.size() > max_size) {
if (static_cast<int>(result.size()) > max_size) {
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
}
auto size = (int)min((size_t)max_length, result.size());
auto size = static_cast<int>(min(static_cast<size_t>(max_length), result.size()));
memcpy(&buf.data()[offset], result.data(), size);
// Do not return more than the requested number of bytes
@ -101,42 +101,42 @@ int ModePageDevice::AddModePages(const vector<int>& cdb, vector<BYTE>& buf, int
void ModePageDevice::ModeSense6()
{
ctrl->length = ModeSense6(ctrl->cmd, controller->GetBuffer());
controller->SetLength(ModeSense6(controller->GetCmd(), controller->GetBuffer()));
EnterDataInPhase();
}
void ModePageDevice::ModeSense10()
{
ctrl->length = ModeSense10(ctrl->cmd, controller->GetBuffer());
controller->SetLength(ModeSense10(controller->GetCmd(), controller->GetBuffer()));
EnterDataInPhase();
}
void ModePageDevice::ModeSelect(scsi_command, const vector<int>&, const vector<BYTE>&, int) const
void ModePageDevice::ModeSelect(scsi_command, const vector<int>&, const vector<uint8_t>&, int) const
{
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_COMMAND_OPERATION_CODE);
}
void ModePageDevice::ModeSelect6()
{
ctrl->length = SaveParametersCheck(ctrl->cmd[4]);
controller->SetLength(SaveParametersCheck(controller->GetCmd(4)));
EnterDataOutPhase();
}
void ModePageDevice::ModeSelect10()
{
const size_t length = min(controller->GetBuffer().size(), (size_t)GetInt16(ctrl->cmd, 7));
const size_t length = min(controller->GetBuffer().size(), static_cast<size_t>(GetInt16(controller->GetCmd(), 7)));
ctrl->length = SaveParametersCheck((int)length);
controller->SetLength(SaveParametersCheck(static_cast<uint32_t>(length)));
EnterDataOutPhase();
}
int ModePageDevice::SaveParametersCheck(int length) const
{
if (!SupportsSaveParameters() && (ctrl->cmd[1] & 0x01)) {
if (!SupportsSaveParameters() && (controller->GetCmd(1) & 0x01)) {
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
}

View File

@ -23,13 +23,13 @@ public:
bool Dispatch(scsi_command) override;
virtual void ModeSelect(scsi_defs::scsi_command, const vector<int>&, const vector<BYTE>&, int) const;
virtual void ModeSelect(scsi_defs::scsi_command, const vector<int>&, const vector<uint8_t>&, int) const;
protected:
bool SupportsSaveParameters() const { return supports_save_parameters; }
void SupportsSaveParameters(bool b) { supports_save_parameters = b; }
int AddModePages(const vector<int>&, vector<BYTE>&, int, int, int) const;
int AddModePages(const vector<int>&, vector<uint8_t>&, int, int, int) const;
virtual void SetUpModePages(map<int, vector<byte>>&, int, bool) const = 0;
virtual void AddVendorPage(map<int, vector<byte>>&, int, bool) const {
// Nothing to add by default
@ -43,8 +43,8 @@ private:
bool supports_save_parameters = false;
virtual int ModeSense6(const vector<int>&, vector<BYTE>&) const = 0;
virtual int ModeSense10(const vector<int>&, vector<BYTE>&) const = 0;
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();

View File

@ -55,7 +55,6 @@ int PrimaryDevice::GetId() const
void PrimaryDevice::SetController(AbstractController *c)
{
controller = c;
ctrl = controller->GetCtrl();
}
void PrimaryDevice::TestUnitReady()
@ -68,16 +67,16 @@ void PrimaryDevice::TestUnitReady()
void PrimaryDevice::Inquiry()
{
// EVPD and page code check
if ((ctrl->cmd[1] & 0x01) || ctrl->cmd[2]) {
if ((controller->GetCmd(1) & 0x01) || controller->GetCmd(2)) {
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
}
vector<byte> buf = InquiryInternal();
const size_t allocation_length = min(buf.size(), (size_t)GetInt16(ctrl->cmd, 3));
const size_t allocation_length = min(buf.size(), static_cast<size_t>(GetInt16(controller->GetCmd(), 3)));
memcpy(controller->GetBuffer().data(), buf.data(), allocation_length);
ctrl->length = (uint32_t)allocation_length;
controller->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)) {
@ -93,20 +92,20 @@ void PrimaryDevice::Inquiry()
void PrimaryDevice::ReportLuns()
{
// Only SELECT REPORT mode 0 is supported
if (ctrl->cmd[2]) {
if (controller->GetCmd(2)) {
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
}
const uint32_t allocation_length = GetInt32(ctrl->cmd, 6);
const uint32_t allocation_length = GetInt32(controller->GetCmd(), 6);
vector<BYTE>& buf = controller->GetBuffer();
fill_n(buf.begin(), min(buf.size(), (size_t)allocation_length), 0);
vector<uint8_t>& buf = controller->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)) {
size += 8;
buf[size + 7] = (BYTE)lun;
buf[size + 7] = (uint8_t)lun;
}
}
@ -114,7 +113,7 @@ void PrimaryDevice::ReportLuns()
size += 8;
ctrl->length = min(allocation_length, size);
controller->SetLength(min(allocation_length, size));
EnterDataInPhase();
}
@ -139,10 +138,10 @@ void PrimaryDevice::RequestSense()
vector<byte> buf = controller->GetDeviceForLun(lun)->HandleRequestSense();
const size_t allocation_length = min(buf.size(), (size_t)ctrl->cmd[4]);
const size_t allocation_length = min(buf.size(), static_cast<size_t>(controller->GetCmd(4)));
memcpy(controller->GetBuffer().data(), buf.data(), allocation_length);
ctrl->length = (uint32_t)allocation_length;
controller->SetLength(static_cast<uint32_t>(allocation_length));
EnterDataInPhase();
}
@ -150,12 +149,12 @@ void PrimaryDevice::RequestSense()
void PrimaryDevice::SendDiagnostic()
{
// Do not support PF bit
if (ctrl->cmd[1] & 0x10) {
if (controller->GetCmd(1) & 0x10) {
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
}
// Do not support parameter list
if ((ctrl->cmd[3] != 0) || (ctrl->cmd[4] != 0)) {
if ((controller->GetCmd(3) != 0) || (controller->GetCmd(4) != 0)) {
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
}
@ -229,13 +228,13 @@ 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__, (int)controller->GetStatus(),
(int)buf[2], (int)buf[12])
LOGTRACE("%s Status $%02X, Sense Key $%02X, ASC $%02X",__PRETTY_FUNCTION__, static_cast<int>(controller->GetStatus()),
static_cast<int>(buf[2]), static_cast<int>(buf[12]))
return buf;
}
bool PrimaryDevice::WriteByteSequence(vector<BYTE>&, uint32_t)
bool PrimaryDevice::WriteByteSequence(vector<uint8_t>&, uint32_t)
{
LOGERROR("%s Writing bytes is not supported by this device", __PRETTY_FUNCTION__)

View File

@ -29,7 +29,7 @@ public:
int GetId() const override;
void SetController(AbstractController *);
virtual bool WriteByteSequence(vector<BYTE>&, uint32_t);
virtual bool WriteByteSequence(vector<uint8_t>&, uint32_t);
int GetSendDelay() const { return send_delay; }
@ -60,8 +60,8 @@ protected:
void EnterDataInPhase() { controller->DataIn(); }
void EnterDataOutPhase() { controller->DataOut(); }
// TODO Try to replace this raw pointer, maybe by a weak_ptr
AbstractController *controller = nullptr;
AbstractController::ctrl_t *ctrl = nullptr;
private:

View File

@ -13,7 +13,7 @@
using namespace scsi_defs;
void scsi_command_util::ModeSelect(scsi_command cmd, const vector<int>& cdb, const vector<BYTE>& buf, int length,
void scsi_command_util::ModeSelect(scsi_command cmd, const vector<int>& cdb, const vector<uint8_t>& buf, int length,
int sector_size)
{
assert(cmd == scsi_command::eCmdModeSelect6 || cmd == scsi_command::eCmdModeSelect10);
@ -99,91 +99,91 @@ void scsi_command_util::AddAppleVendorModePage(map<int, vector<byte>>& pages, bo
pages[48] = buf;
}
int scsi_command_util::GetInt16(const vector<BYTE>& buf, int offset)
int scsi_command_util::GetInt16(const vector<uint8_t>& buf, int offset)
{
assert(buf.size() > (size_t)offset + 1);
assert(buf.size() > static_cast<size_t>(offset) + 1);
return ((int)buf[offset] << 8) | buf[offset + 1];
return (static_cast<int>(buf[offset]) << 8) | buf[offset + 1];
}
int scsi_command_util::GetInt16(const vector<int>& buf, int offset)
{
assert(buf.size() > (size_t)offset + 1);
assert(buf.size() > static_cast<size_t>(offset) + 1);
return (buf[offset] << 8) | buf[offset + 1];
}
int scsi_command_util::GetInt24(const vector<int>& buf, int offset)
{
assert(buf.size() > (size_t)offset + 2);
assert(buf.size() > static_cast<size_t>(offset) + 2);
return (buf[offset] << 16) | (buf[offset + 1] << 8) | buf[offset + 2];
}
uint32_t scsi_command_util::GetInt32(const vector<int>& buf, int offset)
{
assert(buf.size() > (size_t)offset + 3);
assert(buf.size() > static_cast<size_t>(offset) + 3);
return ((uint32_t)buf[offset] << 24) | ((uint32_t)buf[offset + 1] << 16) |
((uint32_t)buf[offset + 2] << 8) | (uint32_t)buf[offset + 3];
return (static_cast<uint32_t>(buf[offset]) << 24) | (static_cast<uint32_t>(buf[offset + 1]) << 16) |
(static_cast<uint32_t>(buf[offset + 2]) << 8) | static_cast<uint32_t>(buf[offset + 3]);
}
uint64_t scsi_command_util::GetInt64(const vector<int>& buf, int offset)
{
assert(buf.size() > (size_t)offset + 7);
assert(buf.size() > static_cast<size_t>(offset) + 7);
return ((uint64_t)buf[offset] << 56) | ((uint64_t)buf[offset + 1] << 48) |
((uint64_t)buf[offset + 2] << 40) | ((uint64_t)buf[offset + 3] << 32) |
((uint64_t)buf[offset + 4] << 24) | ((uint64_t)buf[offset + 5] << 16) |
((uint64_t)buf[offset + 6] << 8) | (uint64_t)buf[offset + 7];
return (static_cast<uint64_t>(buf[offset]) << 56) | (static_cast<uint64_t>(buf[offset + 1]) << 48) |
(static_cast<uint64_t>(buf[offset + 2]) << 40) | (static_cast<uint64_t>(buf[offset + 3]) << 32) |
(static_cast<uint64_t>(buf[offset + 4]) << 24) | (static_cast<uint64_t>(buf[offset + 5]) << 16) |
(static_cast<uint64_t>(buf[offset + 6]) << 8) | static_cast<uint64_t>(buf[offset + 7]);
}
void scsi_command_util::SetInt16(vector<byte>& buf, int offset, int value)
{
assert(buf.size() > (size_t)offset + 1);
assert(buf.size() > static_cast<size_t>(offset) + 1);
buf[offset] = (byte)(value >> 8);
buf[offset + 1] = (byte)value;
buf[offset] = static_cast<byte>(value >> 8);
buf[offset + 1] = static_cast<byte>(value);
}
void scsi_command_util::SetInt32(vector<byte>& buf, int offset, uint32_t value)
{
assert(buf.size() > (size_t)offset + 3);
assert(buf.size() > static_cast<size_t>(offset) + 3);
buf[offset] = (byte)(value >> 24);
buf[offset + 1] = (byte)(value >> 16);
buf[offset + 2] = (byte)(value >> 8);
buf[offset + 3] = (byte)value;
buf[offset] = static_cast<byte>(value >> 24);
buf[offset + 1] = static_cast<byte>(value >> 16);
buf[offset + 2] = static_cast<byte>(value >> 8);
buf[offset + 3] = static_cast<byte>(value);
}
void scsi_command_util::SetInt16(vector<BYTE>& buf, int offset, int value)
void scsi_command_util::SetInt16(vector<uint8_t>& buf, int offset, int value)
{
assert(buf.size() > (size_t)offset + 1);
assert(buf.size() > static_cast<size_t>(offset) + 1);
buf[offset] = (BYTE)(value >> 8);
buf[offset + 1] = (BYTE)value;
buf[offset] = static_cast<uint8_t>(value >> 8);
buf[offset + 1] = static_cast<uint8_t>(value);
}
void scsi_command_util::SetInt32(vector<BYTE>& buf, int offset, uint32_t value)
void scsi_command_util::SetInt32(vector<uint8_t>& buf, int offset, uint32_t value)
{
assert(buf.size() > (size_t)offset + 3);
assert(buf.size() > static_cast<size_t>(offset) + 3);
buf[offset] = (BYTE)(value >> 24);
buf[offset + 1] = (BYTE)(value >> 16);
buf[offset + 2] = (BYTE)(value >> 8);
buf[offset + 3] = (BYTE)value;
buf[offset] = static_cast<uint8_t>(value >> 24);
buf[offset + 1] = static_cast<uint8_t>(value >> 16);
buf[offset + 2] = static_cast<uint8_t>(value >> 8);
buf[offset + 3] = static_cast<uint8_t>(value);
}
void scsi_command_util::SetInt64(vector<BYTE>& buf, int offset, uint64_t value)
void scsi_command_util::SetInt64(vector<uint8_t>& buf, int offset, uint64_t value)
{
assert(buf.size() > (size_t)offset + 7);
assert(buf.size() > static_cast<size_t>(offset) + 7);
buf[offset] = (BYTE)(value >> 56);
buf[offset + 1] = (BYTE)(value >> 48);
buf[offset + 2] = (BYTE)(value >> 40);
buf[offset + 3] = (BYTE)(value >> 32);
buf[offset + 4] = (BYTE)(value >> 24);
buf[offset + 5] = (BYTE)(value >> 16);
buf[offset + 6] = (BYTE)(value >> 8);
buf[offset + 7] = (BYTE)value;
buf[offset] = static_cast<uint8_t>(value >> 56);
buf[offset + 1] = static_cast<uint8_t>(value >> 48);
buf[offset + 2] = static_cast<uint8_t>(value >> 40);
buf[offset + 3] = static_cast<uint8_t>(value >> 32);
buf[offset + 4] = static_cast<uint8_t>(value >> 24);
buf[offset + 5] = static_cast<uint8_t>(value >> 16);
buf[offset + 6] = static_cast<uint8_t>(value >> 8);
buf[offset + 7] = static_cast<uint8_t>(value);
}

View File

@ -19,18 +19,18 @@ using namespace std;
namespace scsi_command_util
{
void ModeSelect(scsi_defs::scsi_command, const vector<int>&, const vector<BYTE>&, int, int);
void ModeSelect(scsi_defs::scsi_command, const vector<int>&, const vector<uint8_t>&, int, int);
void EnrichFormatPage(map<int, vector<byte>>&, bool, int);
void AddAppleVendorModePage(map<int, vector<byte>>&, bool);
int GetInt16(const vector<BYTE>&, int);
int GetInt16(const vector<uint8_t>&, int);
int GetInt16(const vector<int>&, int);
int GetInt24(const vector<int>&, int);
uint32_t GetInt32(const vector<int>&, int);
uint64_t GetInt64(const vector<int>&, int);
void SetInt16(vector<byte>&, int, int);
void SetInt32(vector<byte>&, int, uint32_t);
void SetInt16(vector<BYTE>&, int, int);
void SetInt32(vector<BYTE>&, int, uint32_t);
void SetInt64(vector<BYTE>&, int, uint64_t);
void SetInt16(vector<uint8_t>&, int, int);
void SetInt32(vector<uint8_t>&, int, uint32_t);
void SetInt64(vector<uint8_t>&, int, uint64_t);
}

View File

@ -32,8 +32,7 @@
using namespace scsi_defs;
using namespace scsi_command_util;
// TODO Disk must not be the superclass
SCSIDaynaPort::SCSIDaynaPort(int lun) : Disk(SCDP, lun)
SCSIDaynaPort::SCSIDaynaPort(int lun) : PrimaryDevice(SCDP, lun)
{
dispatcher.Add(scsi_command::eCmdTestUnitReady, "TestUnitReady", &SCSIDaynaPort::TestUnitReady);
dispatcher.Add(scsi_command::eCmdRead6, "Read6", &SCSIDaynaPort::Read6);
@ -48,20 +47,10 @@ SCSIDaynaPort::SCSIDaynaPort(int lun) : Disk(SCDP, lun)
SetSendDelay(DAYNAPORT_READ_HEADER_SZ);
SupportsParams(true);
// TODO Remove as soon as SCDP is not a subclass of Disk anymore
SetStoppable(false);
// TODO Remove as soon as SCDP is not a subclass of Disk anymore
SupportsFile(false);
}
bool SCSIDaynaPort::Dispatch(scsi_command cmd)
{
// TODO As long as DaynaPort suffers from being a subclass of Disk at least reject MODE SENSE and MODE SELECT
if (cmd == scsi_command::eCmdModeSense6 || cmd == scsi_command::eCmdModeSelect6 ||
cmd == scsi_command::eCmdModeSense10 || cmd == scsi_command::eCmdModeSelect10) {
return false;
}
// The superclass class handles the less specific commands
return dispatcher.Dispatch(this, cmd) ? true : super::Dispatch(cmd);
}
@ -89,18 +78,13 @@ bool SCSIDaynaPort::Init(const unordered_map<string, string>& params)
return true;
}
void SCSIDaynaPort::Open()
{
m_tap.OpenDump(GetFilename().c_str());
}
vector<byte> SCSIDaynaPort::InquiryInternal() const
{
vector<byte> buf = HandleInquiry(device_type::PROCESSOR, scsi_level::SCSI_2, false);
// The Daynaport driver for the Mac expects 37 bytes: Increase additional length and
// add a vendor-specific byte in order to satisfy this driver.
buf[4] = (byte)((int)buf[4] + 1);
buf[4] = (byte)(to_integer<int>(buf[4]) + 1);
buf.push_back((byte)0);
return buf;
@ -137,7 +121,7 @@ vector<byte> SCSIDaynaPort::InquiryInternal() const
// - The SCSI/Link apparently has about 6KB buffer space for packets.
//
//---------------------------------------------------------------------------
int SCSIDaynaPort::Read(const vector<int>& cdb, vector<BYTE>& buf, uint64_t)
int SCSIDaynaPort::Read(const vector<int>& cdb, vector<uint8_t>& buf, uint64_t)
{
int rx_packet_size = 0;
const auto response = (scsi_resp_read_t*)buf.data();
@ -145,8 +129,8 @@ int SCSIDaynaPort::Read(const vector<int>& cdb, vector<BYTE>& buf, uint64_t)
const int requested_length = cdb[4];
LOGTRACE("%s Read maximum length %d, (%04X)", __PRETTY_FUNCTION__, requested_length, requested_length)
// At host startup, it will send a READ(6) command with a length of 1. We should
// respond by going into the status mode with a code of 0x02
// At startup the host may send a READ(6) command with a sector count of 1 to read the root sector.
// We should respond by going into the status mode with a code of 0x02.
if (requested_length == 1) {
return 0;
}
@ -204,12 +188,12 @@ int SCSIDaynaPort::Read(const vector<int>& cdb, vector<BYTE>& buf, uint64_t)
if (!send_message_to_host) {
LOGDEBUG("%s Received a packet that's not for me: %02X %02X %02X %02X %02X %02X", \
__PRETTY_FUNCTION__,
(int)response->data[0],
(int)response->data[1],
(int)response->data[2],
(int)response->data[3],
(int)response->data[4],
(int)response->data[5])
static_cast<int>(response->data[0]),
static_cast<int>(response->data[1]),
static_cast<int>(response->data[2]),
static_cast<int>(response->data[3]),
static_cast<int>(response->data[4]),
static_cast<int>(response->data[5]))
// If there are pending packets to be processed, we'll tell the host that the read
// length was 0.
@ -253,17 +237,6 @@ int SCSIDaynaPort::Read(const vector<int>& cdb, vector<BYTE>& buf, uint64_t)
return DAYNAPORT_READ_HEADER_SZ;
}
int SCSIDaynaPort::WriteCheck(uint64_t)
{
CheckReady();
if (!m_bTapEnable) {
throw scsi_exception(sense_key::UNIT_ATTENTION, asc::MEDIUM_NOT_PRESENT);
}
return 1;
}
//---------------------------------------------------------------------------
//
// Write
@ -282,7 +255,7 @@ int SCSIDaynaPort::WriteCheck(uint64_t)
// XX XX ... is the actual packet
//
//---------------------------------------------------------------------------
bool SCSIDaynaPort::WriteBytes(const vector<int>& cdb, const vector<BYTE>& buf, uint64_t)
bool SCSIDaynaPort::WriteBytes(const vector<int>& cdb, vector<uint8_t>& buf, uint32_t)
{
const int data_format = cdb[5];
int data_length = GetInt16(cdb, 3);
@ -293,7 +266,7 @@ bool SCSIDaynaPort::WriteBytes(const vector<int>& cdb, const vector<BYTE>& buf,
}
else if (data_format == 0x80) {
// The data length is specified in the first 2 bytes of the payload
data_length = buf[1] + (((int)buf[0] & 0xff) << 8);
data_length = buf[1] + ((static_cast<int>(buf[0]) & 0xff) << 8);
m_tap.Send(&(buf.data()[4]), data_length);
LOGTRACE("%s Transmitted %u bytes (80 format)", __PRETTY_FUNCTION__, data_length)
}
@ -301,6 +274,8 @@ bool SCSIDaynaPort::WriteBytes(const vector<int>& cdb, const vector<BYTE>& buf,
LOGWARN("%s Unknown data format %02X", __PRETTY_FUNCTION__, data_format)
}
controller->SetBlocks(0);
return true;
}
@ -320,11 +295,11 @@ bool SCSIDaynaPort::WriteBytes(const vector<int>& cdb, const vector<BYTE>& buf,
// - long #3: frames lost
//
//---------------------------------------------------------------------------
int SCSIDaynaPort::RetrieveStats(const vector<int>& cdb, vector<BYTE>& buf) const
int SCSIDaynaPort::RetrieveStats(const vector<int>& cdb, vector<uint8_t>& buf) const
{
memcpy(buf.data(), &m_scsi_link_stats, sizeof(m_scsi_link_stats));
return (int)min(sizeof(m_scsi_link_stats), (size_t)GetInt16(cdb, 3));
return static_cast<int>(min(sizeof(m_scsi_link_stats), static_cast<size_t>(GetInt16(cdb, 3))));
}
void SCSIDaynaPort::TestUnitReady()
@ -336,23 +311,24 @@ void SCSIDaynaPort::TestUnitReady()
void SCSIDaynaPort::Read6()
{
// Get record number and block number
const uint32_t record = GetInt24(ctrl->cmd, 1) & 0x1fffff;
ctrl->blocks=1;
const uint32_t record = GetInt24(controller->GetCmd(), 1) & 0x1fffff;
controller->SetBlocks(1);
// If any commands have a bogus control value, they were probably not
// generated by the DaynaPort driver so ignore them
if (ctrl->cmd[5] != 0xc0 && ctrl->cmd[5] != 0x80) {
LOGTRACE("%s Control value %d, (%04X), returning invalid CDB", __PRETTY_FUNCTION__, ctrl->cmd[5], ctrl->cmd[5])
if (controller->GetCmd(5) != 0xc0 && controller->GetCmd(5) != 0x80) {
LOGTRACE("%s Control value %d, (%04X), returning invalid CDB", __PRETTY_FUNCTION__,
controller->GetCmd(5), controller->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, ctrl->blocks)
LOGTRACE("%s READ(6) command record=%d blocks=%d", __PRETTY_FUNCTION__, record, controller->GetBlocks())
ctrl->length = Read(ctrl->cmd, controller->GetBuffer(), record);
LOGTRACE("%s ctrl.length is %d", __PRETTY_FUNCTION__, ctrl->length)
controller->SetLength(Read(controller->GetCmd(), controller->GetBuffer(), record));
LOGTRACE("%s ctrl.length is %d", __PRETTY_FUNCTION__, controller->GetLength())
// Set next block
ctrl->next = record + 1;
controller->SetNext(record + 1);
EnterDataInPhase();
}
@ -362,37 +338,38 @@ void SCSIDaynaPort::Write6()
// Ensure a sufficient buffer size (because it is not transfer for each block)
controller->AllocateBuffer(DAYNAPORT_BUFFER_SIZE);
const int data_format = ctrl->cmd[5];
const int data_format = controller->GetCmd(5);
if (data_format == 0x00) {
ctrl->length = GetInt16(ctrl->cmd, 3);
controller->SetLength(GetInt16(controller->GetCmd(), 3));
}
else if (data_format == 0x80) {
ctrl->length = GetInt16(ctrl->cmd, 3) + 8;
controller->SetLength(GetInt16(controller->GetCmd(), 3) + 8);
}
else {
LOGWARN("%s Unknown data format $%02X", __PRETTY_FUNCTION__, data_format)
}
LOGTRACE("%s length: $%04X (%d) format: $%02X", __PRETTY_FUNCTION__, ctrl->length, ctrl->length, data_format)
LOGTRACE("%s length: $%04X (%d) format: $%02X", __PRETTY_FUNCTION__, controller->GetLength(),
controller->GetLength(), data_format)
if (ctrl->length <= 0) {
if (controller->GetLength() <= 0) {
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
}
// Set next block
ctrl->blocks = 1;
ctrl->next = 1;
controller->SetBlocks(1);
controller->SetNext(1);
EnterDataOutPhase();
}
void SCSIDaynaPort::RetrieveStatistics()
{
ctrl->length = RetrieveStats(ctrl->cmd, controller->GetBuffer());
controller->SetLength(RetrieveStats(controller->GetCmd(), controller->GetBuffer()));
// Set next block
ctrl->blocks = 1;
ctrl->next = 1;
controller->SetBlocks(1);
controller->SetNext(1);
EnterDataInPhase();
}
@ -427,27 +404,27 @@ void SCSIDaynaPort::SetInterfaceMode()
{
// Check whether this command is telling us to "Set Interface Mode" or "Set MAC Address"
ctrl->length = RetrieveStats(ctrl->cmd, controller->GetBuffer());
switch(ctrl->cmd[5]){
controller->SetLength(RetrieveStats(controller->GetCmd(), controller->GetBuffer()));
switch(controller->GetCmd(5)){
case CMD_SCSILINK_SETMODE:
// TODO Not implemented, do nothing
EnterStatusPhase();
break;
case CMD_SCSILINK_SETMAC:
ctrl->length = 6;
controller->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__, ctrl->cmd[5])
LOGWARN("%s Unsupported SetInterface command received: %02X", __PRETTY_FUNCTION__, controller->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__, ctrl->cmd[5])
LOGWARN("%s Unknown SetInterface command received: %02X", __PRETTY_FUNCTION__, controller->GetCmd(5))
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_COMMAND_OPERATION_CODE);
break;
}
@ -455,9 +432,9 @@ void SCSIDaynaPort::SetInterfaceMode()
void SCSIDaynaPort::SetMcastAddr()
{
ctrl->length = ctrl->cmd[4];
if (ctrl->length == 0) {
LOGWARN("%s Not supported SetMcastAddr Command %02X", __PRETTY_FUNCTION__, ctrl->cmd[2])
controller->SetLength(controller->GetCmd(4));
if (controller->GetLength() == 0) {
LOGWARN("%s Not supported SetMcastAddr Command %02X", __PRETTY_FUNCTION__, controller->GetCmd(2))
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
}
@ -479,7 +456,7 @@ void SCSIDaynaPort::SetMcastAddr()
//---------------------------------------------------------------------------
void SCSIDaynaPort::EnableInterface()
{
if (ctrl->cmd[5] & 0x80) {
if (controller->GetCmd(5) & 0x80) {
if (!m_tap.Enable()) {
LOGWARN("Unable to enable the DaynaPort Interface")
@ -502,3 +479,4 @@ void SCSIDaynaPort::EnableInterface()
EnterStatusPhase();
}

View File

@ -29,8 +29,8 @@
#pragma once
#include "os.h"
#include "disk.h"
#include "interfaces/byte_writer.h"
#include "primary_device.h"
#include "ctapdriver.h"
#include <string>
#include <unordered_map>
@ -41,7 +41,7 @@
// DaynaPort SCSI Link
//
//===========================================================================
class SCSIDaynaPort : public Disk
class SCSIDaynaPort : public PrimaryDevice, public ByteWriter
{
public:
@ -49,19 +49,17 @@ public:
~SCSIDaynaPort() override = default;
bool Init(const unordered_map<string, string>&) override;
void Open() override;
// Commands
vector<byte> InquiryInternal() const override;
int Read(const vector<int>&, vector<BYTE>&, uint64_t) override;
bool WriteBytes(const vector<int>&, const vector<BYTE>&, uint64_t);
int WriteCheck(uint64_t block) override;
int Read(const vector<int>&, vector<uint8_t>&, uint64_t);
bool WriteBytes(const vector<int>&, vector<uint8_t>&, uint32_t) override;
int RetrieveStats(const vector<int>&, vector<BYTE>&) const;
int RetrieveStats(const vector<int>&, vector<uint8_t>&) const;
void TestUnitReady() override;
void Read6() override;
void Write6() override;
void Read6();
void Write6();
void RetrieveStatistics();
void SetInterfaceMode();
void SetMcastAddr();
@ -90,7 +88,7 @@ public:
private:
using super = Disk;
using super = PrimaryDevice;
Dispatcher<SCSIDaynaPort> dispatcher;

View File

@ -27,7 +27,7 @@ using namespace std;
using namespace scsi_defs;
using namespace scsi_command_util;
SCSIBR::SCSIBR(int lun) : Disk(SCBR, lun)
SCSIBR::SCSIBR(int lun) : PrimaryDevice(SCBR, lun)
{
// Create host file system
fs.Reset();
@ -37,10 +37,6 @@ SCSIBR::SCSIBR(int lun) : Disk(SCBR, lun)
dispatcher.Add(scsi_command::eCmdWrite6, "SendMessage10", &SCSIBR::SendMessage10);
SupportsParams(true);
// TODO Remove as soon as SCBR is not a subclass of Disk anymore
SetStoppable(false);
// TODO Remove as soon as SCBR is not a subclass of Disk anymore
SupportsFile(false);
}
bool SCSIBR::Init(const unordered_map<string, string>& params)
@ -110,7 +106,7 @@ void SCSIBR::TestUnitReady()
EnterStatusPhase();
}
int SCSIBR::GetMessage10(const vector<int>& cdb, vector<BYTE>& buf)
int SCSIBR::GetMessage10(const vector<int>& cdb, vector<uint8_t>& buf)
{
// Type
const int type = cdb[2];
@ -198,7 +194,7 @@ int SCSIBR::GetMessage10(const vector<int>& cdb, vector<BYTE>& buf)
return 0;
}
bool SCSIBR::WriteBytes(const vector<int>& cdb, vector<BYTE>& buf, uint64_t)
bool SCSIBR::WriteBytes(const vector<int>& cdb, vector<uint8_t>& buf, uint32_t)
{
// Type
const int type = cdb[2];
@ -261,14 +257,14 @@ void SCSIBR::GetMessage10()
// Ensure a sufficient buffer size (because it is not a transfer for each block)
controller->AllocateBuffer(0x1000000);
ctrl->length = GetMessage10(ctrl->cmd, controller->GetBuffer());
if (ctrl->length <= 0) {
controller->SetLength(GetMessage10(controller->GetCmd(), controller->GetBuffer()));
if (controller->GetLength() <= 0) {
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
}
// Set next block
ctrl->blocks = 1;
ctrl->next = 1;
controller->SetBlocks(1);
controller->SetNext(1);
EnterDataInPhase();
}
@ -282,8 +278,8 @@ void SCSIBR::GetMessage10()
//---------------------------------------------------------------------------
void SCSIBR::SendMessage10()
{
ctrl->length = GetInt24(ctrl->cmd, 6);
if (ctrl->length <= 0) {
controller->SetLength(GetInt24(controller->GetCmd(), 6));
if (controller->GetLength() <= 0) {
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
}
@ -291,19 +287,19 @@ void SCSIBR::SendMessage10()
controller->AllocateBuffer(0x1000000);
// Set next block
ctrl->blocks = 1;
ctrl->next = 1;
controller->SetBlocks(1);
controller->SetNext(1);
EnterDataOutPhase();
}
int SCSIBR::GetMacAddr(vector<BYTE>& mac) const
int SCSIBR::GetMacAddr(vector<uint8_t>& mac) const
{
memcpy(mac.data(), mac_addr.data(), mac_addr.size());
return (int)mac_addr.size();
return static_cast<int>(mac_addr.size());
}
void SCSIBR::SetMacAddr(const vector<BYTE>& mac)
void SCSIBR::SetMacAddr(const vector<uint8_t>& mac)
{
memcpy(mac_addr.data(), mac.data(), mac_addr.size());
}
@ -335,7 +331,7 @@ void SCSIBR::ReceivePacket()
}
}
void SCSIBR::GetPacketBuf(vector<BYTE>& buf, int index)
void SCSIBR::GetPacketBuf(vector<uint8_t>& buf, int index)
{
// Size limit
int len = packet_len;
@ -350,7 +346,7 @@ void SCSIBR::GetPacketBuf(vector<BYTE>& buf, int index)
packet_enable = false;
}
void SCSIBR::SendPacket(const vector<BYTE>& buf, int len)
void SCSIBR::SendPacket(const vector<uint8_t>& buf, int len)
{
tap.Send(buf.data(), len);
}
@ -360,7 +356,7 @@ void SCSIBR::SendPacket(const vector<BYTE>& buf, int len)
// $40 - Device Boot
//
//---------------------------------------------------------------------------
void SCSIBR::FS_InitDevice(vector<BYTE>& buf)
void SCSIBR::FS_InitDevice(vector<uint8_t>& buf)
{
fs.Reset();
fsresult = fs.InitDevice((Human68k::argument_t*)buf.data());
@ -371,7 +367,7 @@ void SCSIBR::FS_InitDevice(vector<BYTE>& buf)
// $41 - Directory Check
//
//---------------------------------------------------------------------------
void SCSIBR::FS_CheckDir(vector<BYTE>& buf)
void SCSIBR::FS_CheckDir(vector<uint8_t>& buf)
{
auto dp = (uint32_t*)buf.data();
const uint32_t nUnit = ntohl(*dp);
@ -387,7 +383,7 @@ void SCSIBR::FS_CheckDir(vector<BYTE>& buf)
// $42 - Create Directory
//
//---------------------------------------------------------------------------
void SCSIBR::FS_MakeDir(vector<BYTE>& buf)
void SCSIBR::FS_MakeDir(vector<uint8_t>& buf)
{
auto dp = (uint32_t*)buf.data();
const uint32_t nUnit = ntohl(*dp);
@ -403,7 +399,7 @@ void SCSIBR::FS_MakeDir(vector<BYTE>& buf)
// $43 - Remove Directory
//
//---------------------------------------------------------------------------
void SCSIBR::FS_RemoveDir(vector<BYTE>& buf)
void SCSIBR::FS_RemoveDir(vector<uint8_t>& buf)
{
auto dp = (uint32_t*)buf.data();
const uint32_t nUnit = ntohl(*dp);
@ -419,7 +415,7 @@ void SCSIBR::FS_RemoveDir(vector<BYTE>& buf)
// $44 - Rename
//
//---------------------------------------------------------------------------
void SCSIBR::FS_Rename(vector<BYTE>& buf)
void SCSIBR::FS_Rename(vector<uint8_t>& buf)
{
auto dp = (uint32_t*)buf.data();
const uint32_t nUnit = ntohl(*dp);
@ -438,7 +434,7 @@ void SCSIBR::FS_Rename(vector<BYTE>& buf)
// $45 - Delete File
//
//---------------------------------------------------------------------------
void SCSIBR::FS_Delete(vector<BYTE>& buf)
void SCSIBR::FS_Delete(vector<uint8_t>& buf)
{
auto dp = (uint32_t*)buf.data();
const uint32_t nUnit = ntohl(*dp);
@ -454,7 +450,7 @@ void SCSIBR::FS_Delete(vector<BYTE>& buf)
// $46 - Get / Set file attributes
//
//---------------------------------------------------------------------------
void SCSIBR::FS_Attribute(vector<BYTE>& buf)
void SCSIBR::FS_Attribute(vector<uint8_t>& buf)
{
auto dp = (uint32_t*)buf.data();
const uint32_t nUnit = ntohl(*dp);
@ -474,7 +470,7 @@ void SCSIBR::FS_Attribute(vector<BYTE>& buf)
// $47 - File Search
//
//---------------------------------------------------------------------------
void SCSIBR::FS_Files(vector<BYTE>& buf)
void SCSIBR::FS_Files(vector<uint8_t>& buf)
{
auto dp = (uint32_t*)buf.data();
const uint32_t nUnit = ntohl(*dp);
@ -515,7 +511,7 @@ void SCSIBR::FS_Files(vector<BYTE>& buf)
// $48 - File next search
//
//---------------------------------------------------------------------------
void SCSIBR::FS_NFiles(vector<BYTE>& buf)
void SCSIBR::FS_NFiles(vector<uint8_t>& buf)
{
auto dp = (uint32_t*)buf.data();
const uint32_t nUnit = ntohl(*dp);
@ -553,7 +549,7 @@ void SCSIBR::FS_NFiles(vector<BYTE>& buf)
// $49 - File Creation
//
//---------------------------------------------------------------------------
void SCSIBR::FS_Create(vector<BYTE>& buf)
void SCSIBR::FS_Create(vector<uint8_t>& buf)
{
auto dp = (uint32_t*)buf.data();
const uint32_t nUnit = ntohl(*dp);
@ -602,7 +598,7 @@ void SCSIBR::FS_Create(vector<BYTE>& buf)
// $4A - Open File
//
//---------------------------------------------------------------------------
void SCSIBR::FS_Open(vector<BYTE>& buf)
void SCSIBR::FS_Open(vector<uint8_t>& buf)
{
auto dp = (uint32_t*)buf.data();
const uint32_t nUnit = ntohl(*dp);
@ -643,7 +639,7 @@ void SCSIBR::FS_Open(vector<BYTE>& buf)
// $4B - Close File
//
//---------------------------------------------------------------------------
void SCSIBR::FS_Close(vector<BYTE>& buf)
void SCSIBR::FS_Close(vector<uint8_t>& buf)
{
auto dp = (uint32_t*)buf.data();
const uint32_t nUnit = ntohl(*dp);
@ -681,7 +677,7 @@ void SCSIBR::FS_Close(vector<BYTE>& buf)
// $4C - Read File
//
//---------------------------------------------------------------------------
void SCSIBR::FS_Read(vector<BYTE>& buf)
void SCSIBR::FS_Read(vector<uint8_t>& buf)
{
auto dp = (uint32_t*)buf.data();
const uint32_t nKey = ntohl(*dp);
@ -721,7 +717,7 @@ void SCSIBR::FS_Read(vector<BYTE>& buf)
// $4D - Write file
//
//---------------------------------------------------------------------------
void SCSIBR::FS_Write(vector<BYTE>& buf)
void SCSIBR::FS_Write(vector<uint8_t>& buf)
{
auto dp = (uint32_t*)buf.data();
const uint32_t nKey = ntohl(*dp);
@ -759,7 +755,7 @@ void SCSIBR::FS_Write(vector<BYTE>& buf)
// $4E - Seek file
//
//---------------------------------------------------------------------------
void SCSIBR::FS_Seek(vector<BYTE>& buf)
void SCSIBR::FS_Seek(vector<uint8_t>& buf)
{
auto dp = (uint32_t*)buf.data();
const uint32_t nKey = ntohl(*dp);
@ -801,7 +797,7 @@ void SCSIBR::FS_Seek(vector<BYTE>& buf)
// $4F - File Timestamp Get / Set
//
//---------------------------------------------------------------------------
void SCSIBR::FS_TimeStamp(vector<BYTE>& buf)
void SCSIBR::FS_TimeStamp(vector<uint8_t>& buf)
{
auto dp = (uint32_t*)buf.data();
const uint32_t nUnit = ntohl(*dp);
@ -843,7 +839,7 @@ void SCSIBR::FS_TimeStamp(vector<BYTE>& buf)
// $50 - Get Capacity
//
//---------------------------------------------------------------------------
void SCSIBR::FS_GetCapacity(vector<BYTE>& buf)
void SCSIBR::FS_GetCapacity(vector<uint8_t>& buf)
{
auto dp = (uint32_t*)buf.data();
const uint32_t nUnit = ntohl(*dp);
@ -865,7 +861,7 @@ void SCSIBR::FS_GetCapacity(vector<BYTE>& buf)
// $51 - Drive status inspection/control
//
//---------------------------------------------------------------------------
void SCSIBR::FS_CtrlDrive(vector<BYTE>& buf)
void SCSIBR::FS_CtrlDrive(vector<uint8_t>& buf)
{
auto dp = (uint32_t*)buf.data();
const uint32_t nUnit = ntohl(*dp);
@ -884,7 +880,7 @@ void SCSIBR::FS_CtrlDrive(vector<BYTE>& buf)
// $52 - Get DPB
//
//---------------------------------------------------------------------------
void SCSIBR::FS_GetDPB(vector<BYTE>& buf)
void SCSIBR::FS_GetDPB(vector<uint8_t>& buf)
{
auto dp = (uint32_t*)buf.data();
const uint32_t nUnit = ntohl(*dp);
@ -908,7 +904,7 @@ void SCSIBR::FS_GetDPB(vector<BYTE>& buf)
// $53 - Read Sector
//
//---------------------------------------------------------------------------
void SCSIBR::FS_DiskRead(vector<BYTE>& buf)
void SCSIBR::FS_DiskRead(vector<uint8_t>& buf)
{
auto dp = (uint32_t*)buf.data();
const uint32_t nUnit = ntohl(*dp);
@ -930,7 +926,7 @@ void SCSIBR::FS_DiskRead(vector<BYTE>& buf)
// $54 - Write Sector
//
//---------------------------------------------------------------------------
void SCSIBR::FS_DiskWrite(vector<BYTE>& buf)
void SCSIBR::FS_DiskWrite(vector<uint8_t>& buf)
{
auto dp = (uint32_t*)buf.data();
const uint32_t nUnit = ntohl(*dp);
@ -943,7 +939,7 @@ void SCSIBR::FS_DiskWrite(vector<BYTE>& buf)
// $55 - IOCTRL
//
//---------------------------------------------------------------------------
void SCSIBR::FS_Ioctrl(vector<BYTE>& buf)
void SCSIBR::FS_Ioctrl(vector<uint8_t>& buf)
{
auto dp = (uint32_t*)buf.data();
const uint32_t nUnit = ntohl(*dp);
@ -989,7 +985,7 @@ void SCSIBR::FS_Ioctrl(vector<BYTE>& buf)
// $56 - Flush
//
//---------------------------------------------------------------------------
void SCSIBR::FS_Flush(vector<BYTE>& buf)
void SCSIBR::FS_Flush(vector<uint8_t>& buf)
{
auto dp = (uint32_t*)buf.data();
const uint32_t nUnit = ntohl(*dp);
@ -1002,7 +998,7 @@ void SCSIBR::FS_Flush(vector<BYTE>& buf)
// $57 - Check Media
//
//---------------------------------------------------------------------------
void SCSIBR::FS_CheckMedia(vector<BYTE>& buf)
void SCSIBR::FS_CheckMedia(vector<uint8_t>& buf)
{
auto dp = (uint32_t*)buf.data();
const uint32_t nUnit = ntohl(*dp);
@ -1015,7 +1011,7 @@ void SCSIBR::FS_CheckMedia(vector<BYTE>& buf)
// $58 - Lock
//
//---------------------------------------------------------------------------
void SCSIBR::FS_Lock(vector<BYTE>& buf)
void SCSIBR::FS_Lock(vector<uint8_t>& buf)
{
auto dp = (uint32_t*)buf.data();
const uint32_t nUnit = ntohl(*dp);
@ -1028,7 +1024,7 @@ void SCSIBR::FS_Lock(vector<BYTE>& buf)
// Read Filesystem (result code)
//
//---------------------------------------------------------------------------
int SCSIBR::ReadFsResult(vector<BYTE>& buf) const
int SCSIBR::ReadFsResult(vector<uint8_t>& buf) const
{
auto dp = (uint32_t *)buf.data();
*dp = htonl(fsresult);
@ -1040,7 +1036,7 @@ int SCSIBR::ReadFsResult(vector<BYTE>& buf) const
// Read Filesystem (return data)
//
//---------------------------------------------------------------------------
int SCSIBR::ReadFsOut(vector<BYTE>& buf) const
int SCSIBR::ReadFsOut(vector<uint8_t>& buf) const
{
copy_n(fsout.begin(), fsoutlen, buf.begin());
return fsoutlen;
@ -1051,7 +1047,7 @@ int SCSIBR::ReadFsOut(vector<BYTE>& buf) const
// Read file system (return option data)
//
//---------------------------------------------------------------------------
int SCSIBR::ReadFsOpt(vector<BYTE>& buf) const
int SCSIBR::ReadFsOpt(vector<uint8_t>& buf) const
{
copy_n(fsopt.begin(), fsoptlen, buf.begin());
return fsoptlen;
@ -1062,7 +1058,7 @@ int SCSIBR::ReadFsOpt(vector<BYTE>& buf) const
// Write Filesystem
//
//---------------------------------------------------------------------------
void SCSIBR::WriteFs(int func, vector<BYTE>& buf)
void SCSIBR::WriteFs(int func, vector<uint8_t>& buf)
{
fsresult = FS_FATAL_INVALIDCOMMAND;
fsoutlen = 0;
@ -1155,7 +1151,7 @@ void SCSIBR::WriteFs(int func, vector<BYTE>& buf)
// File system write (input option data)
//
//---------------------------------------------------------------------------
void SCSIBR::WriteFsOpt(const vector<BYTE>& buf, int num)
void SCSIBR::WriteFsOpt(const vector<uint8_t>& buf, int num)
{
copy_n(buf.begin(), num, fsopt.begin());
}

View File

@ -17,8 +17,8 @@
//---------------------------------------------------------------------------
#pragma once
#include "os.h"
#include "disk.h"
#include "interfaces/byte_writer.h"
#include "primary_device.h"
#include "ctapdriver.h"
#include "cfilesystem.h"
#include <string>
@ -26,9 +26,9 @@
using namespace std;
class SCSIBR : public Disk
class SCSIBR : public PrimaryDevice, public ByteWriter
{
static constexpr const array<BYTE, 6> bcast_addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
static constexpr const array<uint8_t, 6> bcast_addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
public:
@ -38,73 +38,70 @@ public:
bool Init(const unordered_map<string, string>&) override;
bool Dispatch(scsi_command) override;
// TODO Remove as soon as SCSIBR is not a subclass of Disk anymore
void Open() override { super::ValidateFile(); }
// Commands
vector<byte> InquiryInternal() const override;
int GetMessage10(const vector<int>&, vector<BYTE>&);
bool WriteBytes(const vector<int>&, vector<BYTE>&, uint64_t);
int GetMessage10(const vector<int>&, vector<uint8_t>&);
bool WriteBytes(const vector<int>&, vector<uint8_t>&, uint32_t) override;
void TestUnitReady() override;
void GetMessage10();
void SendMessage10();
private:
using super = Disk;
using super = PrimaryDevice;
Dispatcher<SCSIBR> dispatcher;
int GetMacAddr(vector<BYTE>&) const; // Get MAC address
void SetMacAddr(const vector<BYTE>&); // Set MAC address
int GetMacAddr(vector<uint8_t>&) const; // Get MAC address
void SetMacAddr(const vector<uint8_t>&); // Set MAC address
void ReceivePacket(); // Receive a packet
void GetPacketBuf(vector<BYTE>&, int); // Get a packet
void SendPacket(const vector<BYTE>&, int); // Send a packet
void GetPacketBuf(vector<uint8_t>&, int); // Get a packet
void SendPacket(const vector<uint8_t>&, int); // Send a packet
CTapDriver tap; // TAP driver
bool m_bTapEnable = false; // TAP valid flag
array<BYTE, 6> mac_addr = {}; // MAC Address
array<uint8_t, 6> mac_addr = {}; // MAC Address
int packet_len = 0; // Receive packet size
array<BYTE, 0x1000> packet_buf; // Receive packet buffer
array<uint8_t, 0x1000> packet_buf; // Receive packet buffer
bool packet_enable = false; // Received packet valid
int ReadFsResult(vector<BYTE>&) const; // Read filesystem (result code)
int ReadFsOut(vector<BYTE>&) const; // Read filesystem (return data)
int ReadFsOpt(vector<BYTE>&) const; // Read file system (optional data)
void WriteFs(int, vector<BYTE>&); // File system write (execute)
void WriteFsOpt(const vector<BYTE>&, int); // File system write (optional data)
int ReadFsResult(vector<uint8_t>&) const; // Read filesystem (result code)
int ReadFsOut(vector<uint8_t>&) const; // Read filesystem (return data)
int ReadFsOpt(vector<uint8_t>&) const; // Read file system (optional data)
void WriteFs(int, vector<uint8_t>&); // File system write (execute)
void WriteFsOpt(const vector<uint8_t>&, int); // File system write (optional data)
// Command handlers
void FS_InitDevice(vector<BYTE>&); // $40 - boot
void FS_CheckDir(vector<BYTE>&); // $41 - directory check
void FS_MakeDir(vector<BYTE>&); // $42 - create directory
void FS_RemoveDir(vector<BYTE>&); // $43 - delete directory
void FS_Rename(vector<BYTE>&); // $44 - change filename
void FS_Delete(vector<BYTE>&); // $45 - delete file
void FS_Attribute(vector<BYTE>&); // $46 - get/set file attributes
void FS_Files(vector<BYTE>&); // $47 - file search
void FS_NFiles(vector<BYTE>&); // $48 - find next file
void FS_Create(vector<BYTE>&); // $49 - create file
void FS_Open(vector<BYTE>&); // $4A - open file
void FS_Close(vector<BYTE>&); // $4B - close file
void FS_Read(vector<BYTE>&); // $4C - read file
void FS_Write(vector<BYTE>&); // $4D - write file
void FS_Seek(vector<BYTE>&); // $4E - seek file
void FS_TimeStamp(vector<BYTE>&); // $4F - get/set file time
void FS_GetCapacity(vector<BYTE>&); // $50 - get capacity
void FS_CtrlDrive(vector<BYTE>&); // $51 - drive status check/control
void FS_GetDPB(vector<BYTE>&); // $52 - get DPB
void FS_DiskRead(vector<BYTE>&); // $53 - read sector
void FS_DiskWrite(vector<BYTE>&); // $54 - write sector
void FS_Ioctrl(vector<BYTE>&); // $55 - IOCTRL
void FS_Flush(vector<BYTE>&); // $56 - flush cache
void FS_CheckMedia(vector<BYTE>&); // $57 - check media
void FS_Lock(vector<BYTE>&); // $58 - get exclusive control
void FS_InitDevice(vector<uint8_t>&); // $40 - boot
void FS_CheckDir(vector<uint8_t>&); // $41 - directory check
void FS_MakeDir(vector<uint8_t>&); // $42 - create directory
void FS_RemoveDir(vector<uint8_t>&); // $43 - delete directory
void FS_Rename(vector<uint8_t>&); // $44 - change filename
void FS_Delete(vector<uint8_t>&); // $45 - delete file
void FS_Attribute(vector<uint8_t>&); // $46 - get/set file attributes
void FS_Files(vector<uint8_t>&); // $47 - file search
void FS_NFiles(vector<uint8_t>&); // $48 - find next file
void FS_Create(vector<uint8_t>&); // $49 - create file
void FS_Open(vector<uint8_t>&); // $4A - open file
void FS_Close(vector<uint8_t>&); // $4B - close file
void FS_Read(vector<uint8_t>&); // $4C - read file
void FS_Write(vector<uint8_t>&); // $4D - write file
void FS_Seek(vector<uint8_t>&); // $4E - seek file
void FS_TimeStamp(vector<uint8_t>&); // $4F - get/set file time
void FS_GetCapacity(vector<uint8_t>&); // $50 - get capacity
void FS_CtrlDrive(vector<uint8_t>&); // $51 - drive status check/control
void FS_GetDPB(vector<uint8_t>&); // $52 - get DPB
void FS_DiskRead(vector<uint8_t>&); // $53 - read sector
void FS_DiskWrite(vector<uint8_t>&); // $54 - write sector
void FS_Ioctrl(vector<uint8_t>&); // $55 - IOCTRL
void FS_Flush(vector<uint8_t>&); // $56 - flush cache
void FS_CheckMedia(vector<uint8_t>&); // $57 - check media
void FS_Lock(vector<uint8_t>&); // $58 - get exclusive control
CFileSys fs; // File system accessor
uint32_t fsresult = 0; // File system access result code
array<BYTE, 0x800> fsout; // File system access result buffer
array<uint8_t, 0x800> fsout; // File system access result buffer
uint32_t fsoutlen = 0; // File system access result buffer size
array<BYTE, 0x1000000> fsopt; // File system access buffer
array<uint8_t, 0x1000000> fsopt; // File system access buffer
uint32_t fsoptlen = 0; // File system access buffer size
};

View File

@ -98,7 +98,7 @@ vector<byte> SCSIPrinter::InquiryInternal() const
void SCSIPrinter::Print()
{
const uint32_t length = GetInt24(ctrl->cmd, 2);
const uint32_t length = GetInt24(controller->GetCmd(), 2);
LOGTRACE("Receiving %d byte(s) to be printed", length)
@ -109,7 +109,7 @@ void SCSIPrinter::Print()
throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
}
ctrl->length = length;
controller->SetLength(length);
controller->SetByteTransfer(true);
EnterDataOutPhase();
@ -147,7 +147,7 @@ void SCSIPrinter::SynchronizeBuffer()
EnterStatusPhase();
}
bool SCSIPrinter::WriteByteSequence(vector<BYTE>& buf, uint32_t length)
bool SCSIPrinter::WriteByteSequence(vector<uint8_t>& buf, uint32_t length)
{
if (!out.is_open()) {
vector<char> f(file_template.begin(), file_template.end());

View File

@ -42,7 +42,7 @@ public:
void Print() override;
void SynchronizeBuffer();
bool WriteByteSequence(vector<BYTE>&, uint32_t) override;
bool WriteByteSequence(vector<uint8_t>&, uint32_t) override;
private:

View File

@ -123,9 +123,9 @@ void SCSICD::OpenIso()
+ to_string(size) + " bytes");
}
SetBlockCount((uint32_t)(size / 2352));
SetBlockCount(static_cast<uint32_t>(size / 2352));
} else {
SetBlockCount((uint32_t)(size >> GetSectorSizeShiftCount()));
SetBlockCount(static_cast<uint32_t>(size >> GetSectorSizeShiftCount()));
}
CreateDataTrack();
@ -144,7 +144,7 @@ void SCSICD::OpenPhysical()
size = (size / 512) * 512;
// Set the number of blocks
SetBlockCount((uint32_t)(size >> GetSectorSizeShiftCount()));
SetBlockCount(static_cast<uint32_t>(size >> GetSectorSizeShiftCount()));
CreateDataTrack();
}
@ -154,7 +154,7 @@ void SCSICD::CreateDataTrack()
// Create only one data track
assert(!tracks.size());
auto track = make_unique<CDTrack>();
track->Init(1, 0, (int)GetBlockCount() - 1);
track->Init(1, 0, static_cast<int>(GetBlockCount()) - 1);
track->SetPath(false, GetFilename());
tracks.push_back(move(track));
dataindex = 0;
@ -162,7 +162,7 @@ void SCSICD::CreateDataTrack()
void SCSICD::ReadToc()
{
ctrl->length = ReadTocInternal(ctrl->cmd, controller->GetBuffer());
controller->SetLength(ReadTocInternal(controller->GetCmd(), controller->GetBuffer()));
EnterDataInPhase();
}
@ -222,12 +222,12 @@ void SCSICD::AddVendorPage(map<int, vector<byte>>& pages, int page, bool changea
}
}
int SCSICD::Read(const vector<int>& cdb, vector<BYTE>& buf, uint64_t block)
int SCSICD::Read(const vector<int>& cdb, vector<uint8_t>& buf, uint64_t block)
{
CheckReady();
// Search for the track
const int index = SearchTrack((int)block);
const int index = SearchTrack(static_cast<int>(block));
// If invalid, out of range
if (index < 0) {
@ -254,7 +254,7 @@ int SCSICD::Read(const vector<int>& cdb, vector<BYTE>& buf, uint64_t block)
return super::Read(cdb, buf, block);
}
int SCSICD::ReadTocInternal(const vector<int>& cdb, vector<BYTE>& buf)
int SCSICD::ReadTocInternal(const vector<int>& cdb, vector<uint8_t>& buf)
{
CheckReady();
@ -296,8 +296,8 @@ int SCSICD::ReadTocInternal(const vector<int>& cdb, vector<BYTE>& buf)
// Returns the final LBA+1 because it is AA
buf[0] = 0x00;
buf[1] = 0x0a;
buf[2] = (BYTE)tracks[0]->GetTrackNo();
buf[3] = (BYTE)last;
buf[2] = (uint8_t)tracks[0]->GetTrackNo();
buf[3] = (uint8_t)last;
buf[6] = 0xaa;
const uint32_t lba = tracks[tracks.size() - 1]->GetLast() + 1;
if (msf) {
@ -316,8 +316,8 @@ int SCSICD::ReadTocInternal(const vector<int>& cdb, vector<BYTE>& buf)
// Create header
SetInt16(buf, 0, (loop << 3) + 2);
buf[2] = (BYTE)tracks[0]->GetTrackNo();
buf[3] = (BYTE)last;
buf[2] = (uint8_t)tracks[0]->GetTrackNo();
buf[3] = (uint8_t)last;
int offset = 4;
@ -333,7 +333,7 @@ int SCSICD::ReadTocInternal(const vector<int>& cdb, vector<BYTE>& buf)
}
// track number
buf[offset + 2] = (BYTE)tracks[index]->GetTrackNo();
buf[offset + 2] = (uint8_t)tracks[index]->GetTrackNo();
// track address
if (msf) {
@ -356,7 +356,7 @@ int SCSICD::ReadTocInternal(const vector<int>& cdb, vector<BYTE>& buf)
// LBA→MSF Conversion
//
//---------------------------------------------------------------------------
void SCSICD::LBAtoMSF(uint32_t lba, BYTE *msf) const
void SCSICD::LBAtoMSF(uint32_t lba, uint8_t *msf) const
{
// 75 and 75*60 get the remainder
uint32_t m = lba / (75 * 60);
@ -376,9 +376,9 @@ void SCSICD::LBAtoMSF(uint32_t lba, BYTE *msf) const
assert(s < 60);
assert(f < 75);
msf[0] = 0x00;
msf[1] = (BYTE)m;
msf[2] = (BYTE)s;
msf[3] = (BYTE)f;
msf[1] = (uint8_t)m;
msf[2] = (uint8_t)s;
msf[3] = (uint8_t)f;
}
void SCSICD::ClearTrack()
@ -403,7 +403,7 @@ int SCSICD::SearchTrack(uint32_t lba) const
// Listen to the track
assert(tracks[i]);
if (tracks[i]->IsValid(lba)) {
return (int)i;
return static_cast<int>(i);
}
}

View File

@ -31,7 +31,7 @@ public:
// Commands
vector<byte> InquiryInternal() const override;
int Read(const vector<int>&, vector<BYTE>&, uint64_t) override;
int Read(const vector<int>&, vector<uint8_t>&, uint64_t) override;
protected:
@ -44,7 +44,7 @@ private:
Dispatcher<SCSICD> dispatcher;
int ReadTocInternal(const vector<int>&, vector<BYTE>&);
int ReadTocInternal(const vector<int>&, vector<uint8_t>&);
void AddCDROMPage(map<int, vector<byte>>&, bool) const;
void AddCDDAPage(map<int, vector<byte>>&, bool) const;
@ -56,7 +56,7 @@ private:
void ReadToc() override;
void LBAtoMSF(uint32_t, BYTE *) const; // LBA→MSF conversion
void LBAtoMSF(uint32_t, uint8_t *) const; // LBA→MSF conversion
bool rawfile = false; // RAW flag

View File

@ -74,7 +74,7 @@ void SCSIHD::Open()
// Sector size (default 512 bytes) and number of blocks
SetSectorSizeInBytes(GetConfiguredSectorSize() ? GetConfiguredSectorSize() : 512);
SetBlockCount((uint32_t)(size >> GetSectorSizeShiftCount()));
SetBlockCount(static_cast<uint32_t>(size >> GetSectorSizeShiftCount()));
FinalizeSetup(0);
}
@ -84,7 +84,7 @@ vector<byte> SCSIHD::InquiryInternal() const
return HandleInquiry(device_type::DIRECT_ACCESS, scsi_level, IsRemovable());
}
void SCSIHD::ModeSelect(scsi_command cmd, const vector<int>& cdb, const vector<BYTE>& buf, int length) const
void SCSIHD::ModeSelect(scsi_command cmd, const vector<int>& cdb, const vector<uint8_t>& buf, int length) const
{
scsi_command_util::ModeSelect(cmd, cdb, buf, length, 1 << GetSectorSizeShiftCount());
}

View File

@ -36,7 +36,7 @@ public:
// Commands
vector<byte> InquiryInternal() const override;
void ModeSelect(scsi_defs::scsi_command, const vector<int>&, const vector<BYTE>&, int) const override;
void ModeSelect(scsi_defs::scsi_command, const vector<int>&, const vector<uint8_t>&, int) const override;
void AddFormatPage(map<int, vector<byte>>&, bool) const override;
void AddVendorPage(map<int, vector<byte>>&, int, bool) const override;

View File

@ -23,8 +23,6 @@
using namespace ras_util;
using namespace scsi_command_util;
const unordered_set<uint32_t> SCSIHD_NEC::sector_sizes = { 512 };
void SCSIHD_NEC::Open()
{
assert(!IsReady());
@ -34,7 +32,7 @@ void SCSIHD_NEC::Open()
array<char, 512> root_sector;
ifstream in(GetFilename(), ios::binary);
in.read(root_sector.data(), root_sector.size());
if (!in.good() || size < (off_t)root_sector.size()) {
if (!in.good() || size < static_cast<off_t>(root_sector.size())) {
throw io_exception("Can't read NEC hard disk file root sector");
}
@ -42,9 +40,9 @@ void SCSIHD_NEC::Open()
size = (size / 512) * 512;
// Determine parameters by extension
const auto [image_size, sector_size] = SetParameters(root_sector, (int)size);
const auto [image_size, sector_size] = SetParameters(root_sector, static_cast<int>(size));
SetSectorSizeShiftCount((uint32_t)size);
SetSectorSizeShiftCount(static_cast<uint32_t>(size));
SetBlockCount(image_size >> GetSectorSizeShiftCount());
@ -53,7 +51,7 @@ void SCSIHD_NEC::Open()
pair<int, int> SCSIHD_NEC::SetParameters(const array<char, 512>& data, int size)
{
array<BYTE, 512> root_sector = {};
array<uint8_t, 512> root_sector = {};
memcpy(root_sector.data(), data.data(), root_sector.size());
int image_size;
@ -88,7 +86,7 @@ pair<int, int> SCSIHD_NEC::SetParameters(const array<char, 512>& data, int size)
heads = GetInt16LittleEndian(&root_sector[0x118]);
sectors = GetInt16LittleEndian(&root_sector[0x11a]);
sector_size = GetInt16LittleEndian(&root_sector[0x11c]);
image_size = (int)((off_t)cylinders * heads * sectors * sector_size);
image_size = static_cast<int>(static_cast<off_t>(cylinders * heads * sectors * sector_size));
}
else {
throw io_exception("Invalid NEC image file format");
@ -170,12 +168,12 @@ void SCSIHD_NEC::AddDrivePage(map<int, vector<byte>>& pages, bool changeable) co
pages[4] = buf;
}
int SCSIHD_NEC::GetInt16LittleEndian(const BYTE *buf)
int SCSIHD_NEC::GetInt16LittleEndian(const uint8_t *buf)
{
return ((int)buf[1] << 8) | buf[0];
return (static_cast<int>(buf[1]) << 8) | buf[0];
}
int SCSIHD_NEC::GetInt32LittleEndian(const BYTE *buf)
int SCSIHD_NEC::GetInt32LittleEndian(const uint8_t *buf)
{
return ((int)buf[3] << 24) | ((int)buf[2] << 16) | ((int)buf[1] << 8) | buf[0];
return (static_cast<int>(buf[3]) << 24) | (static_cast<int>(buf[2]) << 16) | (static_cast<int>(buf[1]) << 8) | buf[0];
}

View File

@ -49,10 +49,10 @@ private:
pair<int, int> SetParameters(const array<char, 512>&, int);
static int GetInt16LittleEndian(const BYTE *);
static int GetInt32LittleEndian(const BYTE *);
static int GetInt16LittleEndian(const uint8_t *);
static int GetInt32LittleEndian(const uint8_t *);
static const unordered_set<uint32_t> sector_sizes;
static inline const unordered_set<uint32_t> sector_sizes = { 512 };
// Image file offset
off_t image_offset = 0;

View File

@ -89,7 +89,7 @@ void SCSIMO::AddOptionPage(map<int, vector<byte>>& pages, bool) const
// Do not report update blocks
}
void SCSIMO::ModeSelect(scsi_command cmd, const vector<int>& cdb, const vector<BYTE>& buf, int length) const
void SCSIMO::ModeSelect(scsi_command cmd, const vector<int>& cdb, const vector<uint8_t>& buf, int length) const
{
scsi_command_util::ModeSelect(cmd, cdb, buf, length, 1 << GetSectorSizeShiftCount());
}
@ -182,7 +182,7 @@ void SCSIMO::AddVendorPage(map<int, vector<byte>>& pages, int page, bool changea
buf[2] = (byte)0; // format mode
buf[3] = (byte)0; // type of format
SetInt32(buf, 4, (uint32_t)blocks);
SetInt32(buf, 4, static_cast<uint32_t>(blocks));
SetInt16(buf, 8, spare);
SetInt16(buf, 10, bands);
}

View File

@ -30,7 +30,7 @@ public:
void Open() override;
vector<byte> InquiryInternal() const override;
void ModeSelect(scsi_defs::scsi_command, const vector<int>&, const vector<BYTE>&, int) const override;
void ModeSelect(scsi_defs::scsi_command, const vector<int>&, const vector<uint8_t>&, int) const override;
protected:

View File

@ -15,8 +15,6 @@
using namespace std;
using namespace filesystem;
unordered_map<string, id_set> StorageDevice::reserved_files;
StorageDevice::StorageDevice(PbDeviceType type, int lun) : ModePageDevice(type, lun)
{
SupportsFile(true);

View File

@ -67,5 +67,5 @@ private:
bool medium_changed = false;
// The list of image files in use and the IDs and LUNs using these files
static unordered_map<string, id_set> reserved_files;
static inline unordered_map<string, id_set> reserved_files;
};

View File

@ -15,7 +15,6 @@
#include "hal/sbc_version.h"
#include "hal/systimer.h"
#include "log.h"
#include "os.h"
#include <array>
#include <sys/ioctl.h>
#include <sys/mman.h>
@ -523,7 +522,7 @@ uint32_t GPIOBUS::GetPinRaw(uint32_t raw_data, board_type::pi_physical_pin_e pin
// Receive command handshake
//
//---------------------------------------------------------------------------
int GPIOBUS::CommandHandShake(BYTE *buf)
int GPIOBUS::CommandHandShake(uint8_t *buf)
{
GPIO_FUNCTION_TRACE
// Only works in TARGET mode
@ -646,7 +645,7 @@ int GPIOBUS::CommandHandShake(BYTE *buf)
// Data reception handshake
//
//---------------------------------------------------------------------------
int GPIOBUS::ReceiveHandShake(BYTE *buf, int count)
int GPIOBUS::ReceiveHandShake(uint8_t *buf, int count)
{
GPIO_FUNCTION_TRACE
@ -752,7 +751,7 @@ int GPIOBUS::ReceiveHandShake(BYTE *buf, int count)
// Data transmission handshake
//
//---------------------------------------------------------------------------
int GPIOBUS::SendHandShake(BYTE *buf, int count, int delay_after_bytes)
int GPIOBUS::SendHandShake(uint8_t *buf, int count, int delay_after_bytes)
{
GPIO_FUNCTION_TRACE
@ -1097,7 +1096,7 @@ BUS::phase_t GPIOBUS::GetPhaseRaw(uint32_t raw_data)
// Get the number of bytes for a command
//
//---------------------------------------------------------------------------
int GPIOBUS::GetCommandByteCount(BYTE opcode)
int GPIOBUS::GetCommandByteCount(uint8_t opcode)
{
GPIO_FUNCTION_TRACE
@ -1105,7 +1104,7 @@ int GPIOBUS::GetCommandByteCount(BYTE opcode)
return 16;
} else if (opcode == 0xA0) {
return 12;
} else if (opcode == 0x05 || (opcode >= 0x20 && opcode <= 0x7D)) {
} else if (opcode >= 0x20 && opcode <= 0x7D) {
return 10;
} else {
return 6;

View File

@ -14,6 +14,7 @@
#include "config.h"
#include "hal/board_type.h"
#include "scsi.h"
#include "bus.h"
#include <array>
#include <memory>
#include <vector>
@ -50,7 +51,7 @@
#define GPIO_FUNCTION_TRACE
#endif
using namespace std; // NOSONAR Not relevant for rascsi
using namespace std;
//---------------------------------------------------------------------------
//
@ -340,17 +341,17 @@ class GPIOBUS : public BUS
return board;
}
int CommandHandShake(BYTE *buf) override;
int CommandHandShake(uint8_t *buf) override;
// Command receive handshake
int ReceiveHandShake(BYTE *buf, int count) override;
int ReceiveHandShake(uint8_t *buf, int count) override;
// Data receive handshake
int SendHandShake(BYTE *buf, int count, int delay_after_bytes) override;
int SendHandShake(uint8_t *buf, int count, int delay_after_bytes) override;
// Data transmission handshake
// Get the phase based on raw data
static BUS::phase_t GetPhaseRaw(uint32_t raw_data);
static int GetCommandByteCount(BYTE opcode);
static int GetCommandByteCount(uint8_t opcode);
const string GetConnectDesc();

View File

@ -321,22 +321,23 @@ void GPIOBUS_Allwinner::Cleanup()
LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__)
}
BYTE GPIOBUS_Allwinner::GetDAT()
uint8_t GPIOBUS_Allwinner::GetDAT()
{
LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__)
// LOGDEBUG("0:%02X 1:%02X 2:%02X 3:%02X 4:%02X 5:%02X 6:%02X 7:%02X P:%02X", GetSignal(PIN_DT0),
// GetSignal(PIN_DT1),GetSignal(PIN_DT2),GetSignal(PIN_DT3),GetSignal(PIN_DT4),GetSignal(PIN_DT5),GetSignal(PIN_DT6),GetSignal(PIN_DT7),GetSignal(PIN_DP));
// TODO: This is crazy inefficient...
DWORD data = ((GetSignal(board->pin_dt0) ? 0x01 : 0x00) << 0) | ((GetSignal(board->pin_dt1) ? 0x01 : 0x00) << 1) |
uint8_t data = ((GetSignal(board->pin_dt0) ? 0x01 : 0x00) << 0) | ((GetSignal(board->pin_dt1) ? 0x01 : 0x00) << 1) |
((GetSignal(board->pin_dt2) ? 0x01 : 0x00) << 2) | ((GetSignal(board->pin_dt3) ? 0x01 : 0x00) << 3) |
((GetSignal(board->pin_dt4) ? 0x01 : 0x00) << 0) | ((GetSignal(board->pin_dt5) ? 0x01 : 0x00) << 5) |
((GetSignal(board->pin_dt6) ? 0x01 : 0x00) << 6) | ((GetSignal(board->pin_dt7) ? 0x01 : 0x00) << 7);
return (BYTE)data;
return (uint8_t)data;
// return 0;
}
void GPIOBUS_Allwinner::SetDAT(BYTE dat)
void GPIOBUS_Allwinner::SetDAT(uint8_t dat)
{
// TODO: This is crazy inefficient...
PinSetSignal(board->pin_dt0, (dat & (1 << 0)) != 0 ? board_type::gpio_high_low_e::GPIO_STATE_HIGH
@ -522,7 +523,7 @@ void GPIOBUS_Allwinner::PinSetSignal(board_type::pi_physical_pin_e pin, board_ty
// LOGERROR("%s not implemented!!", __PRETTY_FUNCTION__)
}
void GPIOBUS_Allwinner::DrvConfig(DWORD drive)
void GPIOBUS_Allwinner::DrvConfig(uint32_t drive)
{
(void)drive;
LOGERROR("%s not implemented!!", __PRETTY_FUNCTION__)

View File

@ -43,9 +43,9 @@ class GPIOBUS_Allwinner : public GPIOBUS
//---------------------------------------------------------------------------
uint32_t Acquire() override;
BYTE GetDAT() override;
uint8_t GetDAT() override;
// Get DAT signal
void SetDAT(BYTE dat) override;
void SetDAT(uint8_t dat) override;
// Set DAT signal
// TODO: Restore these back to protected
// protected:
@ -76,7 +76,7 @@ class GPIOBUS_Allwinner : public GPIOBUS
// GPIO pin pull up/down resistor setting
void PinSetSignal(board_type::pi_physical_pin_e pin, board_type::gpio_high_low_e ast) override;
// Set GPIO output signal
void DrvConfig(DWORD drive) override;
void DrvConfig(uint32_t drive) override;
// Set GPIO drive strength
// Map the physical pin number to the logical GPIO number

View File

@ -16,7 +16,6 @@
#include "hal/gpiobus.h"
#include "hal/systimer.h"
#include "log.h"
#include "os.h"
#include <map>
#include <string.h>
#include <sys/epoll.h>
@ -53,7 +52,7 @@ static uint32_t get_dt_ranges(const char *filename, uint32_t offset)
uint32_t address = ~0;
if (FILE *fp = fopen(filename, "rb"); fp) {
fseek(fp, offset, SEEK_SET);
if (array<BYTE, 4> buf; fread(buf.data(), 1, buf.size(), fp) == buf.size()) {
if (array<uint8_t, 4> buf; fread(buf.data(), 1, buf.size(), fp) == buf.size()) {
address = (int)buf[0] << 24 | (int)buf[1] << 16 | (int)buf[2] << 8 | (int)buf[3] << 0;
}
fclose(fp);
@ -395,7 +394,7 @@ void GPIOBUS_Raspberry::Cleanup()
// Get data signals
//
//---------------------------------------------------------------------------
BYTE GPIOBUS_Raspberry::GetDAT()
uint8_t GPIOBUS_Raspberry::GetDAT()
{
GPIO_FUNCTION_TRACE
uint32_t data = Acquire();
@ -407,7 +406,7 @@ BYTE GPIOBUS_Raspberry::GetDAT()
((data >> (phys_to_gpio_map.at(board->pin_dt5) - 5)) & (1 << 5)) |
((data >> (phys_to_gpio_map.at(board->pin_dt6) - 6)) & (1 << 6)) |
((data >> (phys_to_gpio_map.at(board->pin_dt7) - 7)) & (1 << 7));
return (BYTE)data;
return (uint8_t)data;
}
//---------------------------------------------------------------------------
@ -415,7 +414,7 @@ BYTE GPIOBUS_Raspberry::GetDAT()
// Set data signals
//
//---------------------------------------------------------------------------
void GPIOBUS_Raspberry::SetDAT(BYTE dat)
void GPIOBUS_Raspberry::SetDAT(uint8_t dat)
{
GPIO_FUNCTION_TRACE
// Write to port

View File

@ -46,9 +46,9 @@ class GPIOBUS_Raspberry final : public GPIOBUS
//---------------------------------------------------------------------------
uint32_t Acquire() override;
BYTE GetDAT() override;
uint8_t GetDAT() override;
// Get DAT signal
void SetDAT(BYTE dat) override;
void SetDAT(uint8_t dat) override;
// Set DAT signal
// TODO: Restore this back to private
// private:

View File

@ -161,13 +161,13 @@ bool SBC_Version::IsBananaPi()
// The following functions are only used on the Raspberry Pi
// (imported from bcm_host.c)
DWORD SBC_Version::GetDeviceTreeRanges(const char *filename, DWORD offset)
uint32_t SBC_Version::GetDeviceTreeRanges(const char *filename, uint32_t offset)
{
LOGTRACE("%s", __PRETTY_FUNCTION__)
DWORD address = ~0;
uint32_t address = ~0;
if (FILE *fp = fopen(filename, "rb"); fp) {
fseek(fp, offset, SEEK_SET);
if (std::array<BYTE, 4> buf; fread(buf.data(), 1, buf.size(), fp) == buf.size()) {
if (std::array<uint8_t, 4> buf; fread(buf.data(), 1, buf.size(), fp) == buf.size()) {
address = (int)buf[0] << 24 | (int)buf[1] << 16 | (int)buf[2] << 8 | (int)buf[3] << 0;
}
fclose(fp);
@ -176,25 +176,25 @@ DWORD SBC_Version::GetDeviceTreeRanges(const char *filename, DWORD offset)
}
#if defined __linux__
DWORD SBC_Version::GetPeripheralAddress(void)
uint32_t SBC_Version::GetPeripheralAddress(void)
{
LOGTRACE("%s", __PRETTY_FUNCTION__)
DWORD address = GetDeviceTreeRanges("/proc/device-tree/soc/ranges", 4);
uint32_t address = GetDeviceTreeRanges("/proc/device-tree/soc/ranges", 4);
if (address == 0) {
address = GetDeviceTreeRanges("/proc/device-tree/soc/ranges", 8);
}
address = (address == (DWORD)~0) ? 0x20000000 : address;
address = (address == (uint32_t)~0) ? 0x20000000 : address;
LOGDEBUG("Peripheral address : 0x%8x\n", address)
return address;
}
#elif defined __NetBSD__
DWORD SBC_Version::GetPeripheralAddress(void)
uint32_t SBC_Version::GetPeripheralAddress(void)
{
char buf[1024];
size_t len = sizeof(buf);
DWORD address;
uint32_t address;
if (sysctlbyname("hw.model", buf, &len, NULL, 0) || strstr(buf, "ARM1176JZ-S") != buf) {
// Failed to get CPU model || Not BCM2835
@ -208,7 +208,7 @@ DWORD SBC_Version::GetPeripheralAddress(void)
return address;
}
#else
DWORD SBC_Version::GetPeripheralAddress(void)
uint32_t SBC_Version::GetPeripheralAddress(void)
{
return 0;
}

View File

@ -10,7 +10,7 @@
//---------------------------------------------------------------------------
#pragma once
#include "os.h"
#include <map>
#include <string>
@ -47,7 +47,7 @@ class SBC_Version
static const std::string *GetString();
static DWORD GetPeripheralAddress();
static uint32_t GetPeripheralAddress();
private:
static sbc_version_type m_sbc_version;
@ -66,5 +66,5 @@ class SBC_Version
static const std::string m_device_tree_model_path;
static DWORD GetDeviceTreeRanges(const char *filename, DWORD offset);
};
static uint32_t GetDeviceTreeRanges(const char *filename, uint32_t offset);
};

View File

@ -18,7 +18,6 @@
#include "hal/gpiobus.h"
#include "hal/sbc_version.h"
#include "os.h"
#include "config.h"
#include "log.h"

View File

@ -13,7 +13,6 @@
#include <sys/mman.h>
#include "hal/gpiobus.h"
#include "os.h"
#include "config.h"
#include "log.h"
@ -99,14 +98,14 @@ void SysTimer_AllWinner::disable_hs_timer()
sysbus_regs->bus_soft_rst_reg0)
}
DWORD SysTimer_AllWinner::GetTimerLow()
uint32_t SysTimer_AllWinner::GetTimerLow()
{
// RaSCSI expects the timer to count UP, but the Allwinner HS timer counts
// down. So, we subtract the current timer value from UINT32_MAX
return UINT32_MAX - (hsitimer_regs->hs_tmr_curnt_lo_reg / 200);
}
DWORD SysTimer_AllWinner::GetTimerHigh()
uint32_t SysTimer_AllWinner::GetTimerHigh()
{
return (uint32_t)0;
}
@ -116,7 +115,7 @@ DWORD SysTimer_AllWinner::GetTimerHigh()
// Sleep in nanoseconds
//
//---------------------------------------------------------------------------
void SysTimer_AllWinner::SleepNsec(DWORD nsec)
void SysTimer_AllWinner::SleepNsec(uint32_t nsec)
{
// If time is less than one HS timer clock tick, don't do anything
if (nsec < 20) {
@ -127,7 +126,7 @@ void SysTimer_AllWinner::SleepNsec(DWORD nsec)
// one clock tick every 5 ns.
auto clockticks = (uint32_t)std::ceil(nsec / 5);
DWORD enter_time = hsitimer_regs->hs_tmr_curnt_lo_reg;
uint32_t enter_time = hsitimer_regs->hs_tmr_curnt_lo_reg;
LOGTRACE("%s entertime: %08X ns: %d clockticks: %d", __PRETTY_FUNCTION__, enter_time, nsec, clockticks)
while ((enter_time - hsitimer_regs->hs_tmr_curnt_lo_reg) < clockticks)
@ -141,7 +140,7 @@ void SysTimer_AllWinner::SleepNsec(DWORD nsec)
// Sleep in microseconds
//
//---------------------------------------------------------------------------
void SysTimer_AllWinner::SleepUsec(DWORD usec)
void SysTimer_AllWinner::SleepUsec(uint32_t usec)
{
LOGTRACE("%s", __PRETTY_FUNCTION__)
@ -150,7 +149,7 @@ void SysTimer_AllWinner::SleepUsec(DWORD usec)
return;
}
DWORD enter_time = GetTimerLow();
uint32_t enter_time = GetTimerLow();
while ((GetTimerLow() - enter_time) < usec)
;
}

View File

@ -18,7 +18,6 @@
#include "hal/gpiobus.h"
#include "hal/sbc_version.h"
#include "os.h"
#include "config.h"
#include "log.h"
@ -69,8 +68,8 @@ void SysTimer_Raspberry::Init()
std::array<uint32_t, 32> maxclock = {32, 0, 0x00030004, 8, 0, 4, 0, 0};
// Save the base address
systaddr = (DWORD *)map + SYST_OFFSET / sizeof(DWORD);
armtaddr = (DWORD *)map + ARMT_OFFSET / sizeof(DWORD);
systaddr = (uint32_t *)map + SYST_OFFSET / sizeof(uint32_t);
armtaddr = (uint32_t *)map + ARMT_OFFSET / sizeof(uint32_t);
// Change the ARM timer to free run mode
armtaddr[ARMT_CTRL] = 0x00000282;
@ -88,7 +87,7 @@ void SysTimer_Raspberry::Init()
// Get system timer low byte
//
//---------------------------------------------------------------------------
DWORD SysTimer_Raspberry::GetTimerLow()
uint32_t SysTimer_Raspberry::GetTimerLow()
{
return systaddr[SYST_CLO];
}
@ -98,7 +97,7 @@ DWORD SysTimer_Raspberry::GetTimerLow()
// Get system timer high byte
//
//---------------------------------------------------------------------------
DWORD SysTimer_Raspberry::GetTimerHigh()
uint32_t SysTimer_Raspberry::GetTimerHigh()
{
return systaddr[SYST_CHI];
}
@ -108,7 +107,7 @@ DWORD SysTimer_Raspberry::GetTimerHigh()
// Sleep in nanoseconds
//
//---------------------------------------------------------------------------
void SysTimer_Raspberry::SleepNsec(DWORD nsec)
void SysTimer_Raspberry::SleepNsec(uint32_t nsec)
{
// If time is 0, don't do anything
if (nsec == 0) {
@ -116,7 +115,7 @@ void SysTimer_Raspberry::SleepNsec(DWORD nsec)
}
// Calculate the timer difference
DWORD diff = corefreq * nsec / 1000;
uint32_t diff = corefreq * nsec / 1000;
// Return if the difference in time is too small
if (diff == 0) {
@ -124,7 +123,7 @@ void SysTimer_Raspberry::SleepNsec(DWORD nsec)
}
// Start
DWORD start = armtaddr[ARMT_FREERUN];
uint32_t start = armtaddr[ARMT_FREERUN];
// Loop until timer has elapsed
while ((armtaddr[ARMT_FREERUN] - start) < diff)
@ -136,14 +135,14 @@ void SysTimer_Raspberry::SleepNsec(DWORD nsec)
// Sleep in microseconds
//
//---------------------------------------------------------------------------
void SysTimer_Raspberry::SleepUsec(DWORD usec)
void SysTimer_Raspberry::SleepUsec(uint32_t usec)
{
// If time is 0, don't do anything
if (usec == 0) {
return;
}
DWORD now = GetTimerLow();
uint32_t now = GetTimerLow();
while ((GetTimerLow() - now) < usec)
;
}

View File

@ -8,7 +8,7 @@
// [ SCSI Bus Monitor ]
//
//---------------------------------------------------------------------------
#include "os.h"
#include "scsi.h"
#include "data_sample.h"

View File

@ -35,7 +35,7 @@ inline bool GetCd(const data_capture *sample) { return bus->GetPinRaw(sample->d
inline bool GetIo(const data_capture *sample) { return bus->GetPinRaw(sample->data, bus->GetBoard()->pin_io); }
inline bool GetReq(const data_capture *sample) { return bus->GetPinRaw(sample->data, bus->GetBoard()->pin_req); }
inline bool GetDp(const data_capture *sample) { return bus->GetPinRaw(sample->data, bus->GetBoard()->pin_dp); }
inline BYTE GetData(const data_capture *sample)
inline uint8_t GetData(const data_capture *sample)
{
uint32_t result = 0;
result |= (bus->GetPinRaw(sample->data, bus->GetBoard()->pin_dt0) != 0) ? (1 << 0) : 0;

View File

@ -10,7 +10,6 @@
#include <iostream>
#include <fstream>
#include "os.h"
#include "log.h"
#include "sm_reports.h"
#include "rascsi_version.h"

View File

@ -9,7 +9,6 @@
//
//---------------------------------------------------------------------------
#include "os.h"
#include "log.h"
#include <sstream>
#include <iostream>
@ -52,17 +51,17 @@ const int PIN_PHASE = 0;
//
//---------------------------------------------------------------------------
// TODO: prev_value can be smaller. Just making up a big number for now
static BYTE prev_value[128] = {0xFF};
static uint8_t prev_value[128] = {0xFF};
extern double ns_per_loop;
static BYTE get_pin_value(uint32_t data, board_type::pi_physical_pin_e pin)
static uint8_t get_pin_value(uint32_t data, board_type::pi_physical_pin_e pin)
{
return bus->GetPinRaw(data, pin);
// return (data >> pin) & 1;
}
static BYTE get_data_field(uint32_t data)
static uint8_t get_data_field(uint32_t data)
{
// TODO: This is a quick hack to re-use the GetData() function from data_sample.h
const struct data_capture dummy_data_capture =
@ -71,21 +70,20 @@ static BYTE get_data_field(uint32_t data)
.timestamp = 0,
};
return GetData(&dummy_data_capture);
}
static void vcd_output_if_changed_phase(ofstream& fp, uint32_t data, int pin, char symbol)
{
const BUS::phase_t new_value = GPIOBUS::GetPhaseRaw(data);
if (prev_value[pin] != (int)new_value) {
prev_value[pin] = (int)new_value;
if (prev_value[pin] != static_cast<int>(new_value)) {
prev_value[pin] = static_cast<int>(new_value);
fp << "s" << GPIOBUS::GetPhaseStrRaw(new_value) << " " << symbol << endl;
}
}
static void vcd_output_if_changed_bool(ofstream& fp, uint32_t data, board_type::pi_physical_pin_e pin, char symbol)
{
const BYTE new_value = get_pin_value(data, pin);
const uint8_t new_value = get_pin_value(data, pin);
if (prev_value[(int)pin] != new_value) {
prev_value[(int)pin] = new_value;
fp << new_value << symbol << endl;
@ -94,7 +92,7 @@ static void vcd_output_if_changed_bool(ofstream& fp, uint32_t data, board_type::
static void vcd_output_if_changed_byte(ofstream& fp, uint32_t data, int pin, char symbol)
{
const BYTE new_value = get_data_field(data);
const uint8_t new_value = get_data_field(data);
if (prev_value[pin] != new_value) {
prev_value[pin] = new_value;
fp << "b"

View File

@ -1,17 +0,0 @@
//---------------------------------------------------------------------------
//
// SCSI Target Emulator RaSCSI Reloaded
// for Raspberry Pi
//
// Powered by XM6 TypeG Technology.
// Copyright (C) 2016-2020 GIMONS
// Copyright (C) 2020 akuker
//
//---------------------------------------------------------------------------
#pragma once
#include <cstdint>
using BYTE = unsigned char;
using DWORD = uint32_t;

View File

@ -28,7 +28,7 @@ void ProtobufSerializer::SerializeMessage(int fd, const google::protobuf::Messag
message.SerializeToString(&data);
// Write the size of the protobuf data as a header
auto size = (int32_t)data.length();
auto size = static_cast<int32_t>(data.length());
if (write(fd, &size, sizeof(size)) != sizeof(size)) {
throw io_exception("Can't write protobuf message header");
}
@ -47,8 +47,8 @@ void ProtobufSerializer::DeserializeMessage(int fd, google::protobuf::Message& m
throw io_exception("Invalid protobuf message header");
}
const int size = ((int)header_buf[3] << 24) + ((int)header_buf[2] << 16)
+ ((int)header_buf[1] << 8) + (int)header_buf[0];
const int size = (static_cast<int>(header_buf[3]) << 24) + (static_cast<int>(header_buf[2]) << 16)
+ (static_cast<int>(header_buf[1]) << 8) + static_cast<int>(header_buf[0]);
if (size < 0) {
throw io_exception("Invalid protobuf message header");
}

View File

@ -40,7 +40,7 @@
#include <fstream>
#include <list>
#include <map>
#include <iostream>
#include <deque>
using namespace std;
using namespace spdlog;
@ -73,6 +73,9 @@ shared_ptr<RascsiResponse> rascsi_response;
shared_ptr<RascsiExecutor> executor;
const ProtobufSerializer serializer;
using optarg_value_type = std::pair<int,string>;
using optarg_queue_type = std::deque<optarg_value_type>;
void Banner(int argc, char* argv[])
{
cout << Banner("Reloaded");
@ -206,40 +209,32 @@ bool ProcessId(const string& id_spec, int& id, int& unit)
return true;
}
bool ParseArgument(int argc, char* argv[], int& port)
bool ParseArgument(int argc, char* argv[], int& port, optarg_queue_type& post_process)
{
PbCommand command;
int id = -1;
int unit = -1;
PbDeviceType type = UNDEFINED;
int block_size = 0;
string name;
string log_level;
const char *locale = setlocale(LC_MESSAGES, "");
if (locale == nullptr || !strcmp(locale, "C")) {
locale = "en";
}
opterr = 1;
int opt;
while ((opt = getopt(argc, argv, "-Iib:d:n:p:r:t:z:D:F:L:P:R:")) != -1) {
while ((opt = getopt(argc, argv, "-Iib:d:n:p:r:t:z:D:F:L:P:R:C:v")) != -1) {
switch (opt) {
// The two options below are kind of a compound option with two letters
// The following options can not be processed until AFTER
// the 'bus' object is created and configured
case 'i':
case 'I':
id = -1;
unit = -1;
continue;
case 'd':
case 'D': {
if (!ProcessId(optarg, id, unit)) {
return false;
}
case 'D':
case 'R':
case 'n':
case 'r':
case 't':
case 'F':
case 'z':
{
string optarg_str = (optarg == nullptr) ? "" : string(optarg);
post_process.push_back(optarg_value_type(opt,optarg_str));
continue;
}
case 'b': {
if (!GetAsInt(optarg, block_size)) {
cerr << "Invalid block size " << optarg << endl;
@ -248,33 +243,8 @@ bool ParseArgument(int argc, char* argv[], int& port)
continue;
}
case 'z':
locale = optarg;
continue;
case 'F': {
if (const string result = rascsi_image.SetDefaultFolder(optarg); !result.empty()) {
cerr << result << endl;
return false;
}
continue;
}
case 'L':
log_level = optarg;
continue;
case 'R':
int depth;
if (!GetAsInt(optarg, depth) || depth < 0) {
cerr << "Invalid image file scan depth " << optarg << endl;
return false;
}
rascsi_image.SetDepth(depth);
continue;
case 'n':
name = optarg;
current_log_level = optarg;
continue;
case 'p':
@ -289,9 +259,91 @@ bool ParseArgument(int argc, char* argv[], int& port)
return false;
}
continue;
case 'v':
cout << rascsi_get_version_string() << endl;
exit(0);
case 1:
{
// Encountered filename
string optarg_str = (optarg == nullptr) ? "" : string(optarg);
post_process.push_back(optarg_value_type(opt,optarg_str));
continue;
}
default:
return false;
}
if (optopt) {
return false;
}
}
return true;
}
static bool CreateInitialDevices(optarg_queue_type& optarg_queue){
PbCommand command;
int id = -1;
int unit = -1;
PbDeviceType type = UNDEFINED;
int block_size = 0;
string name;
string log_level;
const char *locale = setlocale(LC_MESSAGES, "");
if (locale == nullptr || !strcmp(locale, "C")) {
locale = "en";
}
opterr = 1;
for(auto current_arg : optarg_queue){
switch (current_arg.first) {
// The two options below are kind of a compound option with two letters
case 'i':
case 'I':
id = -1;
unit = -1;
continue;
case 'd':
case 'D': {
if (!ProcessId(current_arg.second, id, unit)) {
return false;
}
continue;
}
case 'z':
locale = current_arg.second.c_str();
continue;
case 'F': {
if (const string result = rascsi_image.SetDefaultFolder(current_arg.second); !result.empty()) {
cerr << result << endl;
return false;
}
continue;
}
case 'R':
int depth;
if (!GetAsInt(current_arg.second, depth) || depth < 0) {
cerr << "Invalid image file scan depth " << current_arg.second << endl;
return false;
}
rascsi_image.SetDepth(depth);
continue;
case 'n':
name = current_arg.second;
continue;
case 'r': {
string error = executor->SetReservedIds(optarg);
string error = executor->SetReservedIds(current_arg.second);
if (!error.empty()) {
cerr << error << endl;
return false;
@ -300,10 +352,10 @@ bool ParseArgument(int argc, char* argv[], int& port)
continue;
case 't': {
string t = optarg;
string t = current_arg.second;
transform(t.begin(), t.end(), t.begin(), ::toupper);
if (!PbDeviceType_Parse(t, &type)) {
cerr << "Illegal device type '" << optarg << "'" << endl;
cerr << "Illegal device type '" << current_arg.second << "'" << endl;
return false;
}
}
@ -312,13 +364,6 @@ bool ParseArgument(int argc, char* argv[], int& port)
case 1:
// Encountered filename
break;
default:
return false;
}
if (optopt) {
return false;
}
// Set up the device data
@ -328,7 +373,7 @@ bool ParseArgument(int argc, char* argv[], int& port)
device->set_type(type);
device->set_block_size(block_size);
ParseParameters(*device, optarg);
ParseParameters(*device, current_arg.second);
if (size_t separator_pos = name.find(COMPONENT_SEPARATOR); separator_pos != string::npos) {
device->set_vendor(name.substr(0, separator_pos));
@ -352,10 +397,6 @@ bool ParseArgument(int argc, char* argv[], int& port)
name = "";
}
if (!log_level.empty() && executor->SetLogLevel(log_level)) {
current_log_level = log_level;
}
// Attach all specified devices
command.set_operation(ATTACH);
@ -524,6 +565,7 @@ static bool ExecuteCommand(const CommandContext& context, PbCommand& command)
int main(int argc, char* argv[])
{
optarg_queue_type optarg_queue;
GOOGLE_PROTOBUF_VERIFY_VERSION;
// added setvbuf to override stdout buffering, so logs are written immediately and not when the process exits.
@ -532,15 +574,12 @@ int main(int argc, char* argv[])
// Output the Banner
Banner(argc, argv);
// ParseArgument() requires the bus to have been initialized first, which requires the root user.
// The -v option should be available for any user, which requires special handling.
for (int i = 1 ; i < argc; i++) {
if (!strcasecmp(argv[i], "-v")) {
cout << rascsi_get_version_string() << endl;
return 0;
}
int port = DEFAULT_PORT;
if (!ParseArgument(argc, argv, port, optarg_queue)) {
return -1;
}
// Note that current_log_level may have been modified by ParseArgument()
executor->SetLogLevel(current_log_level);
// Create a thread-safe stdout logger to process the log messages
@ -550,12 +589,13 @@ int main(int argc, char* argv[])
return EPERM;
}
int port = DEFAULT_PORT;
if (!service.Init(&ExecuteCommand, port)) {
return EPERM;
}
if (!ParseArgument(argc, argv, port)) {
// 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;
}
@ -629,7 +669,7 @@ int main(int argc, char* argv[])
int initiator_id = -1;
// The initiator and target ID
const BYTE id_data = bus->GetDAT();
const uint8_t id_data = bus->GetDAT();
BUS::phase_t phase = BUS::phase_t::busfree;

View File

@ -201,7 +201,7 @@ string Localizer::Localize(LocalizationKey key, const string& locale, const stri
const auto& m = messages.find(key);
if (m == messages.end()) {
return "Missing localization for enum value " + to_string((int)key);
return "Missing localization for enum value " + to_string(static_cast<int>(key));
}
string message = m->second;

View File

@ -49,16 +49,16 @@ bool RascsiExecutor::ProcessDeviceCmd(const CommandContext& context, const PbDev
auto device = controller_manager.GetDeviceByIdAndLun(id, lun);
if (!ValidateOperationAgainstDevice(context, device, operation)) {
if (!ValidateOperationAgainstDevice(context, *device, operation)) {
return false;
}
switch (operation) {
case START:
return Start(device, dryRun);
return Start(*device, dryRun);
case STOP:
return Stop(device, dryRun);
return Stop(*device, dryRun);
case ATTACH:
return Attach(context, pb_device, dryRun);
@ -70,13 +70,13 @@ bool RascsiExecutor::ProcessDeviceCmd(const CommandContext& context, const PbDev
return Insert(context, pb_device, device, dryRun);
case EJECT:
return Eject(device, dryRun);
return Eject(*device, dryRun);
case PROTECT:
return Protect(device, dryRun);
return Protect(*device, dryRun);
case UNPROTECT:
return Unprotect(device, dryRun);
return Unprotect(*device, dryRun);
break;
case CHECK_AUTHENTICATION:
@ -196,62 +196,62 @@ bool RascsiExecutor::SetLogLevel(const string& log_level) const
return true;
}
bool RascsiExecutor::Start(shared_ptr<PrimaryDevice> device, bool dryRun) const
bool RascsiExecutor::Start(PrimaryDevice& device, bool dryRun) const
{
if (!dryRun) {
LOGINFO("Start requested for %s ID %d, unit %d", device->GetTypeString(), device->GetId(), device->GetLun())
LOGINFO("Start requested for %s ID %d, unit %d", device.GetTypeString(), device.GetId(), device.GetLun())
if (!device->Start()) {
LOGWARN("Starting %s ID %d, unit %d failed", device->GetTypeString(), device->GetId(), device->GetLun())
if (!device.Start()) {
LOGWARN("Starting %s ID %d, unit %d failed", device.GetTypeString(), device.GetId(), device.GetLun())
}
}
return true;
}
bool RascsiExecutor::Stop(shared_ptr<PrimaryDevice> device, bool dryRun) const
bool RascsiExecutor::Stop(PrimaryDevice& device, bool dryRun) const
{
if (!dryRun) {
LOGINFO("Stop requested for %s ID %d, unit %d", device->GetTypeString(), device->GetId(), device->GetLun())
LOGINFO("Stop requested for %s ID %d, unit %d", device.GetTypeString(), device.GetId(), device.GetLun())
device->Stop();
device.Stop();
}
return true;
}
bool RascsiExecutor::Eject(shared_ptr<PrimaryDevice> device, bool dryRun) const
bool RascsiExecutor::Eject(PrimaryDevice& device, bool dryRun) const
{
if (!dryRun) {
LOGINFO("Eject requested for %s ID %d, unit %d", device->GetTypeString(), device->GetId(), device->GetLun())
LOGINFO("Eject requested for %s ID %d, unit %d", device.GetTypeString(), device.GetId(), device.GetLun())
if (!device->Eject(true)) {
LOGWARN("Ejecting %s ID %d, unit %d failed", device->GetTypeString(), device->GetId(), device->GetLun())
if (!device.Eject(true)) {
LOGWARN("Ejecting %s ID %d, unit %d failed", device.GetTypeString(), device.GetId(), device.GetLun())
}
}
return true;
}
bool RascsiExecutor::Protect(shared_ptr<PrimaryDevice> device, bool dryRun) const
bool RascsiExecutor::Protect(PrimaryDevice& device, bool dryRun) const
{
if (!dryRun) {
LOGINFO("Write protection requested for %s ID %d, unit %d", device->GetTypeString(), device->GetId(),
device->GetLun())
LOGINFO("Write protection requested for %s ID %d, unit %d", device.GetTypeString(), device.GetId(),
device.GetLun())
device->SetProtected(true);
device.SetProtected(true);
}
return true;
}
bool RascsiExecutor::Unprotect(shared_ptr<PrimaryDevice> device, bool dryRun) const
bool RascsiExecutor::Unprotect(PrimaryDevice& device, bool dryRun) const
{
if (!dryRun) {
LOGINFO("Write unprotection requested for %s ID %d, unit %d", device->GetTypeString(), device->GetId(),
device->GetLun())
LOGINFO("Write unprotection requested for %s ID %d, unit %d", device.GetTypeString(), device.GetId(),
device.GetLun())
device->SetProtected(false);
device.SetProtected(false);
}
return true;
@ -286,7 +286,7 @@ bool RascsiExecutor::Attach(const CommandContext& context, const PbDeviceDefinit
auto storage_device = dynamic_pointer_cast<StorageDevice>(device);
device->SetRemoved(storage_device != nullptr ? filename.empty() : false);
if (!SetProductData(context, pb_device, device)) {
if (!SetProductData(context, pb_device, *device)) {
return false;
}
@ -301,7 +301,7 @@ bool RascsiExecutor::Attach(const CommandContext& context, const PbDeviceDefinit
return context.ReturnLocalizedError(LocalizationKey::ERROR_MISSING_FILENAME, PbDeviceType_Name(type));
}
if (!ValidateImageFile(context, storage_device, filename, full_path)) {
if (!ValidateImageFile(context, *storage_device, filename, full_path)) {
return false;
}
}
@ -319,12 +319,11 @@ bool RascsiExecutor::Attach(const CommandContext& context, const PbDeviceDefinit
}
if (device->SupportsParams() && !device->Init(params)) {
return context.ReturnLocalizedError(LocalizationKey::ERROR_INITIALIZATION, PbDeviceType_Name(type),
return context.ReturnLocalizedError(LocalizationKey::ERROR_INITIALIZATION, PbDeviceType_Name(device->GetType()),
to_string(id), to_string(lun));
}
// Remove SupportsFile as soon as Daynaport and bridge do not inherit from Disk anymore
if (storage_device != nullptr && storage_device->SupportsFile()) {
if (storage_device != nullptr) {
storage_device->ReserveFile(full_path, id, lun);
}
@ -351,7 +350,7 @@ bool RascsiExecutor::Attach(const CommandContext& context, const PbDeviceDefinit
}
bool RascsiExecutor::Insert(const CommandContext& context, const PbDeviceDefinition& pb_device,
shared_ptr<PrimaryDevice> device, bool dryRun) const
const shared_ptr<PrimaryDevice>& device, bool dryRun) const
{
auto storage_device = dynamic_pointer_cast<StorageDevice>(device);
if (storage_device == nullptr) {
@ -384,7 +383,7 @@ bool RascsiExecutor::Insert(const CommandContext& context, const PbDeviceDefinit
}
string full_path;
if (!ValidateImageFile(context, storage_device, filename, full_path)) {
if (!ValidateImageFile(context, *storage_device, filename, full_path)) {
return false;
}
@ -395,9 +394,8 @@ bool RascsiExecutor::Insert(const CommandContext& context, const PbDeviceDefinit
return true;
}
bool RascsiExecutor::Detach(const CommandContext& context, shared_ptr<PrimaryDevice> device, bool dryRun) const
bool RascsiExecutor::Detach(const CommandContext& context, const shared_ptr<PrimaryDevice>& device, bool dryRun) const
{
cerr << "AAA " << device->GetId() << endl;
auto controller = controller_manager.FindController(device->GetId());
if (controller == nullptr) {
return context.ReturnLocalizedError(LocalizationKey::ERROR_DETACH);
@ -541,7 +539,7 @@ string RascsiExecutor::SetReservedIds(string_view ids)
return "";
}
bool RascsiExecutor::ValidateImageFile(const CommandContext& context, shared_ptr<StorageDevice> storage_device,
bool RascsiExecutor::ValidateImageFile(const CommandContext& context, StorageDevice& storage_device,
const string& filename, string& full_path) const
{
if (filename.empty()) {
@ -569,19 +567,19 @@ bool RascsiExecutor::ValidateImageFile(const CommandContext& context, shared_ptr
}
}
storage_device->SetFilename(effective_filename);
storage_device.SetFilename(effective_filename);
if (storage_device->IsReadOnlyFile()) {
if (storage_device.IsReadOnlyFile()) {
// Permanently write-protected
storage_device->SetReadOnly(true);
storage_device->SetProtectable(false);
storage_device.SetReadOnly(true);
storage_device.SetProtectable(false);
}
else {
storage_device->SetReadOnly(false);
storage_device->SetProtectable(true);
storage_device.SetReadOnly(false);
storage_device.SetProtectable(true);
}
storage_device->Open();
storage_device.Open();
full_path = effective_filename;
@ -701,23 +699,23 @@ bool RascsiExecutor::SetSectorSize(const CommandContext& context, shared_ptr<Pri
return true;
}
bool RascsiExecutor::ValidateOperationAgainstDevice(const CommandContext& context,
const shared_ptr<PrimaryDevice> device, const PbOperation& operation)
bool RascsiExecutor::ValidateOperationAgainstDevice(const CommandContext& context, const PrimaryDevice& device,
const PbOperation& operation)
{
if ((operation == START || operation == STOP) && !device->IsStoppable()) {
return context.ReturnLocalizedError(LocalizationKey::ERROR_OPERATION_DENIED_STOPPABLE, device->GetTypeString());
if ((operation == START || operation == STOP) && !device.IsStoppable()) {
return context.ReturnLocalizedError(LocalizationKey::ERROR_OPERATION_DENIED_STOPPABLE, device.GetTypeString());
}
if ((operation == INSERT || operation == EJECT) && !device->IsRemovable()) {
return context.ReturnLocalizedError(LocalizationKey::ERROR_OPERATION_DENIED_REMOVABLE, device->GetTypeString());
if ((operation == INSERT || operation == EJECT) && !device.IsRemovable()) {
return context.ReturnLocalizedError(LocalizationKey::ERROR_OPERATION_DENIED_REMOVABLE, device.GetTypeString());
}
if ((operation == PROTECT || operation == UNPROTECT) && !device->IsProtectable()) {
return context.ReturnLocalizedError(LocalizationKey::ERROR_OPERATION_DENIED_PROTECTABLE, device->GetTypeString());
if ((operation == PROTECT || operation == UNPROTECT) && !device.IsProtectable()) {
return context.ReturnLocalizedError(LocalizationKey::ERROR_OPERATION_DENIED_PROTECTABLE, device.GetTypeString());
}
if ((operation == PROTECT || operation == UNPROTECT) && !device->IsReady()) {
return context.ReturnLocalizedError(LocalizationKey::ERROR_OPERATION_DENIED_READY, device->GetTypeString());
if ((operation == PROTECT || operation == UNPROTECT) && !device.IsReady()) {
return context.ReturnLocalizedError(LocalizationKey::ERROR_OPERATION_DENIED_READY, device.GetTypeString());
}
return true;
@ -740,17 +738,17 @@ bool RascsiExecutor::ValidateIdAndLun(const CommandContext& context, int id, int
}
bool RascsiExecutor::SetProductData(const CommandContext& context, const PbDeviceDefinition& pb_device,
shared_ptr<PrimaryDevice> device)
PrimaryDevice& device)
{
try {
if (!pb_device.vendor().empty()) {
device->SetVendor(pb_device.vendor());
device.SetVendor(pb_device.vendor());
}
if (!pb_device.product().empty()) {
device->SetProduct(pb_device.product());
device.SetProduct(pb_device.product());
}
if (!pb_device.revision().empty()) {
device->SetRevision(pb_device.revision());
device.SetRevision(pb_device.revision());
}
}
catch(const invalid_argument& e) {

View File

@ -45,27 +45,26 @@ public:
bool ProcessDeviceCmd(const CommandContext&, const PbDeviceDefinition&, const PbCommand&, bool);
bool ProcessCmd(const CommandContext&, const PbCommand&);
bool SetLogLevel(const string&) const;
bool Start(shared_ptr<PrimaryDevice>, bool) const;
bool Stop(shared_ptr<PrimaryDevice>, bool) const;
bool Eject(shared_ptr<PrimaryDevice>, bool) const;
bool Protect(shared_ptr<PrimaryDevice>, bool) const;
bool Unprotect(shared_ptr<PrimaryDevice>, bool) const;
bool Start(PrimaryDevice&, bool) const;
bool Stop(PrimaryDevice&, bool) const;
bool Eject(PrimaryDevice&, bool) const;
bool Protect(PrimaryDevice&, bool) const;
bool Unprotect(PrimaryDevice&, bool) const;
bool Attach(const CommandContext&, const PbDeviceDefinition&, bool);
bool Insert(const CommandContext&, const PbDeviceDefinition&, shared_ptr<PrimaryDevice>, bool) const;
bool Detach(const CommandContext&, shared_ptr<PrimaryDevice>, bool) const;
bool Insert(const CommandContext&, const PbDeviceDefinition&, const shared_ptr<PrimaryDevice>&, bool) const;
bool Detach(const CommandContext&, const shared_ptr<PrimaryDevice>&, bool) const;
void DetachAll();
bool ShutDown(const CommandContext&, const string&);
string SetReservedIds(string_view);
bool ValidateImageFile(const CommandContext&, shared_ptr<StorageDevice>, const string&, string&) const;
bool ValidateImageFile(const CommandContext&, StorageDevice&, const string&, string&) const;
void PrintCommand(const PbCommand&, const PbDeviceDefinition&, bool) const;
string ValidateLunSetup(const PbCommand&) const;
bool VerifyExistingIdAndLun(const CommandContext&, int, int) const;
shared_ptr<PrimaryDevice> CreateDevice(const CommandContext&, const PbDeviceType, int, const string&) const;
bool SetSectorSize(const CommandContext&, shared_ptr<PrimaryDevice>, int) const;
static bool ValidateOperationAgainstDevice(const CommandContext&, const shared_ptr<PrimaryDevice>,
const PbOperation&);
static bool ValidateOperationAgainstDevice(const CommandContext&, const PrimaryDevice&, const PbOperation&);
static bool ValidateIdAndLun(const CommandContext&, int, int);
static bool SetProductData(const CommandContext&, const PbDeviceDefinition&, shared_ptr<PrimaryDevice>);
static bool SetProductData(const CommandContext&, const PbDeviceDefinition&, PrimaryDevice&);
};

View File

@ -169,19 +169,20 @@ bool RascsiImage::DeleteImage(const CommandContext& context, const PbCommand& co
return context.ReturnStatus(false, ("Invalid folder hierarchy depth '" + filename + "'").c_str());
}
const string full_filename = GetFullName(filename);
const auto full_filename = path(GetFullName(filename));
if (!exists(full_filename)) {
return context.ReturnStatus(false, "Image file '" + string(full_filename) + "' does not exist");
}
const auto [id, lun] = StorageDevice::GetIdsForReservedFile(full_filename);
if (id == -1 || lun == -1) {
return context.ReturnStatus(false, "Can't delete image file '" + full_filename +
if (id != -1 || lun != -1) {
return context.ReturnStatus(false, "Can't delete image file '" + string(full_filename) +
"', it is currently being used by device ID " + to_string(id) + ", LUN " + to_string(lun));
}
try {
remove(path(full_filename));
}
catch(const filesystem_error& e) {
return context.ReturnStatus(false, "Can't delete image file '" + full_filename + "': " + e.what());
if (error_code error; !remove(full_filename, error)) {
return context.ReturnStatus(false, "Can't delete image file '" + string(full_filename) + "'");
}
// Delete empty subfolders
@ -194,12 +195,8 @@ bool RascsiImage::DeleteImage(const CommandContext& context, const PbCommand& co
break;
}
try {
remove(full_folder);
}
catch(const filesystem_error& e) {
return context.ReturnStatus(false, "Can't delete empty image folder '" + string(full_folder)
+ "': " + e.what());
if (error_code error; !remove(full_folder)) {
return context.ReturnStatus(false, "Can't delete empty image folder '" + string(full_folder) + "'");
}
last_slash = folder.rfind('/');
@ -218,6 +215,12 @@ bool RascsiImage::RenameImage(const CommandContext& context, const PbCommand& co
return false;
}
const auto [id, lun] = StorageDevice::GetIdsForReservedFile(from);
if (id != -1 || lun != -1) {
return context.ReturnStatus(false, "Can't rename/move image file '" + from +
"', it is currently being used by device ID " + to_string(id) + ", LUN " + to_string(lun));
}
if (!CreateImageFolder(context, to)) {
return false;
}
@ -246,6 +249,12 @@ bool RascsiImage::CopyImage(const CommandContext& context, const PbCommand& comm
return context.ReturnStatus(false, "Can't read source image file '" + from + "'");
}
const auto [id, lun] = StorageDevice::GetIdsForReservedFile(from);
if (id != -1 || lun != -1) {
return context.ReturnStatus(false, "Can't copy image file '" + from +
"', it is currently being used by device ID " + to_string(id) + ", LUN " + to_string(lun));
}
if (!CreateImageFolder(context, to)) {
return false;
}

View File

@ -11,7 +11,7 @@
#include "rascsi_interface.pb.h"
#include <dirent.h>
#include <list>
#include <array>
#include <string>
using namespace std;
@ -51,7 +51,7 @@ private:
int max_luns;
const list<string> log_levels = { "trace", "debug", "info", "warn", "err", "off" };
const 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;

View File

@ -19,8 +19,6 @@
using namespace rascsi_interface;
volatile bool RascsiService::running = false;
void RascsiService::Cleanup() const
{
if (service_socket != -1) {

View File

@ -28,7 +28,7 @@ class RascsiService
thread monthread;
static volatile bool running;
static inline volatile bool running = false;
public:

View File

@ -30,9 +30,10 @@ private:
unordered_map<int, PbOperation> operations = {
{ 'a', ATTACH },
{ 'd', DETACH },
{ 'i', INSERT },
{ 'e', EJECT },
{ 'i', INSERT },
{ 'p', PROTECT },
{ 's', DEVICES_INFO },
{ 'u', UNPROTECT }
};

View File

@ -12,7 +12,6 @@
#include <cerrno>
#include <csignal>
#include <unistd.h>
#include "os.h"
#include "rasdump_fileio.h"
#include "hal/gpiobus.h"
#include "hal/gpiobus_factory.h"
@ -41,7 +40,7 @@ int targetid; // Target ID
int boardid; // Board ID (own ID)
string hdsfile; // HDS file
bool restore; // Restore flag
BYTE buffer[BUFSIZE]; // Work Buffer
uint8_t buffer[BUFSIZE]; // Work Buffer
int result; // Result Code
//---------------------------------------------------------------------------
@ -249,7 +248,7 @@ void BusFree()
bool Selection(int id)
{
// ID setting and SEL assert
BYTE data = 1 << boardid;
uint8_t data = 1 << boardid;
data |= (1 << id);
bus->SetDAT(data);
bus->SetSEL(true);
@ -278,7 +277,7 @@ bool Selection(int id)
// Command Phase
//
//---------------------------------------------------------------------------
bool Command(BYTE *buf, int length)
bool Command(uint8_t *buf, int length)
{
// Waiting for Phase
if (!WaitPhase(BUS::phase_t::command)) {
@ -303,7 +302,7 @@ bool Command(BYTE *buf, int length)
// Data in phase
//
//---------------------------------------------------------------------------
int DataIn(BYTE *buf, int length)
int DataIn(uint8_t *buf, int length)
{
// Wait for phase
if (!WaitPhase(BUS::phase_t::datain)) {
@ -319,7 +318,7 @@ int DataIn(BYTE *buf, int length)
// Data out phase
//
//---------------------------------------------------------------------------
int DataOut(BYTE *buf, int length)
int DataOut(uint8_t *buf, int length)
{
// Wait for phase
if (!WaitPhase(BUS::phase_t::dataout)) {
@ -337,7 +336,7 @@ int DataOut(BYTE *buf, int length)
//---------------------------------------------------------------------------
int Status()
{
BYTE buf[256];
uint8_t buf[256];
// Wait for phase
if (!WaitPhase(BUS::phase_t::status)) {
@ -360,7 +359,7 @@ int Status()
//---------------------------------------------------------------------------
int MessageIn()
{
BYTE buf[256];
uint8_t buf[256];
// Wait for phase
if (!WaitPhase(BUS::phase_t::msgin)) {
@ -383,7 +382,7 @@ int MessageIn()
//---------------------------------------------------------------------------
int TestUnitReady(int id)
{
array<BYTE, 256> cmd = {};
array<uint8_t, 256> cmd = {};
// Result code initialization
result = 0;
@ -425,9 +424,9 @@ exit:
// REQUEST SENSE
//
//---------------------------------------------------------------------------
int RequestSense(int id, BYTE *buf)
int RequestSense(int id, uint8_t *buf)
{
array<BYTE, 256> cmd = {};
array<uint8_t, 256> cmd = {};
// Result code initialization
result = 0;
@ -484,9 +483,9 @@ exit:
// MODE SENSE
//
//---------------------------------------------------------------------------
int ModeSense(int id, BYTE *buf)
int ModeSense(int id, uint8_t *buf)
{
array<BYTE, 256> cmd = {};
array<uint8_t, 256> cmd = {};
// Result code initialization
result = 0;
@ -544,9 +543,9 @@ exit:
// INQUIRY
//
//---------------------------------------------------------------------------
int Inquiry(int id, BYTE *buf)
int Inquiry(int id, uint8_t *buf)
{
array<BYTE, 256> cmd = {};
array<uint8_t, 256> cmd = {};
// Result code initialization
result = 0;
@ -603,9 +602,9 @@ exit:
// READ CAPACITY
//
//---------------------------------------------------------------------------
int ReadCapacity(int id, BYTE *buf)
int ReadCapacity(int id, uint8_t *buf)
{
array<BYTE, 256> cmd = {};
array<uint8_t, 256> cmd = {};
// Result code initialization
result = 0;
@ -661,9 +660,9 @@ exit:
// READ10
//
//---------------------------------------------------------------------------
int Read10(int id, uint32_t bstart, uint32_t blength, uint32_t length, BYTE *buf)
int Read10(int id, uint32_t bstart, uint32_t blength, uint32_t length, uint8_t *buf)
{
array<BYTE, 256> cmd = {};
array<uint8_t, 256> cmd = {};
// Result code initialization
result = 0;
@ -677,12 +676,12 @@ int Read10(int id, uint32_t bstart, uint32_t blength, uint32_t length, BYTE *buf
// COMMAND
cmd[0] = 0x28;
cmd[2] = (BYTE)(bstart >> 24);
cmd[3] = (BYTE)(bstart >> 16);
cmd[4] = (BYTE)(bstart >> 8);
cmd[5] = (BYTE)bstart;
cmd[7] = (BYTE)(blength >> 8);
cmd[8] = (BYTE)blength;
cmd[2] = (uint8_t)(bstart >> 24);
cmd[3] = (uint8_t)(bstart >> 16);
cmd[4] = (uint8_t)(bstart >> 8);
cmd[5] = (uint8_t)bstart;
cmd[7] = (uint8_t)(blength >> 8);
cmd[8] = (uint8_t)blength;
if (!Command(cmd.data(), 10)) {
result = -2;
goto exit;
@ -724,9 +723,9 @@ exit:
// WRITE10
//
//---------------------------------------------------------------------------
int Write10(int id, uint32_t bstart, uint32_t blength, uint32_t length, BYTE *buf)
int Write10(int id, uint32_t bstart, uint32_t blength, uint32_t length, uint8_t *buf)
{
array<BYTE, 256> cmd = {};
array<uint8_t, 256> cmd = {};
// Result code initialization
result = 0;
@ -740,12 +739,12 @@ int Write10(int id, uint32_t bstart, uint32_t blength, uint32_t length, BYTE *bu
// COMMAND
cmd[0] = 0x2a;
cmd[2] = (BYTE)(bstart >> 24);
cmd[3] = (BYTE)(bstart >> 16);
cmd[4] = (BYTE)(bstart >> 8);
cmd[5] = (BYTE)bstart;
cmd[7] = (BYTE)(blength >> 8);
cmd[8] = (BYTE)blength;
cmd[2] = (uint8_t)(bstart >> 24);
cmd[3] = (uint8_t)(bstart >> 16);
cmd[4] = (uint8_t)(bstart >> 8);
cmd[5] = (uint8_t)bstart;
cmd[7] = (uint8_t)(blength >> 8);
cmd[8] = (uint8_t)blength;
if (!Command(cmd.data(), 10)) {
result = -2;
goto exit;

View File

@ -60,7 +60,7 @@ bool Fileio::Open(const char *fname, OpenMode mode)
return Open(fname, mode, false);
}
bool Fileio::Read(BYTE *buffer, int size) const
bool Fileio::Read(uint8_t *buffer, int size) const
{
assert(buffer);
assert(size > 0);
@ -69,7 +69,7 @@ bool Fileio::Read(BYTE *buffer, int size) const
return read(handle, buffer, size) == size;
}
bool Fileio::Write(const BYTE *buffer, int size) const
bool Fileio::Write(const uint8_t *buffer, int size) const
{
assert(buffer);
assert(size > 0);

View File

@ -10,7 +10,7 @@
#pragma once
#include "os.h"
#include <cstdint>
#include <cstdlib>
class Fileio
@ -29,8 +29,8 @@ public:
Fileio& operator=(const Fileio&) = default;
bool Open(const char *fname, OpenMode mode);
bool Read(BYTE *buffer, int size) const;
bool Write(const BYTE *buffer, int size) const;
bool Read(uint8_t *buffer, int size) const;
bool Write(const uint8_t *buffer, int size) const;
off_t GetFileSize() const;
void Close();

View File

@ -9,9 +9,6 @@
#pragma once
// TODO Remove this include as soon as gpiobus.cpp/h is open for editing (adding the include there) again
#include "bus.h"
namespace scsi_defs {
enum class scsi_level : int {
SCSI_1_CCS = 1,

View File

@ -8,7 +8,6 @@
//
//---------------------------------------------------------------------------
#include "os.h"
#include "log.h"
#include "hal/gpiobus.h"
#include "hal/gpiobus_factory.h"

View File

@ -109,11 +109,15 @@ TEST(AbstractControllerTest, ProcessPhase)
EXPECT_CALL(controller, MsgOut());
controller.ProcessPhase();
controller.SetPhase(BUS::phase_t::reselection);
EXPECT_THROW(controller.ProcessPhase(), scsi_exception);
controller.SetPhase(BUS::phase_t::reselection);
EXPECT_THAT([&] { controller.ProcessPhase(); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ABORTED_COMMAND),
Property(&scsi_exception::get_asc, asc::NO_ADDITIONAL_SENSE_INFORMATION))));
controller.SetPhase(BUS::phase_t::reserved);
EXPECT_THROW(controller.ProcessPhase(), scsi_exception);
controller.SetPhase(BUS::phase_t::reserved);
EXPECT_THAT([&] { controller.ProcessPhase(); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ABORTED_COMMAND),
Property(&scsi_exception::get_asc, asc::NO_ADDITIONAL_SENSE_INFORMATION))));
}
TEST(AbstractControllerTest, DeviceLunLifeCycle)
@ -139,6 +143,7 @@ TEST(AbstractControllerTest, DeviceLunLifeCycle)
EXPECT_EQ(nullptr, controller.GetDeviceForLun(0));
EXPECT_TRUE(controller.RemoveDevice(device1));
EXPECT_EQ(0, controller.GetLunCount());
EXPECT_FALSE(controller.RemoveDevice(device1));
}
TEST(AbstractControllerTest, ExtractInitiatorId)
@ -159,8 +164,8 @@ TEST(AbstractControllerTest, GetOpcode)
vector<int>& cmd = controller.GetCmd();
cmd[0] = 0x12;
EXPECT_EQ(0x12, (int)controller.GetOpcode());
cmd[0] = static_cast<int>(scsi_command::eCmdInquiry);
EXPECT_EQ(scsi_command::eCmdInquiry, controller.GetOpcode());
}
TEST(AbstractControllerTest, GetLun)
@ -175,7 +180,17 @@ TEST(AbstractControllerTest, GetLun)
EXPECT_EQ(LUN, controller.GetLun());
}
TEST(AbstractControllerTest, SetLength)
TEST(AbstractControllerTest, Blocks)
{
MockAbstractController controller(make_shared<MockBus>(), 0);
controller.SetBlocks(1);
EXPECT_EQ(1, controller.GetBlocks());
controller.DecrementBlocks();
EXPECT_EQ(0, controller.GetBlocks());
}
TEST(AbstractControllerTest, Length)
{
MockAbstractController controller(make_shared<MockBus>(), 0);

View File

@ -12,7 +12,7 @@
TEST(CTapDriverTest, Crc32)
{
array<BYTE, ETH_FRAME_LEN> buf;
array<uint8_t, ETH_FRAME_LEN> buf;
buf.fill(0x00);
EXPECT_EQ(0xe3d887bb, CTapDriver::Crc32(buf.data(), ETH_FRAME_LEN));
@ -30,12 +30,12 @@ TEST(CTapDriverTest, Crc32)
EXPECT_EQ(0x29cbd638, CTapDriver::Crc32(buf.data(), ETH_FRAME_LEN));
for (size_t i = 0; i < buf.size(); i++) {
buf[i] = (BYTE)i;
buf[i] = (uint8_t)i;
}
EXPECT_EQ(0xe7870705, CTapDriver::Crc32(buf.data(), ETH_FRAME_LEN));
for (size_t i = buf.size() - 1; i > 0; i--) {
buf[i] = (BYTE)i;
buf[i] = (uint8_t)i;
}
EXPECT_EQ(0xe7870705, CTapDriver::Crc32(buf.data(), ETH_FRAME_LEN));
}

View File

@ -23,11 +23,7 @@ TEST(DiskTest, Dispatch)
controller.AddDevice(disk);
EXPECT_FALSE(disk->Dispatch(scsi_command::eCmdIcd));
disk->SetRemovable(true);
disk->MediumChanged();
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdTestUnitReady), scsi_exception);
EXPECT_FALSE(disk->Dispatch(scsi_command::eCmdIcd)) << "Command is not supported by this class";
}
TEST(DiskTest, Rezero)
@ -37,8 +33,10 @@ TEST(DiskTest, Rezero)
controller.AddDevice(disk);
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdRezero), scsi_exception)
<< "REZERO must fail because drive is not ready";
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdRezero); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::NOT_READY),
Property(&scsi_exception::get_asc, asc::MEDIUM_NOT_PRESENT))))
<< "REZERO must fail because drive is not ready";
disk->SetReady(true);
@ -52,32 +50,38 @@ TEST(DiskTest, FormatUnit)
MockAbstractController controller(make_shared<MockBus>(), 0);
auto disk = make_shared<MockDisk>();
controller.AddDevice(disk);
controller.AddDevice(disk);
vector<int>& cmd = controller.GetCmd();
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdFormat), scsi_exception);
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdFormat); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::NOT_READY),
Property(&scsi_exception::get_asc, asc::MEDIUM_NOT_PRESENT))))
<< "FORMAT UNIT must fail because drive is not ready";
disk->SetReady(true);
disk->SetReady(true);
EXPECT_CALL(controller, Status());
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdFormat));
EXPECT_EQ(status::GOOD, controller.GetStatus());
cmd[1] = 0x10;
cmd[4] = 1;
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdFormat), scsi_exception);
cmd[1] = 0x10;
cmd[4] = 1;
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdFormat); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_CDB))));
}
TEST(DiskTest, ReassignBlocks)
{
MockAbstractController controller(make_shared<MockBus>(), 0);
auto disk = make_shared<MockDisk>();
controller.AddDevice(disk);
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdReassign), scsi_exception)
<< "REASSIGN must fail because drive is not ready";
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdReassign); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::NOT_READY),
Property(&scsi_exception::get_asc, asc::MEDIUM_NOT_PRESENT))))
<< "REASSIGN must fail because drive is not ready";
disk->SetReady(true);
@ -95,17 +99,21 @@ TEST(DiskTest, Seek6)
vector<int>& cmd = controller.GetCmd();
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdSeek6), scsi_exception)
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdSeek6); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::LBA_OUT_OF_RANGE))))
<< "SEEK(6) must fail for a medium with 0 blocks";
disk->SetBlockCount(1);
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdSeek6), scsi_exception)
// Block count
cmd[4] = 1;
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdSeek6); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::NOT_READY),
Property(&scsi_exception::get_asc, asc::MEDIUM_NOT_PRESENT))))
<< "SEEK(6) must fail because drive is not ready";
disk->SetReady(true);
// Block count
cmd[4] = 1;
EXPECT_CALL(controller, Status());
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdSeek6));
EXPECT_EQ(status::GOOD, controller.GetStatus());
@ -120,23 +128,60 @@ TEST(DiskTest, Seek10)
vector<int>& cmd = controller.GetCmd();
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdSeek10), scsi_exception)
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdSeek10); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::LBA_OUT_OF_RANGE))))
<< "SEEK(10) must fail for a medium with 0 blocks";
disk->SetBlockCount(1);
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdSeek10), scsi_exception)
// Block count
cmd[5] = 1;
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdSeek10); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::NOT_READY),
Property(&scsi_exception::get_asc, asc::MEDIUM_NOT_PRESENT))))
<< "SEEK(10) must fail because drive is not ready";
disk->SetReady(true);
// Block count
cmd[5] = 1;
EXPECT_CALL(controller, Status());
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdSeek10));
EXPECT_EQ(status::GOOD, controller.GetStatus());
}
TEST(DiskTest, ReadCapacity)
TEST(DiskTest, ReadCapacity10)
{
MockAbstractController controller(make_shared<MockBus>(), 0);
auto disk = make_shared<MockDisk>();
controller.AddDevice(disk);
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdReadCapacity10); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::NOT_READY),
Property(&scsi_exception::get_asc, asc::MEDIUM_NOT_PRESENT))))
<< "READ CAPACITY(10) must fail because drive is not ready";
disk->SetReady(true);
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdReadCapacity10); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::MEDIUM_NOT_PRESENT))))
<< "READ CAPACITY(10) must fail because the medium has no capacity";
disk->SetBlockCount(0x12345678);
EXPECT_CALL(controller, DataIn());
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdReadCapacity10));
auto& buf = controller.GetBuffer();
EXPECT_EQ(0x1234, GetInt16(buf, 0));
EXPECT_EQ(0x5677, GetInt16(buf, 2));
disk->SetBlockCount(0x1234567887654321);
EXPECT_CALL(controller, DataIn());
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdReadCapacity10));
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 disk = make_shared<MockDisk>();
@ -145,59 +190,36 @@ TEST(DiskTest, ReadCapacity)
vector<int>& cmd = controller.GetCmd();
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdReadCapacity16_ReadLong16), scsi_exception)
<< "Neithed READ CAPACITY(16) nor READ LONG(16)";
cmd[1] = 0x00;
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdReadCapacity16_ReadLong16); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_CDB))))
<< "Neither READ CAPACITY(16) nor READ LONG(16)";
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdReadCapacity10), scsi_exception)
<< "READ CAPACITY(10) must fail because drive is not ready";
// READ CAPACITY(16), not READ LONG(16)
cmd[1] = 0x10;
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdReadCapacity16_ReadLong16), scsi_exception)
<< "READ CAPACITY(16) must fail because drive is not ready";
cmd[1] = 0x00;
disk->SetReady(true);
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdReadCapacity10), scsi_exception)
<< "READ CAPACITY(10) must fail because the medium has no capacity";
// READ CAPACITY(16), not READ LONG(16)
cmd[1] = 0x10;
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdReadCapacity16_ReadLong16), scsi_exception)
<< "READ CAPACITY(16) must fail because the medium has no capacity";
cmd[1] = 0x00;
disk->SetBlockCount(0x12345678);
EXPECT_CALL(controller, DataIn());
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdReadCapacity10));
EXPECT_EQ(0x12, controller.GetBuffer()[0]);
EXPECT_EQ(0x34, controller.GetBuffer()[1]);
EXPECT_EQ(0x56, controller.GetBuffer()[2]);
EXPECT_EQ(0x77, controller.GetBuffer()[3]);
disk->SetBlockCount(0x1234567887654321);
EXPECT_CALL(controller, DataIn());
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdReadCapacity10));
EXPECT_EQ(0xff, controller.GetBuffer()[0]);
EXPECT_EQ(0xff, controller.GetBuffer()[1]);
EXPECT_EQ(0xff, controller.GetBuffer()[2]);
EXPECT_EQ(0xff, controller.GetBuffer()[3]);
disk->SetSectorSizeInBytes(1024);
// READ CAPACITY(16), not READ LONG(16)
cmd[1] = 0x10;
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdReadCapacity16_ReadLong16); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::NOT_READY),
Property(&scsi_exception::get_asc, asc::MEDIUM_NOT_PRESENT))))
<< "READ CAPACITY(16) must fail because drive is not ready";
disk->SetReady(true);
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdReadCapacity16_ReadLong16); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::MEDIUM_NOT_PRESENT))))
<< "READ CAPACITY(16) must fail because the medium has no capacity";
disk->SetBlockCount(0x1234567887654321);
disk->SetSectorSizeInBytes(1024);
EXPECT_CALL(controller, DataIn());
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdReadCapacity16_ReadLong16));
EXPECT_EQ(0x12, controller.GetBuffer()[0]);
EXPECT_EQ(0x34, controller.GetBuffer()[1]);
EXPECT_EQ(0x56, controller.GetBuffer()[2]);
EXPECT_EQ(0x78, controller.GetBuffer()[3]);
EXPECT_EQ(0x87, controller.GetBuffer()[4]);
EXPECT_EQ(0x65, controller.GetBuffer()[5]);
EXPECT_EQ(0x43, controller.GetBuffer()[6]);
EXPECT_EQ(0x20, controller.GetBuffer()[7]);
EXPECT_EQ(0x00, controller.GetBuffer()[8]);
EXPECT_EQ(0x00, controller.GetBuffer()[9]);
EXPECT_EQ(0x04, controller.GetBuffer()[10]);
EXPECT_EQ(0x00, controller.GetBuffer()[11]);
const auto& buf = controller.GetBuffer();
EXPECT_EQ(0x1234, GetInt16(buf, 0));
EXPECT_EQ(0x5678, GetInt16(buf, 2));
EXPECT_EQ(0x8765, GetInt16(buf, 4));
EXPECT_EQ(0x4320, GetInt16(buf, 6));
EXPECT_EQ(0x0000, GetInt16(buf, 8));
EXPECT_EQ(0x0400, GetInt16(buf, 10));
}
TEST(DiskTest, Read6)
@ -207,7 +229,9 @@ TEST(DiskTest, Read6)
controller.AddDevice(disk);
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdRead6), scsi_exception)
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdRead6); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::LBA_OUT_OF_RANGE))))
<< "READ(6) must fail for a medium with 0 blocks";
// Further testing requires filesystem access
@ -220,7 +244,9 @@ TEST(DiskTest, Read10)
controller.AddDevice(disk);
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdRead10), scsi_exception)
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdRead10); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::LBA_OUT_OF_RANGE))))
<< "READ(10) must fail for a medium with 0 blocks";
disk->SetBlockCount(1);
@ -238,7 +264,9 @@ TEST(DiskTest, Read16)
controller.AddDevice(disk);
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdRead16), scsi_exception)
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdRead16); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::LBA_OUT_OF_RANGE))))
<< "READ(16) must fail for a medium with 0 blocks";
disk->SetBlockCount(1);
@ -256,7 +284,9 @@ TEST(DiskTest, Write6)
controller.AddDevice(disk);
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdWrite6), scsi_exception)
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdWrite6); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::LBA_OUT_OF_RANGE))))
<< "WRIte(6) must fail for a medium with 0 blocks";
// Further testing requires filesystem access
@ -269,7 +299,9 @@ TEST(DiskTest, Write10)
controller.AddDevice(disk);
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdWrite10), scsi_exception)
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdWrite10); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::LBA_OUT_OF_RANGE))))
<< "WRITE(10) must fail for a medium with 0 blocks";
disk->SetBlockCount(1);
@ -287,7 +319,9 @@ TEST(DiskTest, Write16)
controller.AddDevice(disk);
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdWrite16), scsi_exception)
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdWrite16); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::LBA_OUT_OF_RANGE))))
<< "WRITE(16) must fail for a medium with 0 blocks";
disk->SetBlockCount(1);
@ -305,12 +339,14 @@ TEST(DiskTest, Verify10)
controller.AddDevice(disk);
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdVerify10), scsi_exception)
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdVerify10); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::LBA_OUT_OF_RANGE))))
<< "VERIFY(10) must fail for a medium with 0 blocks";
disk->SetBlockCount(1);
EXPECT_CALL(controller, Status());
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdWrite10));
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdVerify10));
EXPECT_EQ(status::GOOD, controller.GetStatus());
// Further testing requires filesystem access
@ -323,12 +359,14 @@ TEST(DiskTest, Verify16)
controller.AddDevice(disk);
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdVerify16), scsi_exception)
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdVerify16); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::LBA_OUT_OF_RANGE))))
<< "VERIFY(16) must fail for a medium with 0 blocks";
disk->SetBlockCount(1);
EXPECT_CALL(controller, Status());
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdWrite16));
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdVerify16));
EXPECT_EQ(status::GOOD, controller.GetStatus());
// Further testing requires filesystem access
@ -348,12 +386,16 @@ TEST(DiskTest, ReadLong10)
EXPECT_EQ(status::GOOD, controller.GetStatus());
cmd[2] = 1;
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdReadLong10), scsi_exception)
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdReadLong10); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::LBA_OUT_OF_RANGE))))
<< "READ LONG(10) must fail because the capacity is exceeded";
cmd[2] = 0;
cmd[7] = 1;
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdReadLong10), scsi_exception)
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdReadLong10); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_CDB))))
<< "READ LONG(10) must fail because it currently only supports 0 bytes transfer length";
}
@ -369,7 +411,9 @@ TEST(DiskTest, ReadLong16)
// READ LONG(16), not READ CAPACITY(16)
cmd[1] = 0x11;
cmd[2] = 1;
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdReadCapacity16_ReadLong16), scsi_exception)
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdReadCapacity16_ReadLong16); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::LBA_OUT_OF_RANGE))))
<< "READ LONG(16) must fail because the capacity is exceeded";
cmd[2] = 0;
@ -378,7 +422,9 @@ TEST(DiskTest, ReadLong16)
EXPECT_EQ(status::GOOD, controller.GetStatus());
cmd[13] = 1;
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdReadCapacity16_ReadLong16), scsi_exception)
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdReadCapacity16_ReadLong16); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_CDB))))
<< "READ LONG(16) must fail because it currently only supports 0 bytes transfer length";
}
@ -396,12 +442,16 @@ TEST(DiskTest, WriteLong10)
EXPECT_EQ(status::GOOD, controller.GetStatus());
cmd[2] = 1;
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdWriteLong10), scsi_exception)
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdWriteLong10); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::LBA_OUT_OF_RANGE))))
<< "WRITE LONG(10) must fail because the capacity is exceeded";
cmd[2] = 0;
cmd[7] = 1;
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdWriteLong10), scsi_exception)
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdWriteLong10); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_CDB))))
<< "WRITE LONG(10) must fail because it currently only supports 0 bytes transfer length";
}
@ -415,7 +465,9 @@ TEST(DiskTest, WriteLong16)
vector<int>& cmd = controller.GetCmd();
cmd[2] = 1;
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdWriteLong16), scsi_exception)
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdWriteLong16); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::LBA_OUT_OF_RANGE))))
<< "WRITE LONG(16) must fail because the capacity is exceeded";
cmd[2] = 0;
@ -424,7 +476,9 @@ TEST(DiskTest, WriteLong16)
EXPECT_EQ(status::GOOD, controller.GetStatus());
cmd[13] = 1;
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdWriteLong16), scsi_exception)
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdWriteLong16); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_CDB))))
<< "WRITE LONG(16) must fail because it currently only supports 0 bytes transfer length";
}
@ -457,12 +511,16 @@ TEST(DiskTest, StartStopUnit)
disk->SetReady(false);
EXPECT_CALL(*disk, FlushCache).Times(0);
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdStartStop), scsi_exception);
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdStartStop); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::LOAD_OR_EJECT_FAILED))));
disk->SetReady(true);
disk->SetLocked(true);
EXPECT_CALL(*disk, FlushCache).Times(0);
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdStartStop), scsi_exception);
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdStartStop); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::LOAD_OR_EJECT_FAILED))));
// Start/Unload
cmd[4] = 0x01;
@ -487,8 +545,10 @@ TEST(DiskTest, PreventAllowMediumRemoval)
vector<int>& cmd = controller.GetCmd();
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdRemoval), scsi_exception)
<< "REMOVAL must fail because drive is not ready";
EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdRemoval); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::NOT_READY),
Property(&scsi_exception::get_asc, asc::MEDIUM_NOT_PRESENT))))
<< "REMOVAL must fail because drive is not ready";
disk->SetReady(true);

View File

@ -31,10 +31,6 @@ TEST(GpioBusTest, GetCommandByteCount)
EXPECT_EQ(12, GPIOBUS::GetCommandByteCount(0xa0));
opcodes.insert(0xa0);
// TODO Opcode 0x05 must be removed from gpiobus.cpp
EXPECT_EQ(10, GPIOBUS::GetCommandByteCount(0x05));
opcodes.insert(0x05);
for (int i = 0x20; i <= 0x7d; i++) {
EXPECT_EQ(10, GPIOBUS::GetCommandByteCount(i));
opcodes.insert(i);

View File

@ -69,7 +69,9 @@ TEST(HostServicesTest, StartStopUnit)
// START
cmd[4] = 0x01;
EXPECT_THROW(services->Dispatch(scsi_command::eCmdStartStop), scsi_exception);
EXPECT_THAT([&] { services->Dispatch(scsi_command::eCmdStartStop); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_CDB))));
}
TEST(HostServicesTest, ModeSense6)
@ -79,27 +81,31 @@ TEST(HostServicesTest, ModeSense6)
vector<int>& cmd = controller.GetCmd();
EXPECT_THROW(services->Dispatch(scsi_command::eCmdModeSense6), scsi_exception)
<< "Unsupported mode page was returned";
EXPECT_THAT([&] { services->Dispatch(scsi_command::eCmdModeSense6); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_CDB))))
<< "Unsupported mode page was returned";
cmd[2] = 0x20;
EXPECT_THROW(services->Dispatch(scsi_command::eCmdModeSense6), scsi_exception)
<< "Block descriptors are not supported";
EXPECT_THAT([&] { services->Dispatch(scsi_command::eCmdModeSense6); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_CDB))))
<< "Block descriptors are not supported";
cmd[1] = 0x08;
// ALLOCATION LENGTH
cmd[4] = 255;
EXPECT_CALL(controller, DataIn());
EXPECT_TRUE(services->Dispatch(scsi_command::eCmdModeSense6));
vector<BYTE> &buffer = controller.GetBuffer();
// Major version 1
EXPECT_EQ(0x01, buffer[6]);
// Minor version 0
EXPECT_EQ(0x00, buffer[7]);
// Year
EXPECT_NE(0x00, buffer[9]);
// Day
EXPECT_NE(0x00, buffer[10]);
vector<uint8_t>& buffer = controller.GetBuffer();
// Major version 1
EXPECT_EQ(0x01, buffer[6]);
// Minor version 0
EXPECT_EQ(0x00, buffer[7]);
// Year
EXPECT_NE(0x00, buffer[9]);
// Day
EXPECT_NE(0x00, buffer[10]);
// ALLOCATION LENGTH
cmd[4] = 2;
@ -116,27 +122,31 @@ TEST(HostServicesTest, ModeSense10)
vector<int>& cmd = controller.GetCmd();
EXPECT_THROW(services->Dispatch(scsi_command::eCmdModeSense10), scsi_exception)
<< "Unsupported mode page was returned";
EXPECT_THAT([&] { services->Dispatch(scsi_command::eCmdModeSense10); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_CDB))))
<< "Unsupported mode page was returned";
cmd[2] = 0x20;
EXPECT_THROW(services->Dispatch(scsi_command::eCmdModeSense10), scsi_exception)
<< "Block descriptors are not supported";
EXPECT_THAT([&] { services->Dispatch(scsi_command::eCmdModeSense10); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_CDB))))
<< "Block descriptors are not supported";
cmd[1] = 0x08;
// ALLOCATION LENGTH
cmd[8] = 255;
EXPECT_CALL(controller, DataIn());
EXPECT_TRUE(services->Dispatch(scsi_command::eCmdModeSense10));
vector<BYTE> &buffer = controller.GetBuffer();
// Major version 1
EXPECT_EQ(0x01, buffer[10]);
// Minor version 0
EXPECT_EQ(0x00, buffer[11]);
// Year
EXPECT_NE(0x00, buffer[13]);
// Day
EXPECT_NE(0x00, buffer[14]);
vector<uint8_t>& buffer = controller.GetBuffer();
// Major version 1
EXPECT_EQ(0x01, buffer[10]);
// Minor version 0
EXPECT_EQ(0x00, buffer[11]);
// Year
EXPECT_NE(0x00, buffer[13]);
// Day
EXPECT_NE(0x00, buffer[14]);
// ALLOCATION LENGTH
cmd[8] = 2;

View File

@ -60,8 +60,39 @@ class MockBus : public BUS // NOSONAR Having many fields/methods cannot be avoid
MOCK_METHOD(bool, GetSignal, (int), (const override));
MOCK_METHOD(void, SetSignal, (int, bool), (override));
MockBus() = default;
~MockBus() override = default;
MOCK_METHOD(bool, Init, (mode_e), (override));
MOCK_METHOD(void, Reset, (), (override));
MOCK_METHOD(void, Cleanup, (), (override));
MOCK_METHOD(bool, GetBSY, (), (const override));
MOCK_METHOD(void, SetBSY, (bool), (override));
MOCK_METHOD(bool, GetSEL, (), (const override));
MOCK_METHOD(void, SetSEL, (bool), (override));
MOCK_METHOD(bool, GetATN, (), (const override));
MOCK_METHOD(void, SetATN, (bool), (override));
MOCK_METHOD(bool, GetACK, (), (const override));
MOCK_METHOD(void, SetACK, (bool), (override));
MOCK_METHOD(bool, GetRST, (), (const override));
MOCK_METHOD(void, SetRST, (bool), (override));
MOCK_METHOD(bool, GetMSG, (), (const override));
MOCK_METHOD(void, SetMSG, (bool), (override));
MOCK_METHOD(bool, GetCD, (), (const override));
MOCK_METHOD(void, SetCD, (bool), (override));
MOCK_METHOD(bool, GetIO, (), (override));
MOCK_METHOD(void, SetIO, (bool), (override));
MOCK_METHOD(bool, GetREQ, (), (const override));
MOCK_METHOD(void, SetREQ, (bool), (override));
MOCK_METHOD(uint8_t, GetDAT, (), (override));
MOCK_METHOD(void, SetDAT, (uint8_t), (override));
MOCK_METHOD(bool, GetDP, (), (const override));
MOCK_METHOD(uint32_t, Acquire, (), (override));
MOCK_METHOD(int, CommandHandShake, (uint8_t *), (override));
MOCK_METHOD(int, ReceiveHandShake, (uint8_t *, int), (override));
MOCK_METHOD(int, SendHandShake, (uint8_t *, int, int), (override));
MOCK_METHOD(bool, GetSignal, (int), (const override));
MOCK_METHOD(void, SetSignal, (int, bool), (override));
MockBus() = default;
~MockBus() override = default;
};
class MockPhaseHandler : public PhaseHandler
@ -95,7 +126,8 @@ class MockAbstractController : public AbstractController // NOSONAR Having many
FRIEND_TEST(AbstractControllerTest, ExtractInitiatorId);
FRIEND_TEST(AbstractControllerTest, GetOpcode);
FRIEND_TEST(AbstractControllerTest, GetLun);
FRIEND_TEST(AbstractControllerTest, SetLength);
FRIEND_TEST(AbstractControllerTest, Blocks);
FRIEND_TEST(AbstractControllerTest, Length);
FRIEND_TEST(AbstractControllerTest, UpdateOffsetAndLength);
FRIEND_TEST(AbstractControllerTest, Offset);
FRIEND_TEST(PrimaryDeviceTest, Inquiry);
@ -122,7 +154,8 @@ class MockAbstractController : public AbstractController // NOSONAR Having many
FRIEND_TEST(DiskTest, Write16);
FRIEND_TEST(DiskTest, Verify10);
FRIEND_TEST(DiskTest, Verify16);
FRIEND_TEST(DiskTest, ReadCapacity);
FRIEND_TEST(DiskTest, ReadCapacity10);
FRIEND_TEST(DiskTest, ReadCapacity16);
FRIEND_TEST(DiskTest, ReadLong10);
FRIEND_TEST(DiskTest, ReadLong16);
FRIEND_TEST(DiskTest, WriteLong10);
@ -168,6 +201,7 @@ class MockAbstractController : public AbstractController // NOSONAR Having many
// 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
};
class MockScsiController : public ScsiController
@ -196,8 +230,9 @@ class MockScsiController : public ScsiController
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) {}
MockScsiController(shared_ptr<MockBus> bus) : ScsiController(bus, 0) {}
explicit MockScsiController(shared_ptr<MockBus> bus) : ScsiController(bus, 0) {}
~MockScsiController() override = default;
};
@ -253,8 +288,9 @@ class MockModePageDevice : public ModePageDevice
MOCK_METHOD(int, ModeSense6, (const vector<int> &, vector<BYTE> &), (const override));
MOCK_METHOD(int, ModeSense10, (const vector<int> &, vector<BYTE> &), (const override));
explicit MockModePageDevice() : ModePageDevice("test", 0) {}
~MockModePageDevice() override = default;
MOCK_METHOD(vector<byte>, InquiryInternal, (), (const));
MOCK_METHOD(int, ModeSense6, (const vector<int>&, vector<uint8_t>&), (const override));
MOCK_METHOD(int, ModeSense10, (const vector<int>&, vector<uint8_t>&), (const override));
MockModePageDevice() : ModePageDevice(UNDEFINED, 0) {}
~MockModePageDevice() override = default;
@ -296,8 +332,8 @@ public:
MOCK_METHOD(vector<byte>, InquiryInternal, (), (const));
MOCK_METHOD(void, Open, (), (override));
MOCK_METHOD(int, ModeSense6, (const vector<int>&, vector<BYTE>&), (const override));
MOCK_METHOD(int, ModeSense10, (const vector<int>&, vector<BYTE>&), (const override));
MOCK_METHOD(int, ModeSense6, (const vector<int>&, vector<uint8_t>&), (const override));
MOCK_METHOD(int, ModeSense10, (const vector<int>&, vector<uint8_t>&), (const override));
MOCK_METHOD(void, SetUpModePages, ((map<int, vector<byte>>&), int, bool), (const override));
MockStorageDevice() : StorageDevice(UNDEFINED, 0) {}
@ -320,7 +356,8 @@ class MockDisk : public Disk
FRIEND_TEST(DiskTest, Write16);
FRIEND_TEST(DiskTest, Verify10);
FRIEND_TEST(DiskTest, Verify16);
FRIEND_TEST(DiskTest, ReadCapacity);
FRIEND_TEST(DiskTest, ReadCapacity10);
FRIEND_TEST(DiskTest, ReadCapacity16);
FRIEND_TEST(DiskTest, ReadLong10);
FRIEND_TEST(DiskTest, ReadLong16);
FRIEND_TEST(DiskTest, WriteLong10);

View File

@ -26,32 +26,40 @@ TEST(ModePageDeviceTest, SupportsSaveParameters)
TEST(ModePageDeviceTest, AddModePages)
{
vector<int> cdb(6);
vector<BYTE> buf(512);
MockModePageDevice device;
vector<int> cdb(6);
vector<uint8_t> buf(512);
MockModePageDevice device;
// Page 0
cdb[2] = 0x00;
EXPECT_THROW(device.AddModePages(cdb, buf, 0, 12, 255), scsi_exception)
EXPECT_THAT([&] { device.AddModePages(cdb, buf, 0, 12, 255); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_CDB))))
<< "Data were returned for non-existing mode page 0";
// All pages, non changeable
cdb[2] = 0x3f;
EXPECT_EQ(0, device.AddModePages(cdb, buf, 0, 0, 255));
EXPECT_EQ(3, device.AddModePages(cdb, buf, 0, 3, 255));
EXPECT_THROW(device.AddModePages(cdb, buf, 0, 12, -1), scsi_exception) << "Maximum size was ignored";
EXPECT_THAT([&] { device.AddModePages(cdb, buf, 0, 12, -1); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_CDB))))
<< "Maximum size was ignored";
// All pages, changeable
cdb[2]= 0x7f;
EXPECT_EQ(0, device.AddModePages(cdb, buf, 0, 0, 255));
EXPECT_EQ(3, device.AddModePages(cdb, buf, 0, 3, 255));
EXPECT_THROW(device.AddModePages(cdb, buf, 0, 12, -1), scsi_exception) << "Maximum size was ignored";
EXPECT_THAT([&] { device.AddModePages(cdb, buf, 0, 12, -1); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_CDB))))
<< "Maximum size was ignored";
}
TEST(ModePageDeviceTest, Page0)
{
vector<int> cdb(6);
vector<BYTE> buf(512);
vector<uint8_t> buf(512);
MockPage0ModePageDevice device;
cdb[2] = 0x3f;
@ -104,13 +112,17 @@ TEST(ModePageDeviceTest, ModeSense10)
TEST(ModePageDeviceTest, ModeSelect)
{
MockModePageDevice device;
vector<int> cmd;
vector<BYTE> buf;
MockModePageDevice device;
vector<int> cmd;
vector<uint8_t> buf;
EXPECT_THROW(device.ModeSelect(scsi_command::eCmdModeSelect6, cmd, buf, 0), scsi_exception)
EXPECT_THAT([&] { device.ModeSelect(scsi_command::eCmdModeSelect6, cmd, buf, 0); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_COMMAND_OPERATION_CODE))))
<< "Unexpected MODE SELECT(6) default implementation";
EXPECT_THROW(device.ModeSelect(scsi_command::eCmdModeSelect10, cmd, buf, 0), scsi_exception)
EXPECT_THAT([&] { device.ModeSelect(scsi_command::eCmdModeSelect10, cmd, buf, 0); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_COMMAND_OPERATION_CODE))))
<< "Unexpected MODE SELECT(10) default implementation";
}
@ -127,8 +139,10 @@ TEST(ModePageDeviceTest, ModeSelect6)
EXPECT_TRUE(device->Dispatch(scsi_command::eCmdModeSelect6));
cmd[1] = 0x01;
EXPECT_THROW(device->Dispatch(scsi_command::eCmdModeSelect6), scsi_exception)
<< "Saving parameters is not supported for most device types";
EXPECT_THAT([&] { device->Dispatch(scsi_command::eCmdModeSelect6); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_CDB))))
<< "Saving parameters is not supported by base class";
}
TEST(ModePageDeviceTest, ModeSelect10)
@ -144,6 +158,8 @@ TEST(ModePageDeviceTest, ModeSelect10)
EXPECT_TRUE(device->Dispatch(scsi_command::eCmdModeSelect10));
cmd[1] = 0x01;
EXPECT_THROW(device->Dispatch(scsi_command::eCmdModeSelect10), scsi_exception)
<< "Saving parameters is not supported for most device types";
EXPECT_THAT([&] { device->Dispatch(scsi_command::eCmdModeSelect10); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_CDB))))
<< "Saving parameters is not supported for by base class";
}

View File

@ -137,29 +137,39 @@ TEST(PrimaryDeviceTest, TestUnitReady)
controller.AddDevice(device);
device->SetReset(true);
device->SetAttn(true);
device->SetReady(false);
EXPECT_CALL(controller, DataIn()).Times(0);
EXPECT_THROW(device->Dispatch(scsi_command::eCmdTestUnitReady), scsi_exception);
device->SetReset(true);
device->SetAttn(true);
device->SetReady(false);
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_THROW(device->Dispatch(scsi_command::eCmdTestUnitReady), scsi_exception);
device->SetReset(false);
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_THROW(device->Dispatch(scsi_command::eCmdTestUnitReady), scsi_exception);
device->SetReset(true);
device->SetAttn(false);
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_THROW(device->Dispatch(scsi_command::eCmdTestUnitReady), scsi_exception);
device->SetReset(false);
device->SetAttn(true);
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_THROW(device->Dispatch(scsi_command::eCmdTestUnitReady), scsi_exception);
device->SetAttn(false);
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());
@ -212,11 +222,17 @@ TEST(PrimaryDeviceTest, Inquiry)
cmd[1] = 0x01;
EXPECT_CALL(*controller, DataIn()).Times(0);
EXPECT_THROW(device->Dispatch(scsi_command::eCmdInquiry), scsi_exception) << "EVPD bit is not supported";
EXPECT_THAT([&] { device->Dispatch(scsi_command::eCmdInquiry); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_CDB))))
<< "EVPD bit is not supported";
cmd[2] = 0x01;
EXPECT_CALL(*controller, DataIn()).Times(0);
EXPECT_THROW(device->Dispatch(scsi_command::eCmdInquiry), scsi_exception) << "PAGE CODE field is not supported";
EXPECT_THAT([&] { device->Dispatch(scsi_command::eCmdInquiry); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_CDB))))
<< "PAGE CODE field is not supported";
cmd[1] = 0x00;
cmd[2] = 0x00;
@ -240,8 +256,10 @@ TEST(PrimaryDeviceTest, RequestSense)
// ALLOCATION LENGTH
cmd[4] = 255;
device->SetReady(false);
EXPECT_THROW(device->Dispatch(scsi_command::eCmdRequestSense), scsi_exception);
device->SetReady(false);
EXPECT_THAT([&] { device->Dispatch(scsi_command::eCmdRequestSense); }, 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, DataIn());
@ -263,16 +281,22 @@ TEST(PrimaryDeviceTest, SendDiagnostic)
EXPECT_EQ(status::GOOD, controller.GetStatus());
cmd[1] = 0x10;
EXPECT_THROW(device->Dispatch(scsi_command::eCmdSendDiag), scsi_exception)
EXPECT_THAT([&] { device->Dispatch(scsi_command::eCmdSendDiag); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_CDB))))
<< "SEND DIAGNOSTIC must fail because PF bit is not supported";
cmd[1] = 0;
cmd[3] = 1;
EXPECT_THROW(device->Dispatch(scsi_command::eCmdSendDiag), scsi_exception)
EXPECT_THAT([&] { device->Dispatch(scsi_command::eCmdSendDiag); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_CDB))))
<< "SEND DIAGNOSTIC must fail because parameter list is not supported";
cmd[3] = 0;
cmd[4] = 1;
EXPECT_THROW(device->Dispatch(scsi_command::eCmdSendDiag), scsi_exception)
EXPECT_THAT([&] { device->Dispatch(scsi_command::eCmdSendDiag); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_CDB))))
<< "SEND DIAGNOSTIC must fail because parameter list is not supported";
}
@ -296,7 +320,7 @@ TEST(PrimaryDeviceTest, ReportLuns)
EXPECT_CALL(controller, DataIn());
EXPECT_TRUE(device1->Dispatch(scsi_command::eCmdReportLuns));
const vector<BYTE>& buffer = controller.GetBuffer();
const vector<uint8_t>& buffer = controller.GetBuffer();
EXPECT_EQ(0x00, buffer[0]) << "Wrong data length";
EXPECT_EQ(0x00, buffer[1]) << "Wrong data length";
EXPECT_EQ(0x00, buffer[2]) << "Wrong data length";
@ -318,9 +342,11 @@ TEST(PrimaryDeviceTest, ReportLuns)
EXPECT_EQ(0x00, buffer[22]) << "Wrong LUN2 number";
EXPECT_EQ(LUN2, buffer[23]) << "Wrong LUN2 number";
cmd[2] = 0x01;
EXPECT_THROW(device1->Dispatch(scsi_command::eCmdReportLuns), scsi_exception)
<< "Only SELECT REPORT mode 0 is supported";
cmd[2] = 0x01;
EXPECT_THAT([&] { device1->Dispatch(scsi_command::eCmdReportLuns); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_CDB))))
<< "Only SELECT REPORT mode 0 is supported";
}
TEST(PrimaryDeviceTest, UnknownCommand)
@ -345,8 +371,8 @@ TEST(PrimaryDeviceTest, Dispatch)
TEST(PrimaryDeviceTest, WriteByteSequence)
{
vector<BYTE> data;
MockPrimaryDevice device(0);
vector<uint8_t> data;
MockPrimaryDevice device(0);
EXPECT_FALSE(device.WriteByteSequence(data, 0)) << "Primary device does not support writing byte sequences";
}

View File

@ -39,10 +39,10 @@ TEST_F(RascsiExecutorTest, ProcessDeviceCmd)
const int ID = 3;
const int LUN = 0;
shared_ptr<MockBus> bus_ptr = make_shared<MockBus>();
auto bus = make_shared<MockBus>();
DeviceFactory device_factory;
MockAbstractController controller(bus_ptr, ID);
ControllerManager controller_manager(bus_ptr);
MockAbstractController controller(bus, ID);
ControllerManager controller_manager(bus);
RascsiImage rascsi_image;
RascsiResponse rascsi_response(device_factory, controller_manager, 32);
auto executor = make_shared<MockRascsiExecutor>(rascsi_response, rascsi_image, device_factory, controller_manager);
@ -489,10 +489,10 @@ TEST_F(RascsiExecutorTest, ValidateImageFile)
string full_path;
auto device = dynamic_pointer_cast<StorageDevice>(device_factory.CreateDevice(controller_manager, SCHD, 0, "test"));
EXPECT_TRUE(executor.ValidateImageFile(context, device, "", full_path));
EXPECT_TRUE(executor.ValidateImageFile(context, *device, "", full_path));
EXPECT_TRUE(full_path.empty());
EXPECT_FALSE(executor.ValidateImageFile(context, device, "/non_existing_file", full_path));
EXPECT_FALSE(executor.ValidateImageFile(context, *device, "/non_existing_file", full_path));
EXPECT_TRUE(full_path.empty());
}
@ -589,47 +589,47 @@ TEST_F(RascsiExecutorTest, ValidateOperationAgainstDevice)
auto device = make_shared<MockPrimaryDevice>(0);
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, device, ATTACH));
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, device, DETACH));
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, *device, ATTACH));
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, *device, DETACH));
EXPECT_FALSE(executor.ValidateOperationAgainstDevice(context, device, START));
EXPECT_FALSE(executor.ValidateOperationAgainstDevice(context, device, STOP));
EXPECT_FALSE(executor.ValidateOperationAgainstDevice(context, device, INSERT));
EXPECT_FALSE(executor.ValidateOperationAgainstDevice(context, device, EJECT));
EXPECT_FALSE(executor.ValidateOperationAgainstDevice(context, device, PROTECT));
EXPECT_FALSE(executor.ValidateOperationAgainstDevice(context, device, UNPROTECT));
EXPECT_FALSE(executor.ValidateOperationAgainstDevice(context, *device, START));
EXPECT_FALSE(executor.ValidateOperationAgainstDevice(context, *device, STOP));
EXPECT_FALSE(executor.ValidateOperationAgainstDevice(context, *device, INSERT));
EXPECT_FALSE(executor.ValidateOperationAgainstDevice(context, *device, EJECT));
EXPECT_FALSE(executor.ValidateOperationAgainstDevice(context, *device, PROTECT));
EXPECT_FALSE(executor.ValidateOperationAgainstDevice(context, *device, UNPROTECT));
device->SetStoppable(true);
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, device, START));
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, device, STOP));
EXPECT_FALSE(executor.ValidateOperationAgainstDevice(context, device, INSERT));
EXPECT_FALSE(executor.ValidateOperationAgainstDevice(context, device, EJECT));
EXPECT_FALSE(executor.ValidateOperationAgainstDevice(context, device, PROTECT));
EXPECT_FALSE(executor.ValidateOperationAgainstDevice(context, device, UNPROTECT));
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, *device, START));
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, *device, STOP));
EXPECT_FALSE(executor.ValidateOperationAgainstDevice(context, *device, INSERT));
EXPECT_FALSE(executor.ValidateOperationAgainstDevice(context, *device, EJECT));
EXPECT_FALSE(executor.ValidateOperationAgainstDevice(context, *device, PROTECT));
EXPECT_FALSE(executor.ValidateOperationAgainstDevice(context, *device, UNPROTECT));
device->SetRemovable(true);
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, device, START));
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, device, STOP));
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, device, INSERT));
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, device, EJECT));
EXPECT_FALSE(executor.ValidateOperationAgainstDevice(context, device, PROTECT));
EXPECT_FALSE(executor.ValidateOperationAgainstDevice(context, device, UNPROTECT));
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, *device, START));
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, *device, STOP));
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, *device, INSERT));
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, *device, EJECT));
EXPECT_FALSE(executor.ValidateOperationAgainstDevice(context, *device, PROTECT));
EXPECT_FALSE(executor.ValidateOperationAgainstDevice(context, *device, UNPROTECT));
device->SetProtectable(true);
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, device, START));
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, device, STOP));
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, device, INSERT));
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, device, EJECT));
EXPECT_FALSE(executor.ValidateOperationAgainstDevice(context, device, PROTECT));
EXPECT_FALSE(executor.ValidateOperationAgainstDevice(context, device, UNPROTECT));
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, *device, START));
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, *device, STOP));
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, *device, INSERT));
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, *device, EJECT));
EXPECT_FALSE(executor.ValidateOperationAgainstDevice(context, *device, PROTECT));
EXPECT_FALSE(executor.ValidateOperationAgainstDevice(context, *device, UNPROTECT));
device->SetReady(true);
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, device, START));
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, device, STOP));
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, device, INSERT));
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, device, EJECT));
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, device, PROTECT));
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, device, UNPROTECT));
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, *device, START));
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, *device, STOP));
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, *device, INSERT));
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, *device, EJECT));
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, *device, PROTECT));
EXPECT_TRUE(executor.ValidateOperationAgainstDevice(context, *device, UNPROTECT));
}
TEST_F(RascsiExecutorTest, ValidateIdAndLun)
@ -661,26 +661,26 @@ TEST_F(RascsiExecutorTest, SetProductData)
auto device = make_shared<MockPrimaryDevice>(0);
EXPECT_TRUE(executor.SetProductData(context, definition, device));
EXPECT_TRUE(executor.SetProductData(context, definition, *device));
definition.set_vendor("123456789");
EXPECT_FALSE(executor.SetProductData(context, definition, device));
EXPECT_FALSE(executor.SetProductData(context, definition, *device));
definition.set_vendor("1");
EXPECT_TRUE(executor.SetProductData(context, definition, device));
EXPECT_TRUE(executor.SetProductData(context, definition, *device));
definition.set_vendor("12345678");
EXPECT_TRUE(executor.SetProductData(context, definition, device));
EXPECT_TRUE(executor.SetProductData(context, definition, *device));
definition.set_product("12345678901234567");
EXPECT_FALSE(executor.SetProductData(context, definition, device));
EXPECT_FALSE(executor.SetProductData(context, definition, *device));
definition.set_product("1");
EXPECT_TRUE(executor.SetProductData(context, definition, device));
EXPECT_TRUE(executor.SetProductData(context, definition, *device));
definition.set_product("1234567890123456");
EXPECT_TRUE(executor.SetProductData(context, definition, device));
EXPECT_TRUE(executor.SetProductData(context, definition, *device));
definition.set_revision("12345");
EXPECT_FALSE(executor.SetProductData(context, definition, device));
EXPECT_FALSE(executor.SetProductData(context, definition, *device));
definition.set_revision("1");
EXPECT_TRUE(executor.SetProductData(context, definition, device));
EXPECT_TRUE(executor.SetProductData(context, definition, *device));
definition.set_revision("1234");
EXPECT_TRUE(executor.SetProductData(context, definition, device));
EXPECT_TRUE(executor.SetProductData(context, definition, *device));
}

View File

@ -19,11 +19,13 @@ TEST(ScsiCommandUtilTest, ModeSelect6)
const int LENGTH = 26;
vector<int> cdb(6);
vector<BYTE> buf(LENGTH);
vector<uint8_t> buf(LENGTH);
// PF (vendor-specific parameter format)
cdb[1] = 0x00;
EXPECT_THROW(ModeSelect(scsi_command::eCmdModeSelect6, cdb, buf, LENGTH, 0), scsi_exception)
EXPECT_THAT([&] { ModeSelect(scsi_command::eCmdModeSelect6, cdb, buf, LENGTH, 0); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_PARAMETER_LIST))))
<< "Vendor-specific parameters are not supported";
cdb[0] = 0x15;
@ -33,22 +35,30 @@ TEST(ScsiCommandUtilTest, ModeSelect6)
buf[9] = 0x00;
buf[10] = 0x02;
buf[11] = 0x00;
EXPECT_THROW(ModeSelect(scsi_command::eCmdModeSelect6, cdb, buf, LENGTH, 256), scsi_exception)
EXPECT_THAT([&] { ModeSelect(scsi_command::eCmdModeSelect6, cdb, buf, LENGTH, 256); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_PARAMETER_LIST))))
<< "Requested sector size does not match current sector size";
// Page 0
buf[12] = 0x00;
EXPECT_THROW(ModeSelect(scsi_command::eCmdModeSelect6, cdb, buf, LENGTH, 512), scsi_exception)
EXPECT_THAT([&] { ModeSelect(scsi_command::eCmdModeSelect6, cdb, buf, LENGTH, 512); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_PARAMETER_LIST))))
<< "Unsupported page 0 was not rejected";
// Page 3 (Format Device Page)
buf[12] = 0x03;
EXPECT_THROW(ModeSelect(scsi_command::eCmdModeSelect6, cdb, buf, LENGTH, 512), scsi_exception)
EXPECT_THAT([&] { ModeSelect(scsi_command::eCmdModeSelect6, cdb, buf, LENGTH, 512); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_PARAMETER_LIST))))
<< "Requested sector size does not match current sector size";
// Match the requested to the current sector size
buf[24] = 0x02;
EXPECT_THROW(ModeSelect(scsi_command::eCmdModeSelect6, cdb, buf, LENGTH - 1, 512), scsi_exception)
EXPECT_THAT([&] { ModeSelect(scsi_command::eCmdModeSelect6, cdb, buf, LENGTH - 1, 512); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_PARAMETER_LIST))))
<< "Not enough command parameters";
ModeSelect(scsi_command::eCmdModeSelect6, cdb, buf, LENGTH, 512);
@ -59,11 +69,13 @@ TEST(ScsiCommandUtilTest, ModeSelect10)
const int LENGTH = 30;
vector<int> cdb(10);
vector<BYTE> buf(LENGTH);
vector<uint8_t> buf(LENGTH);
// PF (vendor-specific parameter format)
cdb[1] = 0x00;
EXPECT_THROW(ModeSelect(scsi_command::eCmdModeSelect10, cdb, buf, LENGTH, 0), scsi_exception)
EXPECT_THAT([&] { ModeSelect(scsi_command::eCmdModeSelect10, cdb, buf, LENGTH, 0); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_PARAMETER_LIST))))
<< "Vendor-specific parameters are not supported";
// PF (standard parameter format)
@ -72,22 +84,30 @@ TEST(ScsiCommandUtilTest, ModeSelect10)
buf[13] = 0x00;
buf[14] = 0x02;
buf[15] = 0x00;
EXPECT_THROW(ModeSelect(scsi_command::eCmdModeSelect10, cdb, buf, LENGTH, 256), scsi_exception)
EXPECT_THAT([&] { ModeSelect(scsi_command::eCmdModeSelect10, cdb, buf, LENGTH, 256); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_PARAMETER_LIST))))
<< "Requested sector size does not match current sector size";
// Page 0
buf[16] = 0x00;
EXPECT_THROW(ModeSelect(scsi_command::eCmdModeSelect10, cdb, buf, LENGTH, 512), scsi_exception)
EXPECT_THAT([&] { ModeSelect(scsi_command::eCmdModeSelect10, cdb, buf, LENGTH, 512); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_PARAMETER_LIST))))
<< "Unsupported page 0 was not rejected";
// Page 3 (Format Device Page)
buf[16] = 0x03;
EXPECT_THROW(ModeSelect(scsi_command::eCmdModeSelect10, cdb, buf, LENGTH, 512), scsi_exception)
EXPECT_THAT([&] { ModeSelect(scsi_command::eCmdModeSelect10, cdb, buf, LENGTH, 512); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_PARAMETER_LIST))))
<< "Requested sector size does not match current sector size";
// Match the requested to the current sector size
buf[28] = 0x02;
EXPECT_THROW(ModeSelect(scsi_command::eCmdModeSelect10, cdb, buf, LENGTH - 1, 512), scsi_exception)
EXPECT_THAT([&] { ModeSelect(scsi_command::eCmdModeSelect10, cdb, buf, LENGTH - 1, 512); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_PARAMETER_LIST))))
<< "Not enough command parameters";
ModeSelect(scsi_command::eCmdModeSelect10, cdb, buf, LENGTH, 512);
@ -129,7 +149,7 @@ TEST(ScsiCommandUtilTest, AddAppleVendorModePage)
TEST(ScsiCommandUtilTest, GetInt16)
{
vector<BYTE> b = { 0xfe, 0xdc };
vector<uint8_t> b = { 0xfe, 0xdc };
EXPECT_EQ(0xfedc, GetInt16(b, 0));
vector<int> v = { 0x12, 0x34 };
@ -164,7 +184,7 @@ TEST(ScsiCommandUtilTest, SetInt16)
TEST(ScsiCommandUtilTest, SetInt32)
{
vector<BYTE> buf(4);
vector<uint8_t> buf(4);
SetInt32(buf, 0, 0x12345678);
EXPECT_EQ(0x12, buf[0]);
EXPECT_EQ(0x34, buf[1]);
@ -181,7 +201,7 @@ TEST(ScsiCommandUtilTest, SetInt32)
TEST(ScsiCommandUtilTest, SetInt64)
{
vector<BYTE> buf(8);
vector<uint8_t> buf(8);
SetInt64(buf, 0, 0x1234567887654321);
EXPECT_EQ(0x12, buf[0]);
EXPECT_EQ(0x34, buf[1]);

View File

@ -19,7 +19,7 @@ TEST(ScsiControllerTest, GetInitiatorId)
{
const int ID = 2;
MockScsiController controller(make_shared<MockBus>());
MockScsiController controller(make_shared<NiceMock<MockBus>>());
controller.Process(ID);
EXPECT_EQ(ID, controller.GetInitiatorId());
@ -56,7 +56,7 @@ TEST(ScsiControllerTest, Process)
TEST(ScsiControllerTest, BusFree)
{
MockScsiController controller(make_shared<MockBus>());
MockScsiController controller(make_shared<NiceMock<MockBus>>());
controller.SetPhase(BUS::phase_t::busfree);
controller.BusFree();
@ -87,7 +87,7 @@ TEST(ScsiControllerTest, BusFree)
TEST(ScsiControllerTest, Selection)
{
auto bus = make_shared<MockBus>();
auto bus = make_shared<NiceMock<MockBus>>();
MockScsiController controller(bus, 0);
controller.SetPhase(BUS::phase_t::selection);
@ -100,6 +100,7 @@ TEST(ScsiControllerTest, Selection)
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());
@ -142,10 +143,11 @@ TEST(ScsiControllerTest, Selection)
TEST(ScsiControllerTest, Command)
{
auto bus = make_shared<MockBus>();
auto bus = make_shared<NiceMock<MockBus>>();
MockScsiController controller(bus, 0);
controller.SetPhase(BUS::phase_t::command);
EXPECT_CALL(controller, Status);
controller.Command();
EXPECT_EQ(BUS::phase_t::command, controller.GetPhase());
@ -168,7 +170,7 @@ TEST(ScsiControllerTest, Command)
TEST(ScsiControllerTest, MsgIn)
{
auto bus = make_shared<MockBus>();
auto bus = make_shared<NiceMock<MockBus>>();
MockScsiController controller(bus, 0);
controller.SetPhase(BUS::phase_t::reserved);
@ -183,7 +185,7 @@ TEST(ScsiControllerTest, MsgIn)
TEST(ScsiControllerTest, MsgOut)
{
auto bus = make_shared<MockBus>();
auto bus = make_shared<NiceMock<MockBus>>();
MockScsiController controller(bus, 0);
controller.SetPhase(BUS::phase_t::reserved);
@ -198,7 +200,7 @@ TEST(ScsiControllerTest, MsgOut)
TEST(ScsiControllerTest, DataIn)
{
auto bus = make_shared<MockBus>();
auto bus = make_shared<NiceMock<MockBus>>();
MockScsiController controller(bus, 0);
controller.SetPhase(BUS::phase_t::reserved);
@ -218,7 +220,7 @@ TEST(ScsiControllerTest, DataIn)
TEST(ScsiControllerTest, DataOut)
{
auto bus = make_shared<MockBus>();
auto bus = make_shared<NiceMock<MockBus>>();
MockScsiController controller(bus, 0);
controller.SetPhase(BUS::phase_t::reserved);
@ -238,7 +240,7 @@ TEST(ScsiControllerTest, DataOut)
TEST(ScsiControllerTest, Error)
{
auto bus = make_shared<MockBus>();
auto bus = make_shared<NiceMock<MockBus>>();
MockScsiController controller(bus, 0);
ON_CALL(*bus, GetRST).WillByDefault(Return(true));
@ -281,7 +283,7 @@ TEST(ScsiControllerTest, Error)
TEST(ScsiControllerTest, RequestSense)
{
MockScsiController controller(make_shared<MockBus>());
MockScsiController controller(make_shared<NiceMock<MockBus>>());
auto device = make_shared<MockPrimaryDevice>(0);
controller.AddDevice(device);

View File

@ -22,16 +22,6 @@ TEST(ScsiDaynaportTest, Dispatch)
auto daynaport = CreateDevice(SCDP, controller);
EXPECT_FALSE(daynaport->Dispatch(scsi_command::eCmdIcd)) << "Command is not supported by this class";
// TODO Remove tests below as soon as Daynaport does not inherit from Disk anymore
EXPECT_FALSE(daynaport->Dispatch(scsi_command::eCmdModeSense6))
<< "Non-DaynaPort commands inherited from Disk must not be supported";
EXPECT_FALSE(daynaport->Dispatch(scsi_command::eCmdModeSelect6))
<< "Non-DaynaPort commands inherited from Disk must not be supported";
EXPECT_FALSE(daynaport->Dispatch(scsi_command::eCmdModeSense10))
<< "Non-DaynaPort commands inherited from Disk must not be supported";
EXPECT_FALSE(daynaport->Dispatch(scsi_command::eCmdModeSelect10))
<< "Non-DaynaPort commands inherited from Disk must not be supported";
}
TEST(ScsiDaynaportTest, TestUnitReady)
@ -46,7 +36,7 @@ TEST(ScsiDaynaportTest, TestUnitReady)
TEST(ScsiDaynaportTest, Read)
{
vector<BYTE> buf(0);
vector<uint8_t> buf(0);
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
auto daynaport = dynamic_pointer_cast<SCSIDaynaPort>(CreateDevice(SCDP, controller));
@ -57,18 +47,9 @@ TEST(ScsiDaynaportTest, Read)
EXPECT_EQ(0, daynaport->Read(cmd, buf, 0)) << "Trying to read the root sector must fail";
}
TEST(ScsiDaynaportTest, WriteCheck)
{
vector<BYTE> buf(0);
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
auto daynaport = dynamic_pointer_cast<SCSIDaynaPort>(CreateDevice(SCDP, controller));
EXPECT_THROW(daynaport->WriteCheck(0), scsi_exception);
}
TEST(ScsiDaynaportTest, WriteBytes)
{
vector<BYTE> buf(0);
vector<uint8_t> buf(0);
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
auto daynaport = dynamic_pointer_cast<SCSIDaynaPort>(CreateDevice(SCDP, controller));
@ -87,7 +68,10 @@ TEST(ScsiDaynaportTest, Read6)
vector<int>& cmd = controller.GetCmd();
cmd[5] = 0xff;
EXPECT_THROW(daynaport->Dispatch(scsi_command::eCmdRead6), scsi_exception) << "Invalid data format";
EXPECT_THAT([&] { daynaport->Dispatch(scsi_command::eCmdRead6); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_CDB))))
<< "Invalid data format";
}
TEST(ScsiDaynaportTest, Write6)
@ -98,17 +82,26 @@ TEST(ScsiDaynaportTest, Write6)
vector<int>& cmd = controller.GetCmd();
cmd[5] = 0x00;
EXPECT_THROW(daynaport->Dispatch(scsi_command::eCmdWrite6), scsi_exception) << "Invalid transfer length";
EXPECT_THAT([&] { daynaport->Dispatch(scsi_command::eCmdWrite6); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_CDB))))
<< "Invalid transfer length";
cmd[3] = -1;
cmd[4] = -8;
cmd[5] = 0x80;
EXPECT_THROW(daynaport->Dispatch(scsi_command::eCmdWrite6), scsi_exception) << "Invalid transfer length";
EXPECT_THAT([&] { daynaport->Dispatch(scsi_command::eCmdWrite6); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_CDB))))
<< "Invalid transfer length";
cmd[3] = 0;
cmd[4] = 0;
cmd[5] = 0xff;
EXPECT_THROW(daynaport->Dispatch(scsi_command::eCmdWrite6), scsi_exception) << "Invalid transfer length";
EXPECT_THAT([&] { daynaport->Dispatch(scsi_command::eCmdWrite6); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_CDB))))
<< "Invalid transfer length";
}
TEST(ScsiDaynaportTest, TestRetrieveStats)
@ -131,8 +124,10 @@ TEST(ScsiDaynaportTest, SetInterfaceMode)
vector<int>& cmd = controller.GetCmd();
// Unknown interface command
EXPECT_THROW(daynaport->Dispatch(scsi_command::eCmdSetIfaceMode), scsi_exception);
// Unknown interface command
EXPECT_THAT([&] { daynaport->Dispatch(scsi_command::eCmdSetIfaceMode); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_COMMAND_OPERATION_CODE))));
// Not implemented, do nothing
cmd[5] = SCSIDaynaPort::CMD_SCSILINK_SETMODE;
@ -144,17 +139,23 @@ TEST(ScsiDaynaportTest, SetInterfaceMode)
EXPECT_CALL(controller, DataOut());
EXPECT_TRUE(daynaport->Dispatch(scsi_command::eCmdSetIfaceMode));
// Not implemented
cmd[5] = SCSIDaynaPort::CMD_SCSILINK_STATS;
EXPECT_THROW(daynaport->Dispatch(scsi_command::eCmdSetIfaceMode), scsi_exception);
// Not implemented
cmd[5] = SCSIDaynaPort::CMD_SCSILINK_STATS;
EXPECT_THAT([&] { daynaport->Dispatch(scsi_command::eCmdSetIfaceMode); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_COMMAND_OPERATION_CODE))));
// Not implemented
cmd[5] = SCSIDaynaPort::CMD_SCSILINK_ENABLE;
EXPECT_THROW(daynaport->Dispatch(scsi_command::eCmdSetIfaceMode), scsi_exception);
// Not implemented
cmd[5] = SCSIDaynaPort::CMD_SCSILINK_ENABLE;
EXPECT_THAT([&] { daynaport->Dispatch(scsi_command::eCmdSetIfaceMode); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_COMMAND_OPERATION_CODE))));
// Not implemented
cmd[5] = SCSIDaynaPort::CMD_SCSILINK_SET;
EXPECT_THROW(daynaport->Dispatch(scsi_command::eCmdSetIfaceMode), scsi_exception);
// Not implemented
cmd[5] = SCSIDaynaPort::CMD_SCSILINK_SET;
EXPECT_THAT([&] { daynaport->Dispatch(scsi_command::eCmdSetIfaceMode); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_COMMAND_OPERATION_CODE))));
}
TEST(ScsiDaynaportTest, SetMcastAddr)
@ -164,7 +165,10 @@ TEST(ScsiDaynaportTest, SetMcastAddr)
vector<int>& cmd = controller.GetCmd();
EXPECT_THROW(daynaport->Dispatch(scsi_command::eCmdSetMcastAddr), scsi_exception) << "Length of 0 is not supported";
EXPECT_THAT([&] { daynaport->Dispatch(scsi_command::eCmdSetMcastAddr); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_CDB))))
<< "Length of 0 is not supported";
cmd[4] = 1;
EXPECT_CALL(controller, DataOut());
@ -178,12 +182,16 @@ TEST(ScsiDaynaportTest, EnableInterface)
vector<int>& cmd = controller.GetCmd();
// Enable
EXPECT_THROW(daynaport->Dispatch(scsi_command::eCmdEnableInterface), scsi_exception);
// Enable
EXPECT_THAT([&] { daynaport->Dispatch(scsi_command::eCmdEnableInterface); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ABORTED_COMMAND),
Property(&scsi_exception::get_asc, asc::NO_ADDITIONAL_SENSE_INFORMATION))));
// Disable
cmd[5] = 0x80;
EXPECT_THROW(daynaport->Dispatch(scsi_command::eCmdEnableInterface), scsi_exception);
// Disable
cmd[5] = 0x80;
EXPECT_THAT([&] { daynaport->Dispatch(scsi_command::eCmdEnableInterface); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ABORTED_COMMAND),
Property(&scsi_exception::get_asc, asc::NO_ADDITIONAL_SENSE_INFORMATION))));
}
TEST(ScsiDaynaportTest, GetSendDelay)

View File

@ -91,7 +91,10 @@ TEST(ScsiPrinterTest, Print)
cmd[3] = 0xff;
cmd[4] = 0xff;
EXPECT_THROW(printer->Dispatch(scsi_command::eCmdPrint), scsi_exception) << "Buffer overflow was not reported";
EXPECT_THAT([&] { printer->Dispatch(scsi_command::eCmdPrint); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST),
Property(&scsi_exception::get_asc, asc::INVALID_FIELD_IN_CDB))))
<< "Buffer overflow was not reported";
}
TEST(ScsiPrinterTest, StopPrint)
@ -109,7 +112,10 @@ TEST(ScsiPrinterTest, SynchronizeBuffer)
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
auto printer = CreateDevice(SCLP, controller);
EXPECT_THROW(printer->Dispatch(scsi_command::eCmdSynchronizeBuffer), scsi_exception) << "Nothing to print";
EXPECT_THAT([&] { printer->Dispatch(scsi_command::eCmdSynchronizeBuffer); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::ABORTED_COMMAND),
Property(&scsi_exception::get_asc, asc::NO_ADDITIONAL_SENSE_INFORMATION))))
<< "Nothing to print";
// Further testing would use the printing system
}
@ -119,7 +125,7 @@ TEST(ScsiPrinterTest, WriteByteSequence)
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
auto printer = dynamic_pointer_cast<SCSIPrinter>(CreateDevice(SCLP, controller));
vector<BYTE> buf(1);
vector<uint8_t> buf(1);
EXPECT_TRUE(printer->WriteByteSequence(buf, buf.size()));
printer->Cleanup();
}

View File

@ -123,7 +123,9 @@ TEST(ScsiCdTest, ReadToc)
controller.AddDevice(cd);
EXPECT_THROW(cd->Dispatch(scsi_command::eCmdReadToc), scsi_exception) << "Drive is not ready";
EXPECT_THAT([&] { cd->Dispatch(scsi_command::eCmdReadToc); }, Throws<scsi_exception>(AllOf(
Property(&scsi_exception::get_sense_key, sense_key::NOT_READY),
Property(&scsi_exception::get_asc, asc::MEDIUM_NOT_PRESENT))));
// Further testing requires filesystem access
}

View File

@ -57,14 +57,14 @@ TEST(ScsiHdNecTest, TestAddFormatPage)
hd.SetUpModePages(pages, 0x03, false);
EXPECT_EQ(1, pages.size()) << "Unexpected number of mode pages";
vector<byte>& page_3 = pages[3];
EXPECT_EQ(0x80, (int)page_3[0] & 0x80);
EXPECT_EQ(0, (int)page_3[20]);
EXPECT_EQ(0x80, to_integer<int>(page_3[0]) & 0x80);
EXPECT_EQ(0, to_integer<int>(page_3[20]));
hd.SetRemovable(true);
// Non changeable
hd.SetUpModePages(pages, 0x03, false);
page_3 = pages[3];
EXPECT_EQ(0x20, (int)page_3[20]);
EXPECT_EQ(0x20, to_integer<int>(page_3[20]));
pages.clear();
// Changeable

View File

@ -97,7 +97,7 @@ TEST(ScsiHdTest, ModeSelect)
const unordered_set<uint32_t> sector_sizes = { 512 };
MockSCSIHD hd(0, sector_sizes, false);
vector<int> cmd(10);
vector<BYTE> buf(255);
vector<uint8_t> buf(255);
hd.SetSectorSizeInBytes(512);

View File

@ -65,8 +65,8 @@ TEST(ScsiMoTest, TestAddVendorPage)
EXPECT_EQ(1, pages.size()) << "Unexpected number of mode pages";
vector<byte>& page_32 = pages[32];
EXPECT_EQ(12, page_32.size());
EXPECT_EQ(0, (int)page_32[2]) << "Wrong format mode";
EXPECT_EQ(0, (int)page_32[3]) << "Wrong format type";
EXPECT_EQ(0, to_integer<int>(page_32[2])) << "Wrong format mode";
EXPECT_EQ(0, to_integer<int>(page_32[3])) << "Wrong format type";
EXPECT_EQ(0x12345678, GetInt32(page_32, 4)) << "Wrong number of blocks";
EXPECT_EQ(0, GetInt16(page_32, 8)) << "Wrong number of spare blocks";
EXPECT_EQ(0, GetInt16(page_32, 10));
@ -116,8 +116,8 @@ TEST(ScsiMoTest, TestAddVendorPage)
// Changeable page
mo.SetUpModePages(pages, 0x20, true);
EXPECT_EQ(0, (int)page_32[2]);
EXPECT_EQ(0, (int)page_32[3]);
EXPECT_EQ(0, to_integer<int>(page_32[2]));
EXPECT_EQ(0, to_integer<int>(page_32[3]));
EXPECT_EQ(0, GetInt32(page_32, 4));
EXPECT_EQ(0, GetInt16(page_32, 8));
EXPECT_EQ(0, GetInt16(page_32, 10));
@ -128,7 +128,7 @@ TEST(ScsiMoTest, ModeSelect)
const unordered_set<uint32_t> sector_sizes = { 1024, 2048 };
MockSCSIMO mo(0, sector_sizes);
vector<int> cmd(10);
vector<BYTE> buf(255);
vector<uint8_t> buf(255);
mo.SetSectorSizeInBytes(2048);

View File

@ -19,8 +19,7 @@ using namespace filesystem;
shared_ptr<PrimaryDevice> CreateDevice(PbDeviceType type, MockAbstractController& controller, const string& extension)
{
DeviceFactory device_factory;
auto bus = make_shared<MockBus>();
auto controller_manager = make_shared<ControllerManager>(bus);
auto controller_manager = make_shared<ControllerManager>(controller.GetBus());
auto device = device_factory.CreateDevice(*controller_manager, type, 0, extension);
@ -41,11 +40,11 @@ void TestInquiry(PbDeviceType type, device_type t, scsi_level l, const string& i
cmd[4] = 255;
EXPECT_CALL(controller, DataIn());
EXPECT_TRUE(device->Dispatch(scsi_command::eCmdInquiry));
const vector<BYTE>& buffer = controller.GetBuffer();
EXPECT_EQ((int)t, buffer[0]);
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((int)l, buffer[2]);
EXPECT_EQ((int)l > (int)scsi_level::SCSI_2 ? (int)scsi_level::SCSI_2 : (int)l, buffer[3]);
EXPECT_EQ(l, static_cast<scsi_level>(buffer[2]));
EXPECT_EQ(l > scsi_level::SCSI_2 ? scsi_level::SCSI_2 : l, static_cast<scsi_level>(buffer[3]));
EXPECT_EQ(additional_length, buffer[4]);
string product_data;
if (ident.size() == 24) {
@ -93,15 +92,15 @@ path CreateTempFile(int size)
int GetInt16(const vector<byte>& buf, int offset)
{
assert(buf.size() > (size_t)offset + 1);
assert(buf.size() > static_cast<size_t>(offset) + 1);
return ((int)buf[offset] << 8) | (int)buf[offset + 1];
return (to_integer<int>(buf[offset]) << 8) | to_integer<int>(buf[offset + 1]);
}
uint32_t GetInt32(const vector<byte>& buf, int offset)
{
assert(buf.size() > (size_t)offset + 3);
assert(buf.size() > static_cast<size_t>(offset) + 3);
return ((uint32_t)buf[offset] << 24) | ((uint32_t)buf[offset + 1] << 16) |
((uint32_t)buf[offset + 2] << 8) | (uint32_t)buf[offset + 3];
return (to_integer<uint32_t>(buf[offset]) << 24) | (to_integer<uint32_t>(buf[offset + 1]) << 16) |
(to_integer<uint32_t>(buf[offset + 2]) << 8) | to_integer<uint32_t>(buf[offset + 3]);
}

View File

@ -28,7 +28,7 @@ RUN ./easyinstall.sh --run_choice=11
RUN ./easyinstall.sh --run_choice=13
# Setup wired network bridge
RUN ./easyinstall.sh --run_choice=6 --headless
RUN ./easyinstall.sh --run_choice=5 --headless
USER root
WORKDIR /home/pi

View File

@ -58,13 +58,13 @@ PYTHON_COMMON_PATH="$BASE/python/common"
SYSTEMD_PATH="/etc/systemd/system"
SSL_CERTS_PATH="/etc/ssl/certs"
SSL_KEYS_PATH="/etc/ssl/private"
HFS_FORMAT=/usr/bin/hformat
HFDISK_BIN=/usr/bin/hfdisk
LIDO_DRIVER=$BASE/lido-driver.img
GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
GIT_REMOTE=${GIT_REMOTE:-origin}
TOKEN=""
SECRET_FILE="$HOME/.config/rascsi/rascsi_secret"
FILE_SHARE_PATH="$HOME/shared_files"
FILE_SHARE_NAME="Pi File Server"
set -e
@ -106,7 +106,10 @@ function installPackages() {
unar \
disktype \
libgmock-dev \
man2html
man2html \
hfsutils \
dosfstools \
kpartx
}
# install Debian packges for RaSCSI standalone
@ -593,98 +596,30 @@ function createDriveCustom() {
createDrive "$driveSize" "$driveName"
}
# Creates an HFS file system
function formatDrive() {
diskPath="$1"
volumeName="$2"
if [ ! -x $HFS_FORMAT ]; then
# Install hfsutils to have hformat to format HFS
sudo apt-get install hfsutils --assume-yes </dev/null
fi
if [ ! -x $HFDISK_BIN ]; then
# Clone, compile and install 'hfdisk', partition tool
git clone git://www.codesrc.com/git/hfdisk.git
cd hfdisk || exit 1
# Clone, compile and install 'hfdisk', partition tool
function installHfdisk() {
HFDISK_VERSION="2022.11"
if [ ! -x "$HFDISK_BIN" ]; then
cd "$BASE" || exit 1
wget -O "hfdisk-$HFDISK_VERSION.tar.gz" "https://github.com/rdmark/hfdisk/archive/refs/tags/$HFDISK_VERSION.tar.gz" </dev/null
tar -xzvf "hfdisk-$HFDISK_VERSION.tar.gz"
rm "hfdisk-$HFDISK_VERSION.tar.gz"
cd "hfdisk-$HFDISK_VERSION" || exit 1
make
sudo cp hfdisk /usr/bin/hfdisk
fi
sudo cp hfdisk "$HFDISK_BIN"
# Inject hfdisk commands to create Drive with correct partitions
# https://www.codesrc.com/mediawiki/index.php/HFSFromScratch
# i initialize partition map
# continue with default first block
# C Create 1st partition with type specified next)
# continue with default
# 32 32 blocks (required for HFS+)
# Driver_Partition Partition Name
# Apple_Driver Partition Type (available types: Apple_Driver, Apple_Driver43, Apple_Free, Apple_HFS...)
# C Create 2nd partition with type specified next
# continue with default first block
# continue with default block size (rest of the disk)
# ${volumeName} Partition name provided by user
# Apple_HFS Partition Type
# w Write partition map to disk
# y Confirm partition table
# p Print partition map
(echo i; echo ; echo C; echo ; echo 32; echo "Driver_Partition"; echo "Apple_Driver"; echo C; echo ; echo ; echo "${volumeName}"; echo "Apple_HFS"; echo w; echo y; echo p;) | $HFDISK_BIN "$diskPath"
partitionOk=$?
if [ $partitionOk -eq 0 ]; then
if [ ! -f "$LIDO_DRIVER" ];then
echo "Lido driver couldn't be found. Make sure RaSCSI is up-to-date with git pull"
return 1
fi
# Burn Lido driver to the disk
dd if="$LIDO_DRIVER" of="$diskPath" seek=64 count=32 bs=512 conv=notrunc
driverInstalled=$?
if [ $driverInstalled -eq 0 ]; then
# Format the partition with HFS file system
$HFS_FORMAT -l "${volumeName}" "$diskPath" 1
hfsFormattedOk=$?
if [ $hfsFormattedOk -eq 0 ]; then
echo "Disk created with success."
else
echo "Unable to format HFS partition."
return 4
fi
else
echo "Unable to install Lido Driver."
return 3
fi
else
echo "Unable to create the partition."
return 2
echo "Installed $HFDISK_BIN"
fi
}
# Creates an image file
function createDrive() {
if [ $# -ne 2 ]; then
echo "To create a Drive, volume size and volume name must be provided"
echo "$ createDrive 600 \"RaSCSI Drive\""
echo "Drive wasn't created."
return
fi
driveSize=$1
driveName=$2
mkdir -p "$VIRTUAL_DRIVER_PATH"
drivePath="${VIRTUAL_DRIVER_PATH}/${driveSize}M.hda"
if [ ! -f "$drivePath" ]; then
echo "Creating a ${driveSize}MiB Drive"
truncate --size "${driveSize}m" "$drivePath"
echo "Formatting drive with HFS"
formatDrive "$drivePath" "$driveName"
else
echo "Error: drive already exists"
# Fetch HFS drivers that the Web Interface uses
function fetchHardDiskDrivers() {
if [ ! -f "$BASE/mac-hard-disk-drivers" ]; then
cd "$BASE" || exit 1
wget https://macintoshgarden.org/sites/macintoshgarden.org/files/apps/mac-hard-disk-drivers.zip
unzip -d mac-hard-disk-drivers mac-hard-disk-drivers.zip
rm mac-hard-disk-drivers.zip
fi
}
@ -837,14 +772,12 @@ function setupWirelessNetworking() {
# Downloads, compiles, and installs Netatalk (AppleShare server)
function installNetatalk() {
NETATALK_VERSION="2-220801"
AFP_SHARE_PATH="$HOME/afpshare"
AFP_SHARE_NAME="Pi File Server"
NETATALK_CONFIG_PATH="/etc/netatalk"
if [ -d "$NETATALK_CONFIG_PATH" ]; then
echo
echo "WARNING: Netatalk configuration dir $NETATALK_CONFIG_PATH already exists."
echo "This installation process will overwrite existing Netatalk applications and configurations."
echo "This installation process will overwrite existing binaries and configurations."
echo "No shared files will be deleted, but you may have to manually restore your settings after the installation."
echo
echo "Do you want to proceed with the installation? [y/N]"
@ -854,13 +787,27 @@ function installNetatalk() {
fi
fi
if [ ! -d "$FILE_SHARE_PATH" ] && [ -d "$HOME/afpshare" ]; then
echo
echo "File server dir $HOME/afpshare detected. This script will rename it to $FILE_SHARE_PATH."
echo
echo "Do you want to proceed with the installation? [y/N]"
read -r REPLY
if [ "$REPLY" == "y" ] || [ "$REPLY" == "Y" ]; then
sudo mv "$HOME/afpshare" "$FILE_SHARE_PATH" || exit 1
else
exit 0
fi
fi
echo "Downloading netatalk-$NETATALK_VERSION to $HOME"
cd $HOME || exit 1
wget -O "netatalk-$NETATALK_VERSION.tar.gz" "https://github.com/rdmark/Netatalk-2.x/archive/refs/tags/netatalk-$NETATALK_VERSION.tar.gz" </dev/null
tar -xzvf netatalk-$NETATALK_VERSION.tar.gz
tar -xzvf "netatalk-$NETATALK_VERSION.tar.gz"
rm "netatalk-$NETATALK_VERSION.tar.gz"
cd "$HOME/Netatalk-2.x-netatalk-$NETATALK_VERSION/contrib/shell_utils" || exit 1
./debian_install.sh -j="${CORES:-1}" -n="$AFP_SHARE_NAME" -p="$AFP_SHARE_PATH" || exit 1
./debian_install.sh -j="${CORES:-1}" -n="$FILE_SHARE_NAME" -p="$FILE_SHARE_PATH" || exit 1
}
# Appends the images dir as a shared Netatalk volume
@ -938,6 +885,65 @@ function installMacproxy {
echo ""
}
# Installs and configures Samba (SMB server)
function installSamba() {
SAMBA_CONFIG_PATH="/etc/samba"
if [ -d "$SAMBA_CONFIG_PATH" ]; then
echo
echo "Samba configuration dir $SAMBA_CONFIG_PATH already exists."
echo "This installation process may overwrite existing binaries and configurations."
echo "No shared files will be deleted, but you may have to manually restore your settings after the installation."
echo
echo "Do you want to proceed with the installation? [y/N]"
read -r REPLY
if ! [ "$REPLY" == "y" ] || [ "$REPLY" == "Y" ]; then
exit 0
fi
fi
if [ ! -d "$FILE_SHARE_PATH" ] && [ -d "$HOME/afpshare" ]; then
echo
echo "File server dir $HOME/afpshare detected. This script will rename it to $FILE_SHARE_PATH."
echo
echo "Do you want to proceed with the installation? [y/N]"
read -r REPLY
if [ "$REPLY" == "y" ] || [ "$REPLY" == "Y" ]; then
sudo mv "$HOME/afpshare" "$FILE_SHARE_PATH" || exit 1
else
exit 0
fi
elif [ -d "$FILE_SHARE_PATH" ]; then
echo "Found a $FILE_SHARE_PATH directory; will use it for file sharing."
else
echo "Creating the $FILE_SHARE_PATH directory and granting read/write permissions to all users..."
sudo mkdir -p "$FILE_SHARE_PATH"
sudo chown -R "$USER:$USER" "$FILE_SHARE_PATH"
chmod -Rv 775 "$FILE_SHARE_PATH"
fi
echo ""
echo "Installing dependencies..."
sudo apt-get update || true
sudo apt-get install samba --no-install-recommends --assume-yes </dev/null
echo ""
echo "Modifying $SAMBA_CONFIG_PATH/smb.conf ..."
if [[ `sudo grep -c "server min protocol = NT1" $SAMBA_CONFIG_PATH/smb.conf` -eq 0 ]]; then
# Allow Windows XP clients and earlier to connect to the server
sudo sed -i 's/\[global\]/\[global\]\nserver min protocol = NT1/' "$SAMBA_CONFIG_PATH/smb.conf"
echo "server min prototol = NT1"
fi
if [[ `sudo grep -c "\[Pi File Server\]" $SAMBA_CONFIG_PATH/smb.conf` -eq 0 ]]; then
# Define a shared directory with full read/write privileges, while aggressively hiding dot files
echo -e '\n[Pi File Server]\npath = '"$FILE_SHARE_PATH"'\nbrowseable = yes\nwriteable = yes\nhide dot files = yes\nveto files = /.*/' | sudo tee -a "$SAMBA_CONFIG_PATH/smb.conf"
fi
sudo systemctl restart smbd
echo "Please create a Samba password for user $USER"
sudo smbpasswd -a "$USER"
}
# updates configuration files and installs packages needed for the OLED screen script
function installRaScsiScreen() {
if [[ -f "$SECRET_FILE" && -z "$TOKEN" ]] ; then
@ -1183,6 +1189,8 @@ function runChoice() {
stopOldWebInterface
updateRaScsiGit
installPackages
installHfdisk
fetchHardDiskDrivers
stopRaScsiScreen
stopRaScsi
compileRaScsi
@ -1255,16 +1263,19 @@ function runChoice() {
echo "Installing / Updating RaSCSI OLED Screen - Complete!"
;;
4)
echo "Creating an HFS formatted 600 MiB drive image with LIDO driver"
createDrive600M
echo "Creating an HFS formatted 600 MiB drive image with LIDO driver - Complete!"
echo "Installing / Updating RaSCSI Control Board UI"
echo "This script will make the following changes to your system:"
echo "- Install additional packages with apt-get"
echo "- Add and modify systemd services"
echo "- Stop and disable the RaSCSI OLED service if it is running"
echo "- Modify the Raspberry Pi boot configuration (may require a reboot)"
sudoCheck
preparePythonCommon
installRaScsiCtrlBoard
showRaScsiCtrlBoardStatus
echo "Installing / Updating RaSCSI Control Board UI - Complete!"
;;
5)
echo "Creating an HFS formatted drive image with LIDO driver"
createDriveCustom
echo "Creating an HFS formatted drive image with LIDO driver - Complete!"
;;
6)
echo "Configuring wired network bridge"
echo "This script will make the following changes to your system:"
echo "- Create a virtual network bridge interface in /etc/network/interfaces.d"
@ -1274,7 +1285,7 @@ function runChoice() {
setupWiredNetworking
echo "Configuring wired network bridge - Complete!"
;;
7)
6)
echo "Configuring wifi network bridge"
echo "This script will make the following changes to your system:"
echo "- Install additional packages with apt-get"
@ -1285,10 +1296,22 @@ function runChoice() {
setupWirelessNetworking
echo "Configuring wifi network bridge - Complete!"
;;
8)
7)
echo "Installing AppleShare File Server"
installNetatalk
echo "Installing AppleShare File Server - Complete!"
;;
8)
echo "Installing SMB File Server"
echo "This script will make the following changes to your system:"
echo " - Install packages with apt-get"
echo " - Enable Samba systemd services"
echo " - Create a directory in the current user's home directory where shared files will be stored"
echo " - Create a Samba user for the current user"
sudoCheck
installSamba
echo "Installing SMB File Server - Complete!"
;;
9)
echo "Installing Web Proxy Server"
echo "This script will make the following changes to your system:"
@ -1328,6 +1351,8 @@ function runChoice() {
createCfgDir
updateRaScsiGit
installPackages
installHfdisk
fetchHardDiskDrivers
preparePythonCommon
cachePipPackages
installRaScsiWebInterface
@ -1353,19 +1378,6 @@ function runChoice() {
echo "Enabling or disabling Web Interface authentication - Complete!"
;;
14)
echo "Installing / Updating RaSCSI Control Board UI"
echo "This script will make the following changes to your system:"
echo "- Install additional packages with apt-get"
echo "- Add and modify systemd services"
echo "- Stop and disable the RaSCSI OLED service if it is running"
echo "- Modify the Raspberry Pi boot configuration (may require a reboot)"
sudoCheck
preparePythonCommon
installRaScsiCtrlBoard
showRaScsiCtrlBoardStatus
echo "Installing / Updating RaSCSI Control Board UI - Complete!"
;;
15)
shareImagesWithNetatalk
echo "Configuring AppleShare File Server - Complete!"
;;
@ -1383,7 +1395,7 @@ function readChoice() {
choice=-1
until [ $choice -ge "0" ] && [ $choice -le "15" ]; do
echo -n "Enter your choice (0-13) or CTRL-C to exit: "
echo -n "Enter your choice (0-14) or CTRL-C to exit: "
read -r choice
done
@ -1395,27 +1407,24 @@ function showMenu() {
echo ""
echo "Choose among the following options:"
echo "INSTALL/UPDATE RASCSI (${CONNECT_TYPE-FULLSPEC} version)"
echo " 1) install or update RaSCSI Service + Web Interface"
echo " 2) install or update RaSCSI Service"
echo " 3) install or update RaSCSI OLED Screen (requires hardware)"
echo "CREATE HFS FORMATTED (MAC) IMAGE WITH LIDO DRIVERS"
echo "** For the Mac Plus, it's better to create an image through the Web Interface **"
echo " 4) 600 MiB drive (suggested size)"
echo " 5) custom drive size (up to 4000 MiB)"
echo " 1) Install or update RaSCSI Service + Web Interface"
echo " 2) Install or update RaSCSI Service"
echo " 3) Install or update RaSCSI OLED Screen (requires hardware)"
echo " 4) Install or update RaSCSI Control Board UI (requires hardware)"
echo "NETWORK BRIDGE ASSISTANT"
echo " 6) configure network bridge for Ethernet (DHCP)"
echo " 7) configure network bridge for WiFi (static IP + NAT)"
echo " 5) Configure network bridge for Ethernet (DHCP)"
echo " 6) Configure network bridge for WiFi (static IP + NAT)"
echo "INSTALL COMPANION APPS"
echo " 8) install AppleShare File Server (Netatalk)"
echo " 9) install Web Proxy Server (Macproxy)"
echo " 7) Install AppleShare File Server (Netatalk)"
echo " 8) Install SMB File Server (Samba)"
echo " 9) Install Web Proxy Server (Macproxy)"
echo "ADVANCED OPTIONS"
echo " 10) compile and install RaSCSI stand-alone"
echo " 11) configure the RaSCSI Web Interface stand-alone"
echo " 12) enable or disable RaSCSI back-end authentication"
echo " 13) enable or disable RaSCSI Web Interface authentication"
echo " 10) Compile and install RaSCSI stand-alone"
echo " 11) Configure the RaSCSI Web Interface stand-alone"
echo " 12) Enable or disable RaSCSI back-end authentication"
echo " 13) Enable or disable RaSCSI Web Interface authentication"
echo "EXPERIMENTAL FEATURES"
echo " 14) install or update RaSCSI Control Board UI (requires hardware)"
echo " 15) share the images dir over AppleShare (requires Netatalk)"
echo " 14) Share the images dir over AppleShare (requires Netatalk)"
}
# parse arguments passed to the script
@ -1431,8 +1440,8 @@ while [ "$1" != "" ]; do
CONNECT_TYPE=$VALUE
;;
-r | --run_choice)
if ! [[ $VALUE =~ ^[1-9][0-9]?$ && $VALUE -ge 1 && $VALUE -le 15 ]]; then
echo "ERROR: The run choice parameter must have a numeric value between 1 and 15"
if ! [[ $VALUE =~ ^[1-9][0-9]?$ && $VALUE -ge 1 && $VALUE -le 14 ]]; then
echo "ERROR: The run choice parameter must have a numeric value between 1 and 14"
exit 1
fi
RUN_CHOICE=$VALUE

Binary file not shown.

View File

@ -8,11 +8,12 @@ from os import path, walk
from functools import lru_cache
from pathlib import PurePath, Path
from zipfile import ZipFile, is_zipfile
from subprocess import run, CalledProcessError
from subprocess import run, Popen, PIPE, CalledProcessError, TimeoutExpired
from json import dump, load
from shutil import copyfile
from urllib.parse import quote
from tempfile import TemporaryDirectory
from re import search
import requests
@ -366,6 +367,222 @@ class FileCmds:
}
# noinspection PyMethodMayBeStatic
def partition_disk(self, file_name, volume_name, disk_format):
"""
Creates a partition table on an image file.
Takes (str) file_name, (str) volume_name, (str) disk_format as arguments.
disk_format is either HFS or FAT
Returns (dict) with (bool) status, (str) msg
"""
server_info = self.ractl.get_server_info()
full_file_path = Path(server_info["image_dir"]) / file_name
# Inject hfdisk commands to create Drive with correct partitions
# https://www.codesrc.com/mediawiki/index.php/HFSFromScratch
# i initialize partition map
# continue with default first block
# C Create 1st partition with type specified next)
# continue with default
# 32 32 blocks (required for HFS+)
# Driver_Partition Partition Name
# Apple_Driver Partition Type (available types: Apple_Driver,
# Apple_Driver43, Apple_Free, Apple_HFS...)
# C Create 2nd partition with type specified next
# continue with default first block
# continue with default block size (rest of the disk)
# ${volumeName} Partition name provided by user
# Apple_HFS Partition Type
# w Write partition map to disk
# y Confirm partition table
# p Print partition map
if disk_format == "HFS":
partitioning_tool = "hfdisk"
commands = [
"i",
"",
"C",
"",
"32",
"Driver_Partition",
"Apple_Driver",
"C",
"",
"",
volume_name,
"Apple_HFS",
"w",
"y",
"p",
]
# Create a DOS label, primary partition, W95 FAT type
elif disk_format == "FAT":
partitioning_tool = "fdisk"
commands = [
"o",
"n",
"p",
"",
"",
"",
"t",
"b",
"w",
]
try:
process = Popen(
[partitioning_tool, str(full_file_path)],
stdin=PIPE,
stdout=PIPE,
)
for command in commands:
process.stdin.write(bytes(command + "\n", "utf-8"))
process.stdin.flush()
try:
outs, errs = process.communicate(timeout=15)
if outs:
logging.info(str(outs, "utf-8"))
if errs:
logging.error(str(errs, "utf-8"))
if process.returncode:
self.delete_file(Path(file_name))
return {"status": False, "msg": errs}
except TimeoutExpired:
process.kill()
outs, errs = process.communicate()
if outs:
logging.info(str(outs, "utf-8"))
if errs:
logging.error(str(errs, "utf-8"))
self.delete_file(Path(file_name))
return {"status": False, "msg": errs}
except (OSError, IOError) as error:
logging.error(SHELL_ERROR, " ".join(error.cmd), error.stderr.decode("utf-8"))
self.delete_file(Path(file_name))
return {"status": False, "msg": error.stderr.decode("utf-8")}
return {"status": True, "msg": ""}
# noinspection PyMethodMayBeStatic
def format_hfs(self, file_name, volume_name, driver_path):
"""
Initializes an HFS file system and injects a hard disk driver
Takes (str) file_name, (str) volume_name and (Path) driver_path as arguments.
Returns (dict) with (bool) status, (str) msg
"""
server_info = self.ractl.get_server_info()
full_file_path = Path(server_info["image_dir"]) / file_name
try:
run(
[
"dd",
f"if={driver_path}",
f"of={full_file_path}",
"seek=64",
"count=32",
"bs=512",
"conv=notrunc",
],
capture_output=True,
check=True,
)
except (FileNotFoundError, CalledProcessError) as error:
logging.warning(SHELL_ERROR, " ".join(error.cmd), error.stderr.decode("utf-8"))
self.delete_file(Path(file_name))
return {"status": False, "msg": error.stderr.decode("utf-8")}
try:
process = run(
[
"hformat",
"-l",
volume_name,
str(full_file_path),
"1",
],
capture_output=True,
check=True,
)
logging.info(process.stdout.decode("utf-8"))
except (FileNotFoundError, CalledProcessError) as error:
logging.error(SHELL_ERROR, " ".join(error.cmd), error.stderr.decode("utf-8"))
self.delete_file(Path(file_name))
return {"status": False, "msg": error.stderr.decode("utf-8")}
return {"status": True, "msg": ""}
# noinspection PyMethodMayBeStatic
def format_fat(self, file_name, volume_name, fat_size):
"""
Initializes a FAT file system
Takes (str) file_name, (str) volume_name and (str) FAT size (12|16|32) as arguments.
Returns (dict) with (bool) status, (str) msg
"""
server_info = self.ractl.get_server_info()
full_file_path = Path(server_info["image_dir"]) / file_name
loopback_device = ""
try:
process = run(
["kpartx", "-av", str(full_file_path)],
capture_output=True,
check=True,
)
logging.info(process.stdout.decode("utf-8"))
if process.returncode == 0:
loopback_device = search(r"(loop\d\D\d)", process.stdout.decode("utf-8")).group(1)
else:
logging.info(process.stdout.decode("utf-8"))
self.delete_file(Path(file_name))
return {"status": False, "msg": error.stderr.decode("utf-8")}
except (FileNotFoundError, CalledProcessError) as error:
logging.warning(SHELL_ERROR, " ".join(error.cmd), error.stderr.decode("utf-8"))
self.delete_file(Path(file_name))
return {"status": False, "msg": error.stderr.decode("utf-8")}
args = [
"mkfs.fat",
"-v",
"-F",
fat_size,
"-n",
volume_name,
"/dev/mapper/" + loopback_device,
]
try:
process = run(
args,
capture_output=True,
check=True,
)
logging.info(process.stdout.decode("utf-8"))
except (FileNotFoundError, CalledProcessError) as error:
logging.warning(SHELL_ERROR, " ".join(error.cmd), error.stderr.decode("utf-8"))
self.delete_file(Path(file_name))
return {"status": False, "msg": error.stderr.decode("utf-8")}
try:
process = run(
["kpartx", "-dv", str(full_file_path)],
capture_output=True,
check=True,
)
logging.info(process.stdout.decode("utf-8"))
if process.returncode:
logging.info(process.stderr.decode("utf-8"))
logging.warning("Failed to delete loopback device. You may have to do it manually")
except (FileNotFoundError, CalledProcessError) as error:
logging.warning(SHELL_ERROR, " ".join(error.cmd), error.stderr.decode("utf-8"))
self.delete_file(Path(file_name))
return {"status": False, "msg": error.stderr.decode("utf-8")}
return {"status": True, "msg": ""}
def download_file_to_iso(self, url, *iso_args):
"""
Takes (str) url and one or more (str) *iso_args
@ -446,9 +663,12 @@ class FileCmds:
headers={"User-Agent": "Mozilla/5.0"},
) as req:
req.raise_for_status()
with open(f"{save_dir}/{file_name}", "wb") as download:
for chunk in req.iter_content(chunk_size=8192):
download.write(chunk)
try:
with open(f"{save_dir}/{file_name}", "wb") as download:
for chunk in req.iter_content(chunk_size=8192):
download.write(chunk)
except FileNotFoundError as error:
return {"status": False, "msg": str(error)}
except requests.exceptions.RequestException as error:
logging.warning("Request failed: %s", str(error))
return {"status": False, "msg": str(error)}

View File

@ -8,7 +8,7 @@ import rascsi.common_settings
WEB_DIR = getcwd()
HOME_DIR = "/".join(WEB_DIR.split("/")[0:3])
AFP_DIR = f"{HOME_DIR}/afpshare"
FILE_SERVER_DIR = f"{HOME_DIR}/shared_files"
MAX_FILE_SIZE = getenv("MAX_FILE_SIZE", str(1024 * 1024 * 1024 * 4)) # 4gb

View File

@ -439,7 +439,7 @@
<ul>
<li>{{ _("The largest file size accepted in this form is %(max_file_size)s MiB. Use other file transfer means for larger files.", max_file_size=max_file_size) }}</li>
<li>{{ _("File uploads will progress only if you stay on this page. If you navigate away before the transfer is completed, you will end up with an incomplete file.") }}</li>
<li>{{ _("Install <a href=\"%(url)s\" target=\"_blank\">Netatalk</a> to use the AFP File Server.", url="https://github.com/akuker/RASCSI/wiki/AFP-File-Sharing") }}</li>
<li>{{ _("Install Netatalk or Samba to use the File Server.") }}</li>
</ul>
</details>
@ -447,8 +447,8 @@
<p>
<label for="upload_destination">{{ _("Target directory:") }}</label>
<select name="destination" id="upload_destination">
<option value="images">Images - {{ env["image_dir"] }}</option>
<option value="afp">AppleShare - {{ AFP_DIR }}</option>
<option value="images">{{ _("Disk Images") }} - {{ env["image_dir"] }}</option>
<option value="file_server">{{ _("File Server") }} - {{ FILE_SERVER_DIR }}</option>
</select>
</p>
</form>
@ -489,15 +489,15 @@
{{ _("Download File from the Web") }}
</summary>
<ul>
<li>{{ _("Install <a href=\"%(url)s\" target=\"_blank\">Netatalk</a> to use the AFP File Server.", url="https://github.com/akuker/RASCSI/wiki/AFP-File-Sharing") }}</li>
<li>{{ _("Install Netatalk or Samba to use the File Server.") }}</li>
</ul>
</details>
<form action="/files/download_url" method="post">
<label for="download_destination">{{ _("Target directory:") }}</label>
<select name="destination" id="download_destination">
<option value="images">Images - {{ env["image_dir"] }}</option>
<option value="afp">AppleShare - {{ AFP_DIR }}</option>
<option value="images">{{ _("Disk Images") }} - {{ env["image_dir"] }}</option>
<option value="file_server">{{ _("File Server") }} - {{ FILE_SERVER_DIR }}</option>
</select>
<label for="download_url">{{ _("URL:") }}</label>
<input name="url" id="download_url" required="" type="url">
@ -560,6 +560,7 @@
</summary>
<ul>
<li>{{ _("Please refer to <a href=\"%(url)s\" target=\"_blank\">wiki documentation</a> to learn more about the supported image file types.", url="https://github.com/akuker/RASCSI/wiki/Supported-Device-Types#image-types") }}</li>
<li>{{ _("It is not recommended to use the Lido hard disk driver with the Macintosh Plus.") }}</li>
</ul>
</details>
@ -587,6 +588,24 @@
</option>
{% endfor %}
</select>
<label for="drive_format">{{ _("Format as:") }}</label>
<select name="drive_format" id="drive_format">
<option value="">
{{ _("None") }}
</option>
<option value="Lido 7.56">
HFS + Lido
</option>
<option value="SpeedTools 3.6">
HFS + SpeedTools
</option>
<option value="FAT16">
FAT16
</option>
<option value="FAT32">
FAT32
</option>
</select>
<input type="submit" value="{{ _("Create") }}">
</form>

Some files were not shown because too many files have changed in this diff Show More