--- nono/vm/scsidev.cpp 2026/04/29 17:05:11 1.1.1.14 +++ nono/vm/scsidev.cpp 2026/04/29 17:05:25 1.1.1.17 @@ -28,8 +28,8 @@ // // コンストラクタ -SCSIDevice::SCSIDevice(const std::string& objname_) - : inherited(objname_) +SCSIDevice::SCSIDevice(int objid_) + : inherited(objid_) { } @@ -44,8 +44,8 @@ SCSIDevice::~SCSIDevice() // // コンストラクタ -SCSIHostDevice::SCSIHostDevice(const std::string& objname_) - : inherited(objname_) +SCSIHostDevice::SCSIHostDevice(int objid_) + : inherited(objid_) { devtype = SCSI::DevType::Initiator; @@ -83,7 +83,7 @@ SCSIHostDevice::Create() const std::string& image = item.AsString(); // 空ならデバイスなし - if (image.length() == 0) { + if (image.empty()) { // 未接続部分のパラメータは減らしておくか。 // --show-config するとさすがに無駄に多くて邪魔なので。 const std::string wikey = string_format("%s-id%d-writeignore", @@ -112,7 +112,7 @@ SCSIHostDevice::Create() } else if (type == "mo") { target_devtype = SCSI::DevType::MO; } else { - item.Err("invaild device type '%s'", type.c_str()); + item.Err("Invaild device type '%s'", type.c_str()); return false; } target[id].reset(new SCSIDisk(this, id, target_devtype)); @@ -127,6 +127,10 @@ SCSIHostDevice::Create() bool SCSIHostDevice::Init() { + if (inherited::Init() == false) { + return false; + } + // 初期化ではないけどログレベルがセットできたここでデバッグ表示。 // -L オプションの処理は Create() の後なので。 if (loglevel >= 1) { @@ -257,9 +261,9 @@ SCSIHostDevice::MonitorUpdateDevs(Monito // SCSI ターゲットデバイスの共通部分 // -// コンストラクタ -SCSITarget::SCSITarget(const std::string& objname_, SCSIHostDevice *h, int id) - : inherited(objname_) +// コンストラクタ。 +SCSITarget::SCSITarget(SCSIHostDevice *h, int id) + : inherited(OBJ_NONE) // オブジェクト ID で検索することはない { // ホストへのリンク (所有関係のないポインタ) host = h; @@ -577,7 +581,7 @@ SCSITarget::DispatchCmd() if (cname) { name = string_format(" %s", cname); } - putlog(0, "未実装 SCSI コマンド $%02x%s len=%d", + putlog(0, "SCSI Command $%02x%s len=%d not supported", cmdseq[0], name.c_str(), (int)cmdseq.size()); cmd.reset(new SCSICmdNotSupportedCommand(this)); @@ -585,6 +589,16 @@ SCSITarget::DispatchCmd() } } +// コマンド列を指定して対応するコマンドを選択する。なければ NULL を返す。 +// ROM30 エミュレーション用。 +SCSICmd * +SCSITarget::SelectCommand(const std::vector& cmdseq_) +{ + cmdseq = cmdseq_; + DispatchCmd(); + return cmd.get(); +} + // // SCSI Disk @@ -592,7 +606,7 @@ SCSITarget::DispatchCmd() // コンストラクタ SCSIDisk::SCSIDisk(SCSIHostDevice *h, int id, SCSI::DevType devtype_) - : inherited("", h, id) + : inherited(h, id) { devtype = devtype_; @@ -604,6 +618,7 @@ SCSIDisk::SCSIDisk(SCSIHostDevice *h, in // lib/object.h 参照。 SetName(string_format("SCSI%s%d", devtypename, id)); ClearAlias(); + AddAlias(string_format("SCSI%s%d", devtypename, id)); AddAlias(string_format("SCSI%d", id)); AddAlias(string_format("%s%d", devtypename, id)); @@ -624,7 +639,7 @@ SCSIDisk::SCSIDisk(SCSIHostDevice *h, in blocksize = 512; break; default: - __unreachable(); + PANIC("corrupted devtype=%d", (int)devtype); } } @@ -638,6 +653,10 @@ SCSIDisk::~SCSIDisk() bool SCSIDisk::Init() { + if (inherited::Init() == false) { + return false; + } + const std::string keybody = string_format("%s-id%d-", host->GetConfigName(), myid); const std::string imgkey = keybody + "image"; @@ -663,10 +682,10 @@ SCSIDisk::Init() // リムーバブルデバイスのみ UI からの通知を受け取るイベントを用意 if (IsRemovableDevice()) { - gScheduler->ConnectMessage(MessageID::SCSIDEV_LOAD(myid), this, - ToMessageCallback(&SCSIDisk::LoadCallback)); - gScheduler->ConnectMessage(MessageID::SCSIDEV_UNLOAD(myid), this, - ToMessageCallback(&SCSIDisk::UnloadCallback)); + scheduler->ConnectMessage(MessageID::SCSIDEV_LOAD(myid), this, + ToMessageCallback(&SCSIDisk::LoadMessage)); + scheduler->ConnectMessage(MessageID::SCSIDEV_UNLOAD(myid), this, + ToMessageCallback(&SCSIDisk::UnloadMessage)); } // オープン前に writeignore をチェック。 @@ -701,14 +720,7 @@ SCSIDisk::Init() // 設定時点でファイルが指定されていればオープン if (filename.empty() == false) { - std::string path; - if (filename[0] == '/') { - path = filename; - } else { - // 相対パスなら VM ディレクトリから - path = gMainApp.GetVMDir() + filename; - } - + std::string path = gMainApp.NormalizePath(filename); if (LoadDisk(path) == false) { return false; } @@ -753,13 +765,13 @@ SCSIDisk::BusResetCB() bool SCSIDisk::LoadDisk(const std::string& pathname_) { - bool changed = false; + bool unloaded; off_t size; bool w_ok; bool read_only; // すでにあればクローズ (ここでは通知は行わない) - changed = UnloadDisk_internal(); + unloaded = UnloadDisk_internal(); // 新しいイメージをオープン(する準備) pathname = pathname_; @@ -816,7 +828,7 @@ SCSIDisk::LoadDisk(const std::string& pa } break; default: - __unreachable(); + PANIC("corrupted devtype=%d", (int)devtype); } // 書き込みモードをここで確定 @@ -848,21 +860,21 @@ SCSIDisk::LoadDisk(const std::string& pa } medium_loaded = true; - changed = true; -done: - if (changed) { - // HD 初期化時はログに出さない - if (IsRemovableDevice()) { - putlog(1, "Medium loaded"); - } - - // 変化があれば通知 - MediaChanged(); + // リムーバブルデバイスでだけログを出す + if (IsRemovableDevice()) { + putlog(1, "Medium loaded"); } + + done: if (medium_loaded == false) { // ここで状態をクリアする Clear(); } + + // 変化があれば通知 + if (unloaded || medium_loaded) { + MediaChanged(); + } return medium_loaded; } @@ -925,7 +937,7 @@ void SCSIDisk::LoadDiskUI(const std::string& pathname_) { new_pathname = pathname_; - gScheduler->SendMessage(MessageID::SCSIDEV_LOAD(GetMyID())); + scheduler->SendMessage(MessageID::SCSIDEV_LOAD(GetMyID())); } // メディアを排出する。 @@ -933,12 +945,12 @@ SCSIDisk::LoadDiskUI(const std::string& void SCSIDisk::UnloadDiskUI(bool force) { - gScheduler->SendMessage(MessageID::SCSIDEV_UNLOAD(GetMyID()), force); + scheduler->SendMessage(MessageID::SCSIDEV_UNLOAD(GetMyID()), force); } // メディア挿入メッセージコールバック void -SCSIDisk::LoadCallback(MessageID msgid, uint32 arg) +SCSIDisk::LoadMessage(MessageID msgid, uint32 arg) { if (LoadDisk(new_pathname) == false) { // 失敗したら UI に通知 @@ -948,7 +960,7 @@ SCSIDisk::LoadCallback(MessageID msgid, // メディア排出メッセージコールバック void -SCSIDisk::UnloadCallback(MessageID msgid, uint32 arg) +SCSIDisk::UnloadMessage(MessageID msgid, uint32 arg) { bool force = arg; UnloadDisk(force); @@ -1174,6 +1186,6 @@ SCSIDisk::GetWriteModeStr() const case RW::Writeable: return "Writeable"; case RW::WriteIgnore: return "WriteIgnore"; default: - __unreachable(); + PANIC("corrupted write_mode=%d", (int)write_mode); } }