|
|
1.1 root 1: //
2: // nono
1.1.1.4 root 3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
1.1 root 5: //
6:
7: #pragma once
8:
9: #include "device.h"
10:
1.1.1.2 root 11: // このクラスは SCSI プロトコル上の定数などだけを持つ。
1.1 root 12: class SCSI
13: {
14: public:
1.1.1.2 root 15: static const uint IO = 0x01;
16: static const uint CD = 0x02;
17: static const uint MSG = 0x04;
18: static const uint BSY = 0x08;
19: static const uint SEL = 0x10;
20:
21: // SCSI のフェーズを表す。
22: // フェーズは概ね BSY と SEL の状態遷移によって決まる。
23: // 情報転送フェーズの内訳は XferPhase 側で区別する。
24: enum Phase {
25: BusFree = 0,
26: Arbitration = 1,
27: Selection = 2,
28: Reselection = 3,
29: Transfer = 4,
1.1 root 30: };
31:
1.1.1.2 root 32: // 情報転送フェーズを表す。
33: // この値は MSG,CD,IO で表現できる値をそのまま流用して表現する。
34: enum XferPhase { // MSG CD IO
35: DataOut = 0, // 0 0 0
36: DataIn = 1, // 0 0 1
37: Command = 2, // 0 1 0
38: Status = 3, // 0 1 1
39: MsgOut = 6, // 1 1 0
40: MsgIn = 7, // 1 1 1
1.1 root 41:
1.1.1.2 root 42: End = -1, // SCSICmd 内でフェーズ遷移を表現するために使う
43: };
44:
45: // フェーズ文字列を返す
1.1.1.4 root 46: static const char * GetPhaseName(int phase) {
1.1.1.2 root 47: return GetPhaseName((Phase)phase);
48: }
1.1.1.4 root 49: static const char * GetPhaseName(Phase phase) {
1.1.1.2 root 50: switch (phase) {
51: case BusFree: return "BusFree";
52: case Arbitration: return "Arbitration";
53: case Selection: return "Selection";
54: case Reselection: return "Reselection";
55: case Transfer: return "Transfer";
56: }
57: return "Phase?";
58: }
59:
60: // 情報転送フェーズ文字列を返す
1.1.1.4 root 61: static const char * GetXferPhaseName(int xfer) {
1.1.1.2 root 62: return GetXferPhaseName((XferPhase)xfer);
63: }
1.1.1.4 root 64: static const char * GetXferPhaseName(XferPhase xfer) {
1.1.1.2 root 65: switch (xfer) {
66: case DataOut: return "DataOut";
67: case DataIn: return "DataIn";
68: case Command: return "Command";
69: case Status: return "Status";
70: case MsgOut: return "MsgOut";
71: case MsgIn: return "MsgIn";
72: case End: return "End";
73: }
74: return "XferPhase?";
75: }
76:
77: // デバイス種別
1.1.1.5 ! root 78: enum class DevType {
1.1.1.2 root 79: None = 0,
80: HD,
1.1 root 81: };
82:
83: // コマンド。
84: // ダイレクトアクセスデバイスのコマンドを元にしている。
85: // シーケンシャルアクセスデバイスでは 0x01 が Rewind だったり
86: // 同じコードで違うコマンドのようだが、とりあえずそれは放置。
87: struct Command {
88: // Group0
89: static const uint TestUnitReady = 0x00; // 共通
90: static const uint RezeroUnit = 0x01;
91: static const uint RequestSense = 0x03; // 共通
92: static const uint FormatUnit = 0x04;
93: static const uint ReassignBlocks = 0x07;
94: static const uint Read6 = 0x08;
95: static const uint Write6 = 0x0a;
96: static const uint Seek6 = 0x0b;
97: static const uint Inquiry = 0x12; // 共通
98: static const uint ModeSelect6 = 0x15; // 共通
99: static const uint Reserve = 0x16;
100: static const uint Release = 0x17;
101: static const uint Copy = 0x18; // 共通
102: static const uint ModeSense6 = 0x1a;
103: static const uint StartStopUnit = 0x1b;
104: static const uint ReceiveDiagnosticResults = 0x1c; // 共通
105: static const uint SendDiagnostic = 0x1d; // 共通
106: static const uint PreventAllowMediumRemoval = 0x1e;
107: // Group1
108: static const uint ReadCapacity = 0x25;
109: static const uint Read10 = 0x28;
110: static const uint Write10 = 0x2a;
111: static const uint Seek10 = 0x2b;
112: // Group1
113: static const uint WriteAndVerify10 = 0x2e;
114: static const uint Verify10 = 0x2f;
115: static const uint SearchDataHigh10 = 0x30;
116: static const uint SearchDataEqual10 = 0x31;
117: static const uint SearchDataLow10 = 0x32;
118: static const uint SetLimits = 0x33;
119: static const uint PreFetch = 0x34;
120: static const uint SynchronizeCache = 0x35;
121: static const uint LockUnlockCache = 0x36;
122: static const uint ReadDefectData10 = 0x37;
123: static const uint Compare = 0x39; // 共通
124: static const uint CopyAndVerify = 0x3a; // 共通
125: static const uint WriteBuffer = 0x3b; // 共通
126: static const uint ReadBuffer = 0x3c; // 共通
127: static const uint ReadLong = 0x3e;
128: static const uint WriteLong = 0x3f;
129: // Group2
130: static const uint ChangeDefinition = 0x40;
131: static const uint WriteSame = 0x41;
132: static const uint LogSelect = 0x4c; // 共通
133: static const uint LogSense = 0x4d; // 共通
134: static const uint ModeSelect10 = 0x55; // 共通
135: static const uint ModeSense10 = 0x5a; // 共通
136: static const uint MAX = 0x5b; // 最大値+1にすること
137: };
138:
139: // ステータスバイト
140: struct StatusByte {
141: static const uint8 Good = (0x00 << 1);
142: static const uint8 CheckCondition = (0x01 << 1);
143: static const uint8 ConditionMet = (0x02 << 1);
144: static const uint8 Busy = (0x04 << 1);
145: static const uint8 Intermediate = (0x08 << 1);
146: static const uint8 IntermediateCondMet = (0x0a << 1);
147: static const uint8 ReservationConflict = (0x0c << 1);
148: static const uint8 CommandTerminated = (0x11 << 1);
149: static const uint8 QueueFull = (0x14 << 1);
150: };
151:
152: // メッセージバイト
153: struct MsgByte {
154: static const uint8 CommandComplete = 0x00;
155: static const uint8 ExtendMessage = 0x01;
156: static const uint8 SaveDataPointer = 0x02;
157: static const uint8 RestorePointers = 0x03;
158: static const uint8 Disconnect = 0x04;
159: static const uint8 InitiatorDetectedError = 0x05;
160: static const uint8 Abort = 0x06;
161: static const uint8 MessageReject = 0x07;
162: static const uint8 NoOperation = 0x08;
163: static const uint8 MessageParityError = 0x09;
164: static const uint8 LinkedCommandComplete = 0x0a;
165: static const uint8 LinkedCommandCompleteWithFlag = 0x0b;
166: static const uint8 BusDeviceReset = 0x0c;
167: static const uint8 AbortTag = 0x0d;
168: static const uint8 ClearQueue = 0x0e;
169: static const uint8 InitiateRecovery = 0x0f;
170: static const uint8 ReleaseRecovery = 0x10;
171: static const uint8 TerminateIOProcess = 0x11;
172: static const uint8 SimpleQueueTag = 0x20;
173: static const uint8 HeadOfQueueTag = 0x21;
174: static const uint8 OrderedQueueTag = 0x22;
175: static const uint8 IgnoreWideResidue = 0x23;
176: static const uint8 Identify = 0x80; // 0x80..0xff
177: };
178:
1.1.1.5 ! root 179: // センスキー
! 180: struct SenseKey {
! 181: static const uint8 NoSense = 0x0;
! 182: static const uint8 RecoveredError = 0x1;
! 183: static const uint8 NotReady = 0x2;
! 184: static const uint8 MediumError = 0x3;
! 185: static const uint8 HardwareError = 0x4;
! 186: static const uint8 IllegalRequest = 0x5;
! 187: static const uint8 UnitAttention = 0x6;
! 188: static const uint8 DataProtect = 0x7;
! 189: static const uint8 BlankCheck = 0x8;
! 190: static const uint8 VendorSpecific = 0x9;
! 191: static const uint8 CopyAborted = 0xa;
! 192: static const uint8 AbortedCommand = 0xb;
! 193: static const uint8 Equal = 0xc;
! 194: static const uint8 VolumeOverflow = 0xd;
! 195: static const uint8 Miscompare = 0xe;
! 196: static const uint8 Reserved = 0xf;
! 197: };
! 198:
! 199: // ASC/ASCQ
! 200: // 上位バイトが ASC、下位バイトが ASCQ を示す。
! 201: struct ASC {
! 202: static const uint16 NoAdditionalSenseInformation = 0x0000;
! 203: static const uint16 InvalidCommandOperationCode = 0x2000;
! 204: static const uint16 InvalidFieldInCDB = 0x2400;
! 205: };
! 206:
1.1 root 207: // Mode Select(6) ヘッダ
208: struct ModeParamHdr {
1.1.1.3 root 209: uint8 mode_param_len; // バイト長 (このバイトを含まずこれ以降)
1.1 root 210: uint8 media_type;
211: uint8 device_specific_param;
1.1.1.3 root 212: uint8 block_desc_len; // ブロックディスクリプタ長
1.1 root 213: } __packed;
214:
215: // Mode Select(6) ブロックディスクリプタ
216: struct BlockDesc {
217: uint8 density_code;
218: uint8 block_cnt[3]; // ブロック数
219: uint8 reserved;
220: uint8 block_size[3]; // 論理ブロック長 (バイト)
221: } __packed;
222:
1.1.1.2 root 223: // SCSI コマンド名を返す
224: static const char *GetCommandName(uint8 cmd);
1.1 root 225:
226: private:
227: static const char * const commandname[Command::MAX];
228: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.