summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormananth <mananth>2003-11-24 05:36:01 +0000
committermananth <mananth>2003-11-24 05:36:01 +0000
commitb50c94cbad719632bea966b68c566621413019b3 (patch)
treedf241058560487c9eb179bccab5c7926143b32d3
parent2412af53b271f998713307aea1e76d744fff733d (diff)
downloadsysfsutils-b50c94cbad719632bea966b68c566621413019b3.tar.gz
Postpone attr reads, remove getpagesize() usage, sysfs_driver.c cleanup
remove sysutils references
-rw-r--r--COPYING4
-rw-r--r--ChangeLog7
-rw-r--r--README4
-rw-r--r--cmd/lsbus.c48
-rw-r--r--cmd/systool.c51
-rw-r--r--include/libsysfs.h8
-rw-r--r--lib/sysfs.h1
-rw-r--r--lib/sysfs_bus.c12
-rw-r--r--lib/sysfs_class.c14
-rw-r--r--lib/sysfs_device.c14
-rw-r--r--lib/sysfs_dir.c75
-rw-r--r--lib/sysfs_driver.c181
-rw-r--r--lib/sysfs_utils.c4
-rw-r--r--test/get_driver.c18
14 files changed, 291 insertions, 150 deletions
diff --git a/COPYING b/COPYING
index a8ad126..355916d 100644
--- a/COPYING
+++ b/COPYING
@@ -2,9 +2,9 @@
The commands are licensed under the GNU General Public License (GPL)
Version 2, June 1991. The full text of the GPL is located at:
-sysutils/cmd/GPL
+sysfsutils/cmd/GPL
The sysfs library is licensed under the GNU Lesser Public License (LGPL)
Version 2.1, February 1999. The full text of the LGPL is located at:
-sysutils/lib/LGPL
+sysfsutils/lib/LGPL
diff --git a/ChangeLog b/ChangeLog
index 3dedc31..47c35c1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,11 @@
+11/24/2003 - Ananth Mavinakayanahalli <ananth@in.ibm.com>
+ * Removed getpagesize() usage (Dan)
+ * Added patch to postpone reading of attributes until
+ absolutely necessary
+ * Cleaned up sysfs_driver.c
+ * Changed stale sysutils references to sysfsutils
+
11/04/2003 - Ananth Mavinakayanahalli <ananth@in.ibm.com>
* Added code to consider "block" part of "class"
* Fixed systool to show driver details (if available)
diff --git a/README b/README
index a678a4e..6a33772 100644
--- a/README
+++ b/README
@@ -49,13 +49,13 @@ The commands are licensed under the GNU Public License (GPL) Version2,
June 1991. The full text of the GPL is located in this package's "cmd"
directory:
-sysutils/cmd/GPL
+sysfsutils/cmd/GPL
The library is licensed under the GNU Lesser Public License (LGPL)
Version 2.1, February 1999. The full text of the LGPL is located in
this package's "lib" directory:
-sysutils/lib/LGPL
+sysfsutils/lib/LGPL
4. Reporting Bugs
diff --git a/cmd/lsbus.c b/cmd/lsbus.c
index 0c2e5ce..7082874 100644
--- a/cmd/lsbus.c
+++ b/cmd/lsbus.c
@@ -200,33 +200,35 @@ void print_device(struct sysfs_device *device)
{
struct dlist *attributes = NULL;
unsigned int vendor_id, device_id;
- unsigned char buf[128], *value = NULL;
+ unsigned char buf[128], path[SYSFS_PATH_MAX], value[256];
if (device != NULL) {
- if (!(strcmp(bus_to_print, "pci")))
+ if (!(strcmp(bus_to_print, "pci"))) {
fprintf(stdout, " %s: ", device->bus_id);
- else
+ memset(path, 0, SYSFS_PATH_MAX);
+ memset(value, 0, SYSFS_PATH_MAX);
+ strcpy(path, device->path);
+ strcat(path, "/config");
+ if ((sysfs_read_attribute_value(path,
+ value, 256)) == 0) {
+ vendor_id = get_pciconfig_word
+ (PCI_VENDOR_ID, value);
+ device_id = get_pciconfig_word
+ (PCI_DEVICE_ID, value);
+ fprintf(stdout, "%s\n",
+ pci_lookup_name(pacc, buf, 128,
+ PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE,
+ vendor_id, device_id, 0, 0));
+ } else
+ fprintf(stdout, "\n");
+ } else
fprintf(stdout, " %s:\n", device->bus_id);
- attributes = sysfs_get_device_attributes(device);
- if (attributes != NULL) {
- if (!(strcmp(bus_to_print, "pci"))) {
- value = sysfs_get_value_from_attributes
- (attributes, "config");
- if (value != NULL) {
- vendor_id = get_pciconfig_word
- (PCI_VENDOR_ID, value);
- device_id = get_pciconfig_word
- (PCI_DEVICE_ID, value);
- fprintf(stdout, "%s\n",
- pci_lookup_name(pacc, buf, 128,
- PCI_LOOKUP_VENDOR |
- PCI_LOOKUP_DEVICE,
- vendor_id, device_id, 0, 0));
- }
- }
- if (show_options & (SHOW_ATTRIBUTES |
- SHOW_ATTRIBUTE_VALUE | SHOW_ALL_ATTRIB_VALUES))
- print_device_attributes(attributes);
+
+ if (show_options & (SHOW_ATTRIBUTES | SHOW_ATTRIBUTE_VALUE |
+ SHOW_ALL_ATTRIB_VALUES)) {
+ attributes = sysfs_get_device_attributes(device);
+ if (attributes != NULL)
+ print_device_attributes(attributes);
}
if (isalnum(device->driver_name[0]))
fprintf (stdout, "\tDriver: %s\n\n",
diff --git a/cmd/systool.c b/cmd/systool.c
index a2a6bbe..44dba5c 100644
--- a/cmd/systool.c
+++ b/cmd/systool.c
@@ -243,37 +243,36 @@ void show_device(struct sysfs_device *device, int level)
{
struct dlist *attributes = NULL;
unsigned int vendor_id, device_id;
- unsigned char buf[128], *value = NULL;
+ unsigned char buf[128], value[256], path[SYSFS_PATH_MAX];
if (device != NULL) {
indent(level);
- if (show_bus != NULL && (!(strcmp(show_bus, "pci"))))
+ if (show_bus != NULL && (!(strcmp(show_bus, "pci")))) {
fprintf(stdout, "%s: ", device->bus_id);
- else
+ memset(path, 0, SYSFS_PATH_MAX);
+ memset(value, 0, SYSFS_PATH_MAX);
+ strcpy(path, device->path);
+ strcat(path, "/config");
+ if ((sysfs_read_attribute_value(path,
+ value, 256)) == 0) {
+ vendor_id = get_pciconfig_word
+ (PCI_VENDOR_ID, value);
+ device_id = get_pciconfig_word
+ (PCI_DEVICE_ID, value);
+ fprintf(stdout, "%s\n",
+ pci_lookup_name(pacc, buf, 128,
+ PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE,
+ vendor_id, device_id, 0, 0));
+ } else
+ fprintf(stdout, "\n");
+ } else
fprintf(stdout, "%s\n", device->bus_id);
- attributes = sysfs_get_device_attributes(device);
- if (attributes != NULL) {
- if (show_bus != NULL && (!(strcmp(show_bus, "pci")))) {
- value = sysfs_get_value_from_attributes
- (attributes, "config");
- if (value != NULL) {
- vendor_id = get_pciconfig_word
- (PCI_VENDOR_ID, value);
- device_id = get_pciconfig_word
- (PCI_DEVICE_ID, value);
- fprintf(stdout, "%s\n",
- pci_lookup_name(pacc, buf, 128,
- PCI_LOOKUP_VENDOR |
- PCI_LOOKUP_DEVICE,
- vendor_id, device_id,
- 0, 0));
- }
- }
- if (show_options & (SHOW_ATTRIBUTES |
- SHOW_ATTRIBUTE_VALUE |
+
+ if (show_options & (SHOW_ATTRIBUTES | SHOW_ATTRIBUTE_VALUE |
SHOW_ALL_ATTRIB_VALUES)) {
+ attributes = sysfs_get_device_attributes(device);
+ if (attributes != NULL)
show_attributes(attributes, (level+4));
- }
}
if (device->children != NULL)
show_device_children(device->children, (level+4));
@@ -281,7 +280,7 @@ void show_device(struct sysfs_device *device, int level)
indent(level+6);
fprintf (stdout, "Driver: %s\n",
device->driver_name);
- }
+ }
}
}
@@ -312,7 +311,7 @@ void show_driver_attributes(struct sysfs_driver *driver, int level)
{
if (driver != NULL) {
struct dlist *attributes = NULL;
-
+
attributes = sysfs_get_driver_attributes(driver);
if (attributes != NULL) {
struct sysfs_attribute *cur = NULL;
diff --git a/include/libsysfs.h b/include/libsysfs.h
index f7e989e..70cd5e8 100644
--- a/include/libsysfs.h
+++ b/include/libsysfs.h
@@ -163,6 +163,7 @@ extern unsigned char *sysfs_get_value_from_attributes(struct dlist *attr,
const unsigned char * name);
extern void sysfs_close_directory(struct sysfs_directory *sysdir);
extern struct sysfs_directory *sysfs_open_directory(const unsigned char *path);
+extern int sysfs_read_dir_attributes(struct sysfs_directory *sysdir);
extern int sysfs_read_directory(struct sysfs_directory *sysdir);
extern int sysfs_read_all_subdirs(struct sysfs_directory *sysdir);
extern struct sysfs_directory *sysfs_get_subdirectory
@@ -177,15 +178,16 @@ extern struct sysfs_attribute *sysfs_get_directory_attribute
(struct sysfs_directory *dir, unsigned char *attrname);
/* sysfs driver access */
+extern void sysfs_close_bus_driver(struct sysfs_driver *driver);
+extern struct sysfs_driver *sysfs_open_bus_driver(const unsigned char *path);
extern void sysfs_close_driver(struct sysfs_driver *driver);
extern struct sysfs_driver *sysfs_open_driver(const unsigned char *path);
extern struct sysfs_attribute *sysfs_get_driver_attr
(struct sysfs_driver *drv, const unsigned char *name);
extern struct dlist *sysfs_get_driver_attributes(struct sysfs_driver *driver);
extern struct dlist *sysfs_get_driver_links(struct sysfs_driver *driver);
-extern void sysfs_close_driver_by_name(struct sysfs_driver *driver);
-extern struct sysfs_driver *sysfs_open_driver_by_name
- (const unsigned char *drv_name, const unsigned char *bus, size_t bsize);
+extern struct sysfs_device *sysfs_get_driver_device
+ (struct sysfs_driver *driver, const unsigned char *name);
extern struct sysfs_attribute *sysfs_open_driver_attr(const unsigned char *bus,
const unsigned char *drv, const unsigned char *attrib);
diff --git a/lib/sysfs.h b/lib/sysfs.h
index 0059995..e4c148c 100644
--- a/lib/sysfs.h
+++ b/lib/sysfs.h
@@ -36,7 +36,6 @@
/* external library functions */
extern int lstat(const char *file_name, struct stat *buf);
extern int readlink(const char *path, char *buf, size_t bufsize);
-extern int getpagesize(void);
extern int isascii(int c);
/* Debugging */
diff --git a/lib/sysfs_bus.c b/lib/sysfs_bus.c
index 3111154..ec5a6f6 100644
--- a/lib/sysfs_bus.c
+++ b/lib/sysfs_bus.c
@@ -30,7 +30,7 @@ static void sysfs_close_dev(void *dev)
static void sysfs_close_drv(void *drv)
{
- sysfs_close_driver((struct sysfs_driver *)drv);
+ sysfs_close_bus_driver((struct sysfs_driver *)drv);
}
/*
@@ -202,7 +202,7 @@ static int get_all_bus_drivers(struct sysfs_bus *bus)
continue;
dlist_for_each_data(cur->subdirs, cursub,
struct sysfs_directory) {
- driver = sysfs_open_driver(cursub->path);
+ driver = sysfs_open_bus_driver(cursub->path);
if (driver == NULL) {
dprintf("Error opening driver at %s\n",
cursub->path);
@@ -362,6 +362,10 @@ struct dlist *sysfs_get_bus_attributes(struct sysfs_bus *bus)
{
if (bus == NULL || bus->directory == NULL)
return NULL;
+ if (bus->directory->attributes == NULL) {
+ if ((sysfs_read_dir_attributes(bus->directory)) != 0)
+ return NULL;
+ }
return bus->directory->attributes;
}
@@ -379,6 +383,10 @@ struct sysfs_attribute *sysfs_get_bus_attribute(struct sysfs_bus *bus,
errno = EINVAL;
return NULL;
}
+ if (bus->directory->attributes == NULL) {
+ if ((sysfs_read_dir_attributes(bus->directory)) != 0)
+ return NULL;
+ }
return sysfs_get_directory_attribute(bus->directory, attrname);
}
diff --git a/lib/sysfs_class.c b/lib/sysfs_class.c
index d7521df..b57d8d7 100644
--- a/lib/sysfs_class.c
+++ b/lib/sysfs_class.c
@@ -236,7 +236,7 @@ struct sysfs_class_device *sysfs_open_class_device(const unsigned char *path)
}
} else if (strncmp(curl->name,
SYSFS_DRIVERS_NAME, 6) == 0) {
- drv = sysfs_open_driver(curl->target);
+ drv = sysfs_open_bus_driver(curl->target);
if (drv != NULL) {
cdev->driver = drv;
if (cdev->sysdevice != NULL) {
@@ -425,6 +425,10 @@ struct dlist *sysfs_get_classdev_attributes(struct sysfs_class_device *cdev)
if (cdev == NULL || cdev->directory == NULL)
return NULL;
+ if (cdev->directory->attributes == NULL) {
+ if ((sysfs_read_dir_attributes(cdev->directory)) != 0)
+ return NULL;
+ }
return (cdev->directory->attributes);
}
@@ -439,12 +443,14 @@ struct sysfs_attribute *sysfs_get_classdev_attr
{
struct sysfs_attribute *cur = NULL;
- if (clsdev == NULL || clsdev->directory == NULL ||
- clsdev->directory->attributes == NULL || name == NULL) {
+ if (clsdev == NULL || clsdev->directory == NULL || name == NULL) {
errno = EINVAL;
return NULL;
}
-
+ if (clsdev->directory->attributes == NULL) {
+ if ((sysfs_read_dir_attributes(clsdev->directory)) != 0)
+ return NULL;
+ }
cur = sysfs_get_directory_attribute(clsdev->directory,
(unsigned char *)name);
if (cur != NULL)
diff --git a/lib/sysfs_device.c b/lib/sysfs_device.c
index fbd046f..01a7fc1 100644
--- a/lib/sysfs_device.c
+++ b/lib/sysfs_device.c
@@ -165,12 +165,16 @@ struct sysfs_attribute *sysfs_get_device_attr(struct sysfs_device *dev,
{
struct sysfs_attribute *cur = NULL;
- if (dev == NULL || dev->directory == NULL
- || dev->directory->attributes == NULL || name == NULL) {
+ if (dev == NULL || dev->directory == NULL || name == NULL) {
errno = EINVAL;
return NULL;
}
+ if (dev->directory->attributes == NULL) {
+ if ((sysfs_read_dir_attributes(dev->directory)) != 0)
+ return NULL;
+ }
+
cur = sysfs_get_directory_attribute(dev->directory,
(unsigned char *)name);
if (cur != NULL)
@@ -316,7 +320,7 @@ static struct sysfs_directory *open_root_device_dir(const unsigned char *name)
name);
return NULL;
}
- if (sysfs_read_directory(rdir) != 0) {
+ if ((sysfs_read_directory(rdir)) != 0) {
dprintf ("Error reading %s root device at dir %s\n", name,
rootpath);
sysfs_close_directory(rdir);
@@ -409,6 +413,10 @@ struct dlist *sysfs_get_device_attributes(struct sysfs_device *device)
if (device == NULL || device->directory == NULL)
return NULL;
+ if (device->directory->attributes == NULL) {
+ if ((sysfs_read_dir_attributes(device->directory)) != 0)
+ return NULL;
+ }
return (device->directory->attributes);
}
diff --git a/lib/sysfs_dir.c b/lib/sysfs_dir.c
index ff2edf4..fabb695 100644
--- a/lib/sysfs_dir.c
+++ b/lib/sysfs_dir.c
@@ -254,7 +254,7 @@ int sysfs_read_attribute(struct sysfs_attribute *sysattr)
unsigned char *fbuf = NULL;
unsigned char *vbuf = NULL;
size_t length = 0;
- int pgsize = 0;
+ long pgsize = 0;
int fd;
if (sysattr == NULL) {
@@ -266,7 +266,7 @@ int sysfs_read_attribute(struct sysfs_attribute *sysattr)
sysattr->path);
return -1;
}
- pgsize = getpagesize();
+ pgsize = sysconf(_SC_PAGESIZE);
fbuf = (unsigned char *)calloc(1, pgsize+1);
if (fbuf == NULL) {
dprintf("calloc failed\n");
@@ -423,7 +423,7 @@ int sysfs_read_all_subdirs(struct sysfs_directory *sysdir)
if (sysdir->subdirs == NULL)
return 0;
dlist_for_each_data(sysdir->subdirs, cursub, struct sysfs_directory) {
- if (sysfs_read_directory(cursub) != 0)
+ if ((sysfs_read_directory(cursub)) != 0)
dprintf ("Error reading subdirectory %s\n",
cursub->name);
}
@@ -490,18 +490,16 @@ struct sysfs_link *sysfs_open_link(const unsigned char *linkpath)
}
/**
- * sysfs_read_directory: grabs attributes, links, and subdirectories
+ * sysfs_read_dir_attributes: grabs attributes for the given directory
* @sysdir: sysfs directory to open
* returns 0 with success and -1 with error.
*/
-int sysfs_read_directory(struct sysfs_directory *sysdir)
+int sysfs_read_dir_attributes(struct sysfs_directory *sysdir)
{
DIR *dir = NULL;
struct dirent *dirent = NULL;
struct stat astats;
struct sysfs_attribute *attr = NULL;
- struct sysfs_directory *subdir = NULL;
- struct sysfs_link *ln = NULL;
unsigned char file_path[SYSFS_PATH_MAX];
int retval = 0;
@@ -550,7 +548,51 @@ int sysfs_read_directory(struct sysfs_directory *sysdir)
sysfs_del_attribute);
}
dlist_unshift(sysdir->attributes, attr);
- } else if (S_ISDIR(astats.st_mode)) {
+ }
+ }
+ closedir(dir);
+ return(retval);
+}
+
+/**
+ * sysfs_read_directory: grabs attributes, links, and subdirectories
+ * @sysdir: sysfs directory to open
+ * returns 0 with success and -1 with error.
+ */
+int sysfs_read_directory(struct sysfs_directory *sysdir)
+{
+ DIR *dir = NULL;
+ struct dirent *dirent = NULL;
+ struct stat astats;
+ struct sysfs_attribute *attr = NULL;
+ struct sysfs_directory *subdir = NULL;
+ struct sysfs_link *ln = NULL;
+ unsigned char file_path[SYSFS_PATH_MAX];
+ int retval = 0;
+
+ if (sysdir == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+ dir = opendir(sysdir->path);
+ if (dir == NULL) {
+ dprintf("Error opening directory %s\n", sysdir->path);
+ return -1;
+ }
+ while(((dirent = readdir(dir)) != NULL) && retval == 0) {
+ if (0 == strcmp(dirent->d_name, "."))
+ continue;
+ if (0 == strcmp(dirent->d_name, ".."))
+ continue;
+ memset(file_path, 0, SYSFS_PATH_MAX);
+ strncpy(file_path, sysdir->path, sizeof(file_path));
+ strncat(file_path, "/", sizeof(file_path));
+ strncat(file_path, dirent->d_name, sizeof(file_path));
+ if ((lstat(file_path, &astats)) != 0) {
+ dprintf("stat failed\n");
+ continue;
+ }
+ if (S_ISDIR(astats.st_mode)) {
subdir = sysfs_open_directory(file_path);
if (subdir == NULL) {
dprintf("Error opening directory %s\n",
@@ -597,17 +639,20 @@ struct sysfs_attribute *sysfs_get_directory_attribute
errno = EINVAL;
return NULL;
}
-
- attr = (struct sysfs_attribute *)dlist_find_custom(dir->attributes,
- attrname, dir_attribute_name_equal);
- if (attr != NULL)
- return attr;
+
+ if (dir->attributes == NULL) {
+ if ((sysfs_read_dir_attributes(dir)) != 0) {
+ return NULL;
+ }
+ attr = (struct sysfs_attribute *)dlist_find_custom
+ (dir->attributes, attrname, dir_attribute_name_equal);
+ if (attr != NULL)
+ return attr;
+ }
if (dir->subdirs != NULL) {
dlist_for_each_data(dir->subdirs, sdir,
struct sysfs_directory) {
- if (sdir->attributes == NULL)
- continue;
attr = sysfs_get_directory_attribute(sdir, attrname);
if (attr != NULL)
return attr;
diff --git a/lib/sysfs_driver.c b/lib/sysfs_driver.c
index 0011177..15eb239 100644
--- a/lib/sysfs_driver.c
+++ b/lib/sysfs_driver.c
@@ -23,17 +23,17 @@
#include "libsysfs.h"
#include "sysfs.h"
-static void sysfs_close_driver_by_name_dev(void *device)
+static void sysfs_close_driver_device(void *device)
{
sysfs_close_device((struct sysfs_device *)device);
}
/**
- * sysfs_close_driver: closes and cleans up driver structure
+ * sysfs_close_bus_driver: closes and cleans up driver structure
* NOTE: This routine does not deallocate devices list
* @driver: driver to close
*/
-void sysfs_close_driver(struct sysfs_driver *driver)
+void sysfs_close_bus_driver(struct sysfs_driver *driver)
{
if (driver != NULL) {
if (driver->devices != NULL) {
@@ -49,10 +49,10 @@ void sysfs_close_driver(struct sysfs_driver *driver)
}
/**
- * sysfs_close_driver_by_name: closes driver and deletes device lists too
+ * sysfs_close_driver: closes driver and deletes device lists too
* @driver: driver to close
*/
-void sysfs_close_driver_by_name(struct sysfs_driver *driver)
+void sysfs_close_driver(struct sysfs_driver *driver)
{
if (driver != NULL) {
if (driver->devices != NULL)
@@ -73,11 +73,11 @@ static struct sysfs_driver *alloc_driver(void)
}
/**
- * sysfs_open_driver: opens and initializes driver structure
+ * sysfs_open_bus_driver: opens and initializes driver structure
* @path: path to driver directory
* returns struct sysfs_driver with success and NULL with error
*/
-struct sysfs_driver *sysfs_open_driver(const unsigned char *path)
+struct sysfs_driver *sysfs_open_bus_driver(const unsigned char *path)
{
struct sysfs_driver *driver = NULL;
struct sysfs_directory *sdir = NULL;
@@ -120,6 +120,10 @@ struct dlist *sysfs_get_driver_attributes(struct sysfs_driver *driver)
if (driver == NULL || driver->directory == NULL)
return NULL;
+ if (driver->directory->attributes == NULL) {
+ if ((sysfs_read_dir_attributes(driver->directory)) != 0)
+ return NULL;
+ }
return(driver->directory->attributes);
}
@@ -134,12 +138,15 @@ struct sysfs_attribute *sysfs_get_driver_attr(struct sysfs_driver *drv,
{
struct sysfs_attribute *cur = NULL;
- if (drv == NULL || drv->directory == NULL
- || drv->directory->attributes == NULL || name == NULL) {
+ if (drv == NULL || drv->directory == NULL || name == NULL) {
errno = EINVAL;
return NULL;
}
+ if (drv->directory->attributes == NULL) {
+ if ((sysfs_read_dir_attributes(drv->directory)) != 0)
+ return NULL;
+ }
cur = sysfs_get_directory_attribute(drv->directory,
(unsigned char *)name);
if (cur != NULL)
@@ -162,91 +169,137 @@ struct dlist *sysfs_get_driver_links(struct sysfs_driver *driver)
return(driver->directory->links);
}
+
/**
- * get_driver_path: looks up the bus the driver is on and builds path to
- * the driver.
- * @bus: bus on which to search
- * @drv: driver to look for
- * @path: buffer to return path to driver
- * @psize: size of "path"
- * Returns 0 on success and -1 on error
- */
-static int get_driver_path(const unsigned char *bus, const unsigned char *drv,
- unsigned char *path, size_t psize)
+ * sysfs_open_driver_devices: open up the list of devices this driver supports
+ * @driver: sysfs_driver for which devices are needed
+ * Returns 0 on SUCCESS or -1 with ERROR
+ */
+static int sysfs_open_driver_devices(struct sysfs_driver *driver)
{
- if (bus == NULL || drv == NULL || path == NULL) {
+ struct sysfs_link *curlink = NULL;
+ struct sysfs_device *device = NULL;
+
+ if (driver == NULL) {
errno = EINVAL;
return -1;
}
- if (sysfs_get_mnt_path(path, psize) != 0) {
- dprintf("Error getting sysfs mount path\n");
- return -1;
+
+ if (driver->devices != NULL)
+ return 0;
+
+ if (driver->directory->links != NULL) {
+ dlist_for_each_data(driver->directory->links, curlink,
+ struct sysfs_link) {
+ device = sysfs_open_device(curlink->target);
+ if (device == NULL) {
+ dprintf("Error opening device at %s\n",
+ curlink->target);
+ return -1;
+ }
+ strcpy(device->driver_name, driver->name);
+ if (driver->devices == NULL)
+ driver->devices = dlist_new_with_delete
+ (sizeof(struct sysfs_device),
+ sysfs_close_driver_device);
+ dlist_unshift(driver->devices, device);
+ }
}
- strcat(path, SYSFS_BUS_DIR);
- strcat(path, "/");
- strcat(path, bus);
- strcat(path, SYSFS_DRIVERS_DIR);
- strcat(path, "/");
- strcat(path, drv);
return 0;
}
-
/**
- * sysfs_open_driver_by_name: open a driver by name and return the bus
- * the driver is on.
- * @drv_name: driver to open
- * @bus: the driver bus
- * @bsize: size of bus buffer
+ * sysfs_open_driver: open a driver given its path
+ * @path: path to driver to open
* returns struct sysfs_driver if found, NULL otherwise
* NOTE:
- * 1. Need to call sysfs_close_driver_by_name to free up memory
- * 2. Bus the driver is registered with must be supplied.
- * Use sysfs_find_driver_bus() to obtain the bus name
+ * 1. Need to call sysfs_close_driver to free up memory
*/
-struct sysfs_driver *sysfs_open_driver_by_name(const unsigned char *drv_name,
- const unsigned char *bus, size_t bsize)
+struct sysfs_driver *sysfs_open_driver(const unsigned char *path)
{
struct sysfs_driver *driver = NULL;
- struct sysfs_device *device = NULL;
- struct sysfs_link *curlink = NULL;
- unsigned char path[SYSFS_PATH_MAX];
- if (drv_name == NULL || bus == NULL) {
+ if (path == NULL) {
errno = EINVAL;
return NULL;
}
- memset(path, 0, SYSFS_PATH_MAX);
- if (get_driver_path(bus, drv_name, path, SYSFS_PATH_MAX) != 0) {
- dprintf("Error getting to driver %s\n", drv_name);
- return NULL;
- }
- driver = sysfs_open_driver(path);
+ driver = sysfs_open_bus_driver(path);
if (driver == NULL) {
dprintf("Could not open driver %s\n", drv_name);
return NULL;
}
if (driver->directory->links != NULL) {
- dlist_for_each_data(driver->directory->links, curlink,
- struct sysfs_link) {
- device = sysfs_open_device(curlink->target);
- if (device == NULL) {
- dprintf("Error opening device at %s\n",
- curlink->target);
- sysfs_close_driver_by_name(driver);
+ if ((sysfs_open_driver_devices(driver)) != 0) {
+ dprintf("Error reading driver devices\n");
+ sysfs_close_driver(driver);
+ return NULL;
+ }
+ }
+ return driver;
+}
+
+/**
+ * sysfs_get_driver_device: looks up a device from a list of driver's devices
+ * and returns its sysfs_device corresponding to it
+ * @driver: sysfs_driver on which to search
+ * @name: name of the device to search
+ * Returns a sysfs_device if found, NULL otherwise
+ */
+struct sysfs_device *sysfs_get_driver_device(struct sysfs_driver *driver,
+ const unsigned char *name)
+{
+ struct sysfs_device *device = NULL;
+
+ if (driver == NULL || name == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if (driver->devices == NULL) {
+ if (driver->directory->links == NULL) {
+ return NULL;
+ } else {
+ if ((sysfs_open_driver_devices(driver)) != 0) {
+ dprintf("Error getting driver devices\n");
return NULL;
}
- strcpy(device->driver_name, drv_name);
- if (driver->devices == NULL)
- driver->devices = dlist_new_with_delete
- (sizeof(struct sysfs_device),
- sysfs_close_driver_by_name_dev);
- dlist_unshift(driver->devices, device);
}
}
- return driver;
+ dlist_for_each_data(driver->devices, device, struct sysfs_device) {
+ if (!(strncmp(device->name, name, SYSFS_NAME_LEN)))
+ return device;
+ }
+ return NULL;
}
+/**
+ * get_driver_path: looks up the bus the driver is on and builds path to
+ * the driver.
+ * @bus: bus on which to search
+ * @drv: driver to look for
+ * @path: buffer to return path to driver
+ * @psize: size of "path"
+ * Returns 0 on success and -1 on error
+ */
+static int get_driver_path(const unsigned char *bus,
+ const unsigned char *drv, unsigned char *path, size_t psize)
+{
+ if (bus == NULL || drv == NULL || path == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+ if (sysfs_get_mnt_path(path, psize) != 0) {
+ dprintf("Error getting sysfs mount path\n");
+ return -1;
+ }
+ strcat(path, SYSFS_BUS_DIR);
+ strcat(path, "/");
+ strcat(path, bus);
+ strcat(path, SYSFS_DRIVERS_DIR);
+ strcat(path, "/");
+ strcat(path, drv);
+ return 0;
+}
/**
* sysfs_open_driver_attr: read the user supplied driver attribute
diff --git a/lib/sysfs_utils.c b/lib/sysfs_utils.c
index 7563dff..ede4058 100644
--- a/lib/sysfs_utils.c
+++ b/lib/sysfs_utils.c
@@ -225,7 +225,7 @@ struct dlist *sysfs_open_subsystem_list(unsigned char *name)
return NULL;
}
- if (sysfs_read_directory(dir) != 0) {
+ if ((sysfs_read_directory(dir)) != 0) {
dprintf("Error reading sysfs_directory at %s\n", sysfs_path);
sysfs_close_directory(dir);
return NULL;
@@ -303,7 +303,7 @@ struct dlist *sysfs_open_bus_devices_list(unsigned char *name)
return NULL;
}
- if (sysfs_read_directory(dir) != 0) {
+ if ((sysfs_read_directory(dir)) != 0) {
dprintf("Error reading sysfs_directory at %s\n", sysfs_path);
sysfs_close_directory(dir);
return NULL;
diff --git a/test/get_driver.c b/test/get_driver.c
index 8628486..107c9bf 100644
--- a/test/get_driver.c
+++ b/test/get_driver.c
@@ -32,7 +32,7 @@ void print_usage(void)
int main(int argc, char *argv[])
{
- char *bus = NULL;
+ char *bus = NULL, path[SYSFS_PATH_MAX];
struct sysfs_driver *driver = NULL;
struct sysfs_device *device = NULL;
@@ -41,6 +41,7 @@ int main(int argc, char *argv[])
return 1;
}
+ memset(path, 0, SYSFS_PATH_MAX);
bus = (char *)calloc(1, SYSFS_NAME_LEN);
if ((sysfs_find_driver_bus(argv[1], bus, SYSFS_NAME_LEN)) < 0) {
fprintf(stdout, "Driver %s not found\n", argv[1]);
@@ -48,7 +49,18 @@ int main(int argc, char *argv[])
return 1;
}
fprintf(stdout, "Driver %s is a member of bus %s\n", argv[1], bus);
- driver = sysfs_open_driver_by_name(argv[1], bus, SYSFS_NAME_LEN);
+
+ if ((sysfs_get_mnt_path(path, SYSFS_PATH_MAX)) != 0) {
+ fprintf(stdout, "Sysfs not mounted?\n");
+ return 1;
+ }
+ strcat(path, SYSFS_BUS_DIR);
+ strcat(path, "/");
+ strcat(path, bus);
+ strcat(path, SYSFS_DRIVERS_DIR);
+ strcat(path, "/");
+ strcat(path, argv[1]);
+ driver = sysfs_open_driver(path);
if (driver == NULL) {
fprintf(stdout, "Device %s not found\n", argv[1]);
free(bus);
@@ -61,7 +73,7 @@ int main(int argc, char *argv[])
} else
fprintf(stdout, "%s is presently not used by any device\n", argv[1]);
- sysfs_close_driver_by_name(driver);
+ sysfs_close_driver(driver);
free(bus);
return 0;
}