google-ipmi-sys: Add patch for BMC modes transition

Create patch based on https://gerrit.openbmc.org/c/openbmc/google-ipmi-sys/+/64697

Google-Bug-Id: 292038170
Google-Bug-Id: 259113025
Change-Id: I05d447606e259f1bfd891958035e8d5cf932d565
Signed-off-by: Brandon Kim <brandonkim@google.com>
(cherry picked from commit a99c87f9c10b9015e63434b7790a246d943b16ec)
diff --git a/recipes-google/ipmi/google-ipmi-sys/0001-Add-flags-for-bmc-modes-transitions.patch b/recipes-google/ipmi/google-ipmi-sys/0001-Add-flags-for-bmc-modes-transitions.patch
new file mode 100644
index 0000000..bd56811
--- /dev/null
+++ b/recipes-google/ipmi/google-ipmi-sys/0001-Add-flags-for-bmc-modes-transitions.patch
@@ -0,0 +1,115 @@
+From 4baf41c8d22b975d5bfb65fccb5e1cb1ae2efd3d Mon Sep 17 00:00:00 2001
+From: Hao Zhou <haoooamazing@google.com>
+Date: Thu, 6 Jul 2023 22:34:04 +0000
+Subject: [PATCH] Add flags for bmc  modes transitions
+
+1. When /run/bm-drive-cleaning-done.flag is present, it means cleaning
+   is done and we are in BM_MODE. Also, it is acked by renaming flag to
+   bm-drive-cleaning-done-ack.flag
+2. if not case 1, when /run/bm-drive-cleaning-done-ack.flag is present,
+   it means the cleaing is done and acked
+3. if not case 2, when bm-ready.flag is present, it means we are in
+   BM_CLEANING_MODE. /run/bm-drive-cleaning.flag is created if needed
+4. otherwise, we are in NON_BM_MODE
+
+Tested:
+bm-ready.flag is not present. Respond Non-BM mode:
+
+ipmitool raw 0x2e 0x32 0x79 0x2b 0x00 0x10
+ 79 2b 00 10 00
+
+bm-ready.flah is present. For next call, respond Cleaning Mode and
+bm-drive-cleaning.flag is created:
+
+ipmitool raw 0x2e 0x32 0x79 0x2b 0x00 0x10
+ 79 2b 00 10 02
+
+keep responding Cleaning Mode until bm-drive-cleaning-done.flag is
+created. So cleaning is done and for next call, respond BM mode and
+rename bm-drive-cleaning-done.flag to bm-drive-cleaning-done-ack.flag:
+
+ipmitool raw 0x2e 0x32 0x79 0x2b 0x00 0x10
+ 79 2b 00 10 01
+
+Patch Tracking Bug: b/292038170
+Upstream info / review: https://gerrit.openbmc.org/c/openbmc/google-ipmi-sys/+/64697
+Upstream-Status: Accepted
+Justification: Feature required downstream
+
+Change-Id: Id8a6049550631c30c68a536313b81a8d800fede0
+Signed-off-by: Hao Zhou <haoooamazing@google.com>
+---
+ handler.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 42 insertions(+), 5 deletions(-)
+
+diff --git a/handler.cpp b/handler.cpp
+index 9bbd082..4046871 100644
+--- a/handler.cpp
++++ b/handler.cpp
+@@ -68,21 +68,58 @@ using namespace phosphor::logging;
+ using InternalFailure =
+     sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
+ 
++static constexpr auto bmDriveCleaningFlagPath = "/run/bm-drive-cleaning.flag";
++static constexpr auto bmDriveCleaningDoneFlagPath =
++    "/run/bm-drive-cleaning-done.flag";
++static constexpr auto bmDriveCleaningDoneAckFlagPath =
++    "/run/bm-drive-cleaning-done-ack.flag";
++
+ uint8_t isBmcInBareMetalMode()
+ {
+ #if BARE_METAL
+     return static_cast<uint8_t>(BmcMode::BM_MODE);
+ #else
+     std::error_code ec;
+-    if (fs::exists(BM_SIGNAL_PATH, ec))
++
++    if (fs::exists(bmDriveCleaningDoneAckFlagPath, ec))
++    {
++        std::fprintf(
++            stderr,
++            "%s exists so we acked cleaning done and must be in BM mode\n",
++            bmDriveCleaningDoneAckFlagPath);
++        return static_cast<uint8_t>(BmcMode::BM_MODE);
++    }
++
++    if (fs::exists(bmDriveCleaningDoneFlagPath, ec))
+     {
+-        std::fprintf(stderr, "%s exists so we must be in BM mode\n",
+-                     BM_SIGNAL_PATH);
++        fs::rename(bmDriveCleaningDoneFlagPath, bmDriveCleaningDoneAckFlagPath,
++                   ec);
++        std::fprintf(
++            stderr,
++            "%s exists so we just finished cleaning and must be in BM mode\n",
++            bmDriveCleaningDoneFlagPath);
+         return static_cast<uint8_t>(BmcMode::BM_MODE);
+     }
+ 
+-    std::fprintf(stderr, "Unable to find %s so we must not be in BM mode\n",
+-                 BM_SIGNAL_PATH);
++    if (fs::exists(BM_SIGNAL_PATH, ec))
++    {
++        if (!fs::exists(bmDriveCleaningFlagPath, ec))
++        {
++            std::ofstream ofs;
++            ofs.open(bmDriveCleaningFlagPath, std::ofstream::out);
++            ofs.close();
++        }
++
++        std::fprintf(
++            stderr,
++            "%s exists and no done/ack flag, we must be in BM cleaning mode\n",
++            BM_SIGNAL_PATH);
++        return static_cast<uint8_t>(BmcMode::BM_CLEANING_MODE);
++    }
++
++    std::fprintf(
++        stderr,
++        "Unable to find any BM state files so we must not be in BM mode\n");
+     return static_cast<uint8_t>(BmcMode::NON_BM_MODE);
+ #endif
+ }
+-- 
+2.41.0.255.g8b1d071c50-goog
+
diff --git a/recipes-google/ipmi/google-ipmi-sys_%.bbappend b/recipes-google/ipmi/google-ipmi-sys_%.bbappend
new file mode 100644
index 0000000..6a1bb98
--- /dev/null
+++ b/recipes-google/ipmi/google-ipmi-sys_%.bbappend
@@ -0,0 +1,2 @@
+FILESEXTRAPATHS:prepend:gbmc := "${THISDIR}/${PN}:"
+SRC_URI:append:gbmc = " file://0001-Add-flags-for-bmc-modes-transitions.patch"