diff options
Diffstat (limited to 'libsysfs/sysfs_module.c')
-rw-r--r-- | libsysfs/sysfs_module.c | 279 |
1 files changed, 279 insertions, 0 deletions
diff --git a/libsysfs/sysfs_module.c b/libsysfs/sysfs_module.c new file mode 100644 index 0000000..375de1a --- /dev/null +++ b/libsysfs/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); +} |