summaryrefslogtreecommitdiffstats
path: root/occ_status.cpp
blob: 7eafb662ebe0c7f3ae43e2f3f6dc33c3843743d7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <phosphor-logging/log.hpp>
#include "occ_status.hpp"
#include "occ_sensor.hpp"
#include "utils.hpp"
namespace open_power
{
namespace occ
{

bool Status::hubFsiScanDone = false;

// To initiate a FSI rescan
constexpr auto fsiReScan = "1";

// Handles updates to occActive property
bool Status::occActive(bool value)
{
    if (value != this->occActive())
    {
        if (value)
        {
            if (!hubFsiScanDone)
            {
                // Need to do hub scan before we bind
                this->scanHubFSI();
            }

            // Bind the device
            device.bind();

            // And watch for errors
            // Commenting until we solve the occ error monitoring issue
            // TODO: openbmc/openbmc#2126
            // device.addErrorWatch();
        }
        else
        {
            // Stop watching for errors
            // Commenting until we solve the occ error monitoring issue
            // TODO: openbmc/openbmc#2126
            // device.removeErrorWatch();

            // Do the unbind.
            device.unBind();
        }
    }
    return Base::Status::occActive(value);
}

// Callback handler when a device error is reported.
void Status::deviceErrorHandler()
{
    // This would deem OCC inactive
    this->occActive(false);

    // Reset the OCC
    this->resetOCC();
}

// Sends message to host control command handler to reset OCC
void Status::resetOCC()
{
    using namespace phosphor::logging;
    constexpr auto CONTROL_HOST_PATH = "/org/open_power/control/host0";
    constexpr auto CONTROL_HOST_INTF = "org.open_power.Control.Host";

    // This will throw exception on failure
    auto service = getService(bus, CONTROL_HOST_PATH, CONTROL_HOST_INTF);

    auto method = bus.new_method_call(service.c_str(),
                                      CONTROL_HOST_PATH,
                                      CONTROL_HOST_INTF,
                                      "Execute");
    // OCC Reset control command
    method.append(convertForMessage(
                Control::Host::Command::OCCReset).c_str());

    // OCC Sensor ID for callout reasons
    method.append(sdbusplus::message::variant<uint8_t>(
                        sensorMap.at(instance)));
    bus.call_noreply(method);
    return;
}

// Handler called by Host control command handler to convey the
// status of the executed command
void Status::hostControlEvent(sdbusplus::message::message& msg)
{
    using namespace phosphor::logging;

    std::string cmdCompleted{};
    std::string cmdStatus{};

    msg.read(cmdCompleted, cmdStatus);

    log<level::DEBUG>("Host control signal values",
                      entry("COMMAND=%s",cmdCompleted.c_str()),
                      entry("STATUS=%s",cmdStatus.c_str()));

    if(Control::Host::convertResultFromString(cmdStatus) !=
            Control::Host::Result::Success)
    {
        if(Control::Host::convertCommandFromString(cmdCompleted) ==
                Control::Host::Command::OCCReset)
        {
            // Must be a Timeout. Log an Erorr trace
            log<level::ERR>("Error resetting the OCC.",
                    entry("PATH=%s", path.c_str()),
                    entry("SensorID=0x%X",sensorMap.at(instance)));
        }
    }
    return;
}

// Scans the secondary FSI hub to make sure /dev/occ files are populated
// Write "1" to achieve that
void Status::scanHubFSI()
{
    std::ofstream file(FSI_SCAN_FILE, std::ios::out);
    file << fsiReScan;
    file.close();

    // Hub FSI scan has been done. No need to do this for all the OCCs
    hubFsiScanDone = true;
    return;
}

} // namespace occ
} // namespace open_power
OpenPOWER on IntegriCloud