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