summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--test/udev-test.pl9
-rw-r--r--udev_rules.c14
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);