summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormananth <mananth>2003-10-15 12:13:24 +0000
committermananth <mananth>2003-10-15 12:13:24 +0000
commit079fd53e745babf94eda3dd3aa6b79f8a7872aa4 (patch)
treebec5c404f3d4db1702b41b072f7ef1dc1d7e7032
parent9823fffa72ad2b296ef9e223635985718f7e9939 (diff)
downloadsysfsutils-079fd53e745babf94eda3dd3aa6b79f8a7872aa4.tar.gz
Added function to open a driver by name
-rw-r--r--ChangeLog6
-rw-r--r--include/libsysfs.h2
-rw-r--r--lib/sysfs_driver.c107
3 files changed, 114 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index c7898ce..6779aac 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,10 @@
+09/11/2003 - Ananth Mavinakayanahalli <ananth@in.ibm.com>
+ * Added sysfs_open_driver_by_name() to open a driver and
+ its device, given the driver name
+
09/09/2003 - Ananth Mavinakayanahalli <ananth@in.ibm.com>
- * Added sysfs_find_device_class to find what class a
+ * Added sysfs_find_device_class() to find what class a
device is on
09/05/2003 - Ananth Mavinakayanahalli <ananth@in.ibm.com>
diff --git a/include/libsysfs.h b/include/libsysfs.h
index 46d5a11..07a8603 100644
--- a/include/libsysfs.h
+++ b/include/libsysfs.h
@@ -174,6 +174,8 @@ 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);
+extern struct sysfs_driver *sysfs_open_driver_by_name
+ (unsigned char *drv_name, unsigned char *bus, size_t bsize);
/* generic sysfs device access */
extern void sysfs_close_root_device(struct sysfs_root_device *root);
diff --git a/lib/sysfs_driver.c b/lib/sysfs_driver.c
index c1a6268..63fef1f 100644
--- a/lib/sysfs_driver.c
+++ b/lib/sysfs_driver.c
@@ -23,8 +23,14 @@
#include "libsysfs.h"
#include "sysfs.h"
+void sysfs_close_drv_dev(void *device)
+{
+ sysfs_close_device((struct sysfs_device *)device);
+}
+
/**
* sysfs_close_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)
@@ -41,6 +47,23 @@ void sysfs_close_driver(struct sysfs_driver *driver)
}
}
+/**
+ * sysfs_close_drv: closes driver and deletes device lists too
+ * @driver: driver to close
+ */
+void sysfs_close_drv(struct sysfs_driver *driver)
+{
+ if (driver != NULL) {
+ if (driver->devices != NULL)
+ dlist_destroy(driver->devices);
+ if (driver->directory != NULL)
+ sysfs_close_directory(driver->directory);
+ free(driver);
+ }
+}
+
+
+
/**
* alloc_driver: allocates and initializes driver
* returns struct sysfs_driver with success and NULL with error.
@@ -114,3 +137,87 @@ struct dlist *sysfs_get_driver_links(struct sysfs_driver *driver)
return(driver->directory->links);
}
+
+/**
+ * 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
+ * NOTE: Need to call sysfs_close_drv to free up memory
+ * returns struct sysfs_driver if found, NULL otherwise
+ */
+struct sysfs_driver *sysfs_open_driver_by_name(unsigned char *drv_name,
+ unsigned char *bus, size_t bsize)
+{
+ struct dlist *buslist = NULL, *drivers = NULL, *devices = NULL;
+ struct sysfs_driver *driver = NULL;
+ struct sysfs_device *device = NULL;
+ struct sysfs_link *curlink = NULL;
+ char path[SYSFS_PATH_MAX], fullpath[SYSFS_PATH_MAX],
+ *curbus = NULL, *curdrv = NULL;
+
+ if (drv_name == NULL || bus == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ memset(path, 0, SYSFS_PATH_MAX);
+ memset(fullpath, 0, SYSFS_PATH_MAX);
+ buslist = sysfs_open_subsystem_list(SYSFS_BUS_DIR);
+ if (buslist != NULL) {
+ dlist_for_each_data(buslist, curbus, char) {
+ strcpy(path, SYSFS_BUS_DIR);
+ strcat(path, "/");
+ strcat(path, curbus);
+ strcat(path, "/drivers/");
+ drivers = sysfs_open_subsystem_list(path);
+ if (drivers != NULL) {
+ dlist_for_each_data(drivers, curdrv, char) {
+ if (strcmp(drv_name, curdrv) == 0) {
+ strncpy(bus, curbus, bsize);
+ strcat(path, curdrv);
+ sysfs_close_list(drivers);
+ sysfs_close_list(buslist);
+ goto open_device;
+ }
+ }
+ sysfs_close_list(drivers);
+ }
+ }
+ sysfs_close_list(buslist);
+ return NULL;
+ }
+
+open_device:
+ if (sysfs_get_mnt_path(fullpath, SYSFS_PATH_MAX) != 0) {
+ dprintf("Error getting sysfs mount path\n");
+ return NULL;
+ }
+ strcat(fullpath, path);
+ driver = sysfs_open_driver(fullpath);
+ if (driver == NULL) {
+ dprintf("Driver %s not found\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_drv(driver);
+ return NULL;
+ }
+ strcpy(device->driver_name, drv_name);
+ if (driver->devices == NULL)
+ driver->devices = dlist_new_with_delete
+ (sizeof(struct sysfs_device),
+ sysfs_close_drv_dev);
+ dlist_unshift(driver->devices, device);
+ }
+ }
+ return driver;
+}
+