mirror of
https://github.com/akuker/RASCSI.git
synced 2024-12-27 16:31:36 +00:00
Improve MO support by removing capacity restrictions (#284)
* Improve MO support by removing capacity restrictions, resolves #283 * Updated geometry handling
This commit is contained in:
parent
b3b740e3cc
commit
682d35f1e6
@ -28,7 +28,7 @@ DeviceFactory::DeviceFactory()
|
||||
sector_sizes[SAHD] = { 256, 1024 };
|
||||
sector_sizes[SCHD] = { 512, 1024, 2048, 4096 };
|
||||
sector_sizes[SCRM] = { 512, 1024, 2048, 4096 };
|
||||
sector_sizes[SCMO] = {};
|
||||
sector_sizes[SCMO] = { 512, 1024, 2048, 4096 };
|
||||
// Some old Sun CD-ROM drives support 512 bytes per sector
|
||||
sector_sizes[SCCD] = { 512, 2048};
|
||||
sector_sizes[SCBR] = {};
|
||||
@ -170,6 +170,7 @@ Device *DeviceFactory::CreateDevice(PbDeviceType type, const string& filename)
|
||||
device->SetRemovable(true);
|
||||
device->SetLockable(true);
|
||||
device->SetProduct("SCSI MO");
|
||||
((Disk *)device)->SetSectorSizes(sector_sizes[SCRM]);
|
||||
((Disk *)device)->SetGeometries(geometries[SCMO]);
|
||||
break;
|
||||
|
||||
|
@ -46,6 +46,7 @@ private:
|
||||
|
||||
map<PbDeviceType, set<uint32_t>> sector_sizes;
|
||||
|
||||
// Optional mapping of drive capacities to drive geometries
|
||||
map<PbDeviceType, map<uint64_t, Geometry>> geometries;
|
||||
|
||||
map<PbDeviceType, map<string, string>> default_params;
|
||||
|
@ -1690,33 +1690,19 @@ bool Disk::SetConfiguredSectorSize(uint32_t configured_sector_size)
|
||||
|
||||
void Disk::SetGeometries(const map<uint64_t, Geometry>& geometries)
|
||||
{
|
||||
if (!IsMo()) {
|
||||
throw illegal_argument_exception("Can't set geometry for");
|
||||
}
|
||||
|
||||
this->geometries = geometries;
|
||||
}
|
||||
|
||||
void Disk::SetGeometryForCapacity(uint64_t capacity) {
|
||||
bool Disk::SetGeometryForCapacity(uint64_t capacity) {
|
||||
const auto& geometry = geometries.find(capacity);
|
||||
if (geometry != geometries.end()) {
|
||||
SetSectorSizeInBytes(geometry->second.first, false);
|
||||
SetBlockCount(geometry->second.second);
|
||||
|
||||
if (geometry == geometries.end()) {
|
||||
ostringstream error;
|
||||
error << "Invalid file size of " << capacity << " bytes. Supported file sizes are ";
|
||||
bool isFirst = true;
|
||||
for (const auto& g : geometries) {
|
||||
if (!isFirst) {
|
||||
error << ", ";
|
||||
}
|
||||
error << g.first << " bytes";
|
||||
isFirst = false;
|
||||
}
|
||||
error << ".";
|
||||
throw io_exception(error.str());
|
||||
return true;
|
||||
}
|
||||
|
||||
SetSectorSizeInBytes(geometry->second.first, false);
|
||||
SetBlockCount(geometry->second.second);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t Disk::GetBlockCount() const
|
||||
|
@ -134,7 +134,7 @@ public:
|
||||
uint32_t GetConfiguredSectorSize() const;
|
||||
bool SetConfiguredSectorSize(uint32_t);
|
||||
void SetGeometries(const map<uint64_t, Geometry>&);
|
||||
void SetGeometryForCapacity(uint64_t);
|
||||
bool SetGeometryForCapacity(uint64_t);
|
||||
uint64_t GetBlockCount() const;
|
||||
void SetBlockCount(uint32_t);
|
||||
bool GetStartAndCount(SASIDEV *, uint64_t&, uint32_t&, access_mode);
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "../rascsi.h"
|
||||
#include "fileio.h"
|
||||
#include "exceptions.h"
|
||||
#include <sstream>
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
@ -55,7 +56,19 @@ void SCSIMO::Open(const Filepath& path)
|
||||
off_t size = fio.GetFileSize();
|
||||
fio.Close();
|
||||
|
||||
SetGeometryForCapacity(size);
|
||||
// For some priorities there are hard-coded, well-defined sector sizes and block counts
|
||||
if (!SetGeometryForCapacity(size)) {
|
||||
// Sector size (default 512 bytes) and number of blocks
|
||||
SetSectorSizeInBytes(GetConfiguredSectorSize() ? GetConfiguredSectorSize() : 512, true);
|
||||
SetBlockCount(size >> GetSectorSize());
|
||||
}
|
||||
|
||||
// File size must be a multiple of the sector size
|
||||
if (size % GetSectorSizeInBytes()) {
|
||||
stringstream error;
|
||||
error << "File size must be a multiple of " << GetSectorSizeInBytes() << " bytes but is " << size << " bytes";
|
||||
throw io_exception(error.str());
|
||||
}
|
||||
|
||||
SetReadOnly(false);
|
||||
SetProtectable(true);
|
||||
|
@ -65,10 +65,6 @@ PbDeviceProperties *ProtobufResponseHandler::GetDeviceProperties(const Device *d
|
||||
properties->add_block_sizes(block_size);
|
||||
}
|
||||
|
||||
for (const auto& capacity : device_factory.GetCapacities(t)) {
|
||||
properties->add_capacities(capacity);
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
@ -160,8 +160,6 @@ message PbDeviceProperties {
|
||||
uint32 luns = 9;
|
||||
// Unordered list of permitted block sizes in bytes, empty if the block size is not configurable
|
||||
repeated uint32 block_sizes = 10;
|
||||
// Unordered list of permitted media capacities in bytes, empty if there is no capacity restriction
|
||||
repeated uint64 capacities = 11;
|
||||
}
|
||||
|
||||
// The status of a device, only meaningful if the respective feature is supported
|
||||
|
@ -231,24 +231,6 @@ void DisplayDeviceTypesInfo(const PbDeviceTypesInfo& device_types_info)
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
if (properties.capacities_size()) {
|
||||
list<uint64_t> capacities = { properties.capacities().begin(), properties.capacities().end() };
|
||||
capacities.sort([](const auto& a, const auto& b) { return a < b; });
|
||||
|
||||
cout << " Media capacities in bytes: ";
|
||||
|
||||
bool isFirst = true;
|
||||
for (const auto& capacity : capacities) {
|
||||
if (!isFirst) {
|
||||
cout << ", ";
|
||||
}
|
||||
cout << capacity;
|
||||
|
||||
isFirst = false;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user