diff options
-rw-r--r-- | test/udev-test.pl | 9 | ||||
-rw-r--r-- | udev_rules.c | 14 |
2 files changed, 21 insertions, 2 deletions
diff --git a/test/udev-test.pl b/test/udev-test.pl index 5d7c5e5b81..ed94629dd1 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -1224,6 +1224,15 @@ EOF BUS=="scsi", KERNEL=="sda1", PROGRAM=="/bin/echo -e name; (/sbin/badprogram)", RESULT="name_ _/sbin/badprogram_", NAME="sane" EOF }, + { + desc => "read sysfs value from device down in the chain", + subsys => "block", + devpath => "/class/tty/ttyUSB0", + exp_name => "serial-0000:00:09.0", + rules => <<EOF +KERNEL=="ttyUSB*", NAME="serial-%s{serial}" +EOF + }, ); # set env diff --git a/udev_rules.c b/udev_rules.c index 2fca33d063..00199a062f 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -287,8 +287,18 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, break; } if (find_sysfs_attribute(class_dev, sysfs_device, attr, temp2, sizeof(temp2)) != 0) { - dbg("sysfs attribute '%s' not found", attr); - break; + struct sysfs_device *parent_device; + + dbg("sysfs attribute '%s' not found, walk up the physical devices", attr); + parent_device = sysfs_get_device_parent(sysfs_device); + while (parent_device) { + dbg("looking at '%s'", parent_device->path); + if (find_sysfs_attribute(NULL, parent_device, attr, temp2, sizeof(temp2)) == 0) + break; + parent_device = sysfs_get_device_parent(parent_device); + } + if (!parent_device) + break; } /* strip trailing whitespace of sysfs value */ i = strlen(temp2); |