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

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

unix.superglobalmegacorp.com

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