Annotation of nono/vm/scsicmd.h, revision 1.1

1.1     ! root        1: //
        !             2: // nono
        !             3: // Copyright (C) 2021 nono project
        !             4: // Licensed under nono-license.txt
        !             5: //
        !             6: 
        !             7: // SCSI コマンド
        !             8: 
        !             9: #pragma once
        !            10: 
        !            11: #include "scsi.h"
        !            12: #include <functional>
        !            13: #include <vector>
        !            14: 
        !            15: // READ/WRITE は多すぎるのでログを省略したい場合に定義。
        !            16: //#define NO_READWRITE_LOG
        !            17: 
        !            18: class SCSITarget;
        !            19: 
        !            20: //
        !            21: // SCSI コマンドの基本クラス
        !            22: // (黙って成功するコマンドとしても使用可能)
        !            23: //
        !            24: class SCSICmd
        !            25: {
        !            26:  public:
        !            27:        SCSICmd(SCSITarget *parent_);
        !            28:        virtual ~SCSICmd();
        !            29: 
        !            30:        // 転送バッファと転送バイト数。
        !            31:        // IN (ターゲットが送出側)なら、各フェーズ開始までに送出バイト数分の
        !            32:        // バッファを buf に用意すること。recvbytes は操作不要。
        !            33:        //
        !            34:        // OUT(ターゲットが受信側)なら、各フェーズ開始前までに受信バイト数を
        !            35:        // recvbytes にセットすること。buf は操作不要。
        !            36:        // なお parent は OUT(受信)フェーズ中にこの recvbytes を変更しない。
        !            37:        std::vector<uint8> buf;
        !            38:        uint32 recvbytes;
        !            39: 
        !            40:        // このコマンドの動作時間 [nsec]
        !            41:        // シークタイムとかを簡易的に再現するため、次フェーズ遷移時の最初の
        !            42:        // REQ アサートを引き延ばすために使う。
        !            43:        // 主にコマンドフェーズで使うことになると思う。
        !            44:        uint64 optime {};
        !            45: 
        !            46:        // 以下いずれも戻り値は遷移先のフェーズ。
        !            47: 
        !            48:        // コマンドフェーズを処理する。
        !            49:        // コマンドが確定したところで呼ばれる。戻り値に遷移先フェーズを返すこと。
        !            50:        // また、コマンド開始時に各自で ClearSense() を呼ぶこと。センスというか
        !            51:        // CA 状態は次のコマンド実行でクリアされるが (ネクサスはとりあえず無視)、
        !            52:        // RequestSense の場合は現在保持しているセンス情報をホストに返すので、
        !            53:        // つまり RequestSense 以外のコマンドが全員各自でクリアする必要がある。
        !            54:        virtual SCSI::XferPhase Command(std::vector<uint8>& cmdseq);
        !            55: 
        !            56:        // データインフェーズを完了する。
        !            57:        virtual SCSI::XferPhase DoneDataIn() {
        !            58:                return SCSI::XferPhase::Status;
        !            59:        }
        !            60: 
        !            61:        // データアウトフェーズを完了する。
        !            62:        virtual SCSI::XferPhase DoneDataOut() {
        !            63:                return SCSI::XferPhase::Status;
        !            64:        }
        !            65: 
        !            66:        // ステータスフェーズを開始する。
        !            67:        void BeginStatus() {
        !            68:                buf.clear();
        !            69:                buf.push_back(status_byte);
        !            70:        }
        !            71: 
        !            72:        // ステータスフェーズを完了する。
        !            73:        virtual SCSI::XferPhase DoneStatus() {
        !            74:                return SCSI::XferPhase::MsgIn;
        !            75:        }
        !            76: 
        !            77:        // メッセージインフェーズを開始する。
        !            78:        // デフォルトでは Command Complete を返す実装を用意しておく。
        !            79:        virtual void BeginMsgIn() {
        !            80:                buf.clear();
        !            81:                buf.push_back((uint8)SCSI::MsgByte::CommandComplete);
        !            82:        }
        !            83: 
        !            84:        // メッセージインフェーズを完了する。
        !            85:        virtual SCSI::XferPhase DoneMsgIn() {
        !            86:                return SCSI::XferPhase::End;
        !            87:        }
        !            88: 
        !            89:        // メッセージアウトフェーズを開始する。
        !            90:        virtual void BeginMsgOut() { }
        !            91: 
        !            92:        // メッセージアウトフェーズを完了する。
        !            93:        virtual SCSI::XferPhase DoneMsgOut() {
        !            94:                return SCSI::XferPhase::End;
        !            95:        }
        !            96: 
        !            97:  protected:
        !            98:        // このコマンドを実行しているターゲットデバイス。
        !            99:        SCSITarget *parent;
        !           100: 
        !           101:        // ステータスバイト (デフォルトは 0 = Good)
        !           102:        uint8 status_byte {};
        !           103: };
        !           104: 
        !           105: //
        !           106: // SCSI コマンド: サポートしていないコマンド
        !           107: //
        !           108: class SCSICmdNotSupportedCommand : public SCSICmd
        !           109: {
        !           110:        using inherited = SCSICmd;
        !           111:  public:
        !           112:        SCSICmdNotSupportedCommand(SCSITarget *);
        !           113:        virtual ~SCSICmdNotSupportedCommand() override;
        !           114: 
        !           115:        SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
        !           116: };
        !           117: 
        !           118: //
        !           119: // SCSI コマンド 0x03 RequestSense (共通)
        !           120: //
        !           121: class SCSICmdRequestSense : public SCSICmd
        !           122: {
        !           123:        using inherited = SCSICmd;
        !           124:  public:
        !           125:        SCSICmdRequestSense(SCSITarget *);
        !           126:        virtual ~SCSICmdRequestSense() override;
        !           127: 
        !           128:        SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
        !           129: };
        !           130: 
        !           131: //
        !           132: // SCSI コマンド 0x08 Read(6)  (DA / CD-ROM)
        !           133: //               0x28 Read(10) (DA / CD-ROM)
        !           134: //
        !           135: class SCSICmdRead : public SCSICmd
        !           136: {
        !           137:        using inherited = SCSICmd;
        !           138:  public:
        !           139:        SCSICmdRead(SCSIDisk *);
        !           140:        virtual ~SCSICmdRead() override;
        !           141: 
        !           142:        SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
        !           143: 
        !           144:  private:
        !           145:        SCSIDisk *disk {};
        !           146: };
        !           147: 
        !           148: //
        !           149: // SCSI コマンド 0x0a Write(6)  (DA / CD-ROM)
        !           150: //               0x2a Write(10) (DA / CD-ROM)
        !           151: //
        !           152: class SCSICmdWrite : public SCSICmd
        !           153: {
        !           154:        using inherited = SCSICmd;
        !           155:  public:
        !           156:        SCSICmdWrite(SCSIDisk *);
        !           157:        virtual ~SCSICmdWrite() override;
        !           158: 
        !           159:        SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
        !           160:        SCSI::XferPhase DoneDataOut() override;
        !           161: 
        !           162:  private:
        !           163:        uint8 cmd {};
        !           164:        SCSIDisk *disk {};
        !           165:        uint32 lba {};
        !           166:        uint32 blks {};
        !           167: };
        !           168: 
        !           169: //
        !           170: // SCSI コマンド 0x12 Inquiry (共通)
        !           171: //
        !           172: class SCSICmdInquiry : public SCSICmd
        !           173: {
        !           174:        using inherited = SCSICmd;
        !           175:  public:
        !           176:        SCSICmdInquiry(SCSITarget *);
        !           177:        virtual ~SCSICmdInquiry() override;
        !           178: 
        !           179:        SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
        !           180: };
        !           181: 
        !           182: //
        !           183: // SCSI コマンド 0x15 ModeSelect(6)  (共通)
        !           184: //               0x55 ModeSelect(10) (共通)
        !           185: //
        !           186: class SCSICmdModeSelect : public SCSICmd
        !           187: {
        !           188:        using inherited = SCSICmd;
        !           189:  public:
        !           190:        SCSICmdModeSelect(SCSITarget *);
        !           191:        virtual ~SCSICmdModeSelect() override;
        !           192: 
        !           193:        SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
        !           194:        SCSI::XferPhase DoneDataOut() override;
        !           195: 
        !           196:  private:
        !           197:        uint8 cmd {};
        !           198: };
        !           199: 
        !           200: //
        !           201: // SCSI コマンド 0x1a ModeSense(6)  (共通)
        !           202: //               0x5a ModeSense(10) (共通)
        !           203: //
        !           204: class SCSICmdModeSense : public SCSICmd
        !           205: {
        !           206:        using inherited = SCSICmd;
        !           207:  public:
        !           208:        SCSICmdModeSense(SCSITarget *);
        !           209:        virtual ~SCSICmdModeSense() override;
        !           210: 
        !           211:        SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
        !           212: 
        !           213:  private:
        !           214:        using PageFunc = std::function<int(void)>;
        !           215: 
        !           216:        // Page Control
        !           217:        enum PC {
        !           218:                Current         = 0x00, // 現在値
        !           219:                Changeable      = 0x01, // 変更可能値
        !           220:                Default         = 0x02, // デフォルト値
        !           221:                Saved           = 0x03, // セーブ値
        !           222:        };
        !           223:        // ページ処理関数の戻り値 (この値は大小比較する)
        !           224:        enum ModePageResult {
        !           225:                NotImplemented  = -1,   // 未実装や知らないページ
        !           226:                Failed                  = 0,    // 対応しない/出来ないと分かっているページ
        !           227:                Success                 = 1,    // 成功
        !           228:        };
        !           229: 
        !           230:        // 個別ページ処理
        !           231:        int AddNotSupportedPage();
        !           232:        int AddEmptyPage();
        !           233:        int AddCachingPage();
        !           234: 
        !           235:        // ページ処理関数のため
        !           236:        uint pagecode {};
        !           237:        PC pc {};
        !           238: 
        !           239:        // ログ用の文字列
        !           240:        std::string log {};
        !           241: };
        !           242: 
        !           243: //
        !           244: // SCSI コマンド 0x1b StartStopUnit (DA / CD-ROM)
        !           245: //
        !           246: class SCSICmdStartStopUnit : public SCSICmd
        !           247: {
        !           248:        using inherited = SCSICmd;
        !           249:  public:
        !           250:        SCSICmdStartStopUnit(SCSIDisk *);
        !           251:        virtual ~SCSICmdStartStopUnit() override;
        !           252: 
        !           253:        SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
        !           254: 
        !           255:  private:
        !           256:        SCSIDisk *disk {};
        !           257: };
        !           258: 
        !           259: //
        !           260: // SCSI コマンド 0x1e PreventAllowMediumRemoval (DA / CD-ROM)
        !           261: //
        !           262: class SCSICmdPreventAllowMediumRemoval : public SCSICmd
        !           263: {
        !           264:        using inherited = SCSICmd;
        !           265:  public:
        !           266:        SCSICmdPreventAllowMediumRemoval(SCSIDisk *);
        !           267:        virtual ~SCSICmdPreventAllowMediumRemoval() override;
        !           268: 
        !           269:        SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
        !           270: 
        !           271:  private:
        !           272:        SCSIDisk *disk {};
        !           273: };
        !           274: 
        !           275: //
        !           276: // SCSI コマンド 0x25 ReadCapacity        (DA)
        !           277: //               0x25 Read CDROM Capacity (CD-ROM)
        !           278: // (ここでは ReadCapacity として同一視する)
        !           279: //
        !           280: class SCSICmdReadCapacity : public SCSICmd
        !           281: {
        !           282:        using inherited = SCSICmd;
        !           283:  public:
        !           284:        SCSICmdReadCapacity(SCSIDisk *);
        !           285:        virtual ~SCSICmdReadCapacity() override;
        !           286: 
        !           287:        SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
        !           288: 
        !           289:  private:
        !           290:        SCSIDisk *disk {};
        !           291: };
        !           292: 
        !           293: //
        !           294: // SCSI コマンド 0x43 ReadTOC (CD-ROM)
        !           295: //
        !           296: class SCSICmdReadTOC : public SCSICmd
        !           297: {
        !           298:        using inherited = SCSICmd;
        !           299:  public:
        !           300:        SCSICmdReadTOC(SCSIDisk *);
        !           301:        virtual ~SCSICmdReadTOC() override;
        !           302: 
        !           303:        SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
        !           304: 
        !           305:  private:
        !           306:        SCSIDisk *disk {};
        !           307: };

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.