blob: 0cc11ef312a21c181aadd9da62db590a842f54ff [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>
17#include <memory>
Brad Bishop4db64422017-02-16 11:33:32 -050018#include <phosphor-logging/log.hpp>
Brad Bishop613a5b32017-01-05 20:58:13 -050019#include "sysfs.hpp"
20#include "util.hpp"
21#include "directory.hpp"
22
23std::string findHwmon(const std::string& ofNode)
24{
25 static constexpr auto hwmonRoot = "/sys/class/hwmon";
26
27 std::string fullOfPath{"/sys/firmware/devicetree/base"};
28 fullOfPath.append(ofNode);
29
30 std::string hwmonInst;
31 Directory d(hwmonRoot);
32
33 while (d.next(hwmonInst))
34 {
35 std::string hwmonPath{hwmonRoot};
36 hwmonPath.append(1, '/');
37 hwmonPath.append(hwmonInst);
38 std::string path{hwmonPath};
39 path.append(1, '/');
40 path.append("of_node");
41
42 auto real = std::unique_ptr<char, phosphor::utility::Free<char>>(realpath(
43 path.c_str(), nullptr));
44 if (!real || real.get() != fullOfPath)
45 {
46 continue;
47 }
48
49 return hwmonPath;
50 }
51
52 return std::string();
53}
54
Brad Bishop4db64422017-02-16 11:33:32 -050055int readSysfsWithCallout(const std::string& root,
56 const std::string& instance,
57 const std::string& type,
58 const std::string& id,
59 const std::string& sensor)
60{
61 int value = 0;
62 std::string instancePath = root + '/' + instance;
63 std::string fullPath = make_sysfs_path(instancePath,
64 type, id, sensor);
65 std::ifstream ifs;
66
67 ifs.exceptions(std::ifstream::failbit
68 | std::ifstream::badbit
69 | std::ifstream::eofbit);
70 try
71 {
72 ifs.open(fullPath);
73 ifs >> value;
74 }
75 catch (const std::exception& e)
76 {
77 // Too many GCC bugs (53984, 66145) to do
78 // this the right way...
79 using Cleanup = phosphor::utility::Free<char>;
80
81 // errno should still reflect the error from the failing open
82 // or read system calls that got us here.
83 auto rc = errno;
84 std::string devicePath = instancePath + "/device";
85 auto real = std::unique_ptr<char, Cleanup>(
86 realpath(devicePath.c_str(), nullptr));
87 phosphor::logging::log<phosphor::logging::level::ERR>(
88 strerror(rc),
89 phosphor::logging::entry("CALLOUT_DEVICE_PATH=%s", real.get()),
90 phosphor::logging::entry("CALLOUT_ERRNO=%d", rc));
91 exit(EXIT_FAILURE);
92 }
93
94 return value;
95}
96
Brad Bishop613a5b32017-01-05 20:58:13 -050097// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4