fix BUS, ID, $id usage

Signed-off-by: Kay Sievers <kay.sievers@suse.de>
This commit is contained in:
Kay Sievers 2006-01-16 06:12:49 +01:00
parent e3440f37f0
commit 03b24b71e0
6 changed files with 163 additions and 158 deletions

6
TODO
View file

@ -4,12 +4,6 @@ These things need to be done, or would be nice to have:
to syslog, so any error logged from the kernel can be associated with
any of the links at that time.
o Fix inconsistency with KERNEL and ID. ID will walk up the device chain
but it matches on "KERNEL names" too. And ID and SYSFS can only match
on the same device in the chain. That's pretty hard to explain and to
understand. Same for SUBSYSTEM and BUS.
These things are deprecated and scheduled for removal in a future
udev version:

View file

@ -148,66 +148,68 @@
<varlistentry>
<term><option>ACTION</option></term>
<listitem>
<para>Match the kernel action name.</para>
<para>Match the name of the event action.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>KERNEL</option></term>
<listitem>
<para>Match the kernel device name</para>
<para>Match the name of the device.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>DEVPATH</option></term>
<listitem>
<para>Match the kernel devpath.</para>
<para>Match the devpath of the device.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>SUBSYSTEM</option></term>
<listitem>
<para>Match the kernel subsystem name</para>
<para>Match the subsystem of the device.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>BUS</option></term>
<listitem>
<para>Match the type of bus the device is connected to.</para>
<para>Search the devpath upwards for a matching device subsystem name.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>DRIVER</option></term>
<listitem>
<para>Match the kernel driver name.</para>
<para>Search the devpath upwards for a matching device driver name.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>ID</option></term>
<listitem>
<para>Match the device number on the bus.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>ENV{<replaceable>key</replaceable>}</option></term>
<listitem>
<para>Match against the value of an environment key. Depending on
the specified operation, this key is also used as an assignment.</para>
<para>Search the devpath upwards for a matching device name.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>SYSFS{<replaceable>filename</replaceable>}</option></term>
<listitem>
<para>Match the sysfs attribute value. Up to five values can be specified.
Trailing whitespace is ignored, if the specified match value does not contain
trailing whitespace itself.</para>
<para>Search the devpath upwards for a device with matching sysfs attribute values.
Up to five <option>SYSFS</option> keys can be specified per rule. All attributes
must match on the same device. Trailing whitespace in the attribute values is ignored,
if the specified match value does not contain trailing whitespace itself.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>ENV{<replaceable>key</replaceable>}</option></term>
<listitem>
<para>Match against the value of an environment variable. Up to five <option>ENV</option>
keys can be specified per rule. This key can also be used to export a variable to
the environment.</para>
</listitem>
</varlistentry>
@ -290,8 +292,8 @@
<varlistentry>
<term><option>ENV{<replaceable>key</replaceable>}</option></term>
<listitem>
<para>Export the key to the environment. Depending on the specified
operation, this key is also used as a match.</para>
<para>Export a variable to the environment. This key can also be used to match
against an environment variable.</para>
</listitem>
</varlistentry>
@ -320,7 +322,7 @@
<varlistentry>
<term><option>IMPORT{<replaceable>type</replaceable>}</option></term>
<listitem>
<para>Import the printed result or the content of a file in environment key
<para>Import the printed result or the value of a file in environment key
format into the event environment. <option>program</option> will execute an
external program and read its output. <option>file</option> will inport a
text file. If no option is given, udev will determine it from the executable
@ -331,8 +333,8 @@
<varlistentry>
<term><option>WAIT_FOR_SYSFS</option></term>
<listitem>
<para>Wait for the specified sysfs file of the device to be created. May be used
to fight agains timing issues wth the kernel.</para>
<para>Wait for the specified sysfs file of the device to be created. Can be used
to fight against kernel sysfs timing issues.</para>
</listitem>
</varlistentry>
@ -355,14 +357,14 @@
printf-like string substitutions:</para>
<variablelist>
<varlistentry>
<term><option>%k</option>, <option>$kernel</option></term>
<term><option>$kernel</option>, <option>%k</option></term>
<listitem>
<para>The kernel name for this device.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>%n</option>, <option>$number</option></term>
<term><option>$number</option>, <option>%n</option></term>
<listitem>
<para>The kernel number for this device. For example, 'sda3' has
kernel number of '3'</para>
@ -370,42 +372,51 @@
</varlistentry>
<varlistentry>
<term><option>%p</option>, <option>$devpath</option></term>
<term><option>$devpath</option>, <option>%p</option></term>
<listitem>
<para>The devpath of the device.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>%s{<replaceable>file</replaceable>}</option>, <option>$sysfs{<replaceable>file</replaceable>}</option></term>
<term><option>$id</option>, <option>%b</option></term>
<listitem>
<para>The content of a sysfs attribute.</para>
<para>The name of the device matched while searching the devpath upwards for
<option>BUS</option>, <option>ID</option> <option>DRIVER</option> and <option>SYSFS</option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>%E{<replaceable>key</replaceable>}</option>, <option>$env{<replaceable>key</replaceable>}</option></term>
<term><option>$sysfs{<replaceable>file</replaceable>}</option>, <option>%s{<replaceable>file</replaceable>}</option></term>
<listitem>
<para>The value of a sysfs attribute found at the current or a parent device.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>$env{<replaceable>key</replaceable>}</option>, <option>%E{<replaceable>key</replaceable>}</option></term>
<listitem>
<para>The value of an environment variable.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>%m</option>, <option>$major</option></term>
<term><option>$major</option>, <option>%M</option></term>
<listitem>
<para>The kernel major number for the device.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>%M</option> <option>$minor</option></term>
<term><option>$minor</option> <option>%m</option></term>
<listitem>
<para>The kernel minor number for the device.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>%c</option>, <option>$result</option></term>
<term><option>$result</option>, <option>%c</option></term>
<listitem>
<para>The string returned by the external program requested with PROGRAM.
A single part of the string, separated by a space character may be selected
@ -416,21 +427,21 @@
</varlistentry>
<varlistentry>
<term><option>%P</option>, <option>$parent</option></term>
<term><option>$parent</option>, <option>%P</option></term>
<listitem>
<para>The node name of the parent device.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>%r</option>, <option>$root</option></term>
<term><option>$root</option>, <option>%r</option></term>
<listitem>
<para>The udev_root value.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>%N</option>, <option>$tempnode</option></term>
<term><option>$tempnode</option>, <option>%N</option></term>
<listitem>
<para>The name of a created temporary device node to provide access to
the device from a external program before the real node is created.</para>

