chiark / gitweb /
[PATCH] add ability to have up to 5 SYSFS_ file/value pairs for the LABEL rule.
authorgreg@kroah.com <greg@kroah.com>
Tue, 23 Dec 2003 06:31:35 +0000 (22:31 -0800)
committerGreg KH <gregkh@suse.de>
Wed, 27 Apr 2005 04:13:10 +0000 (21:13 -0700)
namedev.c
namedev.h
namedev_parse.c

index 7c422f78779f1f1408ea63f01115314dc0bc5ce8..d879fd55902eb55259fa04e162c180ad9b0e63c4 100644 (file)
--- a/namedev.c
+++ b/namedev.c
@@ -102,19 +102,6 @@ static int strcmp_pattern(const char *p, const char *s)
        if (strlen(b->var))             \
                strcpy(a->var, b->var);
 
-int add_config_dev(struct config_device *new_dev)
-{
-       struct config_device *tmp_dev;
-
-       tmp_dev = malloc(sizeof(*tmp_dev));
-       if (tmp_dev == NULL)
-               return -ENOMEM;
-       memcpy(tmp_dev, new_dev, sizeof(*tmp_dev));
-       list_add_tail(&tmp_dev->node, &config_device_list);
-       //dump_config_dev(tmp_dev);
-       return 0;
-}
-
 int add_perm_dev(struct perm_device *new_dev)
 {
        struct list_head *tmp;
@@ -432,12 +419,50 @@ static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev
        return -ENODEV;
 }
 
