chiark / gitweb /
add WAIT_FOR_SYSFS key to loop until a file in sysfs arrives
authorKay Sievers <kay.sievers@suse.de>
Thu, 7 Jul 2005 18:05:51 +0000 (20:05 +0200)
committerKay Sievers <kay.sievers@suse.de>
Thu, 7 Jul 2005 18:05:51 +0000 (20:05 +0200)
Signed-off-by: Kay Sievers <kay.sievers@suse.de>
udev_rules.c
udev_rules.h
udev_rules_parse.c

index 48397ac1c7bf3b9a6a74069b46ebff8683629f35..932a5b9c6fa9330ddd2797aef4ff3858c536fd09 100644 (file)
@@ -335,6 +335,28 @@ attr_found:
        return 0;
 }
 
+#define WAIT_LOOP_PER_SECOND                   20
+static int wait_for_sysfs(struct udevice *udev, const char *file, int timeout)
+{
+       char filename[PATH_SIZE];
+       struct stat stats;
+       int loop = timeout * WAIT_LOOP_PER_SECOND;
+
+       snprintf(filename, sizeof(filename), "%s%s/%s", sysfs_path, udev->devpath, file);
+       filename[sizeof(filename)-1] = '\0';
+       dbg("wait %i sec for '%s'", timeout, filename);
+
+       while (--loop) {
+               if (stat(filename, &stats) == 0) {
+                       dbg("file appeared after %i loops", (timeout * WAIT_LOOP_PER_SECOND) - loop-1);
+                       return 0;
+               }
+               usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND);
+       }
+       dbg("waiting for '%s' failed", filename);
+       return -1;
+}
+
 static void apply_format(struct udevice *udev, char *string, size_t maxsize,
                         struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device)
 {
@@ -622,15 +644,15 @@ static int match_key(const char *key_name, struct udev_rule *rule, struct key *k
        dbg("check for %s '%s' <-> '%s'", key_name, key_value, val);
        match = (strcmp_pattern(key_value, val) == 0);
        if (match && (key->operation != KEY_OP_NOMATCH)) {
-               dbg("%s key is matching (matching value)", key_name);
+               dbg("%s is matching (matching value)", key_name);
                return 0;
        }
        if (!match && (key->operation == KEY_OP_NOMATCH)) {
-               dbg("%s key is matching, (non matching value)", key_name);
+               dbg("%s is matching, (non matching value)", key_name);
                return 0;
        }
 
-       dbg("%s key is not matching", key_name);
+       dbg("%s is not matching", key_name);
        return -1;
 }
 
@@ -681,6 +703,22 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule,
                dbg("all %i ENV keys matched", rule->env.count);
        }
 
+       if (rule->wait_for_sysfs.operation != KEY_OP_UNSET) {
+               int match;
+
+               match = (wait_for_sysfs(udev, key_val(rule, &rule->wait_for_sysfs), 3) == 0);
+               if (match && (rule->wait_for_sysfs.operation != KEY_OP_NOMATCH)) {
+                       dbg("WAIT_FOR_SYSFS is matching (matching value)");
+                       return 0;
+               }
+               if (!match && (rule->wait_for_sysfs.operation == KEY_OP_NOMATCH)) {
+                       dbg("WAIT_FOR_SYSFS is matching, (non matching value)");
+                       return 0;
+               }
+               dbg("WAIT_FOR_SYSFS is not matching");
+               return -1;
+       }
+
        /* walk up the chain of physical devices and find a match */
        while (1) {
                /* check for matching driver */
index 4ecada1c039dba3632d5b32e779dc1af1857016d..959524a802fc48bdd7ac8fc5fb8835857822a72c 100644 (file)
@@ -66,6 +66,7 @@ struct udev_rule {
        struct key result;
        struct key modalias;
        struct key import;
+       struct key wait_for_sysfs;
        struct key_pairs sysfs;
        struct key_pairs env;
 
index c36fc8224c69772b9cefee303c922c823b13352a..2add91fa9fad720f407cb9bce4db16a528931c7e 100644 (file)
@@ -284,6 +284,12 @@ static int add_to_rules(struct udev_rules *rules, char *line)
                        continue;
                }
 
+               if (strcasecmp(key, "WAIT_FOR_SYSFS") == 0) {
+                       add_rule_key(rule, &rule->wait_for_sysfs, operation, value);
+                       valid = 1;
+                       continue;
+               }
+
                if (strncasecmp(key, "ENV", sizeof("ENV")-1) == 0) {
                        attr = get_key_attribute(key + sizeof("ENV")-1);
                        if (attr == NULL) {