blob: 85e7c43da56a6461ad8de77abc39b9f7454d5e17 [file] [log] [blame]
Matt Spinler015e3ad2017-08-01 11:20:47 -05001/**
2 * Copyright © 2017 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 <experimental/filesystem>
17#include <fstream>
18#include <phosphor-logging/elog.hpp>
19#include <phosphor-logging/elog-errors.hpp>
20#include <xyz/openbmc_project/Common/error.hpp>
21#include <xyz/openbmc_project/Control/Device/error.hpp>
22#include <xyz/openbmc_project/Sensor/Device/error.hpp>
23#include "pmbus.hpp"
24
25namespace witherspoon
26{
27namespace pmbus
28{
29
30using namespace phosphor::logging;
31using namespace sdbusplus::xyz::openbmc_project::Common::Error;
32using namespace sdbusplus::xyz::openbmc_project::Control::Device::Error;
33using namespace sdbusplus::xyz::openbmc_project::Sensor::Device::Error;
34namespace fs = std::experimental::filesystem;
35
36std::string PMBus::insertPageNum(const std::string& templateName,
37 size_t page)
38{
39 auto name = templateName;
40
41 //insert the page where the P was
42 auto pos = name.find('P');
43 if (pos != std::string::npos)
44 {
45 name.replace(pos, 1, std::to_string(page));
46 }
47
48 return name;
49}
50
51bool PMBus::readBitInPage(const std::string& name, size_t page)
52{
53 auto pagedBit = insertPageNum(name, page);
54 return readBit(pagedBit);
55}
56
57bool PMBus::readBit(const std::string& name)
58{
59 unsigned long int value = 0;
60 std::ifstream file;
61 fs::path path{basePath};
62
63 path /= name;
64
65 file.exceptions(std::ifstream::failbit |
66 std::ifstream::badbit |
67 std::ifstream::eofbit);
68
69 try
70 {
71 char* err = NULL;
72 std::string val{1, '\0'};
73
74 file.open(path);
75 file.read(&val[0], 1);
76
77 value = strtoul(val.c_str(), &err, 10);
78
79 if (*err)
80 {
81 log<level::ERR>("Invalid character in sysfs file",
82 entry("FILE=%s", path.c_str()),
83 entry("CONTENTS=%s", val.c_str()));
84
85 //Catch below and handle as a read failure
86 elog<InternalFailure>();
87 }
88 }
89 catch (std::exception& e)
90 {
91 auto rc = errno;
92
93 log<level::ERR>("Failed to read sysfs file",
94 entry("FILENAME=%s", path.c_str()));
95
96 elog<ReadFailure>(xyz::openbmc_project::Sensor::Device::
97 ReadFailure::CALLOUT_ERRNO(rc),
98 xyz::openbmc_project::Sensor::Device::
99 ReadFailure::CALLOUT_DEVICE_PATH(
100 fs::canonical(basePath).c_str()));
101 }
102
103 return value != 0;
104}
105
106void PMBus::write(const std::string& name, int value)
107{
108 std::ofstream file;
109 fs::path path{basePath};
110
111 path /= name;
112
113 file.exceptions(std::ofstream::failbit |
114 std::ofstream::badbit |
115 std::ofstream::eofbit);
116
117 try
118 {
119 file.open(path);
120 file << value;
121 }
122 catch (const std::exception& e)
123 {
124 auto rc = errno;
125
126 log<level::ERR>("Failed to write sysfs file",
127 entry("FILENAME=%s", path.c_str()));
128
129 elog<WriteFailure>(xyz::openbmc_project::Control::Device::
130 WriteFailure::CALLOUT_ERRNO(rc),
131 xyz::openbmc_project::Control::Device::
132 WriteFailure::CALLOUT_DEVICE_PATH(
133 fs::canonical(basePath).c_str()));
134 }
135}
136
137}
138}