summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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