|
|
nono 1.5.0
//
// nono
// Copyright (C) 2020 nono project
// Licensed under nono-license.txt
//
//
// SCSI (定数等)
//
#pragma once
#include "device.h"
// このクラスは SCSI プロトコル上の定数などだけを持つ。
class SCSI
{
public:
enum {
IO = 0x01,
CD = 0x02,
MSG = 0x04,
BSY = 0x08,
SEL = 0x10,
};
// SCSI のフェーズを表す。
// フェーズは概ね BSY と SEL の状態遷移によって決まる。
// 情報転送フェーズの内訳は XferPhase 側で区別する。
enum Phase {
BusFree = 0,
Arbitration = 1,
Selection = 2,
Reselection = 3,
Transfer = 4,
};
// 情報転送フェーズを表す。
// この値は MSG,CD,IO で表現できる値をそのまま流用して表現する。
enum XferPhase { // MSG CD IO
DataOut = 0, // 0 0 0
DataIn = 1, // 0 0 1
Command = 2, // 0 1 0
Status = 3, // 0 1 1
MsgOut = 6, // 1 1 0
MsgIn = 7, // 1 1 1
End = -1, // SCSICmd 内でフェーズ遷移を表現するために使う
};
// フェーズ文字列を返す
static const char *GetPhaseName(Phase phase);
static const char *GetPhaseName(int phase) {
return GetPhaseName((Phase)phase);
}
// 情報転送フェーズ文字列を返す
static const char *GetXferPhaseName(XferPhase xfer);
static const char *GetXferPhaseName(int xfer) {
return GetXferPhaseName((XferPhase)xfer);
}
// デバイス種別
enum class DevType {
None = 0,
Initiator,
HD,
CD,
MO,
};
// デバイス種別文字列を返す
static const char *GetDevTypeName(DevType type);
// コマンド。
// ダイレクトアクセスデバイスのコマンドを元にしている。
// シーケンシャルアクセスデバイスでは 0x01 が Rewind だったり
// 同じコードで違うコマンドのようだが、とりあえずそれは放置。
struct Command {
// Group0
static const uint TestUnitReady = 0x00; // 共通
static const uint RezeroUnit = 0x01;
static const uint RequestSense = 0x03; // 共通
static const uint FormatUnit = 0x04;
static const uint ReassignBlocks = 0x07;
static const uint Read6 = 0x08;
static const uint Write6 = 0x0a;
static const uint Seek6 = 0x0b;
static const uint Inquiry = 0x12; // 共通
static const uint ModeSelect6 = 0x15; // 共通
static const uint Reserve = 0x16;
static const uint Release = 0x17;
static const uint Copy = 0x18; // 共通
static const uint ModeSense6 = 0x1a;
static const uint StartStopUnit = 0x1b;
static const uint ReceiveDiagnosticResults = 0x1c; // 共通
static const uint SendDiagnostic = 0x1d; // 共通
static const uint PreventAllowMediumRemoval = 0x1e;
// Group1
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;
// Group1
static const uint WriteAndVerify10 = 0x2e;
static const uint Verify10 = 0x2f;
static const uint SearchDataHigh10 = 0x30;
static const uint SearchDataEqual10 = 0x31;
static const uint SearchDataLow10 = 0x32;
static const uint SetLimits = 0x33;
static const uint PreFetch = 0x34;
static const uint SynchronizeCache = 0x35;
static const uint LockUnlockCache = 0x36;
static const uint ReadDefectData10 = 0x37;
static const uint Compare = 0x39; // 共通
static const uint CopyAndVerify = 0x3a; // 共通
static const uint WriteBuffer = 0x3b; // 共通
static const uint ReadBuffer = 0x3c; // 共通
static const uint ReadLong = 0x3e;
static const uint WriteLong = 0x3f;
// 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; // 共通
// SCSI-3(?)
static const uint ReportLUNs = 0xa0;
};
// SCSI コマンド名を返す
static const char *GetCommandName(uint8 cmd);
// ステータスバイト
struct StatusByte {
static const uint8 Good = (0x00U << 1);
static const uint8 CheckCondition = (0x01U << 1);
static const uint8 ConditionMet = (0x02U << 1);
static const uint8 Busy = (0x04U << 1);
static const uint8 Intermediate = (0x08U << 1);
static const uint8 IntermediateCondMet = (0x0aU << 1);
static const uint8 ReservationConflict = (0x0cU << 1);
static const uint8 CommandTerminated = (0x11U << 1);
static const uint8 QueueFull = (0x14U << 1);
};
// メッセージバイト
struct MsgByte {
static const uint8 CommandComplete = 0x00;
static const uint8 ExtendMessage = 0x01;
static const uint8 SaveDataPointer = 0x02;
static const uint8 RestorePointers = 0x03;
static const uint8 Disconnect = 0x04;
static const uint8 InitiatorDetectedError = 0x05;
static const uint8 Abort = 0x06;
static const uint8 MessageReject = 0x07;
static const uint8 NoOperation = 0x08;
static const uint8 MessageParityError = 0x09;
static const uint8 LinkedCommandComplete = 0x0a;
static const uint8 LinkedCommandCompleteWithFlag = 0x0b;
static const uint8 BusDeviceReset = 0x0c;
static const uint8 AbortTag = 0x0d;
static const uint8 ClearQueue = 0x0e;
static const uint8 InitiateRecovery = 0x0f;
static const uint8 ReleaseRecovery = 0x10;
static const uint8 TerminateIOProcess = 0x11;
static const uint8 SimpleQueueTag = 0x20;
static const uint8 HeadOfQueueTag = 0x21;
static const uint8 OrderedQueueTag = 0x22;
static const uint8 IgnoreWideResidue = 0x23;
static const uint8 Identify = 0x80; // 0x80..0xff
};
// 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;
};
// センスキー
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 std::vector<const char *> commandname;
static const std::vector<const char *> sensekeyname;
static const std::vector<const char *> modepagename;
};
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.