Annotation of nono/vm/scsicmd.h, revision 1.1.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.