|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2021 nono project
4: // Licensed under nono-license.txt
5: //
6:
1.1.1.3 root 7: //
1.1 root 8: // SCSI コマンド
1.1.1.3 root 9: //
1.1 root 10:
11: #pragma once
12:
13: #include "scsi.h"
14: #include <vector>
15:
16: // READ/WRITE は多すぎるのでログを省略したい場合に定義。
17: //#define NO_READWRITE_LOG
18:
1.1.1.7 root 19: class SCSIDisk;
20: class SCSITarget;
21:
1.1 root 22: //
23: // SCSI コマンドの基本クラス
24: // (黙って成功するコマンドとしても使用可能)
25: //
26: class SCSICmd
27: {
28: public:
1.1.1.7 root 29: explicit SCSICmd(SCSITarget *parent_);
1.1 root 30: virtual ~SCSICmd();
31:
32: // 転送バッファと転送バイト数。
33: // IN (ターゲットが送出側)なら、各フェーズ開始までに送出バイト数分の
34: // バッファを buf に用意すること。recvbytes は操作不要。
35: //
36: // OUT(ターゲットが受信側)なら、各フェーズ開始前までに受信バイト数を
37: // recvbytes にセットすること。buf は操作不要。
38: // なお parent は OUT(受信)フェーズ中にこの recvbytes を変更しない。
1.1.1.3 root 39: std::vector<uint8> buf {};
40: uint32 recvbytes {};
1.1 root 41:
1.1.1.9 ! root 42: // このコマンドの動作時間 [tsec]
1.1 root 43: // シークタイムとかを簡易的に再現するため、次フェーズ遷移時の最初の
44: // REQ アサートを引き延ばすために使う。
45: // 主にコマンドフェーズで使うことになると思う。
46: uint64 optime {};
47:
48: // 以下いずれも戻り値は遷移先のフェーズ。
49:
50: // コマンドフェーズを処理する。
51: // コマンドが確定したところで呼ばれる。戻り値に遷移先フェーズを返すこと。
52: // また、コマンド開始時に各自で ClearSense() を呼ぶこと。センスというか
53: // CA 状態は次のコマンド実行でクリアされるが (ネクサスはとりあえず無視)、
54: // RequestSense の場合は現在保持しているセンス情報をホストに返すので、
55: // つまり RequestSense 以外のコマンドが全員各自でクリアする必要がある。
1.1.1.8 root 56: virtual SCSI::XferPhase ExecCommand(std::vector<uint8>& cmdseq);
1.1 root 57:
58: // データインフェーズを完了する。
59: virtual SCSI::XferPhase DoneDataIn() {
60: return SCSI::XferPhase::Status;
61: }
62:
63: // データアウトフェーズを完了する。
64: virtual SCSI::XferPhase DoneDataOut() {
65: return SCSI::XferPhase::Status;
66: }
67:
68: // ステータスフェーズを開始する。
69: void BeginStatus() {
70: buf.clear();
71: buf.push_back(status_byte);
72: }
73:
74: // ステータスフェーズを完了する。
75: virtual SCSI::XferPhase DoneStatus() {
76: return SCSI::XferPhase::MsgIn;
77: }
78:
79: // メッセージインフェーズを開始する。
80: // デフォルトでは Command Complete を返す実装を用意しておく。
81: virtual void BeginMsgIn() {
82: buf.clear();
83: buf.push_back((uint8)SCSI::MsgByte::CommandComplete);
84: }
85:
86: // メッセージインフェーズを完了する。
87: virtual SCSI::XferPhase DoneMsgIn() {
88: return SCSI::XferPhase::End;
89: }
90:
91: // メッセージアウトフェーズを開始する。
92: virtual void BeginMsgOut() { }
93:
94: // メッセージアウトフェーズを完了する。
95: virtual SCSI::XferPhase DoneMsgOut() {
96: return SCSI::XferPhase::End;
97: }
98:
1.1.1.8 root 99: // ターゲットデバイスを取得。
100: SCSITarget *GetTarget() const noexcept { return parent; }
101:
1.1 root 102: protected:
103: // このコマンドを実行しているターゲットデバイス。
1.1.1.3 root 104: SCSITarget *parent {};
1.1 root 105:
106: // ステータスバイト (デフォルトは 0 = Good)
107: uint8 status_byte {};
108: };
109:
110: //
111: // SCSI コマンド: サポートしていないコマンド
112: //
113: class SCSICmdNotSupportedCommand : public SCSICmd
114: {
115: using inherited = SCSICmd;
116: public:
1.1.1.7 root 117: explicit SCSICmdNotSupportedCommand(SCSITarget *);
1.1.1.8 root 118: ~SCSICmdNotSupportedCommand() override = default;
1.1 root 119:
1.1.1.8 root 120: SCSI::XferPhase ExecCommand(std::vector<uint8>& cmdseq) override;
1.1 root 121: };
122:
123: //
124: // SCSI コマンド 0x03 RequestSense (共通)
125: //
126: class SCSICmdRequestSense : public SCSICmd
127: {
128: using inherited = SCSICmd;
129: public:
1.1.1.7 root 130: explicit SCSICmdRequestSense(SCSITarget *);
1.1.1.8 root 131: ~SCSICmdRequestSense() override = default;
1.1 root 132:
1.1.1.8 root 133: SCSI::XferPhase ExecCommand(std::vector<uint8>& cmdseq) override;
1.1 root 134: };
135:
136: //
137: // SCSI コマンド 0x08 Read(6) (DA / CD-ROM)
138: // 0x28 Read(10) (DA / CD-ROM)
139: //
140: class SCSICmdRead : public SCSICmd
141: {
142: using inherited = SCSICmd;
143: public:
1.1.1.7 root 144: explicit SCSICmdRead(SCSIDisk *);
1.1.1.8 root 145: ~SCSICmdRead() override = default;
1.1 root 146:
1.1.1.8 root 147: SCSI::XferPhase ExecCommand(std::vector<uint8>& cmdseq) override;
1.1 root 148:
149: private:
150: SCSIDisk *disk {};
151: };
152:
153: //
154: // SCSI コマンド 0x0a Write(6) (DA / CD-ROM)
155: // 0x2a Write(10) (DA / CD-ROM)
156: //
157: class SCSICmdWrite : public SCSICmd
158: {
159: using inherited = SCSICmd;
160: public:
1.1.1.7 root 161: explicit SCSICmdWrite(SCSIDisk *);
1.1.1.8 root 162: ~SCSICmdWrite() override = default;
1.1 root 163:
1.1.1.8 root 164: SCSI::XferPhase ExecCommand(std::vector<uint8>& cmdseq) override;
1.1 root 165: SCSI::XferPhase DoneDataOut() override;
166:
167: private:
168: uint8 cmd {};
169: SCSIDisk *disk {};
170: uint32 lba {};
171: uint32 blks {};
172: };
173:
174: //
175: // SCSI コマンド 0x12 Inquiry (共通)
176: //
177: class SCSICmdInquiry : public SCSICmd
178: {
179: using inherited = SCSICmd;
180: public:
1.1.1.7 root 181: explicit SCSICmdInquiry(SCSITarget *);
1.1.1.8 root 182: ~SCSICmdInquiry() override = default;
1.1 root 183:
1.1.1.8 root 184: SCSI::XferPhase ExecCommand(std::vector<uint8>& cmdseq) override;
1.1 root 185: };
186:
187: //
188: // SCSI コマンド 0x15 ModeSelect(6) (共通)
189: // 0x55 ModeSelect(10) (共通)
190: //
191: class SCSICmdModeSelect : public SCSICmd
192: {
193: using inherited = SCSICmd;
194: public:
1.1.1.7 root 195: explicit SCSICmdModeSelect(SCSITarget *);
1.1.1.8 root 196: ~SCSICmdModeSelect() override = default;
1.1 root 197:
1.1.1.8 root 198: SCSI::XferPhase ExecCommand(std::vector<uint8>& cmdseq) override;
1.1 root 199: SCSI::XferPhase DoneDataOut() override;
200:
201: private:
202: uint8 cmd {};
203: };
204:
205: //
206: // SCSI コマンド 0x1a ModeSense(6) (共通)
207: // 0x5a ModeSense(10) (共通)
208: //
209: class SCSICmdModeSense : public SCSICmd
210: {
211: using inherited = SCSICmd;
212: public:
1.1.1.7 root 213: explicit SCSICmdModeSense(SCSITarget *);
1.1.1.8 root 214: ~SCSICmdModeSense() override = default;
1.1 root 215:
1.1.1.8 root 216: SCSI::XferPhase ExecCommand(std::vector<uint8>& cmdseq) override;
1.1 root 217:
218: private:
219: // Page Control
220: enum PC {
221: Current = 0x00, // 現在値
222: Changeable = 0x01, // 変更可能値
223: Default = 0x02, // デフォルト値
224: Saved = 0x03, // セーブ値
225: };
226: // ページ処理関数の戻り値 (この値は大小比較する)
227: enum ModePageResult {
1.1.1.4 root 228: NotSupported = -1, // 未実装や知らないページ
1.1 root 229: Failed = 0, // 対応しない/出来ないと分かっているページ
230: Success = 1, // 成功
231: };
232:
1.1.1.2 root 233: using PageFunc = ModePageResult (SCSICmdModeSense::*)();
234:
1.1 root 235: // 個別ページ処理
1.1.1.2 root 236: ModePageResult AddNotSupportedPage();
237: ModePageResult AddEmptyPage();
238: ModePageResult AddCachingPage();
1.1 root 239:
240: // ページ処理関数のため
241: uint pagecode {};
242: PC pc {};
243:
244: // ログ用の文字列
245: std::string log {};
1.1.1.2 root 246:
247: static const std::vector<std::pair<uint8, PageFunc>> Pagelist;
1.1 root 248: };
249:
250: //
251: // SCSI コマンド 0x1b StartStopUnit (DA / CD-ROM)
252: //
253: class SCSICmdStartStopUnit : public SCSICmd
254: {
255: using inherited = SCSICmd;
256: public:
1.1.1.7 root 257: explicit SCSICmdStartStopUnit(SCSIDisk *);
1.1.1.8 root 258: ~SCSICmdStartStopUnit() override = default;
1.1 root 259:
1.1.1.8 root 260: SCSI::XferPhase ExecCommand(std::vector<uint8>& cmdseq) override;
1.1 root 261:
262: private:
263: SCSIDisk *disk {};
264: };
265:
266: //
267: // SCSI コマンド 0x1e PreventAllowMediumRemoval (DA / CD-ROM)
268: //
269: class SCSICmdPreventAllowMediumRemoval : public SCSICmd
270: {
271: using inherited = SCSICmd;
272: public:
1.1.1.7 root 273: explicit SCSICmdPreventAllowMediumRemoval(SCSIDisk *);
1.1.1.8 root 274: ~SCSICmdPreventAllowMediumRemoval() override = default;
1.1 root 275:
1.1.1.8 root 276: SCSI::XferPhase ExecCommand(std::vector<uint8>& cmdseq) override;
1.1 root 277:
278: private:
279: SCSIDisk *disk {};
280: };
281:
282: //
283: // SCSI コマンド 0x25 ReadCapacity (DA)
284: // 0x25 Read CDROM Capacity (CD-ROM)
285: // (ここでは ReadCapacity として同一視する)
286: //
287: class SCSICmdReadCapacity : public SCSICmd
288: {
289: using inherited = SCSICmd;
290: public:
1.1.1.7 root 291: explicit SCSICmdReadCapacity(SCSIDisk *);
1.1.1.8 root 292: ~SCSICmdReadCapacity() override = default;
1.1 root 293:
1.1.1.8 root 294: SCSI::XferPhase ExecCommand(std::vector<uint8>& cmdseq) override;
1.1 root 295:
296: private:
297: SCSIDisk *disk {};
298: };
299:
300: //
301: // SCSI コマンド 0x43 ReadTOC (CD-ROM)
302: //
303: class SCSICmdReadTOC : public SCSICmd
304: {
305: using inherited = SCSICmd;
306: public:
1.1.1.7 root 307: explicit SCSICmdReadTOC(SCSIDisk *);
1.1.1.8 root 308: ~SCSICmdReadTOC() override = default;
1.1 root 309:
1.1.1.8 root 310: SCSI::XferPhase ExecCommand(std::vector<uint8>& cmdseq) override;
1.1 root 311:
312: private:
313: SCSIDisk *disk {};
314: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.