| 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 |
| |