View file

@ -231,7 +231,7 @@ KERNEL=="ttyUSB0", NAME="sub/direct/ory/visor"
EOF
},
{
desc => "place on bus of scsi partition",
desc => "parent device name match of scsi partition",
subsys => "block",
devpath => "/block/sda/sda3",
exp_name => "first_disk3" ,
@ -243,18 +243,18 @@ EOF
desc => "test substitution chars",
subsys => "block",
devpath => "/block/sda/sda3",
exp_name => "Major:8:minor:3:kernelnumber:3" ,
exp_name => "Major:8:minor:3:kernelnumber:3:id:0:0:0:0" ,
rules => <<EOF
BUS=="scsi", ID=="0:0:0:0", NAME="Major:%M:minor:%m:kernelnumber:%n"
BUS=="scsi", ID=="0:0:0:0", NAME="Major:%M:minor:%m:kernelnumber:%n:id:%b"
EOF
},
{
desc => "test substitution chars (with length limit)",
subsys => "block",
devpath => "/block/sda/sda3",
exp_name => "M8-m3-n3-bsd-sIBM" ,
exp_name => "M8-m3-n3-b0:0-sIBM" ,
rules => <<EOF
BUS=="scsi", ID=="0:0:0:0", NAME="M%M-m%m-n%n-b%2k-s%3s{vendor}"
BUS=="scsi", ID=="0:0:0:0", NAME="M%M-m%m-n%n-b%3b-s%3s{vendor}"
EOF
},
{
@ -322,9 +322,9 @@ EOF
desc => "program result substitution",
subsys => "block",
devpath => "/block/sda/sda3",
exp_name => "test-3" ,
exp_name => "test-0:0:0:0" ,
rules => <<EOF
BUS=="scsi", PROGRAM=="/bin/echo -n test-%n", RESULT=="test-3*", NAME="%c"
BUS=="scsi", PROGRAM=="/bin/echo -n test-%b", RESULT=="test-0:0*", NAME="%c"
EOF
},
{
@ -385,27 +385,27 @@ EOF
desc => "test substitution by variable name",
subsys => "block",
devpath => "/block/sda/sda3",
exp_name => "Major:8-minor:3-kernelnumber:3" ,
exp_name => "Major:8-minor:3-kernelnumber:3-id:0:0:0:0",
rules => <<EOF
BUS=="scsi", ID=="0:0:0:0", NAME="Major:\$major-minor:\$minor-kernelnumber:\$number"
BUS=="scsi", ID=="0:0:0:0", NAME="Major:\$major-minor:\$minor-kernelnumber:\$number-id:\$id"
EOF
},
{
desc => "test substitution by variable name 2",
subsys => "block",
devpath => "/block/sda/sda3",
exp_name => "Major:8-minor:3-kernelnumber:3-name:sda3" ,
exp_name => "Major:8-minor:3-kernelnumber:3-id:0:0:0:0",
rules => <<EOF
BUS=="scsi", ID=="0:0:0:0", DEVPATH="*/sda/*", NAME="Major:\$major-minor:%m-kernelnumber:\$number-name:\$kernel"
BUS=="scsi", ID=="0:0:0:0", DEVPATH="*/sda/*", NAME="Major:\$major-minor:%m-kernelnumber:\$number-id:\$id"
EOF
},
{
desc => "test substitution by variable name 3",
subsys => "block",
devpath => "/block/sda/sda3",
exp_name => "83sda33" ,
exp_name => "830:0:0:03" ,
rules => <<EOF
BUS=="scsi", ID=="0:0:0:0", DEVPATH="*/sda/*", NAME="%M%m%k%n"
BUS=="scsi", ID=="0:0:0:0", DEVPATH="*/sda/*", NAME="%M%m%b%n"
EOF
},
{
@ -421,33 +421,23 @@ EOF
desc => "test substitution by variable name 5",
subsys => "block",
devpath => "/block/sda/sda3",
exp_name => "833sda3" ,
exp_name => "8330:0:0:0" ,
rules => <<EOF
BUS=="scsi", ID=="0:0:0:0", DEVPATH="*/sda/*", NAME="\$major%m%n\$kernel"
BUS=="scsi", ID=="0:0:0:0", DEVPATH="*/sda/*", NAME="\$major%m%n\$id"
EOF
},
{
desc => "invalid program for device with no bus",
desc => "non matching BUS for device with no parent",
subsys => "tty",
devpath => "/class/tty/console",
exp_name => "TTY" ,
exp_name => "TTY",
rules => <<EOF
BUS=="scsi", PROGRAM=="/bin/echo -n foo", RESULT=="foo", NAME="foo"
KERNEL=="console", NAME="TTY"
EOF
},
{
desc => "valid program for device with no bus",
subsys => "tty",
devpath => "/class/tty/console",
exp_name => "foo" ,
rules => <<EOF
PROGRAM=="/bin/echo -n foo", RESULT=="foo", NAME="foo"
KERNEL=="console", NAME="TTY"
EOF
},
{
desc => "invalid label for device with no bus",
desc => "non matching BUS",
subsys => "tty",
devpath => "/class/tty/console",
exp_name => "TTY" ,
@ -457,7 +447,7 @@ KERNEL=="console", NAME="TTY"
EOF
},
{
desc => "valid label for device with no bus",
desc => "SYSFS match",
subsys => "tty",
devpath => "/class/tty/console",
exp_name => "foo" ,
@ -470,11 +460,11 @@ EOF
desc => "program and bus type match",
subsys => "block",
devpath => "/block/sda",
exp_name => "scsi-sda" ,
exp_name => "scsi-0:0:0:0" ,
rules => <<EOF
BUS=="usb", PROGRAM=="/bin/echo -n usb-%k", NAME="%c"
BUS=="scsi", PROGRAM=="/bin/echo -n scsi-%k", NAME="%c"
BUS=="foo", PROGRAM=="/bin/echo -n foo-%k", NAME="%c"
BUS=="usb", PROGRAM=="/bin/echo -n usb-%b", NAME="%c"
BUS=="scsi", PROGRAM=="/bin/echo -n scsi-%b", NAME="%c"
BUS=="foo", PROGRAM=="/bin/echo -n foo-%b", NAME="%c"
EOF
},
{
@ -797,7 +787,7 @@ EOF
exp_name => "symlink2-ttyUSB0",
exp_target => "ttyUSB0",
rules => <<EOF
KERNEL=="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="symlink1-%n symlink2-%k"
KERNEL=="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="symlink1-%n symlink2-%k symlink3-%b"
EOF
},
{
@ -918,13 +908,13 @@ KERNEL=="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK+="major-%M:%m"
EOF
},
{
desc => "symlink %k substitution",
desc => "symlink %b substitution",
subsys => "block",
devpath => "/block/sda",
exp_name => "symlink-sda",
exp_name => "symlink-0:0:0:0",
exp_target => "node",
rules => <<EOF
BUS=="scsi", KERNEL=="sda", NAME="node", SYMLINK+="symlink-%k"
BUS=="scsi", KERNEL=="sda", NAME="node", SYMLINK+="symlink-%b"
EOF
},
{
@ -1564,13 +1554,6 @@ sub udev {
$ENV{DEVPATH} = $devpath;
open my $fd, "$sysfs$devpath/dev";
my $dev = <$fd>;
close $fd;
$dev =~ m/^(.+):(.+)$/;
$ENV{MAJOR} = $1;
$ENV{MINOR} = $2;
# create temporary rules
open CONF, ">$udev_rules" || die "unable to create rules file: $udev_rules";
print CONF $$rules;

66
udev.8
View file

@ -70,31 +70,35 @@ Assign a value to a key finally; disallow any later changes, which may be used t
The following key names can be used to match against device properties:
.TP
\fBACTION\fR
Match the kernel action name.
Match the name of the event action.
.TP
\fBKERNEL\fR
Match the kernel device name
Match the name of the device.
.TP
\fBDEVPATH\fR
Match the kernel devpath.
Match the devpath of the device.
.TP
\fBSUBSYSTEM\fR
Match the kernel subsystem name
Match the subsystem of the device.
.TP
\fBBUS\fR
Match the type of bus the device is connected to.
Search the devpath upwards for a matching device subsystem name.
.TP
\fBDRIVER\fR
Match the kernel driver name.
Search the devpath upwards for a matching device driver name.
.TP
\fBID\fR
Match the device number on the bus.
.TP
\fBENV{\fR\fB\fIkey\fR\fR\fB}\fR
Match against the value of an environment key. Depending on the specified operation, this key is also used as an assignment.
Search the devpath upwards for a matching device name.
.TP
\fBSYSFS{\fR\fB\fIfilename\fR\fR\fB}\fR
Match the sysfs attribute value. Up to five values can be specified. Trailing whitespace is ignored, if the specified match value does not contain trailing whitespace itself.
Search the devpath upwards for a device with matching sysfs attribute values. Up to five
\fBSYSFS\fR
keys can be specified per rule. All attributes must match on the same device. Trailing whitespace in the attribute values is ignored, if the specified match value does not contain trailing whitespace itself.
.TP
\fBENV{\fR\fB\fIkey\fR\fR\fB}\fR
Match against the value of an environment variable. Up to five
\fBENV\fR
keys can be specified per rule. This key can also be used to export a variable to the environment.
.TP
\fBPROGRAM\fR
Execute external program. The key is true, if the program returns without exit code zero. The whole event environment is available to the executed program. The program's output printed to stdout is available for the RESULT key.
@ -125,7 +129,7 @@ The name of a symlink targeting the node. Every matching rule can add this value
The permissions for the device node. Every specified value overwrites the compiled\-in default value.
.TP
\fBENV{\fR\fB\fIkey\fR\fR\fB}\fR
Export the key to the environment. Depending on the specified operation, this key is also used as a match.
Export a variable to the environment. This key can also be used to match against an environment variable.
.TP
\fBRUN\fR
Add a program to the list of programs to be executed for a specific device.
@ -137,14 +141,14 @@ Named label where a GOTO can jump to.
Jumps to the next LABEL with a matching gname
.TP
\fBIMPORT{\fR\fB\fItype\fR\fR\fB}\fR
Import the printed result or the content of a file in environment key format into the event environment.
Import the printed result or the value of a file in environment key format into the event environment.
\fBprogram\fR
will execute an external program and read its output.
\fBfile\fR
will inport a text file. If no option is given, udev will determine it from the executable bit of of the file permissions.
.TP
\fBWAIT_FOR_SYSFS\fR
Wait for the specified sysfs file of the device to be created. May be used to fight agains timing issues wth the kernel.
Wait for the specified sysfs file of the device to be created. Can be used to fight against kernel sysfs timing issues.
.TP
\fBOPTIONS\fR
\fBlast_rule\fR
@ -165,42 +169,46 @@ and
\fBGROUP\fR
fields support simple printf\-like string substitutions:
.TP
\fB%k\fR, \fB$kernel\fR
\fB$kernel\fR, \fB%k\fR
The kernel name for this device.
.TP
\fB%b\fR, \fB$id\fR
The kernel bus id for this device.
.TP
\fB%n\fR, \fB$number\fR
\fB$number\fR, \fB%n\fR
The kernel number for this device. For example, 'sda3' has kernel number of '3'
.TP
\fB%p\fR, \fB$devpath\fR
\fB$devpath\fR, \fB%p\fR
The devpath of the device.
.TP
\fB%s{\fR\fB\fIfile\fR\fR\fB}\fR, \fB$sysfs{\fR\fB\fIfile\fR\fR\fB}\fR
The content of a sysfs attribute.
\fB$id\fR, \fB%b\fR
The name of the device matched while searching the devpath upwards for
\fBBUS\fR,
\fBID\fR \fBDRIVER\fR
and
\fBSYSFS\fR.
.TP
\fB%E{\fR\fB\fIkey\fR\fR\fB}\fR, \fB$env{\fR\fB\fIkey\fR\fR\fB}\fR
\fB$sysfs{\fR\fB\fIfile\fR\fR\fB}\fR, \fB%s{\fR\fB\fIfile\fR\fR\fB}\fR
The value of a sysfs attribute found at the current or a parent device.
.TP
\fB$env{\fR\fB\fIkey\fR\fR\fB}\fR, \fB%E{\fR\fB\fIkey\fR\fR\fB}\fR
The value of an environment variable.
.TP
\fB%m\fR, \fB$major\fR
\fB$major\fR, \fB%M\fR
The kernel major number for the device.
.TP
\fB%M\fR \fB$minor\fR
\fB$minor\fR \fB%m\fR
The kernel minor number for the device.
.TP
\fB%c\fR, \fB$result\fR
\fB$result\fR, \fB%c\fR
The string returned by the external program requested with PROGRAM. A single part of the string, separated by a space character may be selected by specifying the part number as an attribute:
\fB%c{N}\fR. If the number is followed by the '+' char this part plus all remaining parts of the result string are substituted:
\fB%c{N+}\fR
.TP
\fB%P\fR, \fB$parent\fR
\fB$parent\fR, \fB%P\fR
The node name of the parent device.
.TP
\fB%r\fR, \fB$root\fR
\fB$root\fR, \fB%r\fR
The udev_root value.
.TP
\fB%N\fR, \fB$tempnode\fR
\fB$tempnode\fR, \fB%N\fR
The name of a created temporary device node to provide access to the device from a external program before the real node is created.
.TP
\fB%%\fR

37
udev.h
View file

@ -30,41 +30,42 @@
#include "udev_libc_wrapper.h"
#include "udev_version.h"
#define COMMENT_CHARACTER '#'
#define PATH_TO_NAME_CHAR '@'
#define LINE_SIZE 512
#define NAME_SIZE 128
#define PATH_SIZE 256
#define USER_SIZE 32
#define SEQNUM_SIZE 32
#define VALUE_SIZE 128
#define COMMENT_CHARACTER '#'
#define PATH_TO_NAME_CHAR '@'
#define LINE_SIZE 512
#define NAME_SIZE 128
#define PATH_SIZE 256
#define USER_SIZE 32
#define SEQNUM_SIZE 32
#define VALUE_SIZE 128
#define DEFAULT_PARTITIONS_COUNT 15
#define UDEV_ALARM_TIMEOUT 180
#define DEFAULT_PARTITIONS_COUNT 15
#define UDEV_ALARM_TIMEOUT 180
#define UDEV_MAX(a,b) ((a) > (b) ? (a) : (b))
/* pipes */
#define READ_END 0
#define WRITE_END 1
#define READ_END 0
#define WRITE_END 1
#define DB_DIR ".udev/db"
#define DB_DIR ".udev/db"
struct udev_rules;
struct sysfs_device {
struct list_head node; /* for device cache */
struct list_head node; /* for device cache */
char devpath[PATH_SIZE];
char subsystem[NAME_SIZE]; /* $class/$bus/"drivers" */
char kernel_name[NAME_SIZE]; /* device instance name */
char subsystem[NAME_SIZE]; /* $class/$bus/"drivers" */
char kernel_name[NAME_SIZE]; /* device instance name */
char kernel_number[NAME_SIZE];
char driver[NAME_SIZE]; /* device driver name */
char driver[NAME_SIZE]; /* device driver name */
};
struct udevice {
/* device event */
struct sysfs_device *dev; /* points to dev_local by default */
struct sysfs_device *dev; /* points to dev_local by default */
struct sysfs_device dev_local;
struct sysfs_device *dev_parent; /* current parent device used for matching */
char action[NAME_SIZE];
/* node */

View file

@ -376,6 +376,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize)
SUBST_DEVPATH,
SUBST_KERNEL_NUMBER,
SUBST_KERNEL_NAME,
SUBST_ID,
SUBST_MAJOR,
SUBST_MINOR,
SUBST_RESULT,
@ -395,6 +396,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize)
{ .name = "devpath", .fmt = 'p', .type = SUBST_DEVPATH },
{ .name = "number", .fmt = 'n', .type = SUBST_KERNEL_NUMBER },
{ .name = "kernel", .fmt = 'k', .type = SUBST_KERNEL_NAME },
{ .name = "id", .fmt = 'b', .type = SUBST_ID },
{ .name = "major", .fmt = 'M', .type = SUBST_MAJOR },
{ .name = "minor", .fmt = 'm', .type = SUBST_MINOR },
{ .name = "result", .fmt = 'c', .type = SUBST_RESULT },
@ -477,6 +479,12 @@ found:
strlcat(string, udev->dev->kernel_number, maxsize);
dbg("substitute kernel number '%s'", udev->dev->kernel_number);
break;
case SUBST_ID:
if (udev->dev_parent != NULL) {
strlcat(string, udev->dev_parent->kernel_name, maxsize);
dbg("substitute id '%s'", udev->dev_parent->kernel_name);
}
break;
case SUBST_MAJOR:
sprintf(temp2, "%d", major(udev->devt));
strlcat(string, temp2, maxsize);
@ -681,20 +689,19 @@ static int match_key(const char *key_name, struct udev_rule *rule, struct key *k
/* match a single rule against a given device and possibly its parent devices */
static int match_rule(struct udevice *udev, struct udev_rule *rule)
{
struct sysfs_device *dev_parent;
int i;
if (match_key("ACTION", rule, &rule->action, udev->action))
goto exit;
goto nomatch;
if (match_key("KERNEL", rule, &rule->kernel_name, udev->dev->kernel_name))
goto exit;
goto nomatch;
if (match_key("SUBSYSTEM", rule, &rule->subsystem, udev->dev->subsystem))
goto exit;
goto nomatch;
if (match_key("DEVPATH", rule, &rule->devpath, udev->dev->devpath))
goto exit;
goto nomatch;
if (rule->modalias.operation != KEY_OP_UNSET) {
const char *value;
@ -702,10 +709,10 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule)
value = sysfs_attr_get_value(udev->dev->devpath, "modalias");
if (value == NULL) {
dbg("MODALIAS value not found");
goto exit;
goto nomatch;
}
if (match_key("MODALIAS", rule, &rule->modalias, value))
goto exit;
goto nomatch;
}
for (i = 0; i < rule->env.count; i++) {
@ -721,7 +728,7 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule)
value = "";
}
if (match_key("ENV", rule, &pair->key, value))
goto exit;
goto nomatch;
}
}
@ -741,24 +748,24 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule)
return -1;
}
/* walk up the chain of physical devices and find a match */
dev_parent = udev->dev;
/* walk up the chain of parent devices and find a match */
udev->dev_parent = udev->dev;
while (1) {
/* check for matching driver */
if (rule->driver.operation != KEY_OP_UNSET) {
if (match_key("DRIVER", rule, &rule->driver, dev_parent->driver))
if (match_key("DRIVER", rule, &rule->driver, udev->dev_parent->driver))
goto try_parent;
}
/* check for matching bus value */
/* check for matching subsystem/bus value */
if (rule->bus.operation != KEY_OP_UNSET) {
if (match_key("BUS", rule, &rule->bus, dev_parent->subsystem))
if (match_key("BUS", rule, &rule->bus, udev->dev_parent->subsystem))
goto try_parent;
}
/* check for matching bus id */
/* check for matching bus id (device name) */
if (rule->id.operation != KEY_OP_UNSET) {
if (match_key("ID", rule, &rule->id, dev_parent->kernel_name))
if (match_key("ID", rule, &rule->id, udev->dev_parent->kernel_name))
goto try_parent;
}
@ -773,7 +780,7 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule)
char val[VALUE_SIZE];
size_t len;
value = sysfs_attr_get_value(dev_parent->devpath, key_name);
value = sysfs_attr_get_value(udev->dev_parent->devpath, key_name);
if (value == NULL)
goto try_parent;
strlcpy(val, value, sizeof(val));
@ -796,12 +803,13 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule)
/* found matching device */
break;
try_parent:
/* move to parent device */
dbg("try parent sysfs device");
dev_parent = sysfs_device_get_parent(dev_parent);
if (dev_parent == NULL)
goto exit;
dbg("looking at dev_parent->devpath='%s'", dev_parent->devpath);
dbg("looking at dev_parent->bus_kernel_name='%s'", dev_parent->kernel_name);
udev->dev_parent = sysfs_device_get_parent(udev->dev_parent);
if (udev->dev_parent == NULL)
goto nomatch;
dbg("looking at dev_parent->devpath='%s'", udev->dev_parent->devpath);
dbg("looking at dev_parent->bus_kernel_name='%s'", udev->dev_parent->kernel_name);
}
/* execute external program */
@ -815,7 +823,7 @@ try_parent:
dbg("PROGRAM is false");
udev->program_result[0] = '\0';
if (rule->program.operation != KEY_OP_NOMATCH)
goto exit;
goto nomatch;
} else {
int count;
@ -828,14 +836,14 @@ try_parent:
strlcpy(udev->program_result, result, sizeof(udev->program_result));
dbg("PROGRAM returned successful");
if (rule->program.operation == KEY_OP_NOMATCH)
goto exit;
goto nomatch;
}
dbg("PROGRAM key is true");
}
/* check for matching result of external program */
if (match_key("RESULT", rule, &rule->result, udev->program_result))
goto exit;
goto nomatch;
/* import variables returned from program or or file into environment */
if (rule->import.operation != KEY_OP_UNSET) {
@ -857,7 +865,7 @@ try_parent:
if (rc != 0) {
dbg("IMPORT failed");
if (rule->import.operation != KEY_OP_NOMATCH)
goto exit;
goto nomatch;
} else
dbg("IMPORT '%s' imported", key_val(rule, &rule->import));
dbg("IMPORT key is true");
@ -879,7 +887,7 @@ try_parent:
return 0;
exit:
nomatch:
return -1;
}