--- nono/vm/scsidev.h 2026/04/29 17:05:30 1.1.1.17 +++ nono/vm/scsidev.h 2026/04/29 17:06:01 1.1.1.20 @@ -27,6 +27,8 @@ #include "scsibus.h" #include "scsicmd.h" +class SCSIDomain; + // // SCSI デバイスとしての共通部分。 // @@ -37,15 +39,15 @@ class SCSIDevice : public Device explicit SCSIDevice(uint objid_); ~SCSIDevice() override; - // バスに接続された (SCSIBus から呼ばれる) - void OnAttached(SCSIBus *bus_, uint myid_); - // SCSI ID を返す uint GetMyID() const { return myid; } // デバイス種別を返す (主にデバッグ表示用) SCSI::DevType GetDevType() const { return devtype; } + // バスに接続する。 + void Attach(SCSIBus *bus_); + // 自身が接続しているバスを返す。 // イニシエータがバスに接続するのは VM 実行後なことに注意。 SCSIBus *GetBus() const { return bus; } @@ -116,9 +118,12 @@ class SCSIDevice : public Device // デバイス種別 SCSI::DevType devtype {}; - // 自身が繋がっているバスへのポインタ。 - // (イニシエータ自身も含めて) 所有していない。 + // あれば自身が繋がっているバスへのポインタ。 + // (イニシエータ自身も含めて) 所有ではない。 SCSIBus *bus {}; + + // 自身を管理しているドメイン(親) へのポインタ。 + SCSIDomain *domain {}; }; // @@ -138,23 +143,18 @@ class SCSIHostDevice : public SCSIDevice static_cast(f) public: - SCSIHostDevice(IODevice *parent_, const char *config_name_); + SCSIHostDevice(SCSIDomain *domain_, IODevice *parent_); ~SCSIHostDevice() override; - bool Init() override; + // SCSI ID を設定する。(SCSIDomain からのみ呼ぶこと) + void SetID(uint myid_); - // コールバック関数を設定する。 - void SetCallback( + // SCSIBus からのコールバック関数を設定する。 + void SetBusCallback( BusFreeCallback_t busfree_, SCSIHostCallback_t selack_, SCSIHostCallback_t xferreq_); - // 所有している SCSIBus ポインタを返す。こっちは接続前でも使える。 - SCSIBus *GetOwnedBus() const { return scsibus.get(); } - - // ターゲットデバイスを返す。(ショートカット) - SCSITarget *GetTarget(uint id) const { return scsibus->GetTarget(id); } - private: // SCSIBus から呼ばれる @@ -174,34 +174,6 @@ class SCSIHostDevice : public SCSIDevice // 転送フェーズでターゲットが REQ を立てたことを通知する SCSIHostCallback_t TransferReqCallback {}; - // SCSI バス (とターゲットオブジェクト) - // - // ホストデバイスなのでバスオブジェクト(SCSIBus *scsibus)と、このバスに - // 繋がるターゲットデバイスのオブジェクト(SCSITarget *target[]) を所有 - // (unique_ptr) している。これはオブジェクト同士の所有関係の話。 - // ホストデバイスは SCSIDevice を継承しているので target[] にホスト自身は - // 含めない。 - // - // それとは別に SCSI バスと SCSI デバイスの仮想的な接続関係があり、 - // こっちはすべて所有権のないただのポインタで相互にリンクする。 - // これが scsibus->device[] と SCSIDevice::bus の相互リンク。 - // - // こんな感じ。 - // SCSIHostDevice - // +----------------------+ - // | .scsibus | - // +--- || ----+ | - // || |SCSIDevice| - // ID7 ||<----> .bus | - // || +----------+ - // || - // || SCSIDisk(SCSIDevice) - // || +----------+ - // ID0 ||<----> .bus | - // || +----------+ - // - std::unique_ptr scsibus {}; - // コントローラデバイス。 IODevice *parent {}; }; @@ -213,7 +185,7 @@ class SCSITarget : public SCSIDevice { using inherited = SCSIDevice; public: - SCSITarget(SCSIBus *, uint id); + SCSITarget(SCSIDomain *, uint id); ~SCSITarget() override; void ResetHard(bool poweron) override; @@ -224,7 +196,8 @@ class SCSITarget : public SCSIDevice // 現在のコマンド列を返す (モニタ用) std::vector GetCmdSeq() const { return cmdseq; } - // コマンドを選択する (ROM30 エミュレーション用) + // コマンド列から SCSICmd を選択する。 + // (VirtIOSCSI と ROM30 エミュレーションから使う) SCSICmd *SelectCommand(const std::vector& cmdseq_); // 論理ブロック長 @@ -234,8 +207,9 @@ class SCSITarget : public SCSIDevice // ModeSense コマンドのデバイス固有パラメータを返す virtual uint8 GetDeviceSpecificParam() const { return 0; } - // センスキーと ASC/ASCQ + // センスキー uint8 sensekey {}; + // 上位バイトが ASC、下位バイトが ASCQ uint16 senseasc {}; // センスキーをクリア @@ -262,6 +236,9 @@ class SCSITarget : public SCSIDevice void OnTransferAck() override; protected: + // SCSI コマンドを選択する。内部用。 + void SelectCommand(); + // SCSI コマンドのディスパッチャ virtual void DispatchCmd(); @@ -276,6 +253,9 @@ class SCSITarget : public SCSIDevice // 現在実行中の SCSI コマンド std::unique_ptr cmd {}; + // コマンド前のメッセージアウトフェーズ。 + std::vector msgseq {}; + // 現在のフェーズでの転送カウント。 // IN と OUT でカウント方向が違うことに注意。 uint32 bytecount {}; @@ -309,7 +289,7 @@ class SCSIDisk : public SCSITarget }; public: - SCSIDisk(SCSIBus *, uint id, SCSI::DevType type); + SCSIDisk(SCSIDomain *, uint id, SCSI::DevType type); ~SCSIDisk() override; bool Init() override; @@ -338,7 +318,7 @@ class SCSIDisk : public SCSITarget // (エミュレータ特権アクセス) bool Peek(void *buf, uint64 start, uint32 len) const; - // シーク時間[nsec] + // シーク時間[tsec] uint64 GetSeekTime() const { return seektime; } // リムーバブルデバイスなら true @@ -368,7 +348,7 @@ class SCSIDisk : public SCSITarget bool IsMediumRemovalAllowed() const { return !medium_removal_prevented; } void PreventMediumRemoval(bool val); - // イメージファイルのフルパスを返す + // 現在ロードされているイメージファイルのフルパスを返す const std::string& GetPathName() const { return pathname; } // SCSIBus から呼ばれる