1*d7be555eSGeorge Liu /*
2*d7be555eSGeorge Liu // Copyright (c) 2019 Intel Corporation
3*d7be555eSGeorge Liu //
4*d7be555eSGeorge Liu // Licensed under the Apache License, Version 2.0 (the "License");
5*d7be555eSGeorge Liu // you may not use this file except in compliance with the License.
6*d7be555eSGeorge Liu // You may obtain a copy of the License at
7*d7be555eSGeorge Liu //
8*d7be555eSGeorge Liu // http://www.apache.org/licenses/LICENSE-2.0
9*d7be555eSGeorge Liu //
10*d7be555eSGeorge Liu // Unless required by applicable law or agreed to in writing, software
11*d7be555eSGeorge Liu // distributed under the License is distributed on an "AS IS" BASIS,
12*d7be555eSGeorge Liu // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d7be555eSGeorge Liu // See the License for the specific language governing permissions and
14*d7be555eSGeorge Liu // limitations under the License.
15*d7be555eSGeorge Liu */
16*d7be555eSGeorge Liu
17*d7be555eSGeorge Liu #include "NVMeSensor.hpp"
18*d7be555eSGeorge Liu
19*d7be555eSGeorge Liu #include "SensorPaths.hpp"
20*d7be555eSGeorge Liu #include "Thresholds.hpp"
21*d7be555eSGeorge Liu #include "Utils.hpp"
22*d7be555eSGeorge Liu #include "sensor.hpp"
23*d7be555eSGeorge Liu
24*d7be555eSGeorge Liu #include <boost/asio/io_context.hpp>
25*d7be555eSGeorge Liu #include <sdbusplus/asio/connection.hpp>
26*d7be555eSGeorge Liu #include <sdbusplus/asio/object_server.hpp>
27*d7be555eSGeorge Liu
28*d7be555eSGeorge Liu #include <cstddef>
29*d7be555eSGeorge Liu #include <cstdint>
30*d7be555eSGeorge Liu #include <memory>
31*d7be555eSGeorge Liu #include <stdexcept>
32*d7be555eSGeorge Liu #include <string>
33*d7be555eSGeorge Liu #include <utility>
34*d7be555eSGeorge Liu #include <vector>
35*d7be555eSGeorge Liu
36*d7be555eSGeorge Liu static constexpr double maxReading = 127;
37*d7be555eSGeorge Liu static constexpr double minReading = 0;
38*d7be555eSGeorge Liu
NVMeSensor(sdbusplus::asio::object_server & objectServer,boost::asio::io_context &,std::shared_ptr<sdbusplus::asio::connection> & conn,const std::string & sensorName,std::vector<thresholds::Threshold> && thresholdsIn,const std::string & sensorConfiguration,const int busNumber,const uint8_t slaveAddr)39*d7be555eSGeorge Liu NVMeSensor::NVMeSensor(sdbusplus::asio::object_server& objectServer,
40*d7be555eSGeorge Liu boost::asio::io_context& /*unused*/,
41*d7be555eSGeorge Liu std::shared_ptr<sdbusplus::asio::connection>& conn,
42*d7be555eSGeorge Liu const std::string& sensorName,
43*d7be555eSGeorge Liu std::vector<thresholds::Threshold>&& thresholdsIn,
44*d7be555eSGeorge Liu const std::string& sensorConfiguration,
45*d7be555eSGeorge Liu const int busNumber, const uint8_t slaveAddr) :
46*d7be555eSGeorge Liu Sensor(escapeName(sensorName), std::move(thresholdsIn), sensorConfiguration,
47*d7be555eSGeorge Liu NVMeSensor::sensorType, false, false, maxReading, minReading, conn,
48*d7be555eSGeorge Liu PowerState::on),
49*d7be555eSGeorge Liu bus(busNumber), address(slaveAddr), objServer(objectServer)
50*d7be555eSGeorge Liu {
51*d7be555eSGeorge Liu if (bus < 0)
52*d7be555eSGeorge Liu {
53*d7be555eSGeorge Liu throw std::invalid_argument("Invalid bus: Bus ID must not be negative");
54*d7be555eSGeorge Liu }
55*d7be555eSGeorge Liu
56*d7be555eSGeorge Liu sensorInterface = objectServer.add_interface(
57*d7be555eSGeorge Liu "/xyz/openbmc_project/sensors/temperature/" + name,
58*d7be555eSGeorge Liu "xyz.openbmc_project.Sensor.Value");
59*d7be555eSGeorge Liu
60*d7be555eSGeorge Liu for (const auto& threshold : thresholds)
61*d7be555eSGeorge Liu {
62*d7be555eSGeorge Liu std::string interface = thresholds::getInterface(threshold.level);
63*d7be555eSGeorge Liu thresholdInterfaces[static_cast<size_t>(threshold.level)] =
64*d7be555eSGeorge Liu objectServer.add_interface(
65*d7be555eSGeorge Liu "/xyz/openbmc_project/sensors/temperature/" + name, interface);
66*d7be555eSGeorge Liu }
67*d7be555eSGeorge Liu association = objectServer.add_interface(
68*d7be555eSGeorge Liu "/xyz/openbmc_project/sensors/temperature/" + name,
69*d7be555eSGeorge Liu association::interface);
70*d7be555eSGeorge Liu
71*d7be555eSGeorge Liu setInitialProperties(sensor_paths::unitDegreesC);
72*d7be555eSGeorge Liu // Mark as unavailable until the first packet has been received over NVMe
73*d7be555eSGeorge Liu // MI.
74*d7be555eSGeorge Liu markAvailable(false);
75*d7be555eSGeorge Liu }
76*d7be555eSGeorge Liu
~NVMeSensor()77*d7be555eSGeorge Liu NVMeSensor::~NVMeSensor()
78*d7be555eSGeorge Liu {
79*d7be555eSGeorge Liu // close the input dev to cancel async operations
80*d7be555eSGeorge Liu for (const auto& iface : thresholdInterfaces)
81*d7be555eSGeorge Liu {
82*d7be555eSGeorge Liu objServer.remove_interface(iface);
83*d7be555eSGeorge Liu }
84*d7be555eSGeorge Liu objServer.remove_interface(sensorInterface);
85*d7be555eSGeorge Liu objServer.remove_interface(association);
86*d7be555eSGeorge Liu }
87*d7be555eSGeorge Liu
sample()88*d7be555eSGeorge Liu bool NVMeSensor::sample()
89*d7be555eSGeorge Liu {
90*d7be555eSGeorge Liu if (inError())
91*d7be555eSGeorge Liu {
92*d7be555eSGeorge Liu if (scanDelay == 0)
93*d7be555eSGeorge Liu {
94*d7be555eSGeorge Liu scanDelay = scanDelayTicks;
95*d7be555eSGeorge Liu }
96*d7be555eSGeorge Liu
97*d7be555eSGeorge Liu scanDelay--;
98*d7be555eSGeorge Liu }
99*d7be555eSGeorge Liu
100*d7be555eSGeorge Liu return scanDelay == 0;
101*d7be555eSGeorge Liu }
102*d7be555eSGeorge Liu
checkThresholds()103*d7be555eSGeorge Liu void NVMeSensor::checkThresholds()
104*d7be555eSGeorge Liu {
105*d7be555eSGeorge Liu thresholds::checkThresholds(this);
106*d7be555eSGeorge Liu }
107