blob: 389b297586e2d15a11ce277e118a0774b6331375 [file] [log] [blame]
Brad Bishop613a5b32017-01-05 20:58:13 -05001/**
2 * Copyright © 2016 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include <cstdlib>
Brad Bishop08379a32017-03-06 21:28:46 -050017#include <experimental/filesystem>
Brad Bishop613a5b32017-01-05 20:58:13 -050018#include <memory>
Matthew Barth048ac872017-03-09 14:36:08 -060019#include <phosphor-logging/elog.hpp>
20#include <phosphor-logging/elog-errors.hpp>
21#include <xyz/openbmc_project/Control/Device/error.hpp>
Matthew Barth4e1f30f2017-03-21 16:13:27 -050022#include <xyz/openbmc_project/Sensor/Device/error.hpp>
Brad Bishop613a5b32017-01-05 20:58:13 -050023#include "sysfs.hpp"
24#include "util.hpp"
Brad Bishop613a5b32017-01-05 20:58:13 -050025
Matthew Barth048ac872017-03-09 14:36:08 -060026using namespace phosphor::logging;
27
Brad Bishop613a5b32017-01-05 20:58:13 -050028std::string findHwmon(const std::string& ofNode)
29{
Brad Bishop08379a32017-03-06 21:28:46 -050030 namespace fs = std::experimental::filesystem;
Brad Bishop613a5b32017-01-05 20:58:13 -050031 static constexpr auto hwmonRoot = "/sys/class/hwmon";
Brad Bishop08379a32017-03-06 21:28:46 -050032 static constexpr auto ofRoot = "/sys/firmware/devicetree/base";
Brad Bishop613a5b32017-01-05 20:58:13 -050033
Brad Bishop08379a32017-03-06 21:28:46 -050034 fs::path fullOfPath{ofRoot};
35 fullOfPath /= ofNode;
Brad Bishop613a5b32017-01-05 20:58:13 -050036
Brad Bishop08379a32017-03-06 21:28:46 -050037 for (const auto& hwmonInst : fs::directory_iterator(hwmonRoot))
Brad Bishop613a5b32017-01-05 20:58:13 -050038 {
Brad Bishop08379a32017-03-06 21:28:46 -050039 auto path = hwmonInst.path();
40 path /= "of_node";
Brad Bishop613a5b32017-01-05 20:58:13 -050041
Brad Bishop08379a32017-03-06 21:28:46 -050042 if (fs::canonical(path) != fullOfPath)
Brad Bishop613a5b32017-01-05 20:58:13 -050043 {
44 continue;
45 }
46
Brad Bishop08379a32017-03-06 21:28:46 -050047 return hwmonInst.path();
Brad Bishop613a5b32017-01-05 20:58:13 -050048 }
49
50 return std::string();
51}
52
Brad Bishop4db64422017-02-16 11:33:32 -050053int readSysfsWithCallout(const std::string& root,
54 const std::string& instance,
55 const std::string& type,
56 const std::string& id,
57 const std::string& sensor)
58{
Brad Bishop5ec68ab2017-03-27 13:41:02 -040059 namespace fs = std::experimental::filesystem;
60
Brad Bishop4db64422017-02-16 11:33:32 -050061 int value = 0;
Brad Bishop5ec68ab2017-03-27 13:41:02 -040062 std::ifstream ifs;
63 fs::path instancePath{root};
64 instancePath /= instance;
Brad Bishop4db64422017-02-16 11:33:32 -050065 std::string fullPath = make_sysfs_path(instancePath,
66 type, id, sensor);
Brad Bishop4db64422017-02-16 11:33:32 -050067
68 ifs.exceptions(std::ifstream::failbit
69 | std::ifstream::badbit
70 | std::ifstream::eofbit);
71 try
72 {
73 ifs.open(fullPath);
74 ifs >> value;
75 }
76 catch (const std::exception& e)
77 {
78 // Too many GCC bugs (53984, 66145) to do
79 // this the right way...
Brad Bishop4db64422017-02-16 11:33:32 -050080
81 // errno should still reflect the error from the failing open
82 // or read system calls that got us here.
83 auto rc = errno;
Brad Bishop5ec68ab2017-03-27 13:41:02 -040084 instancePath /= "device";
Matthew Barth4e1f30f2017-03-21 16:13:27 -050085 using namespace sdbusplus::xyz::openbmc_project::Sensor::Device::Error;
86 try
87 {
88 elog<ReadFailure>(
89 xyz::openbmc_project::Sensor::Device::
90 ReadFailure::CALLOUT_ERRNO(rc),
91 xyz::openbmc_project::Sensor::Device::
92 ReadFailure::CALLOUT_DEVICE_PATH(
93 fs::canonical(instancePath).c_str()));
94 }
95 catch (ReadFailure& elog)
96 {
97 commit(elog.name());
98 }
Brad Bishop4db64422017-02-16 11:33:32 -050099 exit(EXIT_FAILURE);
100 }
101
102 return value;
103}
104
Matthew Barth048ac872017-03-09 14:36:08 -0600105uint64_t writeSysfsWithCallout(const uint64_t& value,
106 const std::string& root,
107 const std::string& instance,
108 const std::string& type,
109 const std::string& id,
110 const std::string& sensor)
111{
112 namespace fs = std::experimental::filesystem;
113
114 std::string valueStr = std::to_string(value);
115 std::ofstream ofs;
116 fs::path instancePath{root};
117 instancePath /= instance;
118 std::string fullPath = make_sysfs_path(instancePath,
119 type, id, sensor);
120
121 ofs.exceptions(std::ofstream::failbit
122 | std::ofstream::badbit
123 | std::ofstream::eofbit);
124 try
125 {
126 ofs.open(fullPath);
127 ofs << valueStr;
128 }
129 catch (const std::exception& e)
130 {
131 // errno should still reflect the error from the failing open
132 // or write system calls that got us here.
133 auto rc = errno;
134 instancePath /= "device";
135 using namespace sdbusplus::xyz::openbmc_project::Control::Device::Error;
136 try
137 {
138 elog<WriteFailure>(
139 xyz::openbmc_project::Control::Device::
140 WriteFailure::CALLOUT_ERRNO(rc),
141 xyz::openbmc_project::Control::Device::
142 WriteFailure::CALLOUT_DEVICE_PATH(
143 fs::canonical(instancePath).c_str()));
144 }
145 catch (WriteFailure& elog)
146 {
147 commit(elog.name());
148 }
149 exit(EXIT_FAILURE);
150 }
151
152 return value;
153}
154
Brad Bishop613a5b32017-01-05 20:58:13 -0500155// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4