Skip to content

Commit

Permalink
Split executors
Browse files Browse the repository at this point in the history
  • Loading branch information
uweseimet committed Dec 10, 2024
1 parent 93d917b commit 554004e
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 19 deletions.
4 changes: 2 additions & 2 deletions cpp/s2pdump/disk_executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// SCSI2Pi, SCSI device emulator and SCSI tools for the Raspberry Pi
//
// Copyright (C) 2024 Uwe Seimet
// Copyright (C) 2023-2024 Uwe Seimet
//
//---------------------------------------------------------------------------

Expand Down Expand Up @@ -46,7 +46,7 @@ pair<uint64_t, uint32_t> DiskExecutor::ReadCapacity()
return {capacity + 1, sector_size};
}

bool DiskExecutor::ReadWriteDisk(span<uint8_t> buffer, uint32_t bstart, uint32_t blength, int length, bool is_write)
bool DiskExecutor::ReadWrite(span<uint8_t> buffer, uint32_t bstart, uint32_t blength, int length, bool is_write)
{
if (bstart < 16777216 && blength <= 256) {
vector<uint8_t> cdb(6);
Expand Down
4 changes: 2 additions & 2 deletions cpp/s2pdump/disk_executor.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// SCSI2Pi, SCSI device emulator and SCSI tools for the Raspberry Pi
//
// Copyright (C) 2024 Uwe Seimet
// Copyright (C) 2023-2024 Uwe Seimet
//
//---------------------------------------------------------------------------

Expand All @@ -22,7 +22,7 @@ class DiskExecutor : public S2pDumpExecutor
}

pair<uint64_t, uint32_t> ReadCapacity();
bool ReadWriteDisk(span<uint8_t>, uint32_t, uint32_t, int, bool);
bool ReadWrite(span<uint8_t>, uint32_t, uint32_t, int, bool);
void SynchronizeCache();

private:
Expand Down
30 changes: 16 additions & 14 deletions cpp/s2pdump/s2pdump_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <getopt.h>
#include "buses/bus_factory.h"
#include "disk_executor.h"
#include "tape_executor.h"
#include "initiator/initiator_util.h"
#include "shared/s2p_exceptions.h"
#include "shared/simh_util.h"
Expand Down Expand Up @@ -82,7 +83,8 @@ bool S2pDump::Init(bool in_process)
return false;
}

executor = make_unique<DiskExecutor>(*bus, initiator_id, *default_logger());
disk_executor = make_unique<DiskExecutor>(*bus, initiator_id, *default_logger());
tape_executor = make_unique<TapeExecutor>(*bus, initiator_id, *default_logger());

instance = this;
// Signal handler for cleaning up
Expand Down Expand Up @@ -359,7 +361,7 @@ void S2pDump::ScanBus()
continue;
}

auto luns = executor->ReportLuns();
auto luns = disk_executor->ReportLuns();
// LUN 0 has already been dealt with
luns.erase(0);

Expand All @@ -376,13 +378,13 @@ bool S2pDump::DisplayInquiry(bool check_type)
cout << DIVIDER << "\nChecking " << (sasi ? "SASI" : "SCSI") << " target ID:LUN " << target_id << ":"
<< target_lun << "\n" << flush;

executor->SetTarget(target_id, target_lun, sasi);
disk_executor->SetTarget(target_id, target_lun, sasi);

// Clear potential UNIT ATTENTION status
executor->TestUnitReady();
disk_executor->TestUnitReady();

