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

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: 
                     42:        // このコマンドの動作時間 [nsec]
                     43:        // シークタイムとかを簡易的に再現するため、次フェーズ遷移時の最初の
                     44:        // REQ アサートを引き延ばすために使う。
                     45:        // 主にコマンドフェーズで使うことになると思う。
                     46:        uint64 optime {};
                     47: 
                     48:        // 以下いずれも戻り値は遷移先のフェーズ。
                     49: 
                     50:        // コマンドフェーズを処理する。
                     51:        // コマンドが確定したところで呼ばれる。戻り値に遷移先フェーズを返すこと。
                     52:        // また、コマンド開始時に各自で ClearSense() を呼ぶこと。センスというか
                     53:        // CA 状態は次のコマンド実行でクリアされるが (ネクサスはとりあえず無視)、
                     54:        // RequestSense の場合は現在保持しているセンス情報をホストに返すので、
                     55:        // つまり RequestSense 以外のコマンドが全員各自でクリアする必要がある。
                     56:        virtual SCSI::XferPhase Command(std::vector<uint8>& cmdseq);
                     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: 
                     99:  protected:
                    100:        // このコマンドを実行しているターゲットデバイス。
1.1.1.3   root      101:        SCSITarget *parent {};
1.1       root      102: 
                    103:        // ステータスバイト (デフォルトは 0 = Good)
                    104:        uint8 status_byte {};
                    105: };
                    106: 
                    107: //
                    108: // SCSI コマンド: サポートしていないコマンド
                    109: //
                    110: class SCSICmdNotSupportedCommand : public SCSICmd
                    111: {
                    112:        using inherited = SCSICmd;
                    113:  public:
1.1.1.7 ! root      114:        explicit SCSICmdNotSupportedCommand(SCSITarget *);
1.1.1.6   root      115:        ~SCSICmdNotSupportedCommand() override;
1.1       root      116: 
                    117:        SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
                    118: };
                    119: 
                    120: //
                    121: // SCSI コマンド 0x03 RequestSense (共通)
                    122: //
                    123: class SCSICmdRequestSense : public SCSICmd
                    124: {
                    125:        using inherited = SCSICmd;
                    126:  public:
1.1.1.7 ! root      127:        explicit SCSICmdRequestSense(SCSITarget *);
1.1.1.6   root      128:        ~SCSICmdRequestSense() override;
1.1       root      129: 
                    130:        SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
                    131: };
                    132: 
                    133: //
                    134: // SCSI コマンド 0x08 Read(6)  (DA / CD-ROM)
                    135: //               0x28 Read(10) (DA / CD-ROM)
                    136: //
                    137: class SCSICmdRead : public SCSICmd
                    138: {
                    139:        using inherited = SCSICmd;
                    140:  public:
1.1.1.7 ! root      141:        explicit SCSICmdRead(SCSIDisk *);
1.1.1.6   root      142:        ~SCSICmdRead() override;
1.1       root      143: 
                    144:        SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
                    145: 
                    146:  private:
                    147:        SCSIDisk *disk {};
                    148: };
                    149: 
                    150: //
                    151: // SCSI コマンド 0x0a Write(6)  (DA / CD-ROM)
                    152: //               0x2a Write(10) (DA / CD-ROM)
                    153: //
                    154: class SCSICmdWrite : public SCSICmd
                    155: {
                    156:        using inherited = SCSICmd;
                    157:  public:
1.1.1.7 ! root      158:        explicit SCSICmdWrite(SCSIDisk *);
1.1.1.6   root      159:        ~SCSICmdWrite() override;
1.1       root      160: 
                    161:        SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
                    162:        SCSI::XferPhase DoneDataOut() override;
                    163: 
                    164:  private:
                    165:        uint8 cmd {};
                    166:        SCSIDisk *disk {};
                    167:        uint32 lba {};
                    168:        uint32 blks {};
                    169: };
                    170: 
                    171: //
                    172: // SCSI コマンド 0x12 Inquiry (共通)
                    173: //
                    174: class SCSICmdInquiry : public SCSICmd
                    175: {
                    176:        using inherited = SCSICmd;
                    177:  public:
1.1.1.7 ! root      178:        explicit SCSICmdInquiry(SCSITarget *);
1.1.1.6   root      179:        ~SCSICmdInquiry() override;
1.1       root      180: 
                    181:        SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
                    182: };
                    183: 
                    184: //
                    185: // SCSI コマンド 0x15 ModeSelect(6)  (共通)
                    186: //               0x55 ModeSelect(10) (共通)
                    187: //
                    188: class SCSICmdModeSelect : public SCSICmd
                    189: {
                    190:        using inherited = SCSICmd;
                    191:  public:
1.1.1.7 ! root      192:        explicit SCSICmdModeSelect(SCSITarget *);
1.1.1.6   root      193:        ~SCSICmdModeSelect() override;
1.1       root      194: 
                    195:        SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
                    196:        SCSI::XferPhase DoneDataOut() override;
                    197: 
                    198:  private:
                    199:        uint8 cmd {};
                    200: };
                    201: 
                    202: //
                    203: // SCSI コマンド 0x1a ModeSense(6)  (共通)
                    204: //               0x5a ModeSense(10) (共通)
                    205: //
                    206: class SCSICmdModeSense : public SCSICmd
                    207: {
                    208:        using inherited = SCSICmd;
                    209:  public:
1.1.1.7 ! root      210:        explicit SCSICmdModeSense(SCSITarget *);
1.1.1.6   root      211:        ~SCSICmdModeSense() override;
1.1       root      212: 
                    213:        SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
                    214: 
                    215:  private:
                    216:        // Page Control
                    217:        enum PC {
                    218:                Current         = 0x00, // 現在値
                    219:                Changeable      = 0x01, // 変更可能値
                    220:                Default         = 0x02, // デフォルト値
                    221:                Saved           = 0x03, // セーブ値
                    222:        };
                    223:        // ページ処理関数の戻り値 (この値は大小比較する)
                    224:        enum ModePageResult {
1.1.1.4   root      225:                NotSupported    = -1,   // 未実装や知らないページ
1.1       root      226:                Failed                  = 0,    // 対応しない/出来ないと分かっているページ
                    227:                Success                 = 1,    // 成功
                    228:        };
                    229: 
1.1.1.2   root      230:        using PageFunc = ModePageResult (SCSICmdModeSense::*)();
                    231: 
1.1       root      232:        // 個別ページ処理
1.1.1.2   root      233:        ModePageResult AddNotSupportedPage();
                    234:        ModePageResult AddEmptyPage();
                    235:        ModePageResult AddCachingPage();
1.1       root      236: 
                    237:        // ページ処理関数のため
                    238:        uint pagecode {};
                    239:        PC pc {};
                    240: 
                    241:        // ログ用の文字列
                    242:        std::string log {};
1.1.1.2   root      243: 
                    244:        static const std::vector<std::pair<uint8, PageFunc>> Pagelist;
1.1       root      245: };
                    246: 
                    247: //
                    248: // SCSI コマンド 0x1b StartStopUnit (DA / CD-ROM)
                    249: //
                    250: class SCSICmdStartStopUnit : public SCSICmd
                    251: {
                    252:        using inherited = SCSICmd;
                    253:  public:
1.1.1.7 ! root      254:        explicit SCSICmdStartStopUnit(SCSIDisk *);
1.1.1.6   root      255:        ~SCSICmdStartStopUnit() override;
1.1       root      256: 
                    257:        SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
                    258: 
                    259:  private:
                    260:        SCSIDisk *disk {};
                    261: };
                    262: 
                    263: //
                    264: // SCSI コマンド 0x1e PreventAllowMediumRemoval (DA / CD-ROM)
                    265: //
                    266: class SCSICmdPreventAllowMediumRemoval : public SCSICmd
                    267: {
                    268:        using inherited = SCSICmd;
                    269:  public:
1.1.1.7 ! root      270:        explicit SCSICmdPreventAllowMediumRemoval(SCSIDisk *);
1.1.1.6   root      271:        ~SCSICmdPreventAllowMediumRemoval() override;
1.1       root      272: 
                    273:        SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
                    274: 
                    275:  private:
                    276:        SCSIDisk *disk {};
                    277: };
                    278: 
                    279: //
                    280: // SCSI コマンド 0x25 ReadCapacity        (DA)
                    281: //               0x25 Read CDROM Capacity (CD-ROM)
                    282: // (ここでは ReadCapacity として同一視する)
                    283: //
                    284: class SCSICmdReadCapacity : public SCSICmd
                    285: {
                    286:        using inherited = SCSICmd;
                    287:  public:
1.1.1.7 ! root      288:        explicit SCSICmdReadCapacity(SCSIDisk *);
1.1.1.6   root      289:        ~SCSICmdReadCapacity() override;
1.1       root      290: 
                    291:        SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
                    292: 
                    293:  private:
                    294:        SCSIDisk *disk {};
                    295: };
                    296: 
                    297: //
                    298: // SCSI コマンド 0x43 ReadTOC (CD-ROM)
                    299: //
                    300: class SCSICmdReadTOC : public SCSICmd
                    301: {
                    302:        using inherited = SCSICmd;
                    303:  public:
1.1.1.7 ! root      304:        explicit SCSICmdReadTOC(SCSIDisk *);
1.1.1.6   root      305:        ~SCSICmdReadTOC() override;
1.1       root      306: 
                    307:        SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
                    308: 
                    309:  private:
                    310:        SCSIDisk *disk {};
                    311: };

unix.superglobalmegacorp.com

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