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

Reply via email to