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