* directories and then just exit.
*
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
+ * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
#include <sys/stat.h>
#include "logging.h"
+#include "udev_version.h"
#include "libsysfs/sysfs/libsysfs.h"
+#ifndef FILENAME_MAX
+#define FILENAME_MAX 4096
+#endif
+
#ifdef LOG
unsigned char logname[LOGNAME_SIZE];
void log_message(int level, const char *format, ...)
{ .subsystem = "pcmcia_socket", .file = "card_type" },
{ .subsystem = "usb_host", .file = NULL },
{ .subsystem = "bluetooth", .file = "address" },
+ { .subsystem = "firmware", .file = "data" },
{ .subsystem = "i2c-adapter", .file = NULL },
+ { .subsystem = "pci_bus", .file = NULL },
+ { .subsystem = "ieee1394", .file = NULL },
+ { .subsystem = "ieee1394_host", .file = NULL },
+ { .subsystem = "ieee1394_node", .file = NULL },
{ NULL, NULL }
};
struct class_file *classfile;
const char *file = "dev";
+ char filename[FILENAME_MAX];
int loop;
/* look if we want to look for another file instead of "dev" */
break;
}
}
- dbg("looking at class '%s' for specific file '%s'", class_dev->classname, file);
+
+ strcpy(filename, class_dev->path);
+ strcat(filename, "/");
+ strcat(filename, file);
+ dbg("looking at class '%s' for specific file '%s' with full name %s", class_dev->classname, class_dev->path, filename);
loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND;
while (--loop) {
- if (sysfs_get_classdev_attr(class_dev, file) != NULL) {
+ struct stat stats;
+
+ if (stat(class_dev->path, &stats) == -1) {
+ dbg("oops, the directory '%s' just disappeared.", class_dev->path);
+ return -ENODEV;
+ }
+
+ if (stat(filename, &stats) == 0) {
dbg("class '%s' specific file '%s' found", class_dev->classname, file);
return 0;
}
}
dbg("error: getting class '%s' specific file '%s'", class_dev->classname, file);
- return -1;
+ return -ENOENT;
}
-/* skip waiting for physical device */
+/* check if we need to wait for a physical device */
static int class_device_expect_no_device_link(struct sysfs_class_device *class_dev)
{
- /* List of devices without a "device" symlink
- * set .device to NULL to accept all devices in that subsystem */
+ /* list of devices without a "device" symlink to the physical device
+ * if device is set to NULL, no devices in that subsystem has a link */
static struct class_device {
char *subsystem;
char *device;
{ .subsystem = "input", .device = "mice" },
{ .subsystem = "input", .device = "mouse" },
{ .subsystem = "input", .device = "ts" },
- { .subsystem = "vc", .device = "vcs" },
- { .subsystem = "vc", .device = "vcsa" },
+ { .subsystem = "vc", .device = NULL },
{ .subsystem = "tty", .device = NULL },
{ .subsystem = "cpuid", .device = "cpu" },
{ .subsystem = "graphics", .device = "fb" },
{ .subsystem = "misc", .device = NULL },
{ .subsystem = "msr", .device = NULL },
{ .subsystem = "netlink", .device = NULL },
+ { .subsystem = "net", .device = "sit" },
+ { .subsystem = "net", .device = "ppp" },
+ { .subsystem = "net", .device = "lo" },
+ { .subsystem = "net", .device = "tap" },
+ { .subsystem = "net", .device = "ipsec" },
+ { .subsystem = "net", .device = "irda" },
{ .subsystem = "sound", .device = NULL },
- { .subsystem = "snd", .device = NULL },
{ .subsystem = "printer", .device = "lp" },
+ { .subsystem = "nvidia", .device = NULL },
+ { .subsystem = "video4linux", .device = "vbi" },
+ { .subsystem = "lirc", .device = NULL },
+ { .subsystem = "firmware", .device = NULL },
+ { .subsystem = "drm", .device = NULL },
+ { .subsystem = "pci_bus", .device = NULL },
+ { .subsystem = "ieee1394", .device = NULL },
+ { .subsystem = "ieee1394_host", .device = NULL },
+ { .subsystem = "ieee1394_node", .device = NULL },
+ { .subsystem = "raw", .device = NULL },
{ NULL, NULL }
};
struct class_device *classdevice;
int len;
- /* look if we want to look for another file instead of "dev" */
for (classdevice = class_device; classdevice->subsystem != NULL; classdevice++) {
if (strcmp(class_dev->classname, classdevice->subsystem) == 0) {
- /* if device is NULL, all devices in this class are ok */
+ /* see if no device in this class is expected to have a device-link */
if (classdevice->device == NULL)
return 1;
if (strncmp(class_dev->name, classdevice->device, len) != 0)
continue;
- /* exact match */
+ /* exact name match */
if (strlen(class_dev->name) == len)
return 1;
- /* instance numbers are matching too */
+ /* name match with instance number */
if (isdigit(class_dev->name[len]))
return 1;
}
struct sysfs_class_device *class_dev_parent;
struct sysfs_device *device_dev = NULL;
int loop;
+ int retval;
int rc = 0;
init_logging("wait_for_sysfs");
}
dbg("class_device opened '%s'", filename);
- if (wait_for_class_device_attributes(class_dev) != 0) {
+ retval = wait_for_class_device_attributes(class_dev);
+ if (retval == -ENODEV)
+ goto exit_class;
+ if (retval != 0) {
rc = 4;
goto exit_class;
}
if (rc == 0)
dbg("result: waiting for sysfs successful '%s'", devpath);
else
- info("error: wait_for_sysfs needs an update to handle the device '%s' "
- "properly, please report to <linux-hotplug-devel@lists.sourceforge.net>",
- devpath);
+ info("either wait_for_sysfs (udev %s) needs an update to handle the device '%s' "
+ "properly (%d) or the sysfs-support of your device's driver needs to be fixed, "
+ "please report to <linux-hotplug-devel@lists.sourceforge.net>",
+ UDEV_VERSION, devpath, rc);
return rc;
}