sysfs IO enhancements

Add retries for some sysfs IO errors:
 EIO: Tolerate intermittant device or bus failures.
 ETIMEDOUT: Tolerate intermittant timeouts.
 EAGAIN: Tolerate drivers that do not block.
 ENXIO: Tolerate momentarily unplugged devices on busses that don't
    support hotplug.
 EBADMSG: Tolerate CRC errors.

Flush stdio buffers after writes.
Remove redundant retry and delay constants.

Resolves: openbmc/openbmc#2262

Change-Id: I2104139bf7ced96bb10f7450b42ca36e61c84287
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
diff --git a/mainloop.cpp b/mainloop.cpp
index 7399df4..217c34c 100644
--- a/mainloop.cpp
+++ b/mainloop.cpp
@@ -16,7 +16,6 @@
 #include <iostream>
 #include <memory>
 #include <cstdlib>
-#include <algorithm>
 
 #include <phosphor-logging/elog-errors.hpp>
 #include "config.h"
@@ -61,8 +60,6 @@
 decltype(Thresholds<CriticalObject>::alarmHi) Thresholds<CriticalObject>::alarmHi =
     &CriticalObject::criticalAlarmHigh;
 
-
-
 static constexpr auto typeAttrMap =
 {
     // 1 - hwmon class
@@ -157,48 +154,17 @@
     auto& obj = std::get<Object>(info);
     auto& objPath = std::get<std::string>(info);
 
-    auto readWithRetry = [&ioAccess](
-            const auto& type,
-            const auto& id,
-            const auto& sensor,
-            auto retries,
-            const auto& delay)
-    {
-        auto value = 0;
-
-        while(true)
-        {
-            try
-            {
-                value = ioAccess.read(type, id, sensor);
-            }
-            catch (const std::system_error& e)
-            {
-                if (e.code().value() != EAGAIN || !retries)
-                {
-                    throw;
-                }
-
-                --retries;
-                std::this_thread::sleep_for(delay);
-                continue;
-            }
-            break;
-        }
-        return value;
-    };
-
-    static constexpr auto retries = 10;
     auto val = 0;
     try
     {
         // Retry for up to a second if device is busy
-        val = readWithRetry(
+        // or has a transient error.
+        val = ioAccess.read(
                 sensor.first,
                 sensor.second,
-                hwmon::entry::input,
-                retries,
-                std::chrono::milliseconds{100});
+                hwmon::entry::cinput,
+                sysfs::hwmonio::retries,
+                sysfs::hwmonio::delay);
     }
     catch (const std::system_error& e)
     {
@@ -389,10 +355,15 @@
                 int value;
                 try
                 {
+                    // Retry for up to a second if device is busy
+                    // or has a transient error.
+
                     value = ioAccess.read(
                             i.first.first,
                             i.first.second,
-                            hwmon::entry::input);
+                            hwmon::entry::cinput,
+                            sysfs::hwmonio::retries,
+                            sysfs::hwmonio::delay);
 
                     auto& objInfo = std::get<ObjectInfo>(i.second);
                     auto& obj = std::get<Object>(objInfo);
@@ -423,14 +394,6 @@
                 }
                 catch (const std::system_error& e)
                 {
-                    if (e.code().value() == EAGAIN)
-                    {
-                        //Just go with the current values and try again later.
-                        //TODO: openbmc/openbmc#2048 could keep an eye on
-                        //how long the device is actually busy.
-                        continue;
-                    }
-
                     using namespace sdbusplus::xyz::openbmc_project::
                         Sensor::Device::Error;
                     report<ReadFailure>(
@@ -439,7 +402,6 @@
                             xyz::openbmc_project::Sensor::Device::
                                 ReadFailure::CALLOUT_DEVICE_PATH(
                                     _devPath.c_str()));
-
 #ifdef REMOVE_ON_FAIL
                     destroy.push_back(i.first);
 #else