AU: fix bug in GPIO handler that caused failed discovery to be ignored
This solves two issues:
* The GPIO handler will attempt to use GPIO devices even when discovery
via udev has failed. Not any more.
* GPIO discovery would return success even when it failed on a previous
attempt. Now it'll reflect the actual result of the discovery attempt.
* Reporting of file descriptor open errors is obscured due to
intermittent operations that reset errno, now fixed.
* Added test case to ensure that repeat GPIO discovery is not attempted,
and that test mode check will automatically fail if a previous
initialization/discovery had failed.
BUG=None
TEST=Passes unit tests
TEST=All symptoms gone on real update attempt w/ x86-alex
Change-Id: I01a7b1e316dbb5b94487a5aad1560d994feae9ff
Reviewed-on: https://gerrit.chromium.org/gerrit/40946
Commit-Queue: Gilad Arnold <garnold@chromium.org>
Reviewed-by: Gilad Arnold <garnold@chromium.org>
Tested-by: Gilad Arnold <garnold@chromium.org>
diff --git a/gpio_handler.cc b/gpio_handler.cc
index f49a555..8627ba2 100644
--- a/gpio_handler.cc
+++ b/gpio_handler.cc
@@ -46,7 +46,8 @@
: udev_iface_(udev_iface),
fd_(fd),
is_cache_test_mode_(is_cache_test_mode),
- is_discovery_attempted_(false) {
+ is_discovery_attempted_(false),
+ is_discovery_successful_(false) {
CHECK(udev_iface && fd);
// Ensure there's only one instance of this class.
@@ -57,9 +58,8 @@
ResetTestModeSignalingFlags();
// If GPIO discovery not deferred, do it.
- if (!(is_defer_discovery || DiscoverGpios())) {
- LOG(WARNING) << "GPIO discovery failed";
- }
+ if (!is_defer_discovery)
+ DiscoverGpios();
}
StandardGpioHandler::~StandardGpioHandler() {
@@ -67,19 +67,19 @@
}
bool StandardGpioHandler::IsTestModeSignaled() {
- // Attempt GPIO discovery.
- if (!DiscoverGpios()) {
- LOG(WARNING) << "GPIO discovery failed";
- }
+ bool is_returning_cached = false; // for logging purposes
- // Force a check if so requested.
- if (!is_cache_test_mode_)
- ResetTestModeSignalingFlags();
+ // Attempt GPIO discovery first.
+ if (DiscoverGpios()) {
+ // Force a check if so requested.
+ if (!is_cache_test_mode_)
+ ResetTestModeSignalingFlags();
- bool is_returning_cached = !is_first_check_; // for logging purposes
- if (is_first_check_) {
- is_first_check_ = false;
- DoTestModeSignalingProtocol();
+ is_returning_cached = !is_first_check_; // for logging purposes
+ if (is_first_check_) {
+ is_first_check_ = false;
+ DoTestModeSignalingProtocol();
+ }
}
LOG(INFO) << "result: " << (is_test_mode_ ? "test" : "normal") << " mode"
@@ -255,14 +255,14 @@
bool StandardGpioHandler::DiscoverGpios() {
if (is_discovery_attempted_)
- return true;
+ return is_discovery_successful_;
is_discovery_attempted_ = true;
// Obtain libudev instance and attach to a dedicated closer.
struct udev* udev;
if (!(udev = udev_iface_->New())) {
- LOG(ERROR) << "failed to obtain libudev instance";
+ LOG(ERROR) << "failed to obtain libudev instance, aborting GPIO discovery";
return false;
}
scoped_ptr<UdevInterface::UdevCloser>
@@ -284,6 +284,7 @@
}
}
+ is_discovery_successful_ = true;
return true;
}
@@ -302,13 +303,14 @@
string file_name = StringPrintf("%s/%s", gpios_[id].dev_path.c_str(),
dev_name);
if (!fd_->Open(file_name.c_str(), (is_write ? O_WRONLY : O_RDONLY))) {
- const string err_str = StringPrintf("failed to open %s (%s) for %s",
- file_name.c_str(), gpio_defs_[id].name,
- (is_write ? "writing" : "reading"));
if (fd_->IsSettingErrno()) {
- PLOG(ERROR) << err_str;
+ PLOG(ERROR) << "failed to open " << file_name
+ << " (" << gpio_defs_[id].name << ") for "
+ << (is_write ? "writing" : "reading");
} else {
- LOG(ERROR) << err_str;
+ LOG(ERROR) << "failed to open " << file_name
+ << " (" << gpio_defs_[id].name << ") for "
+ << (is_write ? "writing" : "reading");
}
return false;
}