Add FSI scan procedure
This procedure will perform both the FSI master
and FSI hub scans.
It replaces doing the scans by writing to sysfs
using the echo command so that real errors can
be created on failures.
Currently the only way to tell if the master scan
fails is by checking for missing sysfs files, and
this code will do that by checking for the hub
scan file.
Change-Id: Id4b91592b8c8b9a5fc9f1a56f4d89e142a6c6b74
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
diff --git a/Makefile.am b/Makefile.am
index e76cfba..54dc22e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -16,11 +16,13 @@
openpower_proc_control_LDFLAGS = $(PHOSPHOR_LOGGING_LIBS) \
$(PHOSPHOR_DBUS_INTERFACES_LIBS) \
+ $(OPENPOWER_DBUS_INTERFACES_LIBS) \
$(SDBUSPLUS_LIBS) \
-lstdc++fs
openpower_proc_control_CXXFLAGS = $(PHOSPHOR_LOGGING_CFLAGS) \
$(PHOSPHOR_DBUS_INTERFACES_CFLAGS) \
+ $(OPENPOWER_DBUS_INTERFACES_CFLAGS) \
$(SDBUSPLUS_CFLAGS)
SUBDIRS = test
diff --git a/configure.ac b/configure.ac
index cc2d823..e0534a9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -37,9 +37,9 @@
AC_SUBST([OESDK_TESTCASE_FLAGS], [$testcase_flags])
)
-#CHIPS can be passed in a from a recipe, or it will default to P9
+#CHIPS can be passed in a from a recipe, or it will default to P9 and openfsi
AC_ARG_VAR(CHIPS, [The list of chips to build the procedures for])
-AS_IF([test "x$CHIPS" == "x"], [CHIPS="p9"])
+AS_IF([test "x$CHIPS" == "x"], [CHIPS="p9 openfsi"])
AC_CONFIG_FILES([Makefile.generated],
[${srcdir}/gen_makefile.sh ${srcdir} "$myChips" > Makefile.generated],
@@ -47,5 +47,7 @@
PKG_CHECK_MODULES([PHOSPHOR_LOGGING], [phosphor-logging],, [AC_MSG_ERROR([Could not find phosphor-logging...openbmc/phosphor-logging package required])])
PKG_CHECK_MODULES([PHOSPHOR_DBUS_INTERFACES], [phosphor-dbus-interfaces], [], [AC_MSG_ERROR(["phosphor-dbus-interfaces required and not found."])])
+PKG_CHECK_MODULES([OPENPOWER_DBUS_INTERFACES], [openpower-dbus-interfaces], [], [AC_MSG_ERROR(["openpower-dbus-interfaces required and not found."])])
+
AC_CONFIG_FILES([Makefile test/Makefile])
AC_OUTPUT
diff --git a/proc_control.cpp b/proc_control.cpp
index f825510..7de54df 100644
--- a/proc_control.cpp
+++ b/proc_control.cpp
@@ -19,6 +19,7 @@
#include <phosphor-logging/log.hpp>
#include <phosphor-logging/elog.hpp>
#include <phosphor-logging/elog-errors.hpp>
+#include <org/open_power/Proc/FSI/error.hpp>
#include <xyz/openbmc_project/Common/error.hpp>
#include <xyz/openbmc_project/Common/Device/error.hpp>
#include <xyz/openbmc_project/Common/File/error.hpp>
@@ -31,6 +32,7 @@
Common::Device::Error;
namespace file_error = sdbusplus::xyz::openbmc_project::
Common::File::Error;
+namespace fsi_error = sdbusplus::org::open_power::Proc::FSI::Error;
void usage(char** argv, const ProcedureMap& procedures)
{
@@ -93,6 +95,17 @@
commit<common_error::InvalidArgument>();
return -1;
}
+ catch (fsi_error::MasterDetectionFailure& e)
+ {
+ commit<fsi_error::MasterDetectionFailure>();
+ return -1;
+ }
+ catch (fsi_error::SlaveDetectionFailure& e)
+ {
+ commit<fsi_error::SlaveDetectionFailure>();
+ return -1;
+ }
+
return 0;
}
diff --git a/procedures/openfsi/scan.cpp b/procedures/openfsi/scan.cpp
new file mode 100644
index 0000000..273d280
--- /dev/null
+++ b/procedures/openfsi/scan.cpp
@@ -0,0 +1,133 @@
+
+/**
+ * Copyright © 2017 IBM Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <experimental/filesystem>
+#include <fstream>
+#include <org/open_power/Proc/FSI/error.hpp>
+#include <phosphor-logging/log.hpp>
+#include "registration.hpp"
+
+namespace openpower
+{
+namespace openfsi
+{
+
+using namespace phosphor::logging;
+namespace fs = std::experimental::filesystem;
+namespace fsi_error = sdbusplus::org::open_power::Proc::FSI::Error;
+
+constexpr auto masterScanPath =
+ "/sys/bus/platform/devices/gpio-fsi/fsi0/rescan";
+
+constexpr auto hubScanPath =
+ "/sys/devices/platform/gpio-fsi/fsi0/slave@00:00/"
+ "00:00:00:0a/fsi1/rescan";
+
+constexpr auto masterCalloutPath =
+ "/sys/devices/platform/gpio-fsi/fsi0/slave@00:00/raw";
+
+
+/**
+ * Writes a 1 to the sysfs file passed in to trigger
+ * the device driver to do an FSI scan.
+ *
+ * @param[in] path - the sysfs path to write a 1 to
+ */
+static void doScan(const std::string& path)
+{
+ std::ofstream file;
+
+ file.exceptions(std::ofstream::failbit | //logic error on operation
+ std::ofstream::badbit | //read/write error on operation
+ std::ofstream::eofbit); //end of file reached
+ try
+ {
+ file.open(path);
+ file << "1";
+ }
+ catch (std::exception& e)
+ {
+ auto err = errno;
+ throw std::system_error(err, std::generic_category());
+ }
+}
+
+/**
+ * Performs an FSI master scan followed by an FSI hub scan.
+ * This is where the device driver detects which chips are present.
+ *
+ * This is unrelated to scanning a ring out of a chip.
+ */
+void scan()
+{
+ //Note: Currently the FSI device driver will always return success on both
+ //the master and hub scans. The only way we can detect something
+ //went wrong is if the master scan didn't create the hub scan file, so
+ //we will check for that.
+ //It is possible the driver will be updated in the future to actually
+ //return a failure so the code will still check for them.
+
+ try
+ {
+ doScan(masterScanPath);
+ }
+ catch (std::system_error& e)
+ {
+ log<level::ERR>("Failed to run the FSI master scan");
+
+ using metadata = org::open_power::Proc::FSI::MasterDetectionFailure;
+
+ elog<fsi_error::MasterDetectionFailure>(
+ metadata::CALLOUT_ERRNO(e.code().value()),
+ metadata::CALLOUT_DEVICE_PATH(masterCalloutPath));
+ }
+
+ if (!fs::exists(hubScanPath))
+ {
+ log<level::ERR>("The FSI master scan did not create a hub scan file");
+
+ using metadata = org::open_power::Proc::FSI::MasterDetectionFailure;
+
+ elog<fsi_error::MasterDetectionFailure>(
+ metadata::CALLOUT_ERRNO(0),
+ metadata::CALLOUT_DEVICE_PATH(masterCalloutPath));
+ }
+
+ try
+ {
+ doScan(hubScanPath);
+ }
+ catch (std::system_error& e)
+ {
+ //If the device driver is ever updated in the future to fail the sysfs
+ //write call on a scan failure then it should also provide some hints
+ //about which hardware failed so we can do an appropriate callout
+ //here. At this point in time, the driver shouldn't ever fail so
+ //we won't worry about guessing at the callout.
+
+ log<level::ERR>("Failed to run the FSI hub scan");
+
+ using metadata = org::open_power::Proc::FSI::SlaveDetectionFailure;
+
+ elog<fsi_error::SlaveDetectionFailure>(
+ metadata::ERRNO(e.code().value()));
+ }
+}
+
+REGISTER_PROCEDURE("scanFSI", scan);
+
+}
+}