Skip to content

Commit

Permalink
Support temporary sector size change, remove support for image file o…
Browse files Browse the repository at this point in the history
…ffset
  • Loading branch information
uweseimet committed Jan 26, 2024
1 parent 0ba8040 commit db967f1
Show file tree
Hide file tree
Showing 20 changed files with 130 additions and 104 deletions.
2 changes: 1 addition & 1 deletion cpp/command/command_dispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ bool CommandDispatcher::DispatchCommand(const CommandContext &context, PbResult
return context.ReturnLocalizedError(LocalizationKey::ERROR_OPERATION, UNKNOWN_OPERATION, to_string(operation));
}

trace("Executing {0} command", identifier, PbOperation_Name(operation));
trace("{0}Executing {1} command", identifier, PbOperation_Name(operation));

switch (operation) {
case LOG_LEVEL:
Expand Down
14 changes: 5 additions & 9 deletions cpp/controllers/generic_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -337,19 +337,15 @@ void GenericController::Send()

DecrementBlocks();

// Processing after data collection (read/data-in only)
if (IsDataIn() && HasBlocks()) {
// Set next buffer (set offset, length)
if (!XferIn(GetBuffer())) {
Error(sense_key::aborted_command, asc::controller_send_xfer_in);
return;
}
if (IsDataIn() && HasBlocks() && !XferIn(GetBuffer())) {
Error(sense_key::aborted_command, asc::controller_send_xfer_in);
return;
}

// Continue sending if blocks != 0
if (HasBlocks()) {
assert(HasValidLength());
assert(GetOffset() == 0);
assert(!GetOffset());
return;
}

Expand Down Expand Up @@ -442,7 +438,7 @@ void GenericController::Receive()
// Continue to receive if blocks != 0
if (HasBlocks()) {
assert(HasValidLength());
assert(GetOffset() == 0);
assert(!GetOffset());
return;
}

Expand Down
7 changes: 3 additions & 4 deletions cpp/devices/disk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,14 +143,13 @@ void Disk::Dispatch(scsi_command cmd)
}
}

void Disk::SetUpCache(off_t image_offset, bool raw)
void Disk::SetUpCache(bool raw)
{
cache = make_unique<DiskCache>(GetFilename(), size_shift_count, static_cast<uint32_t>(GetBlockCount()),
image_offset);
cache = make_unique<DiskCache>(GetFilename(), size_shift_count, static_cast<uint32_t>(GetBlockCount()));
cache->SetRawMode(raw);
}

void Disk::Resize_cache(const string &path, bool raw)
void Disk::ResizeCache(const string &path, bool raw)
{
cache.reset(new DiskCache(path, size_shift_count, static_cast<uint32_t>(GetBlockCount())));
cache->SetRawMode(raw);
Expand Down
4 changes: 2 additions & 2 deletions cpp/devices/disk.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@ class Disk : public StorageDevice, private ScsiBlockCommands

protected:

void SetUpCache(off_t, bool = false);
void Resize_cache(const string&, bool);
void SetUpCache(bool = false);
void ResizeCache(const string&, bool);

void SetUpModePages(map<int, vector<byte>>&, int, bool) const override;
void AddReadWriteErrorRecoveryPage(map<int, vector<byte>>&, bool) const;
Expand Down
8 changes: 4 additions & 4 deletions cpp/devices/disk_cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
// XM6i
// Copyright (C) 2010-2015 isaki@NetBSD.org
// Copyright (C) 2010 Y.Sugahara
// Copyright (C) 2022-2024 Uwe Seimet
//
//---------------------------------------------------------------------------

Expand All @@ -17,11 +18,10 @@
#include "disk_track.h"
#include "disk_cache.h"

DiskCache::DiskCache(const string &path, int size, uint32_t blocks, off_t imgoff)
: sec_path(path), sec_size(size), sec_blocks(blocks), imgoffset(imgoff)
DiskCache::DiskCache(const string &path, int size, uint32_t blocks)
: sec_path(path), sec_size(size), sec_blocks(blocks)
{
assert(blocks > 0);
assert(imgoff >= 0);
}

bool DiskCache::Save()
Expand Down Expand Up @@ -157,7 +157,7 @@ bool DiskCache::Load(int index, int track, shared_ptr<DiskTrack> disktrk)
disktrk = make_shared<DiskTrack>();
}

