This is an automated email from Gerrit. Antonio Borneo ([email protected]) just uploaded a new patch set to Gerrit, which you can find at http://openocd.zylin.com/5302
-- gerrit commit 36fe8fac08d3acdf815c3265cae433a79f258922 Author: Antonio Borneo <[email protected]> Date: Thu Sep 5 10:48:12 2019 +0200 sysfsgpio: give time to udev to change gpio permission When a gpio is exported by writing in /sys/class/gpio/export, it appears immediately in sysfs but with default access permission for root user only. The daemon udev requires some time to get notified and then change the gpio files permission to allow access to unprivileged users. Due to this race condition, sysfsgpio can fail with EACCES error if OpenOCD is executed by any unprivileged user. Give 0.5 seconds to udev to identify the new files and change the permission. Change-Id: I1316c66ff103ffe23e5e4720f33372dc272a3766 Signed-off-by: Antonio Borneo <[email protected]> diff --git a/src/jtag/drivers/sysfsgpio.c b/src/jtag/drivers/sysfsgpio.c index eb4941e..f82dc13 100644 --- a/src/jtag/drivers/sysfsgpio.c +++ b/src/jtag/drivers/sysfsgpio.c @@ -52,9 +52,12 @@ #include "config.h" #endif +#include <helper/time_support.h> #include <jtag/interface.h> #include "bitbang.h" +#define TIMEOUT_FOR_UDEV_MS 500 + /* * Helper func to determine if gpio number valid * @@ -112,6 +115,7 @@ static void unexport_sysfs_gpio(int gpio) */ static int setup_sysfs_gpio(int gpio, int is_output, int init_high) { + struct timeval timeout, now; char buf[40]; char gpiostr[5]; int ret; @@ -131,8 +135,19 @@ static int setup_sysfs_gpio(int gpio, int is_output, int init_high) } } + gettimeofday(&timeout, NULL); + timeval_add_time(&timeout, 0, TIMEOUT_FOR_UDEV_MS * 1000); + snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/direction", gpio); - ret = open_write_close(buf, is_output ? (init_high ? "high" : "low") : "in"); + for (;;) { + ret = open_write_close(buf, is_output ? (init_high ? "high" : "low") : "in"); + if (ret >= 0 || errno != EACCES) + break; + gettimeofday(&now, NULL); + if (timeval_compare(&now, &timeout) >= 0) + break; + jtag_sleep(10000); + } if (ret < 0) { LOG_ERROR("Couldn't set direction for gpio %d", gpio); perror("sysfsgpio: "); @@ -141,7 +156,15 @@ static int setup_sysfs_gpio(int gpio, int is_output, int init_high) } snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/value", gpio); - ret = open(buf, O_RDWR | O_NONBLOCK | O_SYNC); + for (;;) { + ret = open(buf, O_RDWR | O_NONBLOCK | O_SYNC); + if (ret >= 0 || errno != EACCES) + break; + gettimeofday(&now, NULL); + if (timeval_compare(&now, &timeout) >= 0) + break; + jtag_sleep(10000); + } if (ret < 0) { LOG_ERROR("Couldn't open value for gpio %d", gpio); perror("sysfsgpio: "); -- _______________________________________________ OpenOCD-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/openocd-devel
