--- nono/vm/scsi.h 2026/04/29 17:04:29 1.1.1.2 +++ nono/vm/scsi.h 2026/04/29 17:05:28 1.1.1.9 @@ -1,6 +1,11 @@ // // nono -// Copyright (C) 2018 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt +// + +// +// SCSI (定数等) // #pragma once @@ -11,11 +16,13 @@ class SCSI { public: - static const uint IO = 0x01; - static const uint CD = 0x02; - static const uint MSG = 0x04; - static const uint BSY = 0x08; - static const uint SEL = 0x10; + enum { + IO = 0x01, + CD = 0x02, + MSG = 0x04, + BSY = 0x08, + SEL = 0x10, + }; // SCSI のフェーズを表す。 // フェーズは概ね BSY と SEL の状態遷移によって決まる。 @@ -42,43 +49,29 @@ class SCSI }; // フェーズ文字列を返す - static const char * const GetPhaseName(int phase) { + static const char *GetPhaseName(Phase phase); + static const char *GetPhaseName(int phase) { return GetPhaseName((Phase)phase); } - static const char * const GetPhaseName(Phase phase) { - switch (phase) { - case BusFree: return "BusFree"; - case Arbitration: return "Arbitration"; - case Selection: return "Selection"; - case Reselection: return "Reselection"; - case Transfer: return "Transfer"; - } - return "Phase?"; - } // 情報転送フェーズ文字列を返す - static const char * const GetXferPhaseName(int xfer) { + static const char *GetXferPhaseName(XferPhase xfer); + static const char *GetXferPhaseName(int xfer) { return GetXferPhaseName((XferPhase)xfer); } - static const char * const GetXferPhaseName(XferPhase xfer) { - switch (xfer) { - case DataOut: return "DataOut"; - case DataIn: return "DataIn"; - case Command: return "Command"; - case Status: return "Status"; - case MsgOut: return "MsgOut"; - case MsgIn: return "MsgIn"; - case End: return "End"; - } - return "XferPhase?"; - } // デバイス種別 - enum DevType { + enum class DevType { None = 0, + Initiator, HD, + CD, + MO, }; + // デバイス種別文字列を返す + static const char *GetDevTypeName(DevType type); + // コマンド。 // ダイレクトアクセスデバイスのコマンドを元にしている。 // シーケンシャルアクセスデバイスでは 0x01 が Rewind だったり @@ -104,7 +97,9 @@ class SCSI static const uint SendDiagnostic = 0x1d; // 共通 static const uint PreventAllowMediumRemoval = 0x1e; // Group1 - static const uint ReadCapacity = 0x25; + static const uint ReadFormatCapacities = 0x23; + static const uint ReadCapacity = 0x25; // Direct Access + static const uint ReadCDROMCapacity = 0x25; // CD-ROM static const uint Read10 = 0x28; static const uint Write10 = 0x2a; static const uint Seek10 = 0x2b; @@ -128,12 +123,16 @@ class SCSI // Group2 static const uint ChangeDefinition = 0x40; static const uint WriteSame = 0x41; + static const uint ReadTOC = 0x43; // CD-ROM + static const uint ReadHeader = 0x44; // CD-ROM static const uint LogSelect = 0x4c; // 共通 static const uint LogSense = 0x4d; // 共通 + static const uint ReadDiscInformation = 0x51; // ? static const uint ModeSelect10 = 0x55; // 共通 static const uint ModeSense10 = 0x5a; // 共通 - static const uint MAX = 0x5b; // 最大値+1にすること }; + // SCSI コマンド名を返す + static const char *GetCommandName(uint8 cmd); // ステータスバイト struct StatusByte { @@ -175,25 +174,96 @@ class SCSI static const uint8 Identify = 0x80; // 0x80..0xff }; - // Mode Select(6) ヘッダ - struct ModeParamHdr { - uint8 mode_param_len; // ヘッダ以降のバイト数 - uint8 media_type; - uint8 device_specific_param; - uint8 block_desc_len; // 0 か 8の倍数 - } __packed; - - // Mode Select(6) ブロックディスクリプタ - struct BlockDesc { - uint8 density_code; - uint8 block_cnt[3]; // ブロック数 - uint8 reserved; - uint8 block_size[3]; // 論理ブロック長 (バイト) - } __packed; + // Inquiry コマンドの Peripheral Qualifier フィールド + struct InquiryQualifier { + static const uint8 LU_Present = 0x00; + static const uint8 LU_NotPreseted = 0x20; + static const uint8 Reserved = 0x40; + static const uint8 LU_NotSupported = 0x60; + static const uint8 Mask = 0xe0; + }; + // Inquiry コマンドの Peripheral Device Type フィールド + struct InquiryDeviceType { + static const uint8 DirectAccess = 0x00; + static const uint8 SequentialAccess = 0x01; + static const uint8 Printer = 0x02; + static const uint8 Processor = 0x03; + static const uint8 WriteOnce = 0x04; + static const uint8 CDROM = 0x05; + static const uint8 Scanner = 0x06; + static const uint8 MO = 0x07; + static const uint8 MediaChanger = 0x08; + static const uint8 Communication = 0x09; + static const uint8 Unknown = 0x1f; + }; - // SCSI コマンド名を返す - static const char *GetCommandName(uint8 cmd); + // センスキー + struct SenseKey { + static const uint8 NoSense = 0x0; + static const uint8 RecoveredError = 0x1; + static const uint8 NotReady = 0x2; + static const uint8 MediumError = 0x3; + static const uint8 HardwareError = 0x4; + static const uint8 IllegalRequest = 0x5; + static const uint8 UnitAttention = 0x6; + static const uint8 DataProtect = 0x7; + static const uint8 BlankCheck = 0x8; + static const uint8 VendorSpecific = 0x9; + static const uint8 CopyAborted = 0xa; + static const uint8 AbortedCommand = 0xb; + static const uint8 Equal = 0xc; + static const uint8 VolumeOverflow = 0xd; + static const uint8 Miscompare = 0xe; + static const uint8 Reserved = 0xf; + }; + // センスキーコードとキー名を表示用に整形したものを返す + static std::string GetSenseKeyDisp(uint8 key); + + // ASC/ASCQ + // 上位バイトが ASC、下位バイトが ASCQ を示す。 + struct ASC { + static const uint16 NoAdditionalSenseInformation = 0x0000; + static const uint16 PeripheralDeviceWriteFault = 0x0300; + static const uint16 InvalidCommandOperationCode = 0x2000; + static const uint16 InvalidFieldInCDB = 0x2400; + static const uint16 LogicalUnitNotSupported = 0x2500; + static const uint16 MediumNotPresent = 0x3a00; + }; + + // Mode Select/Sense のページ + // - 詳細解説本の日本語訳が微妙に遠い…。 + // Rigid Disk Geometry Page は「ドライブ・パラメータ」、 + // Flexible Disk Page は「フロッピ・ディスク・パラメータ」、 + // Caching Page は「キャッシュ・コントロール・パラメータ」としてある。 + // ページコード(番号)を軸に読み替えること。 + // - ReadWriteErrorRecovery は CD-ROM クラスではページ番号同じで + // ReadErrorRecovery だがそれはもう区別しない。 + // - 名前の後ろの Page は基本省略しているが、Caching Page は省略すると + // 訳分からんことになるので。 + enum ModePage : uint8 { + VendorSpecific = 0x00, + ReadWriteErrorRecovery = 0x01, + DisconnectReconnect = 0x02, + FormatDevice = 0x03, + RigidDiskGeometry = 0x04, + FlexibleDisk = 0x05, + OpticalMemory = 0x06, + VerifyErrorRecovery = 0x07, + CachingPage = 0x08, + PeripheralDevice = 0x09, + ControlMode = 0x0a, + MediumTypeSupported = 0x0b, + NotchAndPartition = 0x0c, + CDROM = 0x0d, + CDROMAudioControl = 0x0e, + + AllPages = 0x3f, + }; + // ページ番号とページ名を表示用に整形したものを返す + static std::string GetModePageDisp(uint8 page); private: - static const char * const commandname[Command::MAX]; + static const std::vector commandname; + static const std::vector sensekeyname; + static const std::vector modepagename; };