disktrk->Init(track, sec_size, sectors, cd_raw, imgoffset);
disktrk->Init(track, sec_size, sectors, cd_raw);

// Try loading
if (!disktrk->Load(sec_path, cache_miss_read_count)) {
Expand Down
5 changes: 2 additions & 3 deletions cpp/devices/disk_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//
// XM6i
// Copyright (C) 2010-2015 isaki@NetBSD.org
// Copyright (C) 2022-2023 Uwe Seimet
// Copyright (C) 2022-2024 Uwe Seimet
//
//---------------------------------------------------------------------------

Expand Down Expand Up @@ -43,7 +43,7 @@ class DiskCache
uint32_t serial;
};

DiskCache(const string&, int, uint32_t, off_t = 0);
DiskCache(const string&, int, uint32_t);
~DiskCache() = default;

void SetRawMode(bool b)
Expand Down Expand Up @@ -71,6 +71,5 @@ class DiskCache
int sec_size; // Sector Size (8=256, 9=512, 10=1024, 11=2048, 12=4096)
int sec_blocks; // Blocks per sector
bool cd_raw = false; // CD-ROM RAW mode
off_t imgoffset; // Offset to actual data
};

14 changes: 2 additions & 12 deletions cpp/devices/disk_track.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// XM6i
// Copyright (C) 2010-2015 isaki@NetBSD.org
// Copyright (C) 2010 Y.Sugahara
// Copyright (C) 2022-2023 Uwe Seimet
// Copyright (C) 2022-2024 Uwe Seimet
//
//---------------------------------------------------------------------------

Expand All @@ -24,11 +24,10 @@ DiskTrack::~DiskTrack()
free(dt.buffer); // NOSONAR free() must be used here because of allocation with posix_memalign
}

void DiskTrack::Init(int track, int size, int sectors, bool raw, off_t imgoff)
void DiskTrack::Init(int track, int size, int sectors, bool raw)
{
assert(track >= 0);
assert((sectors > 0) && (sectors <= 0x100));
assert(imgoff >= 0);

// Set Parameters
dt.track = track;
Expand All @@ -41,9 +40,6 @@ void DiskTrack::Init(int track, int size, int sectors, bool raw, off_t imgoff)

// Not Changed
dt.changed = false;

// Offset to actual data
dt.imgoffset = imgoff;
}

bool DiskTrack::Load(const string &path, uint64_t &cache_miss_read_count)
Expand All @@ -66,9 +62,6 @@ bool DiskTrack::Load(const string &path, uint64_t &cache_miss_read_count)
offset <<= dt.size;
}

// Add offset to real image
offset += dt.imgoffset;

// Calculate length (data size of this track)
const int length = dt.sectors << dt.size;

Expand Down Expand Up @@ -158,9 +151,6 @@ bool DiskTrack::Save(const string &path, uint64_t &cache_miss_write_count)
off_t offset = ((off_t)dt.track << 8);
offset <<= dt.size;

// Add offset to real image
offset += dt.imgoffset;

// Calculate length per sector
const int length = 1 << dt.size;

Expand Down
9 changes: 4 additions & 5 deletions cpp/devices/disk_track.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//
// XM6i
// Copyright (C) 2010-2015 isaki@NetBSD.org
// Copyright (C) 2022-2023 Uwe Seimet
// Copyright (C) 2022-2024 Uwe Seimet
//
//---------------------------------------------------------------------------

Expand All @@ -33,7 +33,6 @@ class DiskTrack
bool changed; // Changed flag
vector<bool> changemap; // Changed map
bool raw; // RAW mode flag
off_t imgoffset; // Offset to actual data
} dt = { };

public:
Expand All @@ -47,9 +46,9 @@ class DiskTrack

