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

1.1     ! root        1: //
        !             2: // nono
        !             3: // Copyright (C) 2020 [email protected]
        !             4: //
        !             5: 
        !             6: // SCSI デバイス共通部分
        !             7: 
        !             8: #pragma once
        !             9: 
        !            10: #include "scsibus.h"
        !            11: 
        !            12: //         IODevice              (SPCDevice の親になるため)
        !            13: //             |
        !            14: //             v
        !            15: //         SCSIDevice            (SCSI デバイスとしての共通部分)
        !            16: //             |
        !            17: //      +------+---------+
        !            18: //      v                v
        !            19: // SCSIHostDevice    SCSITarget  (SCSI ホスト/ターゲットとしての共通部分)
        !            20: //      |                |
        !            21: //      v                v
        !            22: //   SPCDevice         SCSIHD    (各デバイス、各ターゲット固有部分)
        !            23: 
        !            24: class SCSICmd;
        !            25: 
        !            26: //
        !            27: // SCSI デバイスとしての共通部分。
        !            28: // これ自体は IODevice ではないが SCSI ホストアダプタがこれを継承するため。
        !            29: //
        !            30: class SCSIDevice : public IODevice
        !            31: {
        !            32:  public:
        !            33:        SCSIDevice();
        !            34:        virtual ~SCSIDevice();
        !            35: 
        !            36:        // バスに接続 (SCSIBus::Attach から呼ばれる)
        !            37:        void Attach(SCSIBus *bus_, int id) {
        !            38:                bus = bus_;
        !            39:                myid = id;
        !            40:        }
        !            41: 
        !            42:        //
        !            43:        // 信号線制御
        !            44:        // (ソースコード的なショートカットのため)
        !            45:        //
        !            46:        bool GetRST() const                             { return bus->GetRST(); }
        !            47:        void AssertRST()                                { bus->AssertRST(); }
        !            48:        void NegateRST()                                { bus->NegateRST(); }
        !            49:        bool GetREQ() const                             { return bus->GetREQ(); }
        !            50:        void AssertREQ()                                { bus->AssertREQ(); }
        !            51:        void NegateREQ()                                { bus->NegateREQ(); }
        !            52:        bool GetACK() const                             { return bus->GetACK(); }
        !            53:        void AssertACK()                                { bus->AssertACK(); }
        !            54:        void NegateACK()                                { bus->NegateACK(); }
        !            55:        bool GetATN() const                             { return bus->GetATN(); }
        !            56:        void AssertATN()                                { bus->AssertATN(); }
        !            57:        void NegateATN()                                { bus->NegateATN(); }
        !            58:        uint8 GetSEL() const                    { return bus->GetSEL(); }
        !            59:        void AssertSEL()                                { bus->AssertSEL(myid); }
        !            60:        void NegateSEL()                                { bus->NegateSEL(myid); }
        !            61:        uint8 GetBSY() const                    { return bus->GetBSY(); }
        !            62:        void AssertBSY()                                { bus->AssertBSY(myid); }
        !            63:        void NegateBSY()                                { bus->NegateBSY(myid); }
        !            64:        bool GetMSG() const                             { return bus->GetMSG(); }
        !            65:        bool GetCD() const                              { return bus->GetCD(); }
        !            66:        bool GetIO() const                              { return bus->GetIO(); }
        !            67:        SCSI::XferPhase GetXfer() const { return bus->GetXfer(); }
        !            68:        void SetXfer(uint8 val)                 { bus->SetXfer(val); }
        !            69:        SCSI::Phase GetPhase() const    { return bus->GetPhase(); }
        !            70:        uint8 GetData() const                   { return bus->GetData(); }
        !            71:        void SetData(uint8 val) const   { bus->SetData(val); }
        !            72: 
        !            73:        //
        !            74:        // SCSIBus コールバック
        !            75:        //
        !            76: 
        !            77:        // バスリセットされた (全員に通知される)
        !            78:        virtual void BusResetCB() { }
        !            79: 
        !            80:        // バスフリーになった (全員に通知される)
        !            81:        virtual void BusFreeCB(int id) { }
        !            82: 
        !            83:        // セレクションで選択された (ターゲットのみ通知される)
        !            84:        virtual void SelectionCB() { }
        !            85: 
        !            86:        // ターゲットがセレクションに応答した (イニシエータのみ通知される)
        !            87:        virtual void SelectionAckCB() { }
        !            88: 
        !            89:        // 情報転送フェーズを開始する (ターゲットのみ通知される)
        !            90:        virtual void StartTransferCB() { }
        !            91: 
        !            92:        // 情報転送フェーズで REQ を立てた (イニシエータのみ通知される)
        !            93:        virtual void TransferReqCB() { }
        !            94: 
        !            95:        // 情報転送フェーズで1バイト送受信が進んだ (ターゲットのみ通知される)
        !            96:        virtual void TransferCB() { }
        !            97: 
        !            98:        // 情報転送フェーズ(マニュアル転送)で ACK を下げた (ターゲットのみ通知)
        !            99:        virtual void TransferAckCB() { }
        !           100: 
        !           101:  protected:
        !           102:        // 自身の ID
        !           103:        uint myid;
        !           104: 
        !           105:        // 自身が繋がっているバスへのポインタ。
        !           106:        // (イニシエータ自身も含めて) 所有していない。
        !           107:        SCSIBus *bus;
        !           108: };
        !           109: 
        !           110: //
        !           111: // ホストデバイスの共通部分。
        !           112: //
        !           113: class SCSIHostDevice : public SCSIDevice
        !           114: {
        !           115:  public:
        !           116:        SCSIHostDevice();
        !           117:        virtual ~SCSIHostDevice();
        !           118: 
        !           119:        virtual bool Create();
        !           120:        virtual bool Init();
        !           121: 
        !           122:        // 設定ファイル上のこのホストデバイスを示す接頭語を返す
        !           123:        const char *GetConfigName() const { return config_name; }
        !           124: 
        !           125:        // バスフリーになった (全員に通知される)
        !           126:        virtual void BusFreeCB(int id);
        !           127: 
        !           128:  protected:
        !           129:        // 設定ファイルに使われるこのホストデバイスを示す接頭語。
        !           130:        // ("spc0" とか)
        !           131:        const char *config_name = NULL;
        !           132: 
        !           133:        // SCSI バス (とターゲットオブジェクト)
        !           134:        //
        !           135:        // ホストデバイスなのでバスオブジェクト(SCSIBus *scsibus)と、このバスに
        !           136:        // 繋がるターゲットデバイスのオブジェクト(SCSITarget *target[]) を所有
        !           137:        // (unique_ptr) している。これはオブジェクト同士の所有関係の話。
        !           138:        // ホストは SCSIDevice を継承しているので target[] にホスト自身は含めない。
        !           139:        //
        !           140:        // それとは別に SCSI バスと SCSI デバイスの仮想的な接続関係があり、
        !           141:        // こっちはすべて所有権のないただのポインタで相互にリンクする。
        !           142:        // これが scsibus->device[] と SCSIDevice::bus の相互リンク。
        !           143:        //
        !           144:        // こんな感じ。
        !           145:        //             SCSIHostDevice
        !           146:        // +-------------------------------------+
        !           147:        // |  scsibus                  target[0] |
        !           148:        // +--- || ----+          +---------- | -+
        !           149:        //      ||     |SCSIDevice|           |
        !           150:        //  ID7 ||<----> bus      |           |
        !           151:        //      ||     +----------+           |
        !           152:        //      ||                            |
        !           153:        //      ||      SCSIHD(SCSIDevice)    |
        !           154:        //      ||     +----------+           |
        !           155:        //  ID0 ||<----> bus      |<----------+
        !           156:        //      ||     +----------+        own
        !           157:        //
        !           158:        std::unique_ptr<SCSIBus> scsibus;
        !           159:        std::unique_ptr<SCSITarget> target[8];
        !           160: };
        !           161: 
        !           162: //
        !           163: // ターゲットデバイスの共通部分。
        !           164: //
        !           165: class SCSITarget : public SCSIDevice
        !           166: {
        !           167:        typedef SCSIDevice inherited;
        !           168:        friend class SCSICmdModeSelect6;
        !           169:  public:
        !           170:        SCSITarget(SCSIHostDevice *h, int id, std::vector<uint8>& inq);
        !           171:        virtual ~SCSITarget();
        !           172: 
        !           173:        // デバイス種別を返す (主にデバッグ表示用)
        !           174:        SCSI::DevType GetDevType() const { return devtype; }
        !           175: 
        !           176:        // Inquiry 応答データ
        !           177:        std::vector<uint8> inquiry_data;
        !           178: 
        !           179:        // 現在のコマンド列を返す (モニタ用)
        !           180:        std::vector<uint8> GetCmdSeq() const { return cmdseq; }
        !           181: 
        !           182:        // SCSIBus コールバック
        !           183: 
        !           184:        // セレクションで選択された (ターゲットのみ通知される)
        !           185:        virtual void SelectionCB();
        !           186: 
        !           187:        // 情報転送フェーズを開始する (ターゲットのみ通知される)
        !           188:        virtual void StartTransferCB();
        !           189: 
        !           190:        // 情報転送フェーズで1バイト送受信が進んだ (ターゲットのみ通知される)
        !           191:        virtual void TransferCB();
        !           192: 
        !           193:        // 情報転送フェーズ(マニュアル転送)で ACK を下げた (ターゲットのみ通知)
        !           194:        virtual void TransferAckCB();
        !           195: 
        !           196:  protected:
        !           197:        // デバイス種別
        !           198:        SCSI::DevType devtype;
        !           199:        // ホスト
        !           200:        SCSIHostDevice *host;
        !           201: 
        !           202:        // コマンド
        !           203:        std::vector<uint8> cmdseq {};
        !           204:        // このコマンドの長さ。
        !           205:        // cmdseq の1バイト目で決まるやつのことで、受信目標バイト数。
        !           206:        // 今何バイト受信しているかは cmdseq.size()。
        !           207:        int cmdlen;
        !           208: 
        !           209:        // SCSI コマンドのディスパッチャ
        !           210:        virtual void DispatchCmd();
        !           211: 
        !           212:        // 現在実行中の SCSI コマンド
        !           213:        std::unique_ptr<SCSICmd> cmd;
        !           214: 
        !           215:        // 現在のフェーズでの転送カウント。
        !           216:        // IN と OUT でカウント方向が違うことに注意。
        !           217:        uint32 bytecount = 0;
        !           218: 
        !           219:        // 現在処理中のバイトが(各)フェーズの最終バイトなら true
        !           220:        bool lastbyte = false;
        !           221: 
        !           222:        // 論理ブロック長 (ModeSelect コマンドでホストから指定される)
        !           223:        // XXX: LUNA88K で ROM がたぶんやる。。。
        !           224:        uint32 blocksize = 512;
        !           225: };
        !           226: 
        !           227: //
        !           228: // SCSI HD
        !           229: //
        !           230: class SCSIHD : public SCSITarget
        !           231: {
        !           232:        typedef SCSITarget inherited;
        !           233:        friend class SCSICmdRead6;
        !           234:        friend class SCSICmdWrite6;
        !           235:        friend class SCSICmdReadCapacity;
        !           236:        friend class SCSICmdRead10;
        !           237:  public:
        !           238:        SCSIHD(SCSIHostDevice *h, int id);
        !           239:        virtual ~SCSIHD();
        !           240: 
        !           241:        virtual bool Init();
        !           242:        virtual void DispatchCmd();
        !           243: 
        !           244:  private:
        !           245:        int fd = 0;
        !           246:        uint8 *mem = NULL;
        !           247:        size_t memlen = 0;
        !           248:        bool writeprotect = false;
        !           249: 
        !           250:        static std::vector<uint8> inquiry_data;
        !           251: };

unix.superglobalmegacorp.com

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