summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgreg@kroah.com <greg@kroah.com>2003-12-22 22:31:35 -0800
committerGreg KH <gregkh@suse.de>2005-04-26 21:13:10 -0700
commita8b01705c6204c660062cb6abc8fe7dbb8a42197 (patch)
tree3a99332f45068204e6121bffd70596d1bdf325a6
parentf4f3939a6cfc4fa1fb6a1621fdfb0ef174f11e41 (diff)
[PATCH] add ability to have up to 5 SYSFS_ file/value pairs for the LABEL rule.
-rw-r--r--namedev.c91
-rw-r--r--namedev.h10
-rw-r--r--namedev_parse.c47
3 files changed, 97 insertions, 51 deletions
diff --git a/namedev.c b/namedev.c
index 7c422f7877..d879fd5590 100644
--- 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;
}
diff --git a/namedev.h b/namedev.h
index 69c488936d..1eaf4fee4d 100644
--- 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);
diff --git a/namedev_parse.c b/namedev_parse.c
index 33e0c89e22..266fa35a19 100644
--- a/namedev_parse.c
+++ b/namedev_parse.c
@@ -36,6 +36,19 @@
#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: