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

1.1     ! root        1: //
        !             2: // nono
        !             3: // Copyright (C) 2018 [email protected]
        !             4: //
        !             5: 
        !             6: #pragma once
        !             7: 
        !             8: #include "device.h"
        !             9: 
        !            10: class SCSI
        !            11: {
        !            12:  public:
        !            13:        // デバイス種別
        !            14:        enum DevType {
        !            15:                None = 0,
        !            16:                HD = 1,
        !            17:        };
        !            18: 
        !            19:        // フェーズは、バスフェーズと転送フェーズを一緒くたで扱う。
        !            20:        // 0から7までは転送フェーズを表しているのでこの順序を守ること。
        !            21:        // 8以上はバスフェーズを表している。
        !            22:        struct Phase {                                                          // MSG CD IO
        !            23:                static const uint DataOut               = 0x00; //   0  0  0
        !            24:                static const uint DataIn                = 0x01; //   0  0  1
        !            25:                static const uint Command               = 0x02; //   0  1  0
        !            26:                static const uint Status                = 0x03; //   0  1  1
        !            27:                static const uint MsgOut                = 0x06; //   1  1  0
        !            28:                static const uint MsgIn                 = 0x07; //   1  1  1
        !            29: 
        !            30:                static const uint BusFree               = 8;
        !            31:                static const uint Arbitration   = 9;
        !            32:                static const uint Selection             = 10;
        !            33:                static const uint Reselection   = 11;
        !            34: 
        !            35:                static const uint MAX                   = 12;   // 最大値 +1 にすること
        !            36:        };
        !            37: 
        !            38:        // コマンド。
        !            39:        // ダイレクトアクセスデバイスのコマンドを元にしている。
        !            40:        // シーケンシャルアクセスデバイスでは 0x01 が Rewind だったり
        !            41:        // 同じコードで違うコマンドのようだが、とりあえずそれは放置。
        !            42:        struct Command {
        !            43:                // Group0
        !            44:                static const uint TestUnitReady         = 0x00;         // 共通
        !            45:                static const uint RezeroUnit            = 0x01;
        !            46:                static const uint RequestSense          = 0x03;         // 共通
        !            47:                static const uint FormatUnit            = 0x04;
        !            48:                static const uint ReassignBlocks        = 0x07;
        !            49:                static const uint Read6                         = 0x08;
        !            50:                static const uint Write6                        = 0x0a;
        !            51:                static const uint Seek6                         = 0x0b;
        !            52:                static const uint Inquiry                       = 0x12;         // 共通
        !            53:                static const uint ModeSelect6           = 0x15;         // 共通
        !            54:                static const uint Reserve                       = 0x16;
        !            55:                static const uint Release                       = 0x17;
        !            56:                static const uint Copy                          = 0x18;         // 共通
        !            57:                static const uint ModeSense6            = 0x1a;
        !            58:                static const uint StartStopUnit         = 0x1b;
        !            59:                static const uint ReceiveDiagnosticResults      = 0x1c; // 共通
        !            60:                static const uint SendDiagnostic        = 0x1d;         // 共通
        !            61:                static const uint PreventAllowMediumRemoval     = 0x1e;
        !            62:                // Group1
        !            63:                static const uint ReadCapacity          = 0x25;
        !            64:                static const uint Read10                        = 0x28;
        !            65:                static const uint Write10                       = 0x2a;
        !            66:                static const uint Seek10                        = 0x2b;
        !            67:                // Group1
        !            68:                static const uint WriteAndVerify10      = 0x2e;
        !            69:                static const uint Verify10                      = 0x2f;
        !            70:                static const uint SearchDataHigh10      = 0x30;
        !            71:                static const uint SearchDataEqual10     = 0x31;
        !            72:                static const uint SearchDataLow10       = 0x32;
        !            73:                static const uint SetLimits                     = 0x33;
        !            74:                static const uint PreFetch                      = 0x34;
        !            75:                static const uint SynchronizeCache      = 0x35;
        !            76:                static const uint LockUnlockCache       = 0x36;
        !            77:                static const uint ReadDefectData10      = 0x37;
        !            78:                static const uint Compare                       = 0x39;         // 共通
        !            79:                static const uint CopyAndVerify         = 0x3a;         // 共通
        !            80:                static const uint WriteBuffer           = 0x3b;         // 共通
        !            81:                static const uint ReadBuffer            = 0x3c;         // 共通
        !            82:                static const uint ReadLong                      = 0x3e;
        !            83:                static const uint WriteLong                     = 0x3f;
        !            84:                // Group2
        !            85:                static const uint ChangeDefinition      = 0x40;
        !            86:                static const uint WriteSame                     = 0x41;
        !            87:                static const uint LogSelect                     = 0x4c;         // 共通
        !            88:                static const uint LogSense                      = 0x4d;         // 共通
        !            89:                static const uint ModeSelect10          = 0x55;         // 共通
        !            90:                static const uint ModeSense10           = 0x5a;         // 共通
        !            91:                static const uint MAX                           = 0x5b; // 最大値+1にすること
        !            92:        };
        !            93: 
        !            94:        // ステータスバイト
        !            95:        struct StatusByte {
        !            96:                static const uint8 Good                                 = (0x00 << 1);
        !            97:                static const uint8 CheckCondition               = (0x01 << 1);
        !            98:                static const uint8 ConditionMet                 = (0x02 << 1);
        !            99:                static const uint8 Busy                                 = (0x04 << 1);
        !           100:                static const uint8 Intermediate                 = (0x08 << 1);
        !           101:                static const uint8 IntermediateCondMet  = (0x0a << 1);
        !           102:                static const uint8 ReservationConflict  = (0x0c << 1);
        !           103:                static const uint8 CommandTerminated    = (0x11 << 1);
        !           104:                static const uint8 QueueFull                    = (0x14 << 1);
        !           105:        };
        !           106: 
        !           107:        // メッセージバイト
        !           108:        struct MsgByte {
        !           109:                static const uint8 CommandComplete                      = 0x00;
        !           110:                static const uint8 ExtendMessage                        = 0x01;
        !           111:                static const uint8 SaveDataPointer                      = 0x02;
        !           112:                static const uint8 RestorePointers                      = 0x03;
        !           113:                static const uint8 Disconnect                           = 0x04;
        !           114:                static const uint8 InitiatorDetectedError       = 0x05;
        !           115:                static const uint8 Abort                                        = 0x06;
        !           116:                static const uint8 MessageReject                        = 0x07;
        !           117:                static const uint8 NoOperation                          = 0x08;
        !           118:                static const uint8 MessageParityError           = 0x09;
        !           119:                static const uint8 LinkedCommandComplete        = 0x0a;
        !           120:                static const uint8 LinkedCommandCompleteWithFlag = 0x0b;
        !           121:                static const uint8 BusDeviceReset                       = 0x0c;
        !           122:                static const uint8 AbortTag                                     = 0x0d;
        !           123:                static const uint8 ClearQueue                           = 0x0e;
        !           124:                static const uint8 InitiateRecovery                     = 0x0f;
        !           125:                static const uint8 ReleaseRecovery                      = 0x10;
        !           126:                static const uint8 TerminateIOProcess           = 0x11;
        !           127:                static const uint8 SimpleQueueTag                       = 0x20;
        !           128:                static const uint8 HeadOfQueueTag                       = 0x21;
        !           129:                static const uint8 OrderedQueueTag                      = 0x22;
        !           130:                static const uint8 IgnoreWideResidue            = 0x23;
        !           131:                static const uint8 Identify                                     = 0x80; // 0x80..0xff
        !           132:        };
        !           133: 
        !           134:        // Mode Select(6) ヘッダ
        !           135:        struct ModeParamHdr {
        !           136:                uint8 mode_param_len;           // ヘッダ以降のバイト数
        !           137:                uint8 media_type;
        !           138:                uint8 device_specific_param;
        !           139:                uint8 block_desc_len;           // 0 か 8の倍数
        !           140:        } __packed;
        !           141: 
        !           142:        // Mode Select(6) ブロックディスクリプタ
        !           143:        struct BlockDesc {
        !           144:                uint8 density_code;
        !           145:                uint8 block_cnt[3];                     // ブロック数
        !           146:                uint8 reserved;
        !           147:                uint8 block_size[3];            // 論理ブロック長 (バイト)
        !           148:        } __packed;
        !           149: 
        !           150:        // フェーズ名を返す。
        !           151:        static const char *GetPhaseName(uint);
        !           152: 
        !           153:        // SCSI コマンド名を返す。
        !           154:        static const char *GetCommandName(uint8);
        !           155: 
        !           156:  private:
        !           157:        static const char * const phasename[Phase::MAX];
        !           158:        static const char * const commandname[Command::MAX];
        !           159: };
        !           160: 
        !           161: class SCSIHostDevice : public IODevice
        !           162: {
        !           163:        typedef IODevice inherited;
        !           164:  public:
        !           165:        SCSIHostDevice();
        !           166:        virtual ~SCSIHostDevice();
        !           167: 
        !           168:        virtual bool Create();
        !           169: 
        !           170:        // このホストデバイスを示す接頭語を取得する
        !           171:        const char *GetConfigName() const { return config_name; }
        !           172: 
        !           173:        // ログ識別子を取得する
        !           174:        const std::string& GetLogName() const { return logname; }
        !           175: 
        !           176:        // 自身の SCSI ID (0..7)
        !           177:        int myid = 0;
        !           178: 
        !           179:        // SCSI ターゲット。[0] が ID0, …
        !           180:        // 未接続とイニシエータは NULL。
        !           181:        SCSITarget *target[8] {};
        !           182: 
        !           183:        // Select されているターゲット ID
        !           184:        // 選択されていない状態では -1
        !           185:        int tgtid = 0;
        !           186: 
        !           187:        // Bus Phase
        !           188: 
        !           189:        // バスフェーズが変化した時刻
        !           190:        uint64 BusPhaseTime = 0;
        !           191: 
        !           192:        // 各バスフェーズへ遷移する
        !           193:        void B_BusFree(int id);
        !           194: 
        !           195:        bool Arbitration(int id);
        !           196:        bool ArbitrationAck(int id);
        !           197: 
        !           198:        void InitiatorSelection(int targetid);
        !           199:        void TargetSelectionAck(int targetid);
        !           200:        void InitiatorSelectionAck();
        !           201: 
        !           202:        void TargetReselection(int targetid, int initiatorID);
        !           203:        void InitiatorReselectionAck();
        !           204:        void TargetReselectionAck(int targetid);
        !           205:        void InitiatorReselectionAck2();
        !           206: 
        !           207: #if 0
        !           208:        // Xfer Phase
        !           209:        SCSI::XferPhase GetXferPhase() const { return xfer_phase; }
        !           210: 
        !           211:        // 各転送フェーズへ遷移する
        !           212:        void X_DataOut();
        !           213:        void X_DataIn();
        !           214:        void X_Command();
        !           215:        void X_Status();
        !           216:        void X_MsgOut();
        !           217:        void X_MsgIn();
        !           218: #endif
        !           219: 
        !           220:        uint8 DATA = 0;
        !           221:        uint8 GetDATA() const { return DATA; }
        !           222:        void SetDATA(uint8 data);
        !           223: 
        !           224:        // 信号線はいずれも true でアサート
        !           225:        bool REQ = false;       // REQ 信号
        !           226:        bool GetREQ() const { return REQ; }
        !           227:        void SetREQ(bool val);
        !           228: 
        !           229:        bool ACK = false;       // ACK 信号
        !           230:        bool GetACK() const { return ACK; }
        !           231:        void SetACK(bool val);
        !           232: 
        !           233:        // RST も本来は OR-tied だが、ここではあまり意味がないので bool にする。
        !           234:        bool RST = false;       // RST 信号
        !           235:        bool GetRST() const { return RST; }
        !           236:        void SetRST(bool val);
        !           237: 
        !           238:        uint8 SEL = false;      // SEL 信号
        !           239:        bool GetSEL() const { return SEL != 0; }
        !           240:        void AssertSEL(int id);
        !           241:        void NegateSEL(int id);
        !           242: 
        !           243:        uint8 BSY = false;      // BSY 信号
        !           244:        bool GetBSY() const { return BSY != 0; }
        !           245:        void AssertBSY(int id);
        !           246:        void NegateBSY(int id);
        !           247: 
        !           248:        bool MSG = false;       // MSG 信号
        !           249:        bool GetMSG() const { return MSG; }
        !           250:        void SetMSG(bool val);
        !           251: 
        !           252:        bool CD = false;        // CD 信号
        !           253:        bool GetCD() const { return CD; }
        !           254:        void SetCD(bool val);
        !           255: 
        !           256:        bool IO = false;        // IO 信号
        !           257:        bool GetIO() const { return IO; }
        !           258:        void SetIO(bool val);
        !           259: 
        !           260:        bool ATN = false;       // ATN 信号
        !           261:        bool GetATN() const { return ATN; }
        !           262:        void SetATN(bool val);
        !           263: 
        !           264:        // バスフリーフェーズなら true を返す
        !           265:        bool IsBusFree() const {
        !           266:                return (GetSEL() == false && GetBSY() == false);
        !           267:        }
        !           268: 
        !           269:        // ターゲットがバスフリーフェーズに移行した
        !           270:        virtual void BusRelease() { }
        !           271: 
        !           272:  protected:
        !           273:        // 設定ファイルに使われるこのホストデバイスを示す接頭語。
        !           274:        // ("spc0" とか)
        !           275:        const char *config_name = NULL;
        !           276: 
        !           277: #if 0
        !           278:        SCSI::BusPhase bus_phase;
        !           279:        SCSI::XferPhase xfer_phase;
        !           280: #endif
        !           281: };

unix.superglobalmegacorp.com

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