blob: c99f4a3535d087b9caa71508f63760eaa73ad0e5 [file] [log] [blame]
Matt Spinlere10416e2017-04-10 14:15:53 -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 */
Matt Spinler57352a32017-04-10 14:48:35 -050016#include <algorithm>
Matt Spinleree7f6422017-05-09 11:03:14 -050017#include <phosphor-logging/log.hpp>
Dinesh Chinari618027a2017-06-26 23:26:50 -050018#include <phosphor-logging/elog.hpp>
19#include <phosphor-logging/elog-errors.hpp>
20#include <xyz/openbmc_project/Common/error.hpp>
Matt Spinleree7f6422017-05-09 11:03:14 -050021#include <unistd.h>
Matthew Barth14cc0432019-01-16 15:06:41 -060022#include "config.h"
Matt Spinlere10416e2017-04-10 14:15:53 -050023#include "manager.hpp"
Gunnar Millsf96b01e2017-06-02 16:32:19 -050024#include "utility.hpp"
Matthew Barth803d35b2018-05-09 12:15:46 -050025#include "sdbusplus.hpp"
Matt Spinlere10416e2017-04-10 14:15:53 -050026
27namespace phosphor
28{
29namespace fan
30{
31namespace control
32{
33
Matt Spinleree7f6422017-05-09 11:03:14 -050034using namespace phosphor::logging;
35
36constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1";
37constexpr auto SYSTEMD_OBJ_PATH = "/org/freedesktop/systemd1";
38constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager";
39constexpr auto FAN_CONTROL_READY_TARGET = "obmc-fan-control-ready@0.target";
40
Gunnar Millsf96b01e2017-06-02 16:32:19 -050041/**
42 * Check if a condition is true. Conditions are used to determine
43 * which fan zone to use.
44 *
45 * @param[in] bus - The D-Bus bus object
46 * @param[in] condition - The condition to check if true
47 * @return result - True if the condition is true
48 */
Brad Bishopf0b020f2018-11-21 10:42:34 -050049bool checkCondition(sdbusplus::bus::bus& bus, const Condition& c)
Gunnar Millsf96b01e2017-06-02 16:32:19 -050050{
51 auto& type = std::get<conditionTypePos>(c);
52 auto& properties = std::get<conditionPropertyListPos>(c);
53
54 for (auto& p : properties)
55 {
Matthew Barth803d35b2018-05-09 12:15:46 -050056 auto value = std::get<propertyValuePos>(p);
Gunnar Millsf96b01e2017-06-02 16:32:19 -050057
58 // TODO openbmc/openbmc#1769: Support more types than just getProperty.
59 if (type.compare("getProperty") == 0)
60 {
Matthew Barth803d35b2018-05-09 12:15:46 -050061 auto propertyValue = util::SDBusPlus::getProperty<decltype(value)>(
62 bus,
63 std::get<propertyPathPos>(p),
64 std::get<propertyInterfacePos>(p),
65 std::get<propertyNamePos>(p));
Gunnar Millsf96b01e2017-06-02 16:32:19 -050066
67 if (value != propertyValue)
68 {
69 return false;
70 }
71 }
72 }
73 return true;
74}
75
76
Matt Spinleree7f6422017-05-09 11:03:14 -050077//Note: Future code will check 'mode' before starting control algorithm
78Manager::Manager(sdbusplus::bus::bus& bus,
William A. Kennington III1cfc2f12018-10-19 17:29:46 -070079 const sdeventplus::Event& event,
Matt Spinleree7f6422017-05-09 11:03:14 -050080 Mode mode) :
Matt Spinlere10416e2017-04-10 14:15:53 -050081 _bus(bus)
82{
Matt Spinler57352a32017-04-10 14:48:35 -050083 //Create the appropriate Zone objects based on the
84 //actual system configuration.
85
86 //Find the 1 ZoneGroup that meets all of its conditions
87 for (auto& group : _zoneLayouts)
88 {
89 auto& conditions = std::get<conditionListPos>(group);
90
91 if (std::all_of(conditions.begin(), conditions.end(),
Gunnar Millsf96b01e2017-06-02 16:32:19 -050092 [&bus](const auto& condition)
93 {
94 return checkCondition(bus, condition);
95 }))
Matt Spinler57352a32017-04-10 14:48:35 -050096 {
97 //Create a Zone object for each zone in this group
98 auto& zones = std::get<zoneListPos>(group);
99
100 for (auto& z : zones)
101 {
102 _zones.emplace(std::get<zoneNumPos>(z),
William A. Kennington III1cfc2f12018-10-19 17:29:46 -0700103 std::make_unique<Zone>(mode, _bus, event, z));
Matt Spinler57352a32017-04-10 14:48:35 -0500104 }
105
106 break;
107 }
108 }
109
Matthew Barth14cc0432019-01-16 15:06:41 -0600110 bus.request_name(CONTROL_BUSNAME);
Matt Spinleree7f6422017-05-09 11:03:14 -0500111}
112
113
114void Manager::doInit()
115{
Gunnar Millsf96b01e2017-06-02 16:32:19 -0500116 for (auto& z : _zones)
Matt Spinler57352a32017-04-10 14:48:35 -0500117 {
118 z.second->setFullSpeed();
119 }
Matt Spinleree7f6422017-05-09 11:03:14 -0500120
121 auto delay = _powerOnDelay;
122 while (delay > 0)
123 {
124 delay = sleep(delay);
125 }
126
Matthew Barth20291062018-05-09 13:06:28 -0500127 util::SDBusPlus::callMethod(
128 _bus,
129 SYSTEMD_SERVICE,
130 SYSTEMD_OBJ_PATH,
131 SYSTEMD_INTERFACE,
132 "StartUnit",
133 FAN_CONTROL_READY_TARGET,
134 "replace");
Matt Spinleree7f6422017-05-09 11:03:14 -0500135}
136
Gunnar Millsf96b01e2017-06-02 16:32:19 -0500137} // namespace control
138} // namespace fan
139} // namespace phosphor