summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--namedev.c21
-rw-r--r--test/udev-test.pl32
-rw-r--r--udev.8.in3
3 files changed, 55 insertions, 1 deletions
diff --git a/namedev.c b/namedev.c
index 332e2d57d8..90d988311e 100644
--- a/namedev.c
+++ b/namedev.c
@@ -183,6 +183,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize,
int slen;
struct sysfs_attribute *tmpattr;
unsigned int next_free_number;
+ struct sysfs_class_device *class_dev_parent;
pos = string;
while (1) {
@@ -296,6 +297,22 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize,
strfieldcatmax(string, temp2, maxsize);
}
break;
+ case 'P':
+ class_dev_parent = sysfs_get_classdev_parent(class_dev);
+ if (class_dev_parent != NULL) {
+ struct udevice udev_parent;
+
+ dbg("found parent '%s', get the node name", class_dev_parent->path);
+ memset(&udev_parent, 0x00, sizeof(struct udevice));
+ /* lookup the name in the udev_db with the DEVPATH of the parent */
+ strfieldcpy(udev_parent.devpath, &class_dev_parent->path[strlen(sysfs_path)]);
+ if (udev_db_get_device(&udev_parent) == 0) {
+ strfieldcatmax(string, udev_parent.name, maxsize);
+ dbg("substitute parent node name'%s'", udev_parent.name);
+ } else
+ dbg("parent not found in database");
+ }
+ break;
case 'N':
if (udev->tmp_node[0] == '\0') {
dbg("create temporary device node for callout");
@@ -305,6 +322,10 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize,
strfieldcatmax(string, udev->tmp_node, maxsize);
dbg("substitute temporary device node name '%s'", udev->tmp_node);
break;
+ case 'r':
+ strfieldcatmax(string, udev_root, maxsize);
+ dbg("substitute udev_root '%s'", udev_root);
+ break;
default:
dbg("unknown substitution type '%%%c'", c);
break;
diff --git a/test/udev-test.pl b/test/udev-test.pl
index fa1e4affc6..5a519ef13b 100644
--- a/test/udev-test.pl
+++ b/test/udev-test.pl
@@ -968,7 +968,7 @@ KERNEL="sda", NAME="cdrom%e"
EOF
},
{
- desc => "enumeration char test sequence (1/5 keep)",
+ desc => "enumeration char test sequence 1/5 (keep)",
subsys => "block",
devpath => "/block/sda",
exp_name => "cdrom",
@@ -1086,6 +1086,36 @@ EOF
BUS="scsi", KERNEL="sda", PROGRAM="/bin/echo %p", RESULT="/block/sda" NAME="%k"
EOF
},
+ {
+ desc => "parent node name substitution test sequence 1/2 (keep)",
+ subsys => "block",
+ devpath => "/block/sda",
+ exp_name => "main_device",
+ option => "keep",
+ conf => <<EOF
+BUS="scsi", KERNEL="sda", NAME="main_device"
+EOF
+ },
+ {
+ desc => "parent node name substitution test sequence 2/2 (clean)",
+ subsys => "block",
+ devpath => "/block/sda/sda1",
+ exp_name => "main_device-part-1",
+ option => "clean",
+ conf => <<EOF
+BUS="scsi", KERNEL="sda1", NAME="%P-part-1"
+EOF
+ },
+ {
+ desc => "udev_root substitution",
+ subsys => "block",
+ devpath => "/block/sda/sda1",
+ exp_name => "start-udev-root-end",
+ option => "clean",
+ conf => <<EOF
+BUS="scsi", KERNEL="sda1", NAME="start-%r-end"
+EOF
+ },
);
# set env
diff --git a/udev.8.in b/udev.8.in
index 51c55bc5a6..3fb4bdb8da 100644
--- a/udev.8.in
+++ b/udev.8.in
@@ -218,6 +218,9 @@ all remaining parts of the result string are substituted:
The name of a created temporary device node to provide access to the
device from a external program.
.TP
+.B %P
+The node name of the parent device.
+.TP
.BI %s{ filename }
The content of a sysfs attribute.
.TP