|
|
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:
42: // このコマンドの動作時間 [nsec]
43: // シークタイムとかを簡易的に再現するため、次フェーズ遷移時の最初の
44: // REQ アサートを引き延ばすために使う。
45: // 主にコマンドフェーズで使うことになると思う。
46: uint64 optime {};
47:
48: // 以下いずれも戻り値は遷移先のフェーズ。
49:
50: // コマンドフェーズを処理する。
51: // コマンドが確定したところで呼ばれる。戻り値に遷移先フェーズを返すこと。
52: // また、コマンド開始時に各自で ClearSense() を呼ぶこと。センスというか
53: // CA 状態は次のコマンド実行でクリアされるが (ネクサスはとりあえず無視)、
54: // RequestSense の場合は現在保持しているセンス情報をホストに返すので、
55: // つまり RequestSense 以外のコマンドが全員各自でクリアする必要がある。
56: virtual SCSI::XferPhase Command(std::vector<uint8>& cmdseq);
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:
99: protected:
100: // このコマンドを実行しているターゲットデバイス。
1.1.1.3 root 101: SCSITarget *parent {};
1.1 root 102:
103: // ステータスバイト (デフォルトは 0 = Good)
104: uint8 status_byte {};
105: };
106:
107: //
108: // SCSI コマンド: サポートしていないコマンド
109: //
110: class SCSICmdNotSupportedCommand : public SCSICmd
111: {
112: using inherited = SCSICmd;
113: public:
1.1.1.7 ! root 114: explicit SCSICmdNotSupportedCommand(SCSITarget *);
1.1.1.6 root 115: ~SCSICmdNotSupportedCommand() override;
1.1 root 116:
117: SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
118: };
119:
120: //
121: // SCSI コマンド 0x03 RequestSense (共通)
122: //
123: class SCSICmdRequestSense : public SCSICmd
124: {
125: using inherited = SCSICmd;
126: public:
1.1.1.7 ! root 127: explicit SCSICmdRequestSense(SCSITarget *);
1.1.1.6 root 128: ~SCSICmdRequestSense() override;
1.1 root 129:
130: SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
131: };
132:
133: //
134: // SCSI コマンド 0x08 Read(6) (DA / CD-ROM)
135: // 0x28 Read(10) (DA / CD-ROM)
136: //
137: class SCSICmdRead : public SCSICmd
138: {
139: using inherited = SCSICmd;
140: public:
1.1.1.7 ! root 141: explicit SCSICmdRead(SCSIDisk *);
1.1.1.6 root 142: ~SCSICmdRead() override;
1.1 root 143:
144: SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
145:
146: private:
147: SCSIDisk *disk {};
148: };
149:
150: //
151: // SCSI コマンド 0x0a Write(6) (DA / CD-ROM)
152: // 0x2a Write(10) (DA / CD-ROM)
153: //
154: class SCSICmdWrite : public SCSICmd
155: {
156: using inherited = SCSICmd;
157: public:
1.1.1.7 ! root 158: explicit SCSICmdWrite(SCSIDisk *);
1.1.1.6 root 159: ~SCSICmdWrite() override;
1.1 root 160:
161: SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
162: SCSI::XferPhase DoneDataOut() override;
163:
164: private:
165: uint8 cmd {};
166: SCSIDisk *disk {};
167: uint32 lba {};
168: uint32 blks {};
169: };
170:
171: //
172: // SCSI コマンド 0x12 Inquiry (共通)
173: //
174: class SCSICmdInquiry : public SCSICmd
175: {
176: using inherited = SCSICmd;
177: public:
1.1.1.7 ! root 178: explicit SCSICmdInquiry(SCSITarget *);
1.1.1.6 root 179: ~SCSICmdInquiry() override;
1.1 root 180:
181: SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
182: };
183:
184: //
185: // SCSI コマンド 0x15 ModeSelect(6) (共通)
186: // 0x55 ModeSelect(10) (共通)
187: //
188: class SCSICmdModeSelect : public SCSICmd
189: {
190: using inherited = SCSICmd;
191: public:
1.1.1.7 ! root 192: explicit SCSICmdModeSelect(SCSITarget *);
1.1.1.6 root 193: ~SCSICmdModeSelect() override;
1.1 root 194:
195: SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
196: SCSI::XferPhase DoneDataOut() override;
197:
198: private:
199: uint8 cmd {};
200: };
201:
202: //
203: // SCSI コマンド 0x1a ModeSense(6) (共通)
204: // 0x5a ModeSense(10) (共通)
205: //
206: class SCSICmdModeSense : public SCSICmd
207: {
208: using inherited = SCSICmd;
209: public:
1.1.1.7 ! root 210: explicit SCSICmdModeSense(SCSITarget *);
1.1.1.6 root 211: ~SCSICmdModeSense() override;
1.1 root 212:
213: SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
214:
215: private:
216: // Page Control
217: enum PC {
218: Current = 0x00, // 現在値
219: Changeable = 0x01, // 変更可能値
220: Default = 0x02, // デフォルト値
221: Saved = 0x03, // セーブ値
222: };
223: // ページ処理関数の戻り値 (この値は大小比較する)
224: enum ModePageResult {
1.1.1.4 root 225: NotSupported = -1, // 未実装や知らないページ
1.1 root 226: Failed = 0, // 対応しない/出来ないと分かっているページ
227: Success = 1, // 成功
228: };
229:
1.1.1.2 root 230: using PageFunc = ModePageResult (SCSICmdModeSense::*)();
231:
1.1 root 232: // 個別ページ処理
1.1.1.2 root 233: ModePageResult AddNotSupportedPage();
234: ModePageResult AddEmptyPage();
235: ModePageResult AddCachingPage();
1.1 root 236:
237: // ページ処理関数のため
238: uint pagecode {};
239: PC pc {};
240:
241: // ログ用の文字列
242: std::string log {};
1.1.1.2 root 243:
244: static const std::vector<std::pair<uint8, PageFunc>> Pagelist;
1.1 root 245: };
246:
247: //
248: // SCSI コマンド 0x1b StartStopUnit (DA / CD-ROM)
249: //
250: class SCSICmdStartStopUnit : public SCSICmd
251: {
252: using inherited = SCSICmd;
253: public:
1.1.1.7 ! root 254: explicit SCSICmdStartStopUnit(SCSIDisk *);
1.1.1.6 root 255: ~SCSICmdStartStopUnit() override;
1.1 root 256:
257: SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
258:
259: private:
260: SCSIDisk *disk {};
261: };
262:
263: //
264: // SCSI コマンド 0x1e PreventAllowMediumRemoval (DA / CD-ROM)
265: //
266: class SCSICmdPreventAllowMediumRemoval : public SCSICmd
267: {
268: using inherited = SCSICmd;
269: public:
1.1.1.7 ! root 270: explicit SCSICmdPreventAllowMediumRemoval(SCSIDisk *);
1.1.1.6 root 271: ~SCSICmdPreventAllowMediumRemoval() override;
1.1 root 272:
273: SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
274:
275: private:
276: SCSIDisk *disk {};
277: };
278:
279: //
280: // SCSI コマンド 0x25 ReadCapacity (DA)
281: // 0x25 Read CDROM Capacity (CD-ROM)
282: // (ここでは ReadCapacity として同一視する)
283: //
284: class SCSICmdReadCapacity : public SCSICmd
285: {
286: using inherited = SCSICmd;
287: public:
1.1.1.7 ! root 288: explicit SCSICmdReadCapacity(SCSIDisk *);
1.1.1.6 root 289: ~SCSICmdReadCapacity() override;
1.1 root 290:
291: SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
292:
293: private:
294: SCSIDisk *disk {};
295: };
296:
297: //
298: // SCSI コマンド 0x43 ReadTOC (CD-ROM)
299: //
300: class SCSICmdReadTOC : public SCSICmd
301: {
302: using inherited = SCSICmd;
303: public:
1.1.1.7 ! root 304: explicit SCSICmdReadTOC(SCSIDisk *);
1.1.1.6 root 305: ~SCSICmdReadTOC() override;
1.1 root 306:
307: SCSI::XferPhase Command(std::vector<uint8>& cmdseq) override;
308:
309: private:
310: SCSIDisk *disk {};
311: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.