mirror of
https://github.com/akuker/RASCSI.git
synced 2024-05-29 01:41:27 +00:00
5622694701
* Initial RTC skeleton * Added device info * Added TEST UNIT READY * Fixed command dispatcher * First untested naive implementation * Comment update * Code cleanup * More code cleanup * Updated date/time encoding * Updated versioning * Use standard RaSCSI INQUIRY version for SCRT device * Manpage update * Added shortcut for SCRT type * Added support for rtc "filename" * RTC supports LUNs > 0 * Fixed LUN count * Renaming * Renaming * Manpage update * Initial naive implementation * SCRA is removable * Updated command list * Added controller field * Shut down works, bus free phase is not yet entered * Clear caches on shutdown * Expose BusFree() * Moved code * Logging update * Moved code * Moved code * Added comment * Logging update * Code cleanup * Service device is not removable anymore (was only needed for testing) * Manpage update * Added comment * Comment update * Version update * Renaming * Comment update * Comment update * Renaming * Fixed typo * Added convenience method * Property handling optimization * Code cleanup * Code cleanup * Code cleanup, introduced base class * Added TODO * More code cleanup * Removed unnecessary assignments * Moved code * Removed forward declaration * Added base class * INclude cleanup * Moved scsi_command enum * Fixed warnings * Addressing circular dependencies * Removed duplicate enum * include file cleanup * Include cleanup * Reduced dependencies to Disk class (replaced by Device), fixed TODO * Include cleanup * PrimaryDevice implements ReportLuns * Inheritance update * Removed duplicate code * Moved code to base class * Cleanup * Removed duplicate field * Updated command dispatchign * Comment update * Moved code * Updated method visibilities * Moved MODE SENSE/MODE SELECT base code
168 lines
5.2 KiB
C++
168 lines
5.2 KiB
C++
//---------------------------------------------------------------------------
|
||
//
|
||
// X68000 EMULATOR "XM6"
|
||
//
|
||
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
||
// Copyright (C) 2014-2020 GIMONS
|
||
//
|
||
// XM6i
|
||
// Copyright (C) 2010-2015 isaki@NetBSD.org
|
||
//
|
||
// Imported sava's Anex86/T98Next image and MO format support patch.
|
||
// Comments translated to english by akuker.
|
||
//
|
||
// [ Disk ]
|
||
//
|
||
//---------------------------------------------------------------------------
|
||
|
||
#pragma once
|
||
|
||
#include "log.h"
|
||
#include "scsi.h"
|
||
#include "controllers/scsidev_ctrl.h"
|
||
#include "device.h"
|
||
#include "device_factory.h"
|
||
#include "disk_track_cache.h"
|
||
#include "file_support.h"
|
||
#include "filepath.h"
|
||
#include "interfaces/scsi_block_commands.h"
|
||
#include "interfaces/scsi_primary_commands.h"
|
||
#include "mode_page_device.h"
|
||
#include <string>
|
||
#include <set>
|
||
#include <map>
|
||
|
||
class Disk : public ModePageDevice, ScsiBlockCommands
|
||
{
|
||
private:
|
||
enum access_mode { RW6, RW10, RW16 };
|
||
|
||
// The supported configurable block sizes, empty if not configurable
|
||
set<uint32_t> sector_sizes;
|
||
uint32_t configured_sector_size;
|
||
|
||
// The mapping of supported capacities to block sizes and block counts, empty if there is no capacity restriction
|
||
map<uint64_t, Geometry> geometries;
|
||
|
||
typedef struct {
|
||
uint32_t size; // Sector Size (8=256, 9=512, 10=1024, 11=2048, 12=4096)
|
||
// TODO blocks should be a 64 bit value in order to support higher capacities
|
||
uint32_t blocks; // Total number of sectors
|
||
DiskCache *dcache; // Disk cache
|
||
off_t image_offset; // Offset to actual data
|
||
} disk_t;
|
||
|
||
typedef struct _command_t {
|
||
const char* name;
|
||
void (Disk::*execute)(SASIDEV *);
|
||
|
||
_command_t(const char* _name, void (Disk::*_execute)(SASIDEV *)) : name(_name), execute(_execute) { };
|
||
} command_t;
|
||
std::map<ScsiDefs::scsi_command, command_t*> commands;
|
||
|
||
void AddCommand(ScsiDefs::scsi_command, const char*, void (Disk::*)(SASIDEV *));
|
||
|
||
public:
|
||
Disk(std::string);
|
||
virtual ~Disk();
|
||
|
||
virtual bool Dispatch(SCSIDEV *) override;
|
||
|
||
void ReserveFile(const string&);
|
||
|
||
// Media Operations
|
||
virtual void Open(const Filepath& path);
|
||
void GetPath(Filepath& path) const;
|
||
bool Eject(bool) override;
|
||
|
||
private:
|
||
|
||
// Commands covered by the SCSI specification (see https://www.t10.org/drafts.htm)
|
||
void StartStopUnit(SASIDEV *) override;
|
||
void SendDiagnostic(SASIDEV *) override;
|
||
void PreventAllowMediumRemoval(SASIDEV *);
|
||
void SynchronizeCache10(SASIDEV *) override;
|
||
void SynchronizeCache16(SASIDEV *) override;
|
||
void ReadDefectData10(SASIDEV *);
|
||
virtual void Read6(SASIDEV *);
|
||
void Read10(SASIDEV *) override;
|
||
void Read16(SASIDEV *) override;
|
||
virtual void Write6(SASIDEV *);
|
||
void Write10(SASIDEV *) override;
|
||
void Write16(SASIDEV *) override;
|
||
void ReadLong10(SASIDEV *) override;
|
||
void ReadLong16(SASIDEV *) override;
|
||
void WriteLong10(SASIDEV *) override;
|
||
void WriteLong16(SASIDEV *) override;
|
||
void Verify10(SASIDEV *) override;
|
||
void Verify16(SASIDEV *) override;
|
||
void Seek(SASIDEV *);
|
||
void Seek10(SASIDEV *);
|
||
void ReadCapacity10(SASIDEV *) override;
|
||
void ReadCapacity16(SASIDEV *) override;
|
||
void Reserve6(SASIDEV *);
|
||
void Reserve10(SASIDEV *);
|
||
void Release6(SASIDEV *);
|
||
void Release10(SASIDEV *);
|
||
|
||
public:
|
||
|
||
// Commands covered by the SCSI specification (see https://www.t10.org/drafts.htm)
|
||
void Rezero(SASIDEV *);
|
||
void FormatUnit(SASIDEV *) override;
|
||
void ReassignBlocks(SASIDEV *) override;
|
||
void Seek6(SASIDEV *);
|
||
|
||
// Command helpers
|
||
virtual int Inquiry(const DWORD *cdb, BYTE *buf) = 0; // INQUIRY command
|
||
virtual int WriteCheck(DWORD block); // WRITE check
|
||
virtual bool Write(const DWORD *cdb, const BYTE *buf, DWORD block); // WRITE command
|
||
bool StartStop(const DWORD *cdb); // START STOP UNIT command
|
||
bool SendDiag(const DWORD *cdb); // SEND DIAGNOSTIC command
|
||
|
||
virtual int Read(const DWORD *cdb, BYTE *buf, uint64_t block);
|
||
int ReadDefectData10(const DWORD *cdb, BYTE *buf);
|
||
|
||
uint32_t GetSectorSizeInBytes() const;
|
||
void SetSectorSizeInBytes(uint32_t, bool);
|
||
uint32_t GetSectorSizeShiftCount() const;
|
||
void SetSectorSizeShiftCount(uint32_t);
|
||
bool IsSectorSizeConfigurable() const;
|
||
set<uint32_t> GetSectorSizes() const;
|
||
void SetSectorSizes(const set<uint32_t>&);
|
||
uint32_t GetConfiguredSectorSize() const;
|
||
bool SetConfiguredSectorSize(uint32_t);
|
||
void SetGeometries(const map<uint64_t, Geometry>&);
|
||
bool SetGeometryForCapacity(uint64_t);
|
||
uint64_t GetBlockCount() const;
|
||
void SetBlockCount(uint32_t);
|
||
bool CheckBlockAddress(SASIDEV *, access_mode);
|
||
bool GetStartAndCount(SASIDEV *, uint64_t&, uint32_t&, access_mode);
|
||
|
||
protected:
|
||
int ModeSense6(const DWORD *cdb, BYTE *buf);
|
||
int ModeSense10(const DWORD *cdb, BYTE *buf);
|
||
virtual int AddErrorPage(bool change, BYTE *buf);
|
||
virtual int AddFormatPage(bool change, BYTE *buf);
|
||
virtual int AddDrivePage(bool change, BYTE *buf);
|
||
virtual int AddVendorPage(int page, bool change, BYTE *buf);
|
||
int AddOptionPage(bool change, BYTE *buf);
|
||
int AddCachePage(bool change, BYTE *buf);
|
||
int AddCDROMPage(bool change, BYTE *buf);
|
||
int AddCDDAPage(bool, BYTE *buf);
|
||
|
||
// Internal disk data
|
||
disk_t disk;
|
||
|
||
set<Disk *> disks;
|
||
|
||
private:
|
||
void Read(SASIDEV *, uint64_t);
|
||
void Write(SASIDEV *, uint64_t);
|
||
void Verify(SASIDEV *, uint64_t);
|
||
void ReadWriteLong10(SASIDEV *);
|
||
void ReadWriteLong16(SASIDEV *);
|
||
void ReadCapacity16_ReadLong16(SASIDEV *);
|
||
bool Format(const DWORD *cdb);
|
||
};
|