chiark / gitweb /
[PATCH] don't wait for sysfs if the kernel(2.6.10-rc2) tells us what not to expect
authorkay.sievers@vrfy.org <kay.sievers@vrfy.org>
Sat, 13 Nov 2004 11:36:47 +0000 (12:36 +0100)
committerGreg KH <gregkh@suse.de>
Wed, 27 Apr 2005 05:27:34 +0000 (22:27 -0700)
Newer kernels will tell us if we should wait for the "device" or
the "bus" link. So don't waste the time with our lists or wait
for the timeout.

udev_lib.c
udev_lib.h
udev_sysfs.c
udev_sysfs.h
wait_for_sysfs.c

index 6807f817a1e7b119e6ea8ca64dc2d1d628192c95..a3fab9632d28a273079b46115f2361a63edb1168 100644 (file)
@@ -28,6 +28,7 @@
 #include <dirent.h>
 #include <sys/stat.h>
 #include <sys/mman.h>
+#include <sys/utsname.h>
 
 #include "udev.h"
 #include "logging.h"
@@ -72,6 +73,29 @@ void udev_set_values(struct udevice *udev, const char* devpath,
        udev->type = get_device_type(devpath, subsystem);
 }
 
+int kernel_release_satisfactory(int version, int patchlevel, int sublevel)
+{
+       static struct utsname uts;
+       static int kversion = 0;
+       static int kpatchlevel;
+       static int ksublevel;
+
+       if (kversion == 0) {
+               if (uname(&uts) != 0)
+                       return -1;
+
+               if (sscanf (uts.release, "%u.%u.%u", &kversion, &kpatchlevel, &ksublevel) != 3) {
+                       kversion = 0;
+                       return -1;
+               }
+       }
+
+       if (kversion >= version && kpatchlevel >= patchlevel && ksublevel >= sublevel)
+               return 1;
+       else
+               return 0;
+}
+
 int create_path(const char *path)
 {
        char p[NAME_SIZE];
index 2bc9ba82ab74e2d534e0d5981fadf1df8bf32c2d..80dc49cd541085110778ecf7ad36089c0e4e2115 100644 (file)
@@ -79,12 +79,12 @@ do { \
 extern char get_device_type(const char *path, const char *subsystem);
 extern void udev_set_values(struct udevice *udev, const char* devpath,
                            const char *subsystem, const char* action);
+extern int kernel_release_satisfactory(int version, int patchlevel, int sublevel);
 extern int create_path(const char *path);
 extern int file_map(const char *filename, char **buf, size_t *bufsize);
 extern void file_unmap(char *buf, size_t bufsize);
 extern size_t buf_get_line(char *buf, size_t buflen, size_t cur);
 extern void no_trailing_slash(char *path);
-
 typedef int (*file_fnct_t)(const char *filename, void *data);
 extern int  call_foreach_file(file_fnct_t fnct, const char *dirname,
                              const char *suffix, void *data);
index a11c430df0abe10559b364eba4f787a1fda82d83..1953dd777542c0cbb83db8fa8e56603b447503f9 100644 (file)
 #include <errno.h>
 #include <sys/stat.h>
 
-#include "logging.h"
+#include "libsysfs/sysfs/libsysfs.h"
 #include "udev_version.h"
 #include "udev_sysfs.h"
-#include "libsysfs/sysfs/libsysfs.h"
+#include "udev_lib.h"
+#include "logging.h"
 
-/* list of subsystem specific files
- * NULL if there is no file to wait for
- */
+/* list of subsystem specific files, NULL if there is no file to wait for */
 static struct subsystem_file {
        char *subsystem;
        char *file;
@@ -204,6 +203,13 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d
        struct class_device *classdevice;
        int len;
 
+       /* the kernel may tell us what to wait for */
+       if (kernel_release_satisfactory(2,6,10) > 0)
+               if (getenv("PHYSDEVPATH") == NULL) {
+                       dbg("the kernel says, that there is no physical device for '%s'", class_dev->path);
+                       return 1;
+               }
+
        for (classdevice = class_device; classdevice->subsystem != NULL; classdevice++) {
                if (strcmp(class_dev->classname, classdevice->subsystem) == 0) {
                        /* see if no device in this class is expected to have a device-link */
@@ -229,7 +235,7 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d
        return 0;
 }
 
-/* skip waiting for the bus */
+/* skip waiting for the bus of the devices device */
 static int class_device_expect_no_bus(struct sysfs_class_device *class_dev)
 {
        static char *devices_without_bus[] = {
@@ -250,14 +256,14 @@ static int class_device_expect_no_bus(struct sysfs_class_device *class_dev)
        return 0;
 }
 
-/* wait for the bus and for a bus specific file to show up */
-int wait_for_bus_device(struct sysfs_device *devices_dev,
+/* wait for a devices device specific file to show up */
+int wait_for_devices_device(struct sysfs_device *devices_dev,
                        const char **error)
 {
-       static struct bus_file {
+       static struct device_file {
                char *bus;
                char *file;
-       } bus_files[] = {
+       } device_files[] = {
                { .bus = "scsi",        .file = "vendor" },
                { .bus = "usb",         .file = "idVendor" },
                { .bus = "usb",         .file = "iInterface" },
@@ -272,9 +278,16 @@ int wait_for_bus_device(struct sysfs_device *devices_dev,
                { .bus = "ieee1394",    .file = "address" },
                { NULL, NULL }
        };
-       struct bus_file *busfile;
+       struct device_file *devicefile;
        int loop;
 
+       /* the kernel may tell us what to wait for */
+       if (kernel_release_satisfactory(2,6,10) > 0)
+               if (getenv("PHYSDEVBUS") == NULL) {
+                       dbg("the kernel says, that there is no bus for '%s'", devices_dev->path);
+                       return 0;
+               }
+
        /* wait for the bus device link to the devices device */
        loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND;
        while (--loop) {
@@ -291,22 +304,22 @@ int wait_for_bus_device(struct sysfs_device *devices_dev,
        }
        dbg("bus device link found for bus '%s'", devices_dev->bus);
 
-       /* wait for a bus specific file to show up */
+       /* wait for a bus device specific file to show up */
        loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND;
        while (--loop) {
                int found_bus_type = 0;
 
-               for (busfile = bus_files; busfile->bus != NULL; busfile++) {
-                       if (strcmp(devices_dev->bus, busfile->bus) == 0) {
+               for (devicefile = device_files; devicefile->bus != NULL; devicefile++) {
+                       if (strcmp(devices_dev->bus, devicefile->bus) == 0) {
                                char filename[SYSFS_PATH_MAX];
                                struct stat stats;
 
                                found_bus_type = 1;
-                               snprintf(filename, SYSFS_PATH_MAX-1, "%s/%s", devices_dev->path, busfile->file);
-                               dbg("looking at bus '%s' for specific file '%s'", devices_dev->bus, filename);
+                               snprintf(filename, SYSFS_PATH_MAX-1, "%s/%s", devices_dev->path, devicefile->file);
+                               dbg("looking at bus '%s' device for specific file '%s'", devices_dev->bus, filename);
 
                                if (stat(filename, &stats) == 0) {
-                                       dbg("bus '%s' specific file '%s' found", devices_dev->bus, busfile->file);
+                                       dbg("bus '%s' device specific file '%s' found", devices_dev->bus, devicefile->file);
                                        return 0;
                                }
                        }
@@ -321,14 +334,14 @@ int wait_for_bus_device(struct sysfs_device *devices_dev,
                usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND);
        }
 
-       dbg("error: getting bus '%s' specific file '%s'", devices_dev->bus, busfile->file);
+       dbg("error: getting '%s' device specific file '%s'", devices_dev->bus, devicefile->file);
        if (error)
-               *error = "bus specific file unavailable";
+               *error = "bus device specific file unavailable";
        return -1;
 }
 
 
-struct sysfs_class_device *open_class_device_wait(const char *path)
+struct sysfs_class_device *wait_class_device_open(const char *path)
 {
        struct sysfs_class_device *class_dev;
        int loop;
@@ -358,7 +371,7 @@ int wait_for_class_device(struct sysfs_class_device *class_dev,
        /* skip devices without devices-link */
        if (class_device_expect_no_device_link(class_dev)) {
                dbg("no device symlink expected for '%s', ", class_dev->name);
-               return -ENODEV;
+               return 0;
        }
 
        /* the symlink may be on the parent device */
@@ -388,16 +401,16 @@ int wait_for_class_device(struct sysfs_class_device *class_dev,
        }
        dbg("device symlink found pointing to '%s'", devices_dev->path);
 
-       /* wait for the bus value */
+       /* wait for the devices device */
        if (class_device_expect_no_bus(class_dev)) {
                dbg("no bus device expected for '%s', ", class_dev->classname);
                return 0;
-       } else {
-               return wait_for_bus_device(devices_dev, error);
        }
+
+       return wait_for_devices_device(devices_dev, error);
 }
 
-struct sysfs_device *open_devices_device_wait(const char *path)
+struct sysfs_device *wait_devices_device_open(const char *path)
 {
        struct sysfs_device *devices_dev;
        int loop;
index 922db1be791d2b6ba720bd4a76ebe057d9ecba1a..98ff53e11a57893b0618496d5c4e532eec48c5d5 100644 (file)
 #define WAIT_LOOP_PER_SECOND           20
 
 extern int subsystem_expect_no_dev(const char *subsystem);
-extern int wait_for_bus_device(struct sysfs_device *devices_dev, const char **error);
+
+/* /sys/class /sys/block devices */
+extern struct sysfs_class_device *wait_class_device_open(const char *path);
 extern int wait_for_class_device(struct sysfs_class_device *class_dev, const char **error);
-extern struct sysfs_class_device *open_class_device_wait(const char *path);
-extern struct sysfs_device *open_devices_device_wait(const char *path);
+
+/* /sys/devices devices */
+extern struct sysfs_device *wait_devices_device_open(const char *path);
+extern int wait_for_devices_device(struct sysfs_device *devices_dev, const char **error);
 
 #endif /* _UDEV_SYSFS_H_ */
index 42b9d383dc9cc51467954964dc2028f35ea78c11..84a25adb976b10a82146513aa10734f85463bafb 100644 (file)
 #include <errno.h>
 #include <sys/stat.h>
 
-#include "logging.h"
+#include "libsysfs/sysfs/libsysfs.h"
+#include "udev_lib.h"
 #include "udev_version.h"
 #include "udev_sysfs.h"
-#include "libsysfs/sysfs/libsysfs.h"
+#include "logging.h"
 
 #ifdef LOG
 unsigned char logname[LOGNAME_SIZE];
@@ -106,7 +107,7 @@ int main(int argc, char *argv[], char *envp[])
                }
 
                /* open the class device we are called for */
-               class_dev = open_class_device_wait(filename);
+               class_dev = wait_class_device_open(filename);
                if (!class_dev) {
                        dbg("error: class device unavailable (probably remove has beaten us)");
                        goto exit;
@@ -132,15 +133,15 @@ int main(int argc, char *argv[], char *envp[])
                filename[SYSFS_PATH_MAX-1] = '\0';
 
                /* open the path we are called for */
-               devices_dev = open_devices_device_wait(filename);
+               devices_dev = wait_devices_device_open(filename);
                if (!devices_dev) {
                        dbg("error: devices device unavailable (probably remove has beaten us)");
                        goto exit;
                }
                dbg("devices device opened '%s'", filename);
 
-               /* wait for the bus value */
-               wait_for_bus_device(devices_dev, &error);
+               /* wait for the devices device */
+               wait_for_devices_device(devices_dev, &error);
 
                sysfs_close_device(devices_dev);