//--------------------------------------------------------------------------- // // SCSI Target Emulator PiSCSI // for Raspberry Pi // // Copyright (C) 2024 BogDan Vatra // //--------------------------------------------------------------------------- #pragma once #include "storage_device.h" #include class File { FILE *file = nullptr; inline auto checkSize(auto size) const { if (size < 0) throw scsi_exception(sense_key::medium_error); return size; } public: ~File(); bool open(std::string_view filename); void rewind(); size_t read(uint8_t* buff, size_t size, size_t count = 1); size_t write(const uint8_t *buff, size_t size, size_t count = 1); void seek(long offset, int origin); long tell(); void close(); }; class SCSIST: public StorageDevice { public: SCSIST(int lun); public: bool Init(const param_map &pm) final; void CleanUp() final; private: void Erase(); void Read6(); void ReadBlockLimits() const; void Rewind(); void Space(); void Write6(); void WriteFilemarks(); void LoadUnload(); void ReadPosition(); void Verify(); int ModeSense6(cdb_t cdb, std::vector &buf) const final; int ModeSense10(cdb_t, std::vector &) const final; // PrimaryDevice interface protected: std::vector InquiryInternal() const final; // ModePageDevice interface protected: void ModeSelect(scsi_defs::scsi_command, cdb_t, span, int) final; void SetUpModePages(std::map > &, int, bool) const final; // StorageDevice interface private: void Write(span, uint64_t) final; int Read(span , uint64_t) final; public: void Open() final; void AddBlockDescriptorPage(std::map > &, bool) const; void AddErrorPage(map > &, bool) const; void AddReconnectPage(map > &, bool) const; void AddDevicePage(map > &, bool) const; void AddMediumPartitionPage(map > &, bool) const; void AddMiscellaneousPage(map > &, bool) const; bool Eject(bool force) override; private: File file; };