251 lines
6.2 KiB
Diff
251 lines
6.2 KiB
Diff
--- udev-084/udevstart.c.udevstart2 2006-01-30 08:51:38.000000000 +0100
|
|
+++ udev-084/udevstart.c 2006-02-07 10:11:31.000000000 +0100
|
|
@@ -37,13 +37,13 @@
|
|
#include <sys/wait.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
+#include <fcntl.h>
|
|
+#include <fnmatch.h>
|
|
|
|
#include "udev.h"
|
|
#include "udev_rules.h"
|
|
|
|
-static const char *udev_run_str;
|
|
static const char *udev_log_str;
|
|
-static struct udev_rules rules;
|
|
|
|
#ifdef USE_LOG
|
|
void log_message(int priority, const char *format, ...)
|
|
@@ -101,76 +101,60 @@
|
|
static char *first_list[] = {
|
|
"/class/mem",
|
|
"/class/tty",
|
|
+ "/bus",
|
|
+ NULL,
|
|
+};
|
|
+
|
|
+/* list of devices whose modaliases we should run last */
|
|
+static char *last_modalias_list[] = {
|
|
+ "pci:v*d*sv*sd*bc0Csc03i*", /* USB controller */
|
|
+ "pci:v*d*sv*sd*bc0Csc00i10*", /* Firewire controller */
|
|
NULL,
|
|
};
|
|
|
|
static int add_device(const char *devpath)
|
|
{
|
|
- struct sysfs_device *dev;
|
|
- struct udevice *udev;
|
|
- int retval = 0;
|
|
-
|
|
- /* clear and set environment for next event */
|
|
- clearenv();
|
|
- setenv("ACTION", "add", 1);
|
|
- setenv("UDEV_START", "1", 1);
|
|
- if (udev_log_str)
|
|
- setenv("UDEV_LOG", udev_log_str, 1);
|
|
- if (udev_run_str)
|
|
- setenv("UDEV_RUN", udev_run_str, 1);
|
|
-
|
|
- dev = sysfs_device_get(devpath);
|
|
- if (dev == NULL)
|
|
- return -1;
|
|
-
|
|
- udev = udev_device_init();
|
|
- if (udev == NULL)
|
|
- return -1;
|
|
-
|
|
- /* override built-in sysfs device */
|
|
- udev->dev = dev;
|
|
- strcpy(udev->action, "add");
|
|
- udev->devt = udev_device_get_devt(udev);
|
|
-
|
|
- if (strcmp(udev->dev->subsystem, "net") != 0) {
|
|
- udev->devt = udev_device_get_devt(udev);
|
|
- if (major(udev->devt) == 0)
|
|
- return -1;
|
|
- }
|
|
+ char filename[PATH_SIZE];
|
|
+ int fd;
|
|
+
|
|
+ snprintf(filename, sizeof(filename), "%s/%s/uevent", sysfs_path, devpath);
|
|
+ filename[sizeof(filename)-1] = '\0';
|
|
+
|
|
+ dbg("Trigger %s", filename);
|
|
+ fd = open(filename, O_WRONLY);
|
|
+ if (fd > 0) {
|
|
+ write(fd, "add\n", 4);
|
|
+ close(fd);
|
|
+ }
|
|
+ else return 1;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
|
|
- dbg("add '%s'", udev->dev->devpath);
|
|
- setenv("DEVPATH", udev->dev->devpath, 1);
|
|
- setenv("SUBSYSTEM", udev->dev->subsystem, 1);
|
|
-
|
|
- udev_rules_get_name(&rules, udev);
|
|
- if (udev->ignore_device) {
|
|
- dbg("device event will be ignored");
|
|
- goto exit;
|
|
- }
|
|
- if (udev->name[0] != '\0')
|
|
- retval = udev_add_device(udev);
|
|
- else
|
|
- info("device node creation supressed");
|
|
-
|
|
- if (retval == 0 && udev_run) {
|
|
- struct name_entry *name_loop;
|
|
-
|
|
- dbg("executing run list");
|
|
- list_for_each_entry(name_loop, &udev->run_list, node) {
|
|
- if (strncmp(name_loop->name, "socket:", strlen("socket:")) == 0)
|
|
- pass_env_to_socket(&name_loop->name[strlen("socket:")], udev->dev->devpath, "add");
|
|
- else {
|
|
- char program[PATH_SIZE];
|
|
-
|
|
- strlcpy(program, name_loop->name, sizeof(program));
|
|
- udev_rules_apply_format(udev, program, sizeof(program));
|
|
- run_program(program, udev->dev->subsystem, NULL, 0, NULL, (udev_log_priority >= LOG_INFO));
|
|
- }
|
|
+static int modalias_is_greylisted(struct device *dev)
|
|
+{
|
|
+
|
|
+ char filename[PATH_SIZE];
|
|
+ char alias[PATH_SIZE];
|
|
+ int fd, i;
|
|
+
|
|
+ snprintf(filename,sizeof(filename),"%s/%s/modalias", sysfs_path, dev->path);
|
|
+ filename[sizeof(filename)-1] = '\0';
|
|
+
|
|
+ fd = open(filename, O_RDONLY);
|
|
+ if (fd == -1)
|
|
+ return 0;
|
|
+ read(fd,alias,PATH_SIZE);
|
|
+ alias[sizeof(alias)-1] = '\0';
|
|
+ alias[strlen(alias)-1] = '\0';
|
|
+
|
|
+ for (i = 0; last_modalias_list[i] != NULL; i++)
|
|
+ if (!fnmatch(last_modalias_list[i], alias, 0)) {
|
|
+ close(fd);
|
|
+ return 1;
|
|
}
|
|
- }
|
|
|
|
-exit:
|
|
- udev_device_cleanup(udev);
|
|
+ close(fd);
|
|
return 0;
|
|
}
|
|
|
|
@@ -184,6 +168,8 @@
|
|
list_for_each_entry_safe(loop_device, tmp_device, device_list, node) {
|
|
for (i = 0; first_list[i] != NULL; i++) {
|
|
if (strncmp(loop_device->path, first_list[i], strlen(first_list[i])) == 0) {
|
|
+ if (modalias_is_greylisted(loop_device))
|
|
+ continue;
|
|
add_device(loop_device->path);
|
|
list_del(&loop_device->node);
|
|
free(loop_device);
|
|
@@ -203,6 +189,8 @@
|
|
}
|
|
if (found)
|
|
continue;
|
|
+ if (modalias_is_greylisted(loop_device))
|
|
+ continue;
|
|
|
|
add_device(loop_device->path);
|
|
list_del(&loop_device->node);
|
|
@@ -222,7 +210,7 @@
|
|
char filename[PATH_SIZE];
|
|
struct stat statbuf;
|
|
|
|
- snprintf(filename, sizeof(filename), "%s/dev", path);
|
|
+ snprintf(filename, sizeof(filename), "%s/uevent", path);
|
|
filename[sizeof(filename)-1] = '\0';
|
|
|
|
if (stat(filename, &statbuf) == 0)
|
|
@@ -279,6 +267,50 @@
|
|
}
|
|
}
|
|
|
|
+static void udev_scan_bus(struct list_head *device_list)
|
|
+{
|
|
+ char base[PATH_SIZE];
|
|
+ DIR *dir;
|
|
+ struct dirent *dent;
|
|
+
|
|
+ snprintf(base, sizeof(base), "%s/bus", sysfs_path);
|
|
+ base[sizeof(base)-1] = '\0';
|
|
+
|
|
+ dir = opendir(base);
|
|
+ if (dir != NULL) {
|
|
+ for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
|
|
+ char dirname[PATH_SIZE];
|
|
+ DIR *dir2;
|
|
+ struct dirent *dent2;
|
|
+
|
|
+ if (dent->d_name[0] == '.')
|
|
+ continue;
|
|
+
|
|
+ snprintf(dirname, sizeof(dirname), "%s/%s/devices", base, dent->d_name);
|
|
+ dirname[sizeof(dirname)-1] = '\0';
|
|
+
|
|
+ dir2 = opendir(dirname);
|
|
+ if (dir2 != NULL) {
|
|
+ for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) {
|
|
+ char dirname2[PATH_SIZE];
|
|
+
|
|
+ if (dent2->d_name[0] == '.')
|
|
+ continue;
|
|
+
|
|
+ snprintf(dirname2, sizeof(dirname2), "%s/%s", dirname, dent2->d_name);
|
|
+ dirname2[sizeof(dirname2)-1] = '\0';
|
|
+
|
|
+ if (has_devt(dirname2))
|
|
+ device_list_insert(dirname2, device_list);
|
|
+ }
|
|
+ closedir(dir2);
|
|
+ }
|
|
+ }
|
|
+ closedir(dir);
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
static void udev_scan_class(struct list_head *device_list)
|
|
{
|
|
char base[PATH_SIZE];
|
|
@@ -312,7 +344,7 @@
|
|
snprintf(dirname2, sizeof(dirname2), "%s/%s", dirname, dent2->d_name);
|
|
dirname2[sizeof(dirname2)-1] = '\0';
|
|
|
|
- if (has_devt(dirname2) || strcmp(dent->d_name, "net") == 0)
|
|
+ if (has_devt(dirname2))
|
|
device_list_insert(dirname2, device_list);
|
|
}
|
|
closedir(dir2);
|
|
@@ -342,7 +374,6 @@
|
|
udev_config_init();
|
|
dbg("version %s", UDEV_VERSION);
|
|
|
|
- udev_run_str = getenv("UDEV_RUN");
|
|
udev_log_str = getenv("UDEV_LOG");
|
|
|
|
/* disable all logging if not explicitely requested */
|
|
@@ -362,13 +393,12 @@
|
|
alarm(UDEV_ALARM_TIMEOUT);
|
|
|
|
sysfs_init();
|
|
- udev_rules_init(&rules, 1);
|
|
|
|
+ udev_scan_bus(&device_list);
|
|
udev_scan_class(&device_list);
|
|
udev_scan_block(&device_list);
|
|
exec_list(&device_list);
|
|
|
|
- udev_rules_cleanup(&rules);
|
|
sysfs_cleanup();
|
|
logging_close();
|
|
return 0;
|