blob: e6b17fd45843b0b36addb35637c54a6e8a2386f6 [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;
Marri Devender Rao05711eb2017-04-15 06:47:11 -050086 report<ReadFailure>(
87 xyz::openbmc_project::Sensor::Device::
88 ReadFailure::CALLOUT_ERRNO(rc),
89 xyz::openbmc_project::Sensor::Device::
90 ReadFailure::CALLOUT_DEVICE_PATH(
91 fs::canonical(instancePath).c_str()));
92
Brad Bishop4db64422017-02-16 11:33:32 -050093 exit(EXIT_FAILURE);
94 }
95
96 return value;
97}
98
Matthew Barth048ac872017-03-09 14:36:08 -060099uint64_t writeSysfsWithCallout(const uint64_t& value,
100 const std::string& root,
101 const std::string& instance,
102 const std::string& type,
103 const std::string& id,
104 const std::string& sensor)
105{
106 namespace fs = std::experimental::filesystem;
107
108 std::string valueStr = std::to_string(value);
109 std::ofstream ofs;
110 fs::path instancePath{root};
111 instancePath /= instance;
112 std::string fullPath = make_sysfs_path(instancePath,
113 type, id, sensor);
114
115 ofs.exceptions(std::ofstream::failbit
116 | std::ofstream::badbit
117 | std::ofstream::eofbit);
118 try
119 {
120 ofs.open(fullPath);
121 ofs << valueStr;
122 }
123 catch (const std::exception& e)
124 {
125 // errno should still reflect the error from the failing open
126 // or write system calls that got us here.
127 auto rc = errno;
128 instancePath /= "device";
129 using namespace sdbusplus::xyz::openbmc_project::Control::Device::Error;
Marri Devender Rao05711eb2017-04-15 06:47:11 -0500130 report<WriteFailure>(
131 xyz::openbmc_project::Control::Device::
132 WriteFailure::CALLOUT_ERRNO(rc),
133 xyz::openbmc_project::Control::Device::
134 WriteFailure::CALLOUT_DEVICE_PATH(
135 fs::canonical(instancePath).c_str()));
136
Matthew Barth048ac872017-03-09 14:36:08 -0600137 exit(EXIT_FAILURE);
138 }
139
140 return value;
141}
142
Brad Bishop613a5b32017-01-05 20:58:13 -0500143// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4