vector<uint8_t> buf(36);
if (!executor->Inquiry(buf)) {
if (!disk_executor->Inquiry(buf)) {
return false;
}

Expand Down Expand Up @@ -564,7 +566,7 @@ string S2pDump::DumpRestoreDisk(fstream &fs)

if (restore) {
// Ensure that if the target device is also a SCSI2Pi instance its image file becomes complete immediately
executor->SynchronizeCache();
disk_executor->SynchronizeCache();
}

cout << DIVIDER
Expand All @@ -584,10 +586,10 @@ string S2pDump::DumpRestoreTape(fstream &fs)

cout << "Starting " << (restore ? "restore" : "dump") << "\n";

executor->Rewind();
tape_executor->Rewind();

while (true) {
const int length = executor->ReadWriteTape(buffer, restore);
const int length = tape_executor->ReadWrite(buffer, restore);
if (length == -1) {
return "Can't transfer block";
}
Expand Down Expand Up @@ -616,11 +618,11 @@ string S2pDump::ReadWriteDisk(fstream &fs, int sector_offset, uint32_t sector_co
return "Error reading from file '" + filename + "'";
}

if (!executor->ReadWriteDisk(buffer, sector_offset, sector_count, sector_count * sector_size, true)) {
if (!disk_executor->ReadWrite(buffer, sector_offset, sector_count, sector_count * sector_size, true)) {
return "Error/interrupted while writing to device";
}
} else {
if (!executor->ReadWriteDisk(buffer, sector_offset, sector_count, sector_count * sector_size, false)) {
if (!disk_executor->ReadWrite(buffer, sector_offset, sector_count, sector_count * sector_size, false)) {
return "Error/interrupted while reading from device";
}

Expand Down Expand Up @@ -691,14 +693,14 @@ bool S2pDump::GetDeviceInfo()
}

// Clear any pending error condition, e.g. a medium just having being inserted
executor->RequestSense();
disk_executor->RequestSense();

if (scsi_device_info.type == static_cast<byte>(device_type::sequential_access)) {
return true;
}

if (!sasi) {
const auto [capacity, sector_size] = executor->ReadCapacity();
const auto [capacity, sector_size] = disk_executor->ReadCapacity();
if (!capacity || !sector_size) {
trace("Can't read device capacity");
return false;
Expand Down Expand Up @@ -732,7 +734,7 @@ bool S2pDump::GetDeviceInfo()
void S2pDump::DisplayProperties(int id, int lun) const
{
// Clear any pending error condition, e.g. a medium just having being inserted
executor->RequestSense();
disk_executor->RequestSense();

cout << "\nDevice properties for s2p properties file:\n";

Expand Down Expand Up @@ -766,7 +768,7 @@ void S2pDump::DisplayProperties(int id, int lun) const

vector<uint8_t> buf(255);

if (!executor->ModeSense6(buf)) {
if (!disk_executor->ModeSense6(buf)) {
cout << "Warning: Can't get mode page data, medium may be missing or drive was not ready, try again\n" << flush;
return;
}
Expand Down
4 changes: 3 additions & 1 deletion cpp/s2pdump/s2pdump_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <unordered_map>
#include <vector>
#include "disk_executor.h"
#include "tape_executor.h"

using namespace std;

Expand Down Expand Up @@ -60,7 +61,8 @@ class S2pDump

unique_ptr<Bus> bus;

unique_ptr<DiskExecutor> executor;
unique_ptr<DiskExecutor> disk_executor;
unique_ptr<TapeExecutor> tape_executor;

scsi_device_info_t scsi_device_info = { };

Expand Down
72 changes: 72 additions & 0 deletions cpp/s2pdump/tape_executor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
//---------------------------------------------------------------------------
//
// SCSI2Pi, SCSI device emulator and SCSI tools for the Raspberry Pi
//
// Copyright (C) 2024 Uwe Seimet
//
//---------------------------------------------------------------------------

#include "tape_executor.h"
#include <spdlog/spdlog.h>
#include "shared/memory_util.h"

using namespace spdlog;
using namespace memory_util;

void TapeExecutor::Rewind()
{
vector<uint8_t> cdb(6);

initiator_executor->Execute(scsi_command::rewind, cdb, { }, 0, 300);
}

int TapeExecutor::ReadWrite(span<uint8_t> buffer, bool is_write)
{
vector<uint8_t> cdb(6);
cdb[2] = static_cast<uint8_t>(default_length >> 16);
cdb[3] = static_cast<uint8_t>(default_length >> 8);
cdb[4] = static_cast<uint8_t>(default_length);

int status = initiator_executor->Execute(is_write ? scsi_command::write_6 : scsi_command::read_6, cdb, buffer,
default_length, 300);
if (!status) {
return default_length;
}

fill_n(cdb.begin(), cdb.size(), 0);
cdb[4] = 14;
initiator_executor->Execute(scsi_command::request_sense, cdb, buffer, 14, 3);

if (buffer[2] & 0x80) {
debug("Hit filemark");
return 0;
}

if (!(buffer[0] & 0x80)) {
error("VALID is not set");
return -1;
}

default_length -= GetInt32(buffer, 3);

debug("Found block with {} byte(s)", default_length);

cdb[2] = static_cast<uint8_t>(default_length >> 16);
cdb[3] = static_cast<uint8_t>(default_length >> 8);
cdb[4] = static_cast<uint8_t>(default_length);

status = initiator_executor->Execute(is_write ? scsi_command::write_6 : scsi_command::read_6, cdb, buffer,
default_length, 300);
if (!status) {
return default_length;
}

fill_n(cdb.begin(), cdb.size(), 0);
cdb[4] = 14;
initiator_executor->Execute(scsi_command::request_sense, cdb, buffer, 14, 3);
spdlog::error(buffer[2] & 0x0f);
spdlog::error(buffer[12]);
// TODO Print sense data

return -1;
}
32 changes: 32 additions & 0 deletions cpp/s2pdump/tape_executor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//---------------------------------------------------------------------------
//
// SCSI2Pi, SCSI device emulator and SCSI tools for the Raspberry Pi
//
// Copyright (C) 2024 Uwe Seimet
//
//---------------------------------------------------------------------------

#pragma once

#include "s2pdump_executor.h"

using namespace std;

class TapeExecutor : public S2pDumpExecutor
{

public:

TapeExecutor(Bus &b, int i, logger &l) : S2pDumpExecutor(b, i, l)
{
}

void Rewind();
int ReadWrite(span<uint8_t>, bool);

private:

unique_ptr<S2pDumpExecutor> s2pdump_executor;

int default_length = 0xffffff;
};

0 comments on commit 554004e

Please sign in to comment.