{
char sysdev[FILE_NAME_SIZE];
+ if (pp->sysdev && sysfs_device_verify(pp->sysdev))
+ return pp->sysdev;
+
strlcpy(sysdev,"/block/", FILE_NAME_SIZE);
strlcat(sysdev,pp->dev, FILE_NAME_SIZE);
return 1;
}
+ pp->bus = SYSFS_BUS_UNDEF;
if (!strncmp(pp->dev,"cciss",5))
- strcpy(parent->subsystem,"cciss");
-
- condlog(3, "%s: subsystem = %s", pp->dev, parent->subsystem);
-
- if (!strncmp(parent->subsystem, "scsi",4))
- pp->bus = SYSFS_BUS_SCSI;
- if (!strncmp(parent->subsystem, "ccw",3))
- pp->bus = SYSFS_BUS_CCW;
- if (!strncmp(parent->subsystem,"cciss",5))
pp->bus = SYSFS_BUS_CCISS;
+ if (!strncmp(pp->dev,"dasd", 4))
+ pp->bus = SYSFS_BUS_CCW;
+ if (!strncmp(pp->dev,"sd", 2))
+ pp->bus = SYSFS_BUS_SCSI;
if (pp->bus == SYSFS_BUS_UNDEF)
return 0;
}
}
-void sysfs_device_set_values(struct sysfs_device *dev, const char *devpath,
- const char *subsystem, const char *driver)
+void sysfs_device_set_values(struct sysfs_device *dev, const char *devpath)
{
char *pos;
strlcpy(dev->devpath, devpath, sizeof(dev->devpath));
- if (subsystem != NULL)
- strlcpy(dev->subsystem, subsystem, sizeof(dev->subsystem));
- if (driver != NULL)
- strlcpy(dev->driver, driver, sizeof(dev->driver));
/* set kernel name */
pos = strrchr(dev->devpath, '/');
pos[0] = '/';
pos++;
}
-
- /* get kernel number */
- pos = &dev->kernel[strlen(dev->kernel)];
- while (isdigit(pos[-1]))
- pos--;
- strlcpy(dev->kernel_number, pos, sizeof(dev->kernel_number));
- dbg("kernel_number='%s'", dev->kernel_number);
}
int sysfs_resolve_link(char *devpath, size_t size)
return 0;
}
+/*
+ * Caution: this routine is called extremely often.
+ * Should be as efficient as possible.
+ */
struct sysfs_device *sysfs_device_get(const char *devpath)
{
char path[PATH_SIZE];
struct sysfs_device *dev = NULL;
struct sysfs_dev *sysdev_loop, *sysdev;
struct stat statbuf;
- char link_path[PATH_SIZE];
- char link_target[PATH_SIZE];
- int len;
- char *pos;
-
- /* we handle only these devpathes */
- if (devpath != NULL &&
- strncmp(devpath, "/devices/", 9) != 0 &&
- strncmp(devpath, "/subsystem/", 11) != 0 &&
- strncmp(devpath, "/module/", 8) != 0 &&
- strncmp(devpath, "/bus/", 5) != 0 &&
- strncmp(devpath, "/class/", 7) != 0 &&
- strncmp(devpath, "/block/", 7) != 0) {
- dbg("invalid devpath '%s'", devpath);
- return NULL;
- }
dbg("open '%s'", devpath);
strlcpy(devpath_real, devpath, sizeof(devpath_real));
dev = &sysdev->dev;
}
- sysfs_device_set_values(dev, devpath_real, NULL, NULL);
-
- /* get subsystem name */
- strlcpy(link_path, sysfs_path, sizeof(link_path));
- strlcat(link_path, dev->devpath, sizeof(link_path));
- strlcat(link_path, "/subsystem", sizeof(link_path));
- len = readlink(link_path, link_target, sizeof(link_target));
- if (len > 0) {
- /* get subsystem from "subsystem" link */
- link_target[len] = '\0';
- dbg("subsystem link '%s' points to '%s'", link_path, link_target);
- pos = strrchr(link_target, '/');
- if (pos != NULL)
- strlcpy(dev->subsystem, &pos[1], sizeof(dev->subsystem));
- } else if (strstr(dev->devpath, "/drivers/") != NULL) {
- strlcpy(dev->subsystem, "drivers", sizeof(dev->subsystem));
- } else if (strncmp(dev->devpath, "/module/", 8) == 0) {
- strlcpy(dev->subsystem, "module", sizeof(dev->subsystem));
- } else if (strncmp(dev->devpath, "/subsystem/", 11) == 0) {
- pos = strrchr(dev->devpath, '/');
- if (pos == &dev->devpath[10])
- strlcpy(dev->subsystem, "subsystem",
- sizeof(dev->subsystem));
- } else if (strncmp(dev->devpath, "/class/", 7) == 0) {
- pos = strrchr(dev->devpath, '/');
- if (pos == &dev->devpath[6])
- strlcpy(dev->subsystem, "subsystem",
- sizeof(dev->subsystem));
- } else if (strncmp(dev->devpath, "/bus/", 5) == 0) {
- pos = strrchr(dev->devpath, '/');
- if (pos == &dev->devpath[4])
- strlcpy(dev->subsystem, "subsystem",
- sizeof(dev->subsystem));
- }
-
- /* get driver name */
- strlcpy(link_path, sysfs_path, sizeof(link_path));
- strlcat(link_path, dev->devpath, sizeof(link_path));
- strlcat(link_path, "/driver", sizeof(link_path));
- len = readlink(link_path, link_target, sizeof(link_target));
- if (len > 0) {
- link_target[len] = '\0';
- dbg("driver link '%s' points to '%s'", link_path, link_target);
- pos = strrchr(link_target, '/');
- if (pos != NULL)
- strlcpy(dev->driver, &pos[1], sizeof(dev->driver));
- }
+ sysfs_device_set_values(dev, devpath_real);
return dev;
}
return dev->parent;
}
-struct sysfs_device *sysfs_device_get_parent_with_subsystem(struct sysfs_device *dev, const char *subsystem)
+struct sysfs_device *sysfs_device_verify(struct sysfs_device *dev)
{
- struct sysfs_device *dev_parent;
+ char path[PATH_SIZE];
+ struct stat statbuf;
+
+ strlcpy(path, sysfs_path, sizeof(path));
+ strlcat(path, dev->devpath, sizeof(path));
+ if (stat(dev->devpath, &statbuf) == 0 &&
+ S_ISDIR(statbuf.st_mode))
+ return dev;
- dev_parent = sysfs_device_get_parent(dev);
- while (dev_parent != NULL) {
- if (strcmp(dev_parent->subsystem, subsystem) == 0)
- return dev_parent;
- dev_parent = sysfs_device_get_parent(dev_parent);
- }
return NULL;
}
if ((statbuf.st_mode & S_IWUSR) == 0)
goto out;
- /* read attribute value */
+ /* write attribute value */
fd = open(path_full, O_WRONLY);
if (fd < 0) {
dbg("attribute '%s' can not be opened: %s",
path_full, size);
size = -1;
}
- close(fd);
+ close(fd);
out:
+
return size;
}