aboutsummaryrefslogtreecommitdiff
path: root/sysfsutils/lib/sysfs_module.c
diff options
context:
space:
mode:
Diffstat (limited to 'sysfsutils/lib/sysfs_module.c')
-rw-r--r--sysfsutils/lib/sysfs_module.c279
1 files changed, 279 insertions, 0 deletions
diff --git a/sysfsutils/lib/sysfs_module.c b/sysfsutils/lib/sysfs_module.c
new file mode 100644
index 0000000..375de1a
--- /dev/null
+++ b/sysfsutils/lib/sysfs_module.c
@@ -0,0 +1,279 @@
+/*
+ * sysfs_module.c
+ *
+ * Generic module utility functions for libsysfs
+ *
+ * Copyright (C) IBM Corp. 2003-2005
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include "libsysfs.h"
+#include "sysfs.h"
+
+/**
+ * mod_name_equal: compares modules' name
+ * @a: module_name looking for
+ * @b: sysfs_module being compared
+ */
+static int mod_name_equal(void *a, void *b)
+{
+ if (a == NULL || b == NULL)
+ return 0;
+
+ if (strcmp(((char *)a), ((struct sysfs_module *)b)->name) == 0)
+ return 1;
+
+ return 0;
+}
+
+/**
+ * sysfs_close_module: closes a module.
+ * @module: sysfs_module device to close.
+ */
+void sysfs_close_module(struct sysfs_module *module)
+{
+ /*
+ * since both parms and sections are attribs _under_ the
+ * subdir of module->directory, they will get closed by
+ * this single call
+ */
+ if (module != NULL) {
+ if (module->attrlist != NULL)
+ dlist_destroy(module->attrlist);
+ if (module->parmlist != NULL)
+ dlist_destroy(module->parmlist);
+ if (module->sections != NULL)
+ dlist_destroy(module->sections);
+ free(module);
+ }
+}
+
+/**
+ * alloc_module: callocs and initializes new module struct.
+ * returns sysfs_module or NULL.
+ */
+static struct sysfs_module *alloc_module(void)
+{
+ return (struct sysfs_module *)calloc(1, sizeof(struct sysfs_module));
+}
+
+/**
+ * sysfs_open_module_path: Opens and populates the module struct
+ * @path: path to module.
+ * returns struct sysfs_module with success and NULL with error.
+ */
+struct sysfs_module *sysfs_open_module_path(const char *path)
+{
+ struct sysfs_module *mod = NULL;
+
+ if (path == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
+ if ((sysfs_path_is_dir(path)) != 0) {
+ dprintf("%s is not a valid path to a module\n", path);
+ return NULL;
+ }
+ mod = alloc_module();
+ if (mod == NULL) {
+ dprintf("calloc failed\n");
+ return NULL;
+ }
+ if ((sysfs_get_name_from_path(path, mod->name, SYSFS_NAME_LEN)) != 0) {
+ errno = EINVAL;
+ dprintf("Error getting module name\n");
+ sysfs_close_module(mod);
+ return NULL;
+ }
+
+ safestrcpy(mod->path, path);
+ if ((sysfs_remove_trailing_slash(mod->path)) != 0) {
+ dprintf("Invalid path to module %s\n", mod->path);
+ sysfs_close_module(mod);
+ return NULL;
+ }
+
+ return mod;
+}
+
+/**
+ * sysfs_open_module: opens specific module on a system
+ * returns sysfs_module structure with success or NULL with error.
+ */
+struct sysfs_module *sysfs_open_module(const char *name)
+{
+ struct sysfs_module *mod = NULL;
+ char modpath[SYSFS_PATH_MAX];
+
+ if (name == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ memset(modpath, 0, SYSFS_PATH_MAX);
+ if ((sysfs_get_mnt_path(modpath, SYSFS_PATH_MAX)) != 0) {
+ dprintf("Sysfs not supported on this system\n");
+ return NULL;
+ }
+
+ safestrcat(modpath, "/");
+ safestrcat(modpath, SYSFS_MODULE_NAME);
+ safestrcat(modpath, "/");
+ safestrcat(modpath, name);
+
+ if ((sysfs_path_is_dir(modpath)) != 0) {
+ dprintf("Module %s not found on the system\n", name);
+ return NULL;
+ }
+
+ mod = alloc_module();
+ if (mod == NULL) {
+ dprintf("calloc failed\n");
+ return NULL;
+ }
+ safestrcpy(mod->name, name);
+ safestrcpy(mod->path, modpath);
+ if ((sysfs_remove_trailing_slash(mod->path)) != 0) {
+ dprintf("Invalid path to module %s\n", mod->path);
+ sysfs_close_module(mod);
+ return NULL;
+ }
+
+ return mod;
+}
+
+/**
+ * sysfs_get_module_attributes: returns a dlist of attributes for
+ * the requested sysfs_module
+ * @cdev: sysfs_module for which attributes are needed
+ * returns a dlist of attributes if exists, NULL otherwise
+ */
+struct dlist *sysfs_get_module_attributes(struct sysfs_module *module)
+{
+ if (module == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
+ return get_dev_attributes_list(module);
+}
+
+/**
+ * sysfs_get_module_attr: searches module's attributes by name
+ * @module: module to look through
+ * @name: attribute name to get
+ * returns sysfs_attribute reference with success or NULL with error
+ */
+struct sysfs_attribute *sysfs_get_module_attr
+ (struct sysfs_module *module, const char *name)
+{
+ if (module == NULL || name == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ return get_attribute(module, (char *)name);
+}
+
+/**
+ * sysfs_get_module_parms: Get modules list of parameters
+ * @module: sysfs_module whose parmameter list is required
+ * Returns dlist of parameters on SUCCESS and NULL on error
+ */
+struct dlist *sysfs_get_module_parms(struct sysfs_module *module)
+{
+ char ppath[SYSFS_PATH_MAX];
+
+ if (module == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
+ memset(ppath, 0, SYSFS_PATH_MAX);
+ safestrcpy(ppath, module->path);
+ safestrcat(ppath,"/");
+ safestrcat(ppath, SYSFS_MOD_PARM_NAME);
+
+ return (get_attributes_list(module->parmlist, ppath));
+}
+
+/**
+ * sysfs_get_module_sections: Get the set of sections for this module
+ * @module: sysfs_module whose list of sections is required
+ * Returns dlist of sections on SUCCESS and NULL on error
+ */
+struct dlist *sysfs_get_module_sections(struct sysfs_module *module)
+{
+ char ppath[SYSFS_PATH_MAX];
+
+ if (module == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ memset(ppath, 0, SYSFS_PATH_MAX);
+ safestrcpy(ppath, module->path);
+ safestrcat(ppath,"/");
+ safestrcat(ppath, SYSFS_MOD_SECT_NAME);
+
+ return (get_attributes_list(module->sections, ppath));
+}
+
+/**
+ * sysfs_get_module_parm:
+ * @module: sysfs_module to look through
+ * @parm: name of the parameter to look for
+ * Returns sysfs_attribute * on SUCCESS and NULL on error
+ */
+struct sysfs_attribute *sysfs_get_module_parm
+ (struct sysfs_module *module, const char *parm)
+{
+ struct dlist *parm_list = NULL;
+
+ if (module == NULL || parm == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ parm_list = sysfs_get_module_parms(module);
+ if (parm_list == NULL)
+ return NULL;
+
+ return (struct sysfs_attribute *)dlist_find_custom(parm_list,
+ (void *)parm, mod_name_equal);
+}
+
+/**
+ * sysfs_get_module_section
+ * @module: sysfs_module to look through
+ * @section: name of the section to look for
+ * Returns sysfs_attribute * on SUCCESS and NULL on error
+ */
+struct sysfs_attribute *sysfs_get_module_section
+ (struct sysfs_module *module, const char *section)
+{
+ struct dlist *sect_list = NULL;
+
+ if (module == NULL || section == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ sect_list = sysfs_get_module_sections(module);
+ if (sect_list == NULL)
+ return NULL;
+
+ return (struct sysfs_attribute *)dlist_find_custom(sect_list,
+ (void *)section, mod_name_equal);
+}