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