1 /** 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 <phosphor-logging/log.hpp> 17 #include <phosphor-logging/elog.hpp> 18 #include <phosphor-logging/elog-errors.hpp> 19 #include <xyz/openbmc_project/Common/error.hpp> 20 #include <string> 21 #include "fan.hpp" 22 #include "utility.hpp" 23 #include "sdbusplus.hpp" 24 25 namespace phosphor 26 { 27 namespace fan 28 { 29 namespace control 30 { 31 32 // For throwing exception 33 using namespace phosphor::logging; 34 using InternalFailure = sdbusplus::xyz::openbmc_project::Common:: 35 Error::InternalFailure; 36 37 constexpr auto PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties"; 38 constexpr auto FAN_SENSOR_PATH = "/xyz/openbmc_project/sensors/fan_tach/"; 39 constexpr auto FAN_TARGET_PROPERTY = "Target"; 40 41 42 Fan::Fan(sdbusplus::bus::bus& bus, const FanDefinition& def): 43 _bus(bus), 44 _name(std::get<fanNamePos>(def)), 45 _interface(std::get<targetInterfacePos>(def)) 46 { 47 std::string path; 48 auto sensors = std::get<sensorListPos>(def); 49 for (auto& s : sensors) 50 { 51 path = FAN_SENSOR_PATH + s; 52 _sensors.emplace_back(path); 53 } 54 // All sensors associated with this fan are set to same target speed, 55 // so only need to read target property from one. 56 if (!path.empty()) 57 { 58 _targetSpeed = util::SDBusPlus::getProperty<uint64_t>( 59 bus, 60 path, 61 _interface, 62 FAN_TARGET_PROPERTY); 63 } 64 } 65 66 67 //TODO openbmc/openbmc#1524 Can cache this value when 68 //openbmc/openbmc#1496 is resolved. 69 std::string Fan::getService(const std::string& sensor) 70 { 71 return phosphor::fan::util::getService(sensor, 72 _interface, 73 _bus); 74 } 75 76 77 void Fan::setSpeed(uint64_t speed) 78 { 79 sdbusplus::message::variant<uint64_t> value = speed; 80 std::string property{FAN_TARGET_PROPERTY}; 81 82 for (auto& sensor : _sensors) 83 { 84 auto service = getService(sensor); 85 86 auto method = _bus.new_method_call(service.c_str(), 87 sensor.c_str(), 88 PROPERTY_INTERFACE, 89 "Set"); 90 method.append(_interface, property, value); 91 92 auto response = _bus.call(method); 93 if (response.is_method_error()) 94 { 95 log<level::ERR>( 96 "Failed call to set fan speed ", entry("SENSOR=%s", sensor)); 97 elog<InternalFailure>(); 98 } 99 } 100 101 _targetSpeed = speed; 102 } 103 104 } 105 } 106 } 107