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 24 namespace phosphor 25 { 26 namespace fan 27 { 28 namespace control 29 { 30 31 // For throwing exception 32 using namespace phosphor::logging; 33 using InternalFailure = sdbusplus::xyz::openbmc_project::Common:: 34 Error::InternalFailure; 35 36 constexpr auto PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties"; 37 constexpr auto FAN_SENSOR_PATH = "/xyz/openbmc_project/sensors/fan_tach/"; 38 constexpr auto FAN_SENSOR_CONTROL_INTF = "xyz.openbmc_project.Control.FanSpeed"; 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 { 46 auto sensors = std::get<sensorListPos>(def); 47 for (auto& s : sensors) 48 { 49 _sensors.emplace_back(FAN_SENSOR_PATH + s); 50 } 51 } 52 53 54 //TODO openbmc/openbmc#1524 Can cache this value when 55 //openbmc/openbmc#1496 is resolved. 56 std::string Fan::getService(const std::string& sensor) 57 { 58 return phosphor::fan::util::getService(sensor, 59 FAN_SENSOR_CONTROL_INTF, 60 _bus); 61 } 62 63 64 void Fan::setSpeed(uint64_t speed) 65 { 66 sdbusplus::message::variant<uint64_t> value = speed; 67 std::string property{FAN_TARGET_PROPERTY}; 68 69 for (auto& sensor : _sensors) 70 { 71 auto service = getService(sensor); 72 73 auto method = _bus.new_method_call(service.c_str(), 74 sensor.c_str(), 75 PROPERTY_INTERFACE, 76 "Set"); 77 method.append(FAN_SENSOR_CONTROL_INTF, property, value); 78 79 auto response = _bus.call(method); 80 if (response.is_method_error()) 81 { 82 log<level::ERR>( 83 "Failed call to set fan speed ", entry("SENSOR=%s", sensor)); 84 elog<InternalFailure>(); 85 } 86 } 87 } 88 89 } 90 } 91 } 92