summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Spinler <spinler@us.ibm.com>2017-09-18 14:15:31 -0500
committerMatt Spinler <spinler@us.ibm.com>2017-10-04 12:31:07 -0500
commitee401e9b58d234cc2e8126d264542f9f4548f2ee (patch)
tree477fe4cbc49860dc379b206dee60dbdcb520ebb0
parent88d7b4d1ed713a8221efa78bf4e50d6a4b1f79d6 (diff)
downloadopenpower-proc-control-ee401e9b58d234cc2e8126d264542f9f4548f2ee.tar.gz
openpower-proc-control-ee401e9b58d234cc2e8126d264542f9f4548f2ee.zip
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>
-rw-r--r--Makefile.am2
-rw-r--r--configure.ac6
-rw-r--r--proc_control.cpp13
-rw-r--r--procedures/openfsi/scan.cpp133
4 files changed, 152 insertions, 2 deletions
diff --git a/Makefile.am b/Makefile.am
index e76cfba..54dc22e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -16,11 +16,13 @@ CLEANFILES = openpower_procedures.cpp
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 @@ AS_IF([test "x$enable_oe_sdk" == "xyes"],
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 @@ AC_CONFIG_FILES([Makefile.generated],
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 @@ namespace device_error = sdbusplus::xyz::openbmc_project::
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 @@ int main(int argc, char** argv)
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);
+
+}
+}
OpenPOWER on IntegriCloud