From: greg@kroah.com Date: Fri, 23 Jan 2004 08:21:13 +0000 (-0800) Subject: [PATCH] add support for figuring out which device on the sysfs "chain" the rule appli... X-Git-Tag: 015~27 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=724257d97b452dd563ea1a3a5cdc53b18e8dcb34;p=elogind.git [PATCH] add support for figuring out which device on the sysfs "chain" the rule applies to. This should fix one of the more annoying things to me about udev, and gets rid of a TODO item. --- diff --git a/namedev.c b/namedev.c index e0d396e6f..6b1aa297e 100644 --- a/namedev.c +++ b/namedev.c @@ -585,50 +585,19 @@ exit: return sysfs_device; } -int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *udev) +static int match_rule(struct config_device *dev, struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device) { - struct sysfs_device *sysfs_device = NULL; - struct config_device *dev; - struct perm_device *perm; - char *pos; - - udev->mode = 0; - - /* find the sysfs_device associated with this class device */ - sysfs_device = get_sysfs_device(class_dev); - if (sysfs_device) { - dbg("sysfs_device->path='%s'", sysfs_device->path); - dbg("sysfs_device->bus_id='%s'", sysfs_device->bus_id); - dbg("sysfs_device->bus='%s'", sysfs_device->bus); - strfieldcpy(udev->bus_id, sysfs_device->bus_id); - wait_for_device_to_initialize(sysfs_device); - } else { - dbg("class_dev->name = '%s'", class_dev->name); - } - - strfieldcpy(udev->kernel_name, class_dev->name); - - /* get kernel number */ - pos = class_dev->name + strlen(class_dev->name); - while (isdigit(*(pos-1))) - pos--; - strfieldcpy(udev->kernel_number, pos); - dbg("kernel_number='%s'", udev->kernel_number); - - /* look for a matching rule to apply */ - list_for_each_entry(dev, &config_device_list, node) { - dbg("process rule"); - + while (1) { /* check for matching bus value */ if (dev->bus[0] != '\0') { if (sysfs_device == NULL) { dbg("device has no bus"); - continue; + goto no_good; } dbg("check for " FIELD_BUS " dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus); if (strcmp_pattern(dev->bus, sysfs_device->bus) != 0) { dbg(FIELD_BUS " is not matching"); - continue; + goto no_good; } else { dbg(FIELD_BUS " matches"); } @@ -639,7 +608,7 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud dbg("check for " FIELD_KERNEL " dev->kernel='%s' class_dev->name='%s'", dev->kernel, class_dev->name); if (strcmp_pattern(dev->kernel, class_dev->name) != 0) { dbg(FIELD_KERNEL " is not matching"); - continue; + goto no_good; } else { dbg(FIELD_KERNEL " matches"); } @@ -650,7 +619,7 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud dbg("check " FIELD_ID); if (match_id(dev, class_dev, sysfs_device) != 0) { dbg(FIELD_ID " is not matching"); - continue; + goto no_good; } else { dbg(FIELD_ID " matches"); } @@ -661,7 +630,7 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud dbg("check " FIELD_PLACE); if (match_place(dev, class_dev, sysfs_device) != 0) { dbg(FIELD_PLACE " is not matching"); - continue; + goto no_good; } else { dbg(FIELD_PLACE " matches"); } @@ -672,7 +641,7 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud dbg("check " FIELD_SYSFS " pairs"); if (match_sysfs_pairs(dev, class_dev, sysfs_device) != 0) { dbg(FIELD_SYSFS " is not matching"); - continue; + goto no_good; } else { dbg(FIELD_SYSFS " matches"); } @@ -684,7 +653,7 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud apply_format(udev, dev->program); if (execute_program(dev->program, udev->program_result, NAME_SIZE) != 0) { dbg(FIELD_PROGRAM " returned nozero"); - continue; + goto no_good; } else { dbg(FIELD_PROGRAM " returned successful"); } @@ -697,7 +666,7 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud dev->result, udev->program_result); if (strcmp_pattern(dev->result, udev->program_result) != 0) { dbg(FIELD_RESULT " is not matching"); - continue; + goto no_good; } else { dbg(FIELD_RESULT " matches"); } @@ -709,12 +678,62 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud return -1; } - /* Yup, this rule belongs to us! */ - info("configured rule in '%s' at line %i applied, '%s' becomes '%s'", - udev_rules_filename, dev->config_line, udev->kernel_name, dev->name); - strfieldcpy(udev->name, dev->name); - strfieldcpy(udev->symlink, dev->symlink); - goto found; + /* Yeah, we matched! */ + return 0; + +no_good: + sysfs_device = sysfs_get_device_parent(sysfs_device); + if (sysfs_device == NULL) + return -ENODEV; + dbg("sysfs_device->path='%s'", sysfs_device->path); + dbg("sysfs_device->bus_id='%s'", sysfs_device->bus_id); + dbg("sysfs_device->bus='%s'", sysfs_device->bus); + } + +} + +int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *udev) +{ + struct sysfs_device *sysfs_device = NULL; + struct config_device *dev; + struct perm_device *perm; + char *pos; + + udev->mode = 0; + + /* find the sysfs_device associated with this class device */ + sysfs_device = get_sysfs_device(class_dev); + if (sysfs_device) { + dbg("sysfs_device->path='%s'", sysfs_device->path); + dbg("sysfs_device->bus_id='%s'", sysfs_device->bus_id); + dbg("sysfs_device->bus='%s'", sysfs_device->bus); + strfieldcpy(udev->bus_id, sysfs_device->bus_id); + wait_for_device_to_initialize(sysfs_device); + } else { + dbg("class_dev->name = '%s'", class_dev->name); + } + + strfieldcpy(udev->kernel_name, class_dev->name); + + /* get kernel number */ + pos = class_dev->name + strlen(class_dev->name); + while (isdigit(*(pos-1))) + pos--; + strfieldcpy(udev->kernel_number, pos); + dbg("kernel_number='%s'", udev->kernel_number); + + /* look for a matching rule to apply */ + list_for_each_entry(dev, &config_device_list, node) { + dbg("process rule"); + + if (match_rule(dev, class_dev, udev, sysfs_device) == 0) { + /* Yup, this rule belongs to us! */ + info("configured rule in '%s' at line %i applied, '%s' becomes '%s'", + udev_rules_filename, dev->config_line, udev->kernel_name, dev->name); + strfieldcpy(udev->name, dev->name); + strfieldcpy(udev->symlink, dev->symlink); + goto found; + } } /* no rule was found so we use the kernel name */ diff --git a/test/udev-test.pl b/test/udev-test.pl index b7013e4bd..0700e5357 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -317,6 +317,15 @@ EOF expected => "second-0" , conf => < "sysfs parent heirachy", + subsys => "tty", + devpath => "class/tty/ttyUSB0", + expected => "visor" , + conf => <