-static int do_label(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device)
+static int match_pair(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, struct sysfs_pair *pair)
 {
        struct sysfs_attribute *tmpattr = NULL;
+       char *c;
+
+       if ((pair == NULL) || (pair->file[0] == '\0') || (pair->value == '\0'))
+               return -ENODEV;
+
+       dbg("look for device attribute '%s'", pair->file);
+       /* try to find the attribute in the class device directory */
+       tmpattr = sysfs_get_classdev_attr(class_dev, pair->file);
+       if (tmpattr)
+               goto label_found;
+
+       /* look in the class device directory if present */
+       if (sysfs_device) {
+               tmpattr = sysfs_get_device_attr(sysfs_device, pair->file);
+               if (tmpattr)
+                       goto label_found;
+       }
+
+       return -ENODEV;
+
+label_found:
+       c = tmpattr->value + strlen(tmpattr->value)-1;
+       if (*c == '\n')
+               *c = 0x00;
+       dbg("compare attribute '%s' value '%s' with '%s'",
+                 pair->file, tmpattr->value, pair->value);
+       if (strcmp_pattern(pair->value, tmpattr->value) != 0)
+               return -ENODEV;
+
+       dbg("found matching attribute '%s' with value '%s'",
+           pair->file, pair->value);
+       return 0;
+}
+
+static int do_label(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device)
+{
+       struct sysfs_pair *pair;
        struct config_device *dev;
        struct list_head *tmp;
-       char *c;
+       int i;
+       int match;
 
        list_for_each(tmp, &config_device_list) {
                dev = list_entry(tmp, struct config_device, node);
@@ -450,34 +475,24 @@ static int do_label(struct sysfs_class_device *class_dev, struct udevice *udev,
                                continue;
                }
 
-               dbg("look for device attribute '%s'", dev->sysfs_file);
-               /* try to find the attribute in the class device directory */
-               tmpattr = sysfs_get_classdev_attr(class_dev, dev->sysfs_file);
-               if (tmpattr)
-                       goto label_found;
-
-               /* look in the class device directory if present */
-               if (sysfs_device) {
-                       tmpattr = sysfs_get_device_attr(sysfs_device, dev->sysfs_file);
-                       if (tmpattr)
-                               goto label_found;
+               match = 1;
+               for (i = 0; i < MAX_SYSFS_PAIRS; ++i) {
+                       pair = &dev->sysfs_pair[i];
+                       if ((pair->file[0] == '\0') || (pair->value[0] == '\0'))
+                               break;
+                       if (match_pair(class_dev, sysfs_device, pair) != 0) {
+                               match = 0;
+                               break;
+                       }
                }
-
-               continue;
-
-label_found:
-               c = tmpattr->value + strlen(tmpattr->value)-1;
-               if (*c == '\n')
-                       *c = 0x00;
-               dbg("compare attribute '%s' value '%s' with '%s'",
-                         dev->sysfs_file, tmpattr->value, dev->sysfs_value);
-               if (strcmp_pattern(dev->sysfs_value, tmpattr->value) != 0)
+               if (match == 0)
                        continue;
 
+               /* found match */
                strfieldcpy(udev->name, dev->name);
                strfieldcpy(udev->symlink, dev->symlink);
-               dbg("found matching attribute '%s', '%s' becomes '%s' ",
-                   dev->sysfs_file, class_dev->name, udev->name);
+               dbg("found matching attribute, '%s' becomes '%s' ",
+                   class_dev->name, udev->name);
 
                return 0;
        }
index 69c488936d13cc25a3ea3d9d792b977871cb20e4..1eaf4fee4d9a2123adbe995b3ef4a74cbe0c535c 100644 (file)
--- a/namedev.h
+++ b/namedev.h
@@ -60,20 +60,25 @@ enum config_type {
 #define FIELD_SYMLINK  "SYMLINK"
 
 #define CALLOUT_MAXARG 8
+#define MAX_SYSFS_PAIRS        5
+
+struct sysfs_pair {
+       char file[FILE_SIZE];
+       char value[VALUE_SIZE];
+};
 
 struct config_device {
        struct list_head node;
 
        enum config_type type;
        char bus[BUS_SIZE];
-       char sysfs_file[FILE_SIZE];
-       char sysfs_value[VALUE_SIZE];
        char id[ID_SIZE];
        char place[PLACE_SIZE];
        char kernel_name[NAME_SIZE];
        char exec_program[FILE_SIZE];
        char name[NAME_SIZE];
        char symlink[NAME_SIZE];
+       struct sysfs_pair sysfs_pair[MAX_SYSFS_PAIRS];
 };
 
 struct perm_device {
@@ -93,7 +98,6 @@ extern int namedev_name_device(struct sysfs_class_device *class_dev, struct udev
 extern int namedev_init_permissions(void);
 extern int namedev_init_rules(void);
 
-extern int add_config_dev(struct config_device *new_dev);
 extern int add_perm_dev(struct perm_device *new_dev);
 extern void dump_config_dev(struct config_device *dev);
 extern void dump_config_dev_list(void);
index 33e0c89e2218676086b826c9c92e8ef140cf514f..266fa35a1945939ab5f384d70980dfcd3b2c089e 100644 (file)
 #include "udev.h"
 #include "namedev.h"
 
+static int add_config_dev(struct config_device *new_dev)
+{
+       struct config_device *tmp_dev;
+
+       tmp_dev = malloc(sizeof(*tmp_dev));
+       if (tmp_dev == NULL)
+               return -ENOMEM;
+       memcpy(tmp_dev, new_dev, sizeof(*tmp_dev));
+       list_add_tail(&tmp_dev->node, &config_device_list);
+       //dump_config_dev(tmp_dev);
+       return 0;
+}
+
 int get_pair(char **orig_string, char **left, char **right)
 {
        char *temp;
@@ -78,8 +91,8 @@ void dump_config_dev(struct config_device *dev)
                dbg_parse("KERNEL name='%s'", dev->name);
                break;
        case LABEL:
-               dbg_parse("LABEL name='%s', bus='%s', sysfs_file='%s', sysfs_value='%s'",
-                         dev->name, dev->bus, dev->sysfs_file, dev->sysfs_value);
+               dbg_parse("LABEL name='%s', bus='%s', sysfs_file[0]='%s', sysfs_value[0]='%s'",
+                         dev->name, dev->bus, dev->sysfs_pair[0].file, dev->sysfs_pair[0].value);
                break;
        case NUMBER:
                dbg_parse("NUMBER name='%s', bus='%s', id='%s'",
@@ -225,9 +238,23 @@ keys:
                        }
 
                        if (strncasecmp(temp2, FIELD_SYSFS, sizeof(FIELD_SYSFS)-1) == 0) {
-                               /* remove prepended 'SYSFS_' */
-                               strfieldcpy(dev.sysfs_file, temp2 + sizeof(FIELD_SYSFS)-1);
-                               strfieldcpy(dev.sysfs_value, temp3);
+                               struct sysfs_pair *pair = &dev.sysfs_pair[0];
+                               int sysfs_pair_num = 0;
+
+                               /* find first unused pair */
+                               while (pair->file[0] != '\0') {
+                                       ++sysfs_pair_num;
+                                       if (sysfs_pair_num >= MAX_SYSFS_PAIRS) {
+                                               pair = NULL;
+                                               break;
+                                       }
+                                       ++pair;
+                               }
+                               if (pair) {
+                                       /* remove prepended 'SYSFS_' */
+                                       strfieldcpy(pair->file, temp2 + sizeof(FIELD_SYSFS)-1);
+                                       strfieldcpy(pair->value, temp3);
+                               }
                                continue;
                        }
 
@@ -258,13 +285,13 @@ keys:
                switch (dev.type) {
                case LABEL:
                        dbg_parse(TYPE_LABEL " name='%s', bus='%s', "
-                                 "sysfs_file='%s', sysfs_value='%s', symlink='%s'",
-                                 dev.name, dev.bus, dev.sysfs_file,
-                                 dev.sysfs_value, dev.symlink);
+                                 "sysfs_file[0]='%s', sysfs_value[0]='%s', symlink='%s'",
+                                 dev.name, dev.bus, dev.sysfs_pair[0].file,
+                                 dev.sysfs_pair[0].value, dev.symlink);
                        if ((*dev.name == '\0') ||
                            (*dev.bus == '\0') ||
-                           (*dev.sysfs_file == '\0') ||
-                           (*dev.sysfs_value == '\0'))
+                           (*dev.sysfs_pair[0].file == '\0') ||
+                           (*dev.sysfs_pair[0].value == '\0'))
                                goto error;
                        break;
                case NUMBER: