blob: b42fbe8117e4b0cf652da8642b9ffd46d790e6db [file] [log] [blame] [edit]
From 7786f9c504d94a1e8654b822226faf174a0e3716 Mon Sep 17 00:00:00 2001
From: Matt Johnston <matt@codeconstruct.com.au>
Date: Wed, 3 May 2023 10:07:26 +0800
Subject: [PATCH 05/16] nvme: Hack workaround for drives without secondary
Some drives won't return any secondary controller list,
so just choose the single arbitrary controller as the primary.
Required for Samsung PM9A2 or Micron 7450 M.2 drives
Signed-off-by: Matt Johnston <matt@codeconstruct.com.au>
Change-Id: I180326d882e7094ff0293827afba7cb6c84416b7
(cherry picked from commit c6a4016162c845ca7c3beaf3d7bbdeed2d57579a)
---
src/NVMeSubsys.cpp | 37 ++++++++++++++++++++++++++++++++-----
src/NVMeSubsys.hpp | 2 ++
2 files changed, 34 insertions(+), 5 deletions(-)
diff --git a/src/NVMeSubsys.cpp b/src/NVMeSubsys.cpp
index 4fe1bff..7b13467 100644
--- a/src/NVMeSubsys.cpp
+++ b/src/NVMeSubsys.cpp
@@ -204,13 +204,24 @@ void NVMeSubsystem::markFunctional(bool toggle)
std::span<uint8_t> data) {
if (ec || data.size() < sizeof(nvme_secondary_ctrl_list))
{
- std::cerr << "fail to identify secondary controller list"
- << std::endl;
- self->status = Status::Stop;
- self->markFunctional(false);
- self->markAvailable(false);
+ // std::cerr << "fail to identify secondary controller list"
+ // << std::endl;
+ // self->status = Status::Stop;
+ // self->markFunctional(false);
+ // self->markAvailable(false);
+ // TODO Some drives don't support identify secondary, so use
+ // fallback. This may need refiniing.
+ std::cerr << "Failed to identify secondary controller "
+ "list. error "
+ << ec << " data size " << data.size()
+ << " expected size "
+ << sizeof(nvme_secondary_ctrl_list)
+ << ". Fallback, using arbitrary controller as "
+ "primary.\n";
+ self->fallbackNoSecondary();
return;
}
+
nvme_secondary_ctrl_list& listHdr =
*reinterpret_cast<nvme_secondary_ctrl_list*>(data.data());
@@ -545,3 +556,19 @@ void NVMeSubsystem::stop()
plugin.reset();
}
}
+
+void NVMeSubsystem::fallbackNoSecondary()
+{
+ // choose an arbitrary one
+ auto& pc = controllers.begin()->second.first;
+ primaryController = NVMeControllerEnabled::create(std::move(*pc));
+ // replace with the new controller object
+ pc = primaryController;
+
+ // start controller
+ for (auto& [_, pair] : controllers)
+ {
+ pair.first->start(pair.second);
+ }
+ status = Status::Start;
+}
diff --git a/src/NVMeSubsys.hpp b/src/NVMeSubsys.hpp
index dd9dbfa..3308cd6 100644
--- a/src/NVMeSubsys.hpp
+++ b/src/NVMeSubsys.hpp
@@ -78,6 +78,8 @@ class NVMeSubsystem : public std::enable_shared_from_this<NVMeSubsystem>
// mark the availability of the Storage device.
void markAvailable(bool toggle);
+ void fallbackNoSecondary();
+
// a counter to skip health poll when NVMe subsystem becomes Unavailable
unsigned UnavailableCount = 0;
static constexpr unsigned UnavailableMaxCount = 60;
--
2.42.0.283.g2d96d420d3-goog