xref: /openbmc/phosphor-hwmon/sysfs.hpp (revision 8b574a7e)
1 #pragma once
2 
3 #include <exception>
4 #include <fstream>
5 #include <string>
6 
7 namespace sysfs {
8 
9 /**
10  * @class DeviceBusyException
11  *
12  * An internal exception which will be thrown when
13  * readSysfsWithCallout() hits an EAGAIN.  Will never bubble
14  * up to terminate the application, nor does it need to be
15  * reported.
16  */
17 class DeviceBusyException : public std::runtime_error
18 {
19     public:
20 
21         DeviceBusyException(const std::string& path) :
22             std::runtime_error(path + " busy")
23         {
24         }
25 };
26 
27 inline std::string make_sysfs_path(const std::string& path,
28                                    const std::string& type,
29                                    const std::string& id,
30                                    const std::string& entry)
31 {
32     using namespace std::literals;
33 
34     return path + "/"s + type + id + "_"s + entry;
35 }
36 
37 /** @brief Return the path to the phandle file matching value in io-channels.
38  *
39  *  This function will take two passed in paths.
40  *  One path is used to find the io-channels file.
41  *  The other path is used to find the phandle file.
42  *  The 4 byte phandle value is read from the phandle file(s).
43  *  The 4 byte phandle value and 4 byte index value is read from io-channels.
44  *  When a match is found, the path to the matching phandle file is returned.
45  *
46  *  @param[in] iochanneldir - Path to file for getting phandle from io-channels
47  *  @param[in] phandledir - Path to use for reading from phandle file
48  *
49  *  @return Path to phandle file with value matching that in io-channels
50  */
51 std::string findPhandleMatch(
52         const std::string& iochanneldir,
53         const std::string& phandledir);
54 
55 /** @brief Find hwmon instances
56  *
57  *  Look for a matching hwmon instance given an
58  *  open firmware device path.
59  *
60  *  @param[in] ofNode- The open firmware device path.
61  *
62  *  @returns[in] - The hwmon instance path or an empty
63  *                 string if no match is found.
64  */
65 std::string findHwmon(const std::string& ofNode);
66 
67 /** @brief Return the path to use for a call out.
68  *
69  *  Return an empty string if a callout path cannot be
70  *  found.
71  *
72  *  @param[in] instancePath - /sys/class/hwmon/hwmon<N> path.
73  *
74  *  @return Path to use for call out
75  */
76 std::string findCalloutPath(const std::string& instancePath);
77 
78 /** @brief Read an hwmon sysfs value.
79  *
80  *  Calls exit(3) with bad status on failure.
81  *
82  *  @param[in] root - The hwmon class root.
83  *  @param[in] instance - The hwmon instance (ex. hwmon1).
84  *  @param[in] type - The hwmon type (ex. temp).
85  *  @param[in] id - The hwmon id (ex. 1).
86  *  @param[in] sensor - The hwmon sensor (ex. input).
87  *  @param[in] throwDeviceBusy - will throw a DeviceBusyException
88  *             on an EAGAIN errno instead of an error log exception.
89  *
90  *  @returns - The read value.
91  */
92 int readSysfsWithCallout(const std::string& root,
93                          const std::string& instance,
94                          const std::string& type,
95                          const std::string& id,
96                          const std::string& sensor,
97                          bool throwDeviceBusy = true);
98 
99  /** @brief Write a hwmon sysfs value
100   *
101   *  Calls exit(3) with bad status on failure
102   *
103   *  @param[in] value - The value to be written
104   *  @param[in] root - The hwmon class root.
105   *  @param[in] instance - The hwmon instance (ex. hwmon1).
106   *  @param[in] type - The hwmon type (ex. fan).
107   *  @param[in] id - The hwmon id (ex. 1).
108   *  @param[in] sensor - The hwmon sensor (ex. target).
109   *
110   *  @returns - The value written
111   */
112 uint64_t writeSysfsWithCallout(const uint64_t& value,
113                                const std::string& root,
114                                const std::string& instance,
115                                const std::string& type,
116                                const std::string& id,
117                                const std::string& sensor);
118 
119 namespace hwmonio
120 {
121 
122 /** @class HwmonIO
123  *  @brief Convenience wrappers for HWMON sysfs attribute IO.
124  *
125  *  Unburden the rest of the application from having to check
126  *  ENOENT after every hwmon attribute io operation.  Hwmon
127  *  device drivers can be unbound at any time; the program
128  *  cannot always be terminated externally before we try to
129  *  do an io.
130  */
131 class HwmonIO
132 {
133     public:
134         HwmonIO() = delete;
135         HwmonIO(const HwmonIO&) = default;
136         HwmonIO(HwmonIO&&) = default;
137         HwmonIO& operator=(const HwmonIO&) = default;
138         HwmonIO& operator=(HwmonIO&&) = default;
139         ~HwmonIO() = default;
140 
141         /** @brief Constructor
142          *
143          *  @param[in] path - hwmon instance root - eg:
144          *      /sys/class/hwmon/hwmon<N>
145          */
146         explicit HwmonIO(const std::string& path);
147 
148         /** @brief Perform formatted hwmon sysfs read.
149          *
150          *  Propogates any exceptions other than ENOENT.
151          *  ENOENT will result in a call to exit(0) in case
152          *  the underlying hwmon driver is unbound and
153          *  the program is inadvertently left running.
154          *
155          *  @param[in] type - The hwmon type (ex. temp).
156          *  @param[in] id - The hwmon id (ex. 1).
157          *  @param[in] sensor - The hwmon sensor (ex. input).
158          *
159          *  @return val - The read value.
160          */
161         uint32_t read(
162                 const std::string& type,
163                 const std::string& id,
164                 const std::string& sensor) const;
165 
166         /** @brief Perform formatted hwmon sysfs write.
167          *
168          *  Propogates any exceptions other than ENOENT.
169          *  ENOENT will result in a call to exit(0) in case
170          *  the underlying hwmon driver is unbound and
171          *  the program is inadvertently left running.
172          *
173          *  @param[in] val - The value to be written.
174          *  @param[in] type - The hwmon type (ex. fan).
175          *  @param[in] id - The hwmon id (ex. 1).
176          *  @param[in] sensor - The hwmon sensor (ex. target).
177          */
178         void write(
179                 uint32_t val,
180                 const std::string& type,
181                 const std::string& id,
182                 const std::string& sensor) const;
183 
184         /** @brief Hwmon instance path access.
185          *
186          *  @return path - The hwmon instance path.
187          */
188         std::string path() const;
189 
190     private:
191         std::string p;
192 };
193 } // namespace hwmonio
194 }
195 
196 // vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
197