blob: 273d2800ff946c0cb8559f77923dcdbe9d43e732 [file] [log] [blame]
Matt Spinleree401e92017-09-18 14:15:31 -05001
2/**
3 * Copyright © 2017 IBM Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17#include <experimental/filesystem>
18#include <fstream>
19#include <org/open_power/Proc/FSI/error.hpp>
20#include <phosphor-logging/log.hpp>
21#include "registration.hpp"
22
23namespace openpower
24{
25namespace openfsi
26{
27
28using namespace phosphor::logging;
29namespace fs = std::experimental::filesystem;
30namespace fsi_error = sdbusplus::org::open_power::Proc::FSI::Error;
31
32constexpr auto masterScanPath =
33 "/sys/bus/platform/devices/gpio-fsi/fsi0/rescan";
34
35constexpr auto hubScanPath =
36 "/sys/devices/platform/gpio-fsi/fsi0/slave@00:00/"
37 "00:00:00:0a/fsi1/rescan";
38
39constexpr auto masterCalloutPath =
40 "/sys/devices/platform/gpio-fsi/fsi0/slave@00:00/raw";
41
42
43/**
44 * Writes a 1 to the sysfs file passed in to trigger
45 * the device driver to do an FSI scan.
46 *
47 * @param[in] path - the sysfs path to write a 1 to
48 */
49static void doScan(const std::string& path)
50{
51 std::ofstream file;
52
53 file.exceptions(std::ofstream::failbit | //logic error on operation
54 std::ofstream::badbit | //read/write error on operation
55 std::ofstream::eofbit); //end of file reached
56 try
57 {
58 file.open(path);
59 file << "1";
60 }
61 catch (std::exception& e)
62 {
63 auto err = errno;
64 throw std::system_error(err, std::generic_category());
65 }
66}
67
68/**
69 * Performs an FSI master scan followed by an FSI hub scan.
70 * This is where the device driver detects which chips are present.
71 *
72 * This is unrelated to scanning a ring out of a chip.
73 */
74void scan()
75{
76 //Note: Currently the FSI device driver will always return success on both
77 //the master and hub scans. The only way we can detect something
78 //went wrong is if the master scan didn't create the hub scan file, so
79 //we will check for that.
80 //It is possible the driver will be updated in the future to actually
81 //return a failure so the code will still check for them.
82
83 try
84 {
85 doScan(masterScanPath);
86 }
87 catch (std::system_error& e)
88 {
89 log<level::ERR>("Failed to run the FSI master scan");
90
91 using metadata = org::open_power::Proc::FSI::MasterDetectionFailure;
92
93 elog<fsi_error::MasterDetectionFailure>(
94 metadata::CALLOUT_ERRNO(e.code().value()),
95 metadata::CALLOUT_DEVICE_PATH(masterCalloutPath));
96 }
97
98 if (!fs::exists(hubScanPath))
99 {
100 log<level::ERR>("The FSI master scan did not create a hub scan file");
101
102 using metadata = org::open_power::Proc::FSI::MasterDetectionFailure;
103
104 elog<fsi_error::MasterDetectionFailure>(
105 metadata::CALLOUT_ERRNO(0),
106 metadata::CALLOUT_DEVICE_PATH(masterCalloutPath));
107 }
108
109 try
110 {
111 doScan(hubScanPath);
112 }
113 catch (std::system_error& e)
114 {
115 //If the device driver is ever updated in the future to fail the sysfs
116 //write call on a scan failure then it should also provide some hints
117 //about which hardware failed so we can do an appropriate callout
118 //here. At this point in time, the driver shouldn't ever fail so
119 //we won't worry about guessing at the callout.
120
121 log<level::ERR>("Failed to run the FSI hub scan");
122
123 using metadata = org::open_power::Proc::FSI::SlaveDetectionFailure;
124
125 elog<fsi_error::SlaveDetectionFailure>(
126 metadata::ERRNO(e.code().value()));
127 }
128}
129
130REGISTER_PROCEDURE("scanFSI", scan);
131
132}
133}