friend class DiskCache;

void Init(int track, int size, int sectors, bool raw = false, off_t imgoff = 0);
bool Load(const string &path, uint64_t&);
bool Save(const string &path, uint64_t&);
void Init(int, int, int, bool = false);
bool Load(const string&, uint64_t&);
bool Save(const string&, uint64_t&);

bool ReadSector(span<uint8_t>, int) const;
bool WriteSector(span<const uint8_t> buf, int);
Expand Down
2 changes: 1 addition & 1 deletion cpp/devices/mode_page_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ void ModePageDevice::ModeSense10() const
EnterDataInPhase();
}

void ModePageDevice::ModeSelect(scsi_command, cdb_t, span<const uint8_t>, int) const
void ModePageDevice::ModeSelect(scsi_command, cdb_t, span<const uint8_t>, int)
{
// There is no default implementation of MODE SELECT
assert(false);
Expand Down
2 changes: 1 addition & 1 deletion cpp/devices/mode_page_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class ModePageDevice : public PrimaryDevice

bool Init(const param_map&) override;

virtual void ModeSelect(scsi_defs::scsi_command, cdb_t, span<const uint8_t>, int) const;
virtual void ModeSelect(scsi_defs::scsi_command, cdb_t, span<const uint8_t>, int);

protected:

Expand Down
36 changes: 23 additions & 13 deletions cpp/devices/mode_page_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,20 @@ using namespace spdlog;
using namespace scsi_defs;
using namespace memory_util;

void mode_page_util::ModeSelect(scsi_command cmd, cdb_t cdb, span<const uint8_t> buf, int length, int sector_size)
int mode_page_util::ModeSelect(scsi_command cmd, cdb_t cdb, span<const uint8_t> buf, int length, int sector_size)
{
assert(cmd == scsi_command::cmd_mode_select6 || cmd == scsi_command::cmd_mode_select10);

// PF
if (!(cdb[1] & 0x10)) {
// Vendor-specific parameters (SCSI-1) are not supported.
// Do not report an error in order to support Apple's HD SC Setup.
return;
return sector_size;
}

// The page data are optional
if (!length) {
return;
return sector_size;
}

int offset = EvaluateBlockDescriptors(cmd, buf, length, sector_size);
Expand All @@ -53,10 +53,10 @@ void mode_page_util::ModeSelect(scsi_command cmd, cdb_t cdb, span<const uint8_t>
throw scsi_exception(sense_key::illegal_request, asc::parameter_list_length_error);
}

// With this page the sector size for a subsequent FORMAT can be selected, but only very few
// drives support this, e.g FUJITSU M2624S.
// We are fine as long as the current sector size remains unchanged.
HandleSectorSizeChange(buf, offset + 12, sector_size);
// With this page the sector size for a subsequent FORMAT can be selected, but only a few drives
// support this, e.g FUJITSU M2624S.
// We are fine as long as the permanent current sector size remains unchanged.
HandleSectorSizeChange(buf, offset + 12, sector_size, false);

break;
}
Expand All @@ -79,9 +79,11 @@ void mode_page_util::ModeSelect(scsi_command cmd, cdb_t cdb, span<const uint8_t>
length -= size;
offset += size;
}

return sector_size;
}

int mode_page_util::EvaluateBlockDescriptors(scsi_command cmd, span<const uint8_t> buf, int length, int sector_size)
int mode_page_util::EvaluateBlockDescriptors(scsi_command cmd, span<const uint8_t> buf, int length, int &sector_size)
{
assert(cmd == scsi_command::cmd_mode_select6 || cmd == scsi_command::cmd_mode_select10);

Expand All @@ -102,24 +104,32 @@ int mode_page_util::EvaluateBlockDescriptors(scsi_command cmd, span<const uint8_

// Check for temporary sector size change in first block descriptor
if (block_descriptor_length && length >= required_length + 8) {
HandleSectorSizeChange(buf, required_length + 6, sector_size);
sector_size = HandleSectorSizeChange(buf, required_length + 6, sector_size, true);
}

return block_descriptor_length + required_length;
}

void mode_page_util::HandleSectorSizeChange(span<const uint8_t> buf, int offset, int sector_size)
int mode_page_util::HandleSectorSizeChange(span<const uint8_t> buf, int offset, int sector_size, bool temporary)
{
if (const int requested_size = GetInt16(buf, offset); requested_size != sector_size) {
// Simple consistency check
if (!(requested_size & 0xe1ff)) {
warn(
"Sector size change from {} to {} bytes requested. Configure the requested sector size in the s2p settings.",
sector_size, requested_size);
if (temporary) {
trace("Temporarily changing sector size from {0} to {1} bytes", sector_size, requested_size);
return requested_size;
}
else {
warn(
"Sector size change from {0} to {1} bytes requested. Configure the requested sector size in the s2p settings.",
sector_size, requested_size);
}
}

throw scsi_exception(sense_key::illegal_request, asc::invalid_field_in_parameter_list);
}

return sector_size;
}

void mode_page_util::EnrichFormatPage(map<int, vector<byte>> &pages, bool changeable, int sector_size)
Expand Down
8 changes: 3 additions & 5 deletions cpp/devices/mode_page_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
//
// Copyright (C) 2022-2024 Uwe Seimet
//
// Shared code for SCSI command implementations
//
//---------------------------------------------------------------------------

#pragma once
Expand All @@ -19,9 +17,9 @@ using namespace std;

namespace mode_page_util
{
void ModeSelect(scsi_defs::scsi_command, cdb_t, span<const uint8_t>, int, int);
int EvaluateBlockDescriptors(scsi_defs::scsi_command, span<const uint8_t>, int, int);
void HandleSectorSizeChange(span<const uint8_t>, int, int);
int ModeSelect(scsi_defs::scsi_command, cdb_t, span<const uint8_t>, int, int);
int EvaluateBlockDescriptors(scsi_defs::scsi_command, span<const uint8_t>, int, int&);
int HandleSectorSizeChange(span<const uint8_t>, int, int, bool);
void EnrichFormatPage(map<int, vector<byte>>&, bool, int);
void AddAppleVendorModePage(map<int, vector<byte>>&, bool);
}
14 changes: 11 additions & 3 deletions cpp/devices/optical_memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ void OpticalMemory::Open()

Disk::ValidateFile();

SetUpCache(0);
SetUpCache();

// Attention if ready
if (IsReady()) {
Expand Down Expand Up @@ -86,9 +86,17 @@ void OpticalMemory::AddOptionPage(map<int, vector<byte>> &pages, bool) const
// Do not report update blocks
}

void OpticalMemory::ModeSelect(scsi_command cmd, cdb_t cdb, span<const uint8_t> buf, int length) const
void OpticalMemory::ModeSelect(scsi_command cmd, cdb_t cdb, span<const uint8_t> buf, int length)
{
mode_page_util::ModeSelect(cmd, cdb, buf, length, 1 << GetSectorSizeShiftCount());
const auto current_sector_size = static_cast<int>(GetSectorSizeInBytes());
const auto new_sector_size = mode_page_util::ModeSelect(cmd, cdb, buf, length, current_sector_size);
if (new_sector_size != current_sector_size) {
const uint64_t capacity = current_sector_size * GetBlockCount();
SetSectorSizeInBytes(new_sector_size);
SetBlockCount(static_cast<uint32_t>(capacity >> GetSectorSizeShiftCount()));

SetUpCache();
}
}

//
Expand Down
2 changes: 1 addition & 1 deletion cpp/devices/optical_memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class OpticalMemory : public Disk
void Open() override;

vector<uint8_t> InquiryInternal() const override;
void ModeSelect(scsi_defs::scsi_command, cdb_t, span<const uint8_t>, int) const override;
void ModeSelect(scsi_defs::scsi_command, cdb_t, span<const uint8_t>, int) override;

protected:

Expand Down
Loading

0 comments on commit db967f1

Please sign in to comment.