summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormananth <mananth>2003-08-29 11:31:17 +0000
committermananth <mananth>2003-08-29 11:31:17 +0000
commit293fac7445f27c20ee3f2b7d3d2b6f183a0d2656 (patch)
treeecd6b1ba9b4822cef300b8d0a62d7327c8942aa6
parent98819486dc2b8a3be8c07cb096503f08fe656ebc (diff)
downloadsysfsutils-293fac7445f27c20ee3f2b7d3d2b6f183a0d2656.tar.gz
More utility functions.
Modified commands to not to use sysfs_directory
-rw-r--r--ChangeLog8
-rw-r--r--cmd/lsbus.c149
-rw-r--r--cmd/systool.c230
-rw-r--r--include/libsysfs.h11
-rw-r--r--lib/sysfs_class.c92
-rw-r--r--lib/sysfs_device.c13
-rw-r--r--lib/sysfs_dir.c6
-rw-r--r--lib/sysfs_driver.c28
-rw-r--r--lib/sysfs_utils.c76
9 files changed, 370 insertions, 243 deletions
diff --git a/ChangeLog b/ChangeLog
index 178fcf9..6b5917a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,12 @@
+08/28/2003 - Ananth Mavinakayanahalli <ananth@in.ibm.com>
+ * Added more utility functions to sysfsutils
+ * Modified commands to make use of the new functions
+ * Updated libsysfs.txt to reflect new structure modifications
+ * Added sysfs_open_subsystem_list() to get subsystem specific
+ lists from the library
+ * Added sysfs_close_list() - a generic list deletion routine
+
08/28/2003 - Daniel Stekloff <dsteklof@us.ibm.com>
* Added sysfs_root_device struct for modelling /sys/devices
path.
diff --git a/cmd/lsbus.c b/cmd/lsbus.c
index 7f92021..9b9a709 100644
--- a/cmd/lsbus.c
+++ b/cmd/lsbus.c
@@ -85,33 +85,6 @@ void remove_end_newline(unsigned char *value)
}
/**
- * print_device_children: prints out device subdirs.
- * @sdir: print this directory's subdirectories/children.
- */
-void print_device_children(struct sysfs_directory *sdir)
-{
- if (sdir != NULL) {
- fprintf(stdout, "\tChildren:\n");
- if (sdir->subdirs != NULL) {
- struct sysfs_directory *cur;
-
- dlist_for_each_data(sdir->subdirs, cur,
- struct sysfs_directory) {
- fprintf(stdout, "\t\t%s\n", cur->name);
- }
- }
- if (sdir->links != NULL) {
- struct sysfs_link *curl = NULL;
-
- dlist_for_each_data(sdir->links, curl,
- struct sysfs_link) {
- fprintf(stdout, "\t\t%s\n", curl->name);
- }
- }
- }
-}
-
-/**
* isbinaryvalue: checks to see if attribute is binary or not.
* @attr: attribute to check.
* returns 1 if binary or 0 if not.
@@ -191,18 +164,16 @@ void print_attribute(struct sysfs_attribute *attr)
/**
* print_device_attributes: prints out device attributes.
- * @sdir: print this directory's attributes/files.
+ * @sdir: print this device's attributes/files.
*/
-void print_device_attributes(struct sysfs_directory *sdir)
+void print_device_attributes(struct dlist *attributes)
{
- if (sdir != NULL && sdir->attributes != NULL) {
- struct sysfs_attribute *cur = NULL;;
+ struct sysfs_attribute *cur = NULL;;
- fprintf (stdout, "\tAttributes:\n");
- dlist_for_each_data(sdir->attributes, cur,
+ fprintf (stdout, "\tAttributes:\n");
+ dlist_for_each_data(attributes, cur,
struct sysfs_attribute) {
- print_attribute(cur);
- }
+ print_attribute(cur);
}
}
@@ -212,16 +183,16 @@ void print_device_attributes(struct sysfs_directory *sdir)
*/
void print_device(struct sysfs_device *device)
{
- if (device != NULL && device->directory != NULL) {
- fprintf (stdout, " %s %s\n", device->bus_id, device->name);
- if (device->directory->subdirs != NULL
- || device->directory->links != NULL)
- print_device_children(device->directory);
- if (device->directory->attributes != NULL && (show_options
- & (SHOW_ATTRIBUTES | SHOW_ATTRIBUTE_VALUE
- | SHOW_ALL_ATTRIB_VALUES)))
- print_device_attributes(device->directory);
- if (device->driver_name != NULL)
+ struct dlist *attributes = NULL;
+
+ if (device != NULL) {
+ fprintf (stdout, " %s\n", device->bus_id);
+ 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",
device->driver_name);
}
@@ -233,14 +204,15 @@ void print_device(struct sysfs_device *device)
*/
void print_driver_attributes(struct sysfs_driver *driver)
{
- if (driver != NULL && driver->directory != NULL) {
- struct sysfs_directory *sdir = driver->directory;
-
- if (sdir->attributes != NULL) {
+ struct dlist *attributes = NULL;
+
+ if (driver != NULL) {
+ attributes = sysfs_get_driver_attributes(driver);
+ if (attributes != NULL) {
struct sysfs_attribute *cur = NULL;
fprintf (stdout, "\t%s Attributes:\n", driver->name);
- dlist_for_each_data(sdir->attributes, cur,
+ dlist_for_each_data(attributes, cur,
struct sysfs_attribute) {
print_attribute(cur);
}
@@ -254,17 +226,14 @@ void print_driver_attributes(struct sysfs_driver *driver)
*/
void print_driver_devices(struct sysfs_driver *driver)
{
- if (driver != NULL && driver->directory != NULL) {
- struct sysfs_directory *sdir = driver->directory;
-
- if (sdir->links != NULL) {
- struct sysfs_link *cur = NULL;
-
+ struct sysfs_device *device = NULL;
+
+ if (driver != NULL) {
+ if (driver->devices != NULL) {
fprintf (stdout, "\tDevices:\n");
- dlist_for_each_data(sdir->links, cur,
- struct sysfs_link) {
- fprintf(stdout, "\t\t%s\n", cur->name);
- }
+ dlist_for_each_data(driver->devices, device,
+ struct sysfs_device)
+ fprintf(stdout, "\t\t%s\n", device->bus_id);
}
}
}
@@ -275,19 +244,14 @@ void print_driver_devices(struct sysfs_driver *driver)
*/
void print_driver(struct sysfs_driver *driver)
{
- struct sysfs_directory *sdir = NULL;
-
+ struct dlist *links = NULL, *attributes = NULL;
+
if (driver != NULL) {
fprintf (stdout, " %s\n", driver->name);
- sdir = driver->directory;
- if (sdir != NULL) {
- if (sdir->links != NULL)
- print_driver_devices(driver);
- if(sdir->attributes != NULL && (show_options
- & (SHOW_ATTRIBUTES | SHOW_ATTRIBUTE_VALUE
- | SHOW_ALL_ATTRIB_VALUES)))
- print_driver_attributes(driver);
- }
+ print_driver_devices(driver);
+ if(show_options & (SHOW_ATTRIBUTES | SHOW_ATTRIBUTE_VALUE
+ | SHOW_ALL_ATTRIB_VALUES))
+ print_driver_attributes(driver);
}
}
@@ -319,7 +283,7 @@ int print_sysfs_bus(unsigned char *busname)
dlist_for_each_data(bus->devices, curdev,
struct sysfs_device) {
if (bus_device == NULL || (strcmp(bus_device,
- curdev->bus_id) == 0))
+ curdev->bus_id) == 0))
print_device(curdev);
}
}
@@ -340,35 +304,20 @@ int print_sysfs_bus(unsigned char *busname)
*/
int print_sysfs_buses(void)
{
- struct sysfs_directory *busdir = NULL, *current = NULL;
- unsigned char buspath[SYSFS_PATH_MAX];
- int ret = 0;
-
- /* get sysfs mount point */
- if ((sysfs_get_mnt_path(buspath, SYSFS_PATH_MAX) != 0)) {
- perror("sysfs_get_mnt_path");
- fprintf(stderr, "Error getting sysfs mount path - exiting\n");
- exit(1);
- }
- strcat(buspath, SYSFS_BUS_DIR);
- busdir = sysfs_open_directory(buspath);
- if (busdir == NULL) {
- fprintf(stderr, "Error opening sysfs bus directory at %s\n",
- buspath);
- return 1;
- }
- if ((sysfs_read_directory(busdir)) != 0) {
- fprintf(stderr, "Error reading sysfs bus directory at %s\n",
- buspath);
- sysfs_close_directory(busdir);
- return 1;
- }
-
- fprintf(stdout, "Supported sysfs buses:\n");
- dlist_for_each_data(busdir->subdirs, current, struct sysfs_directory) {
- fprintf(stdout, "\t%s\n", current->name);
+ unsigned char subsys[SYSFS_NAME_LEN];
+ struct dlist *list = NULL;
+ char *cur = NULL;
+ int ret = 0;
+
+ strcpy(subsys, SYSFS_BUS_DIR);
+ list = sysfs_open_subsystem_list(subsys);
+ if (list != NULL) {
+ fprintf(stdout, "Supported sysfs buses:\n");
+ dlist_for_each_data(list, cur, char)
+ fprintf(stdout, "\t%s\n", cur);
}
- sysfs_close_directory(busdir);
+ sysfs_close_list(list);
+
return ret;
}
diff --git a/cmd/systool.c b/cmd/systool.c
index 7d482e0..fe5e903 100644
--- a/cmd/systool.c
+++ b/cmd/systool.c
@@ -103,30 +103,19 @@ void remove_end_newline(unsigned char *value)
/**
* show_device_children: prints out device subdirs.
- * @sdir: print this directory's subdirectories/children.
+ * @children: dlist of child devices.
*/
-void show_device_children(struct sysfs_directory *sdir, int level)
+void show_device_children(struct dlist *children, int level)
{
- if (sdir != NULL) {
+ struct sysfs_device *child = NULL;
+
+ if (children != NULL) {
indent(level);
fprintf(stdout, "Children:\n");
- if (sdir->subdirs != NULL) {
- struct sysfs_directory *cur;
-
- dlist_for_each_data(sdir->subdirs, cur,
- struct sysfs_directory) {
- indent(level+4);
- fprintf(stdout, "%s\n", cur->name);
- }
- }
- if (sdir->links != NULL) {
- struct sysfs_link *curl = NULL;
-
- dlist_for_each_data(sdir->links, curl,
- struct sysfs_link) {
- indent(level+4);
- fprintf(stdout, "%s\n", curl->name);
- }
+ dlist_for_each_data(children, child,
+ struct sysfs_device) {
+ indent(level+4);
+ fprintf(stdout, "%s\n", child->bus_id);
}
}
}
@@ -213,17 +202,17 @@ void show_attribute(struct sysfs_attribute *attr, int level)
}
/**
- * show_attributes: prints out a directory's attributes.
- * @sdir: print this directory's attributes/files.
+ * show_attributes: prints out a list of attributes.
+ * @attributes: print this dlist of attributes/files.
*/
-void show_attributes(struct sysfs_directory *sdir, int level)
+void show_attributes(struct dlist *attributes, int level)
{
- if (sdir != NULL && sdir->attributes != NULL) {
+ if (attributes != NULL) {
struct sysfs_attribute *cur = NULL;
-
+
indent(level);
fprintf (stdout, "Attributes:\n");
- dlist_for_each_data(sdir->attributes, cur,
+ dlist_for_each_data(attributes, cur,
struct sysfs_attribute) {
show_attribute(cur, (level+4));
}
@@ -236,16 +225,19 @@ void show_attributes(struct sysfs_directory *sdir, int level)
*/
void show_device(struct sysfs_device *device, int level)
{
- if (device != NULL && device->directory != NULL) {
+ struct dlist *attributes = NULL;
+
+ if (device != NULL) {
indent(level);
- fprintf (stdout, "%s %s\n", device->bus_id, device->name);
- if (device->directory->subdirs != NULL
- || device->directory->links != NULL)
- show_device_children(device->directory, (level+4));
- if (device->directory->attributes != NULL && (show_options
- & (SHOW_ATTRIBUTES | SHOW_ATTRIBUTE_VALUE
- | SHOW_ALL_ATTRIB_VALUES)))
- show_attributes(device->directory, (level+4));
+ fprintf (stdout, "%s\n", device->bus_id);
+ if (device->children != NULL)
+ show_device_children(device->children, (level+4));
+ 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 (isalnum(device->driver_name[0])) {
indent(level+4);
fprintf (stdout, "Driver: %s\n",
@@ -260,13 +252,16 @@ void show_device(struct sysfs_device *device, int level)
*/
void show_root_device(struct sysfs_device *device, int level)
{
- if (device != NULL && device->directory != NULL) {
+ if (device != NULL) {
indent(level);
- fprintf (stdout, "%s %s\n", device->bus_id, device->name);
- if (device->directory->attributes != NULL && (show_options
- & (SHOW_ATTRIBUTES | SHOW_ATTRIBUTE_VALUE
- | SHOW_ALL_ATTRIB_VALUES)))
- show_attributes(device->directory, (level+4));
+ fprintf (stdout, "%s\n", device->bus_id);
+ if (show_options & (SHOW_ATTRIBUTES | SHOW_ATTRIBUTE_VALUE
+ | SHOW_ALL_ATTRIB_VALUES)) {
+ struct dlist *attributes = NULL;
+ attributes = sysfs_get_device_attributes(device);
+ if (attributes != NULL)
+ show_attributes(attributes, (level+4));
+ }
}
}
@@ -276,15 +271,16 @@ void show_root_device(struct sysfs_device *device, int level)
*/
void show_driver_attributes(struct sysfs_driver *driver, int level)
{
- if (driver != NULL && driver->directory != NULL) {
- struct sysfs_directory *sdir = driver->directory;
-
- if (sdir->attributes != NULL) {
+ if (driver != NULL) {
+ struct dlist *attributes = NULL;
+
+ attributes = sysfs_get_driver_attributes(driver);
+ if (attributes != NULL) {
struct sysfs_attribute *cur = NULL;
indent(level);
fprintf (stdout, "%s Attributes:\n", driver->name);
- dlist_for_each_data(sdir->attributes, cur,
+ dlist_for_each_data(attributes, cur,
struct sysfs_attribute) {
show_attribute(cur, (level+4));
}
@@ -298,18 +294,16 @@ void show_driver_attributes(struct sysfs_driver *driver, int level)
*/
void show_driver_devices(struct sysfs_driver *driver, int level)
{
- if (driver != NULL && driver->directory != NULL) {
- struct sysfs_directory *sdir = driver->directory;
-
- if (sdir->links != NULL) {
- struct sysfs_link *cur = NULL;
+ if (driver != NULL) {
+ if (driver->devices != NULL) {
+ struct sysfs_device *cur = NULL;
indent(level);
fprintf (stdout, "Devices:\n");
- dlist_for_each_data(sdir->links, cur,
- struct sysfs_link) {
+ dlist_for_each_data(driver->devices, cur,
+ struct sysfs_device) {
indent(level+4);
- fprintf (stdout, "%s\n", cur->name);
+ fprintf (stdout, "%s\n", cur->bus_id);
}
}
}
@@ -321,20 +315,15 @@ void show_driver_devices(struct sysfs_driver *driver, int level)
*/
void show_driver(struct sysfs_driver *driver, int level)
{
- struct sysfs_directory *sdir = NULL;
-
if (driver != NULL) {
indent(level);
fprintf (stdout, "%s\n", driver->name);
- sdir = driver->directory;
- if (sdir != NULL) {
- if (sdir->links != NULL)
- show_driver_devices(driver, (level+4));
- if(sdir->attributes != NULL && (show_options
- & (SHOW_ATTRIBUTES | SHOW_ATTRIBUTE_VALUE
- | SHOW_ALL_ATTRIB_VALUES)))
- show_driver_attributes(driver, (level+4));
- }
+ if (driver->devices != NULL)
+ show_driver_devices(driver, (level+4));
+
+ if (show_options & (SHOW_ATTRIBUTES | SHOW_ATTRIBUTE_VALUE
+ | SHOW_ALL_ATTRIB_VALUES))
+ show_driver_attributes(driver, (level+4));
}
}
@@ -407,27 +396,20 @@ int show_sysfs_bus(unsigned char *busname)
*/
void show_class_device(struct sysfs_class_device *dev, int level)
{
- struct sysfs_directory *cur = NULL;
-
+ struct dlist *attributes = NULL;
+
if (dev != NULL) {
indent(level);
fprintf(stdout, "%s\n", dev->name);
- if (dev->directory != NULL && (show_options
- & (SHOW_ATTRIBUTES | SHOW_ATTRIBUTE_VALUE
- | SHOW_ALL_ATTRIB_VALUES))) {
- show_attributes(dev->directory, (level+4));
- if (dev->directory->subdirs == NULL)
- return;
- dlist_for_each_data(dev->directory->subdirs, cur,
- struct sysfs_directory) {
- indent(level+4);
- fprintf(stdout, "%s\n", cur->name);
- show_attributes(cur, (level+4));
- }
- }
- if (dev->sysdevice != NULL && (show_options & SHOW_DEVICES))
+ if (show_options & (SHOW_ATTRIBUTES | SHOW_ATTRIBUTE_VALUE
+ | SHOW_ALL_ATTRIB_VALUES)) {
+ attributes = sysfs_get_classdev_attributes(dev);
+ if (attributes != NULL)
+ show_attributes(attributes, (level+4));
+ }
+ if (dev->sysdevice != NULL && (show_options & SHOW_DEVICES))
show_device(dev->sysdevice, (level+4));
- if (dev->driver != NULL && (show_options & SHOW_DRIVERS))
+ if (dev->driver != NULL && (show_options & SHOW_DRIVERS))
show_driver(dev->driver, (level+4));
}
}
@@ -502,37 +484,6 @@ int show_sysfs_root(unsigned char *rootname)
return 0;
}
-/**
- * show_subdirectories: prints all subdirectory names at path
- * @path: sysfs path where subdirs are.
- * returns 0 with success or 1 with error.
- */
-int show_subdirectories(unsigned char *path, int level)
-{
- struct sysfs_directory *dir = NULL, *current = NULL;
- int ret = 0;
-
- dir = sysfs_open_directory(path);
- if (dir == NULL) {
- fprintf(stderr, "Error opening sysfs directory at %s\n", path);
- return 1;
- }
- if ((sysfs_read_directory(dir)) != 0) {
- fprintf(stderr, "Error reading sysfs directory at %s\n", path);
- sysfs_close_directory(dir);
- return 1;
- }
-
- if (dir->subdirs != NULL) {
- dlist_for_each_data(dir->subdirs, current,
- struct sysfs_directory) {
- indent(level);
- fprintf(stdout, "%s\n", current->name);
- }
- }
- sysfs_close_directory(dir);
- return ret;
-}
/**
* show_default_info: prints current buses, classes, and root devices
@@ -541,42 +492,41 @@ int show_subdirectories(unsigned char *path, int level)
*/
int show_default_info(void)
{
- unsigned char sysfs_root[SYSFS_PATH_MAX];
- unsigned char path_to_print[SYSFS_PATH_MAX];
+ unsigned char subsys[SYSFS_NAME_LEN];
+ struct dlist *list = NULL;
+ char *cur = NULL;
int retval = 0;
- /* get sysfs mount point */
- if (sysfs_get_mnt_path(sysfs_root, SYSFS_PATH_MAX) != 0) {
- perror("sysfs_get_mnt_path");
- fprintf(stderr, "Error getting sysfs mount point\n");
- exit(1);
+ strcpy(subsys, SYSFS_BUS_DIR);
+ list = sysfs_open_subsystem_list(subsys);
+ if (list != NULL) {
+ fprintf(stdout, "Supported sysfs buses:\n");
+ dlist_for_each_data(list, cur, char)
+ fprintf(stdout, "\t%s\n", cur);
}
- strcpy(path_to_print, sysfs_root);
+ sysfs_close_list(list);
- /* print supported buses */
- strcat(path_to_print, SYSFS_BUS_DIR);
- fprintf(stdout, "Supported sysfs buses:\n");
- retval = show_subdirectories(path_to_print, 4);
-
- if (retval == 0) {
- /* print supported classes */
- strcpy(path_to_print, sysfs_root);
- strcat(path_to_print, SYSFS_CLASS_DIR);
+ strcpy(subsys, SYSFS_CLASS_DIR);
+ list = sysfs_open_subsystem_list(subsys);
+ if (list != NULL) {
fprintf(stdout, "Supported sysfs classes:\n");
- retval = show_subdirectories(path_to_print, 4);
+ dlist_for_each_data(list, cur, char)
+ fprintf(stdout, "\t%s\n", cur);
}
-
- if (retval == 0) {
- /* print supported root devices */
- strcpy(path_to_print, sysfs_root);
- strcat(path_to_print, SYSFS_DEVICES_DIR);
- fprintf(stdout, "Supported sysfs root devices:\n");
- retval = show_subdirectories(path_to_print, 4);
+ sysfs_close_list(list);
+
+ strcpy(subsys, SYSFS_DEVICES_DIR);
+ list = sysfs_open_subsystem_list(subsys);
+ if (list != NULL) {
+ fprintf(stdout, "Supported sysfs devices:\n");
+ dlist_for_each_data(list, cur, char)
+ fprintf(stdout, "\t%s\n", cur);
}
-
+ sysfs_close_list(list);
+
return retval;
}
-
+
/* MAIN */
int main(int argc, char *argv[])
{
diff --git a/include/libsysfs.h b/include/libsysfs.h
index ffeb916..9a3eb66 100644
--- a/include/libsysfs.h
+++ b/include/libsysfs.h
@@ -140,6 +140,8 @@ extern int sysfs_get_name_from_path(const unsigned char *path,
unsigned char *name, size_t len);
extern int sysfs_get_link(const unsigned char *path, unsigned char *target,
size_t len);
+extern struct dlist *sysfs_open_subsystem_list(unsigned char *name);
+extern void sysfs_close_list(struct dlist *list);
/* sysfs directory and file access */
extern void sysfs_close_attribute(struct sysfs_attribute *sysattr);
@@ -170,6 +172,8 @@ extern struct sysfs_attribute *sysfs_get_directory_attribute
/* sysfs driver access */
extern void sysfs_close_driver(struct sysfs_driver *driver);
extern struct sysfs_driver *sysfs_open_driver(const unsigned char *path);
+extern struct dlist *sysfs_get_driver_attributes(struct sysfs_driver *driver);
+extern struct dlist *sysfs_get_driver_links(struct sysfs_driver *driver);
/* generic sysfs device access */
extern void sysfs_close_root_device(struct sysfs_root_device *root);
@@ -181,6 +185,7 @@ extern struct sysfs_device *sysfs_open_device(const unsigned char *path);
extern struct sysfs_device *sysfs_open_device_tree(const unsigned char *path);
extern struct sysfs_attribute *sysfs_get_device_attr
(struct sysfs_device *dev, const unsigned char *name);
+extern struct dlist *sysfs_get_device_attributes(struct sysfs_device *device);
/* generic sysfs bus access */
extern void sysfs_close_bus(struct sysfs_bus *bus);
@@ -203,6 +208,12 @@ extern struct sysfs_class_device *sysfs_open_class_device
(const unsigned char *path);
extern void sysfs_close_class(struct sysfs_class *cls);
extern struct sysfs_class *sysfs_open_class(const unsigned char *name);
+extern struct sysfs_class_device *sysfs_get_class_device
+ (struct sysfs_class *class, unsigned char *name);
+extern struct sysfs_class_device *sysfs_open_class_device_by_name
+ (unsigned char *class, unsigned char *name);
+extern struct dlist *sysfs_get_classdev_attributes
+ (struct sysfs_class_device *cdev);
#ifdef __cplusplus
}
diff --git a/lib/sysfs_class.c b/lib/sysfs_class.c
index 3b34c79..c93428a 100644
--- a/lib/sysfs_class.c
+++ b/lib/sysfs_class.c
@@ -29,6 +29,23 @@ void sysfs_close_cls_dev(void *dev)
}
/**
+ * class_name_equal: compares class_devices' name
+ * @a: class_name looking for
+ * @b: sysfs_class_device being compared
+ */
+static int class_name_equal(void *a, void *b)
+{
+ if (a == NULL || b == NULL)
+ return 0;
+
+ if (strcmp(((unsigned char *)a), ((struct sysfs_class_device *)b)->name)
+ == 0)
+ return 1;
+
+ return 0;
+}
+
+/**
* sysfs_close_class_device: closes a single class device.
* @dev: class device to close.
*/
@@ -268,3 +285,78 @@ struct sysfs_class *sysfs_open_class(const unsigned char *name)
return cls;
}
+
+/**
+ * sysfs_get_class_device: Get specific class device using the device's id
+ * @class: class to find device on
+ * @name: class name of the device
+ */
+struct sysfs_class_device *sysfs_get_class_device(struct sysfs_class *class,
+ unsigned char *name)
+{
+ if (class == NULL || name == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ return (struct sysfs_class_device *)dlist_find_custom(class->devices,
+ name, class_name_equal);
+}
+
+/**
+ * sysfs_open_class_device_by_name: Locates a specific class_device and returns it.
+ * Class_device must be closed using sysfs_close_class_device
+ * @classname: Class to search
+ * @name: name of the class_device
+ */
+struct sysfs_class_device *sysfs_open_class_device_by_name
+ (unsigned char *classname, unsigned char *name)
+{
+ struct sysfs_class *class = NULL;
+ struct sysfs_class_device *cdev = NULL, *rcdev = NULL;
+
+ if (classname == NULL || name == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ class = sysfs_open_class(classname);
+ if (class == NULL) {
+ dprintf("Error opening class %s\n", classname);
+ return NULL;
+ }
+
+ cdev = sysfs_get_class_device(class, name);
+ if (cdev == NULL) {
+ dprintf("Error getting class device %s from class %s\n",
+ name, classname);
+ sysfs_close_class(class);
+ return NULL;
+ }
+
+ rcdev = sysfs_open_class_device(cdev->directory->path);
+ if (rcdev == NULL) {
+ dprintf("Error getting class device %s from class %s\n",
+ name, classname);
+ sysfs_close_class(class);
+ return NULL;
+ }
+ sysfs_close_class(class);
+
+ return rcdev;
+}
+
+
+/**
+ * sysfs_get_classdev_attributes: returns a dlist of attributes for
+ * the requested class_device
+ * @cdev: sysfs_class_dev for which attributes are needed
+ * returns a dlist of attributes if exists, NULL otherwise
+ */
+struct dlist *sysfs_get_classdev_attributes(struct sysfs_class_device *cdev)
+{
+ if (cdev == NULL || cdev->directory == NULL)
+ return NULL;
+
+ return (cdev->directory->attributes);
+}
diff --git a/lib/sysfs_device.c b/lib/sysfs_device.c
index c68a987..7e18e23 100644
--- a/lib/sysfs_device.c
+++ b/lib/sysfs_device.c
@@ -331,3 +331,16 @@ struct sysfs_root_device *sysfs_open_root_device(const unsigned char *name)
return root;
}
+
+/**
+ * sysfs_get_device_attributes: returns a dlist of attributes corresponding to
+ * the specific device
+ * @device: struct sysfs_device * for which attributes are to be returned
+ */
+struct dlist *sysfs_get_device_attributes(struct sysfs_device *device)
+{
+ if (device == NULL || device->directory == NULL)
+ return NULL;
+
+ return (device->directory->attributes);
+}
diff --git a/lib/sysfs_dir.c b/lib/sysfs_dir.c
index c75193e..4c271cc 100644
--- a/lib/sysfs_dir.c
+++ b/lib/sysfs_dir.c
@@ -28,7 +28,7 @@
*/
static void sysfs_del_attribute(void *attr)
{
- sysfs_close_attribute((struct sysfs_attribute *)attr);
+ sysfs_close_attribute((struct sysfs_attribute *)attr);
}
/**
@@ -36,7 +36,7 @@ static void sysfs_del_attribute(void *attr)
*/
static void sysfs_del_link(void *ln)
{
- sysfs_close_link((struct sysfs_link *)ln);
+ sysfs_close_link((struct sysfs_link *)ln);
}
/**
@@ -44,7 +44,7 @@ static void sysfs_del_link(void *ln)
*/
static void sysfs_del_directory(void *dir)
{
- sysfs_close_directory((struct sysfs_directory *)dir);
+ sysfs_close_directory((struct sysfs_directory *)dir);
}
/**
diff --git a/lib/sysfs_driver.c b/lib/sysfs_driver.c
index 04b2b17..c1a6268 100644
--- a/lib/sysfs_driver.c
+++ b/lib/sysfs_driver.c
@@ -86,3 +86,31 @@ struct sysfs_driver *sysfs_open_driver(const unsigned char *path)
return driver;
}
+
+/**
+ * sysfs_get_driver_attributes: gets list of attributes for the given driver
+ * @driver: sysfs_driver for which attributes are required
+ * returns a dlist of attributes corresponding to the driver if present
+ * NULL otherwise
+ */
+struct dlist *sysfs_get_driver_attributes(struct sysfs_driver *driver)
+{
+ if (driver == NULL || driver->directory == NULL)
+ return NULL;
+
+ return(driver->directory->attributes);
+}
+
+/**
+ * sysfs_get_driver_links: gets list of links from the given driver
+ * @driver: sysfs_driver for which links list is required
+ * returns a dlist of links corresponding to the driver if present
+ * NULL otherwise
+ */
+struct dlist *sysfs_get_driver_links(struct sysfs_driver *driver)
+{
+ if (driver == NULL || driver->directory == NULL)
+ return NULL;
+
+ return(driver->directory->links);
+}
diff --git a/lib/sysfs_utils.c b/lib/sysfs_utils.c
index d4c085b..16a2d77 100644
--- a/lib/sysfs_utils.c
+++ b/lib/sysfs_utils.c
@@ -154,3 +154,79 @@ int sysfs_get_link(const unsigned char *path, unsigned char *target, size_t len)
return 0;
}
+
+
+/**
+ * sysfs_del_name: free function for sysfs_open_subsystem_list
+ * @name: memory area to be freed
+ */
+void sysfs_del_name(void *name)
+{
+ free(name);
+}
+
+
+/**
+ * sysfs_close_list: generic list free routine
+ * @list: dlist to free
+ * Returns nothing
+ */
+void sysfs_close_list(struct dlist *list)
+{
+ if (list != NULL)
+ dlist_destroy(list);
+}
+
+/**
+ * sysfs_open_subsystem_list: gets a list of all supported "name" subsystem
+ * details from the system
+ * @name: name of the subsystem, eg., "bus", "class", "devices"
+ * Returns a dlist of supported names or NULL if subsystem not supported
+ */
+struct dlist *sysfs_open_subsystem_list(unsigned char *name)
+{
+ unsigned char sysfs_path[SYSFS_PATH_MAX], *subsys_name = NULL;
+ struct sysfs_directory *dir = NULL, *cur = NULL;
+ struct dlist *list = NULL;
+
+ if (name == NULL)
+ return NULL;
+
+ if (sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX) != 0) {
+ dprintf("Error getting sysfs mount point\n");
+ return NULL;
+ }
+
+ strcat(sysfs_path, name);
+ dir = sysfs_open_directory(sysfs_path);
+ if (dir == NULL) {
+ dprintf("Error opening sysfs_directory at %s\n", sysfs_path);
+ return NULL;
+ }
+
+ if (sysfs_read_directory(dir) != 0) {
+ dprintf("Error reading sysfs_directory at %s\n", sysfs_path);
+ sysfs_close_directory(dir);
+ return NULL;
+ }
+
+ if (dir->subdirs != NULL) {
+ list = dlist_new_with_delete(SYSFS_NAME_LEN,
+ sysfs_del_name);
+ if (list == NULL) {
+ dprintf("Error creating list\n");
+ sysfs_close_directory(dir);
+ return NULL;
+ }
+
+ dlist_for_each_data(dir->subdirs, cur,
+ struct sysfs_directory) {
+ subsys_name = (char *)calloc(1, SYSFS_NAME_LEN);
+ strcpy(subsys_name, cur->name);
+ dlist_unshift(list, subsys_name);
+ }
+ }
+ sysfs_close_directory(dir);
+ return list;
+}
+