summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormananth <mananth>2003-11-06 06:30:45 +0000
committermananth <mananth>2003-11-06 06:30:45 +0000
commit2412af53b271f998713307aea1e76d744fff733d (patch)
treecc3af77f18155953b572db201ef46090263f31a1
parentd874adee536019b3565f5b6620c30bc27c2b799b (diff)
downloadsysfsutils_0_3_0.tar.gz
Final set of patches for release 0.3.0sysfsutils_0_3_0
-rw-r--r--ChangeLog12
-rw-r--r--Makefile.in2
-rw-r--r--NEWS9
-rw-r--r--README10
-rw-r--r--TODO10
-rw-r--r--cmd/systool.c6
-rw-r--r--docs/libsysfs.txt223
-rw-r--r--include/libsysfs.h31
-rw-r--r--lib/sysfs_bus.c46
-rw-r--r--lib/sysfs_class.c239
-rw-r--r--lib/sysfs_device.c269
-rw-r--r--lib/sysfs_driver.c169
-rw-r--r--lib/sysfs_utils.c23
-rw-r--r--test/Makefile.am8
-rw-r--r--test/Makefile.in62
-rw-r--r--test/get_class_dev.c (renamed from test/get_dev_class.c)38
-rw-r--r--test/get_dev_bus.c53
-rw-r--r--test/get_device.c30
-rw-r--r--test/write_attr.c85
-rw-r--r--test/write_attr_2.c27
20 files changed, 580 insertions, 772 deletions
diff --git a/ChangeLog b/ChangeLog
index 785b5a2..3dedc31 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,16 @@
+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)
+ when listing the class device
+ * Added bus to struct sysfs_device
+ * Modified "read_attr" functions for device/driver/classdev
+ to return a sysfs_attribute
+ * Modified test functions, added a test function to
+ demonstrate usage of "write" attribute functions
+ * Updated libsysfs.txt to reflect latest updates to the
+ library
+
10/27/2003 - Daniel Stekloff <dsteklof@us.ibm.com>
* Fixed bug in sysfs_get_name_from_path()
* Added code to check if SYSFS_PATH environment variable
diff --git a/Makefile.in b/Makefile.in
index 0510d3e..174f75c 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -31,7 +31,7 @@ localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
-includedir = @includedir@
+includedir = /usr/include/sysfs
oldincludedir = /usr/include
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
diff --git a/NEWS b/NEWS
index 7061732..a633d0c 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,15 @@
Version History:
---------------
+ 0.3.0 - Released November 6, 2003
+ * Added support to build shared library
+ * Added patch to consider "block" as a class
+ * Corrected "write" attribute functions
+ * Added more "find/open" functions
+ * Added pci name decode support
+ * Added "test" functions to demonstrate API usage
+ * Lots of other updates resulting from user feedback
+
0.2.0 - Released August 29, 2003
* Added autoconf configuration support.
* Added Eric J Bohm's dlist patch.
diff --git a/README b/README
index 5fc2d9a..a678a4e 100644
--- a/README
+++ b/README
@@ -31,8 +31,16 @@ This package currently includes:
2. How to Install
-----------------
-Use make to create the library and the commands.
+Run the "configure" script to generate Makefiles. Use "make" to build the
+library and utilities. Use "make install" to install the binaries and the
+header files. "make uninstall" will delete all installed binaries and
+header files.
+The header files are installed in /usr/include/sysfs by default. In case
+a different path is desired, specify "includedir=xxx" while running configure
+as in
+
+./configure --includedir="path for header installs"
3. Licenses
-----------
diff --git a/TODO b/TODO
index 89522c8..8c9d495 100644
--- a/TODO
+++ b/TODO
@@ -1,25 +1,17 @@
Library:
--------
-- Make bus lists of devices using topology.
- Rework debugging error messages and look into better logging on error.
- Need to properly set errno.
-- Add more "find"/utility functions.
-- Add subsystem specific support for PCI, SCSI, USB, etc
+- Code optimization: open()/read()/close() only when required.
Commands:
---------
-- Add capability to just take a device as an argument.
- Add topology tree view.
- Need to clean up error messages.
- Clean up how attribute values are printed.
-- Add capability to use of attribute "write" functions.
-- Use sysfs_root_device as the base structure for listing from the
- devices subsystem.
-- Add subsystem specific support. Commands can, for example, do PCI id lookup.
Docs:
-----
-- Update libsysfs.txt with changes/additions to the library.
- Create man pages for commands and for library.
Test:
diff --git a/cmd/systool.c b/cmd/systool.c
index 1da9018..a2a6bbe 100644
--- a/cmd/systool.c
+++ b/cmd/systool.c
@@ -446,9 +446,11 @@ void show_class_device(struct sysfs_class_device *dev, int level)
if (attributes != NULL)
show_attributes(attributes, (level+4));
}
- if (dev->sysdevice != NULL && (show_options & SHOW_DEVICES))
+ if (dev->sysdevice != NULL && (show_options & (SHOW_DEVICES |
+ SHOW_ALL_ATTRIB_VALUES)))
show_device(dev->sysdevice, (level+4));
- if (dev->driver != NULL && (show_options & SHOW_DRIVERS))
+ if (dev->driver != NULL && (show_options & (SHOW_DRIVERS |
+ SHOW_ALL_ATTRIB_VALUES)))
show_driver(dev->driver, (level+4));
}
}
diff --git a/docs/libsysfs.txt b/docs/libsysfs.txt
index 7b8f890..bfbe491 100644
--- a/docs/libsysfs.txt
+++ b/docs/libsysfs.txt
@@ -3,7 +3,7 @@
=========================================
Version: 0.3.0
-October 22, 2003
+November 04, 2003
Contents
--------
@@ -31,14 +31,15 @@ Contents
6.4 Class Functions
6.5 Device Functions
6.6 Driver Functions
-7. Usage
-8. Conclusion
+7. Navigating a dlist
+8. Usage
+9. Conclusion
1. Introduction
---------------
-Libsysfs' purpose is to provide a consistant and stable interface for
+Libsysfs' purpose is to provide a consistent and stable interface for
querying system device information exposed through the sysfs filesystem.
The library implements functions for querying filesystem information,
such as reading directories and files. It also contains routines for
@@ -95,7 +96,7 @@ development that need access to sysfs and system devices. Udev, on a
hotplug event, must take a sysfs device path and create a /dev node. Our
diagnostic client needs to list all system devices. Finally, our Error
Log Analysis piece is required to retrieve VPD information for a
-failing device. We devided to create a single library interface rather
+failing device. We divided to create a single library interface rather
than having these separate applications create their own accesses to
sysfs involving reading directories and files.
@@ -128,7 +129,11 @@ and devices, here's some examples:
#define SYSFS_FSTYPE_NAME "sysfs"
#define SYSFS_PROC_MNTS "/proc/mounts"
#define SYSFS_BUS_DIR "/bus"
+#define SYSFS_BUS_NAME "bus"
#define SYSFS_CLASS_DIR "/class"
+#define SYSFS_CLASS_DIR "/class"
+#define SYSFS_BLOCK_DIR "/block"
+#define SYSFS_BLOCK_NAME "block"
#define SYSFS_DEVICES_DIR "/devices"
#define SYSFS_DEVICES_NAME "devices"
#define SYSFS_DRIVERS_DIR "/drivers"
@@ -260,19 +265,20 @@ struct sysfs_class_device {
struct sysfs_device *sysdevice; /* NULL if virtual */
struct sysfs_driver *driver; /* NULL if not implemented */
unsigned char name[SYSFS_NAME_LEN];
+ unsigned char classname[SYSFS_NAME_LEN];
unsigned char path[SYSFS_PATH_MAX];
/* for internal use only */
struct sysfs_directory *directory;
};
-A class device isn't the same as a sysfs_device, it's specific to the class
-in which it belongs. The class device structure contains the sysfs_device
-reference and that device's driver reference (if any). It also contains
-the name of the class device - like "eth0", its sysfs directory information
-including links and attributes (for internal use only). The following
-function may be used by applications to retrieve data from the
-sysfs_directory structure:
+A class device isn't the same as a sysfs_device, it's specific to the class in
+which it belongs. The class device structure contains the name of the class
+the class device belongs to, its sysfs_device reference and that device's
+driver reference (if any). It also contains the name of the class device
+- like "eth0", its sysfs directory information including links and
+attributes (for internal use only). The following function may be
+used by applications to retrieve data from the sysfs_directory structure:
struct dlist *sysfs_get_classdev_attributes(struct sysfs_class_device *cdev);
@@ -280,7 +286,7 @@ struct dlist *sysfs_get_classdev_attributes(struct sysfs_class_device *cdev);
5.4 Root Device Data Structure
------------------------------
-Device heirarchies in sysfs are represented under the /sys/devices directory
+Device hierarchies in sysfs are represented under the /sys/devices directory
structure. Sysfs devices typically spawn off from base devices which are
represented by a sysfs_root_device.
@@ -310,7 +316,9 @@ struct sysfs_device {
struct dlist *children;
unsigned char name[SYSFS_NAME_LEN];
unsigned char bus_id[SYSFS_NAME_LEN];
+ unsigned char bus[SYSFS_NAME_LEN];
unsigned char driver_name[SYSFS_NAME_LEN];
+ unsigned char path[SYSFS_PATH_MAX];
/* for internal use only */
struct sysfs_directory *directory;
@@ -318,10 +326,11 @@ struct sysfs_device {
The sysfs_device structure contains a "parent" pointer, a list of child
devices, if any, device's directory, its bus id - which is the name of
-device's directory, and a its driver name. The device structure also
-contains a directory structure, which contains a list of the device's
-attributes (for internal use only). The following functions may be
-used to obtain information from sysfs_directory structure:
+device's directory, the bus name on which this device is registered and
+its driver name. The device structure also contains the absolute path
+to the device and a directory structure, which contains a list of the
+device's attributes (for internal use only). The following functions
+may be used to obtain information from sysfs_directory structure:
struct sysfs_attribute *sysfs_get_device_attribute(struct sysfs_device *dev,
const unsigned char *name)
@@ -632,7 +641,7 @@ Prototype: void sysfs_close_link(struct sysfs_link *ln)
-------------------------------------------------------------------------------
Name: sysfs_get_directory_link
-Description: Function walks the list of links for the giveni sysfs directory
+Description: Function walks the list of links for the given sysfs directory
and returns the sysfs_link structure for the specified link
name.
@@ -879,24 +888,6 @@ Prototype: struct sysfs_device *sysfs_open_bus_device
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-Name: sysfs_find_device_bus
-
-Description: Given the name of a device, this function finds the name of the
- bus the device is on.
-
-Arguments: const unsigned char *dev_id Name of the device to look for
- unsigned char *busname Buffer to return the bus name
- size_t bsize Size of the "busname" buffer
-
-Returns: 0 with success.
- -1 with error. Errno will be set with error, returning
- - EINVAL for invalid arguments
-
-Prototype: int sysfs_find_device_bus(const unsigned char *dev_id,
- unsigned char *busname, size_t bsize)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
Name: sysfs_find_driver_bus
Description: Given the name of a driver, this function finds the name of the
@@ -957,7 +948,7 @@ Prototype: void sysfs_close_class(struct sysfs_class *class);
Name: sysfs_open_class_device
Description: Function opens up one of the class devices represented in
- sysfs in sysfs/class/"class"/ directory. It retunrs a
+ sysfs in sysfs/class/"class"/ directory. It returns a
sysfs_class_device structure.
Arguments: const unsigned char *path Path to class device
@@ -1011,8 +1002,7 @@ Description: Given the name of the class on which to look for, this function
return from this function has to be closed by calling
sysfs_close_class_device().
2. Class this device belongs to must be known prior to calling
- this function. Use sysfs_find_device_class() to determine
- the class name.
+ this function.
Arguments: const unsigned char *classname Class on which to search
unsigned char *name Class device "name" to open
@@ -1043,29 +1033,11 @@ Prototype: struct dlist *sysfs_get_classdev_attributes
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-Name: sysfs_find_device_class
-
-Description: Given the name of a class device, this function finds the class
- the device is located on.
-
-Arguments: const unsigned char *bus_id Class device to look for
- unsigned char *classname Buffer to return class name
- size_t bsize Size of buffer "classname"
-
-Returns: 0 with success.
- -1 with error. Errno will be set with error, returning
- - EINVAL for invalid arguments
-
-Prototype: int sysfs_find_device_class(const unsigned char *bus_id,
- unsigned char *classname, size_t bsize)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
Name: sysfs_get_classdev_attr
Description: Searches supplied class device's attributes by name and returns
the attribute.
-
+
Arguments: struct sysfs_class_device *clsdev Device to search
const unsigned char *name Attribute name to find
@@ -1078,23 +1050,27 @@ Prototype: struct sysfs_attribute *sysfs_get_classdev_attr
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-Name: sysfs_write_classdev_attr
+Name: sysfs_open_classdev_attr
-Description: Function takes as arguments, a class device, an attribute of
- the class device to change, the value to change to and tries
- to write the new value to the specified attribute.
+Description: Function takes as arguments, a the name of the class, the class
+ device name and the name of the required attribute.
-Arguements: unsigned char *dev Class device to look for
- unsigned char *attrib Name of the attribute to modify
- unsigned char *value New value for "attrib"
- size_t len Length of "value"
+ NOTE:
+ 1. The struct sysfs_attribute * obtained upon successful
+ return from this function has to be closed by making
+ a call to sysfs_close_attribute()
-Returns: 0 with success.
- -1 with error. Errno will be set with error, returning
+Arguments: unsigned char *classname Class name on which to search
+ unsigned char *dev Name of the class device
+ unsigned char *attrib Attribute to open
+
+Returns: struct sysfs_attribute * with success.
+ NULL with error. Errno will be set with error, returning
- EINVAL for invalid arguments
-Prototype: int sysfs_write_classdev_attr(unsigned char *dev,
- unsigned char *attrib, unsigned char *value, size_t len)
+Prototype: struct sysfs_attribute *sysfs_write_classdev_attr
+ (const unsigned char *classname, const unsigned char *dev,
+ const unsigned char *attrib)
-------------------------------------------------------------------------------
@@ -1208,8 +1184,7 @@ Description: Given the name of the bus on which to look for, this function
from this function has to be closed by calling
sysfs_close_device().
2. Bus on which to look for this device should be known prior
- to calling this function. Use sysfs_find_device_bus()
- to determine this.
+ to calling this function.
Arguments: const unsigned char *bus_id Device to look for
const unsigned char *bus Bus on which to search
@@ -1225,23 +1200,27 @@ Prototype: struct sysfs_device *sysfs_open_device_by_id
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-Name: sysfs_write_device_attr
+Name: sysfs_open_device_attr
-Description: Function takes as arguments, a device, an attribute of the device
- to change, the value to change to and tries to write the new
- value to the specified attribute.
+Description: Function takes as arguments, the bus on which to search for a
+ device, and an attribute of the device to open.
-Arguements: unsigned char *dev Device to look for
- unsigned char *attrib Name of the attribute to modify
- unsigned char *value New value for "attrib"
- size_t len Length of "value"
+ NOTE:
+ 1. The struct sysfs_attribute * obtained upon successful
+ return from this function has to be closed by making
+ a call to sysfs_close_attribute()
-Returns: 0 with success.
- -1 with error. Errno will be set with error, returning
+Arguments: unsigned char *bus Bus on which to search
+ unsigned char *bus_id Device to look for
+ unsigned char *attrib Name of the attribute to open
+
+Returns: struct sysfs_attribute * with success.
+ NULL with error. Errno will be set with error, returning
- EINVAL for invalid arguments
-Prototype: int sysfs_write_device_attr(unsigned char *dev,
- unsigned char *attrib, unsigned char *value, size_t len)
+Prototype: struct sysfs_attribute *sysfs_open_device_attr
+ (const unsigned char *bus, const unsigned char *bus_id,
+ const unsigned char *attrib)
-------------------------------------------------------------------------------
@@ -1365,27 +1344,75 @@ Prototype: struct dlist *sysfs_get_driver_links
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-Name: sysfs_write_driver_attr
+Name: sysfs_open_driver_attr
-Description: Function takes as arguments, a device, an attribute of the driver
- to change, the value to change to and tries to write the new
- value to the specified attribute.
+Description: Function takes as arguments, the bus the driver is registered
+ on, the driver name and the name of the attribute to open.
+
+ NOTE:
+ 1. The struct sysfs_attribute * obtained upon successful
+ return from this function has to be closed by making
+ a call to sysfs_close_attribute()
-Arguements: unsigned char *drv Driver to look for
- unsigned char *attrib Name of the attribute to modify
- unsigned char *value New value for "attrib"
- size_t len Length of "value"
+Arguments: unsigned char *bus Bus on which driver is present
+ unsigned char *drv Driver to look for
+ unsigned char *attrib Name of the attribute to open
-Returns: 0 with success.
- -1 with error. Errno will be set with error, returning
+Returns: struct sysfs_attribute * with success.
+ NULL with error. Errno will be set with error, returning
- EINVAL for invalid arguments
-Prototype: int sysfs_write_driver_attr(unsigned char *drv,
- unsigned char *attrib, unsigned char *value, size_t len)
+Prototype: struct sysfs_attribute *sysfs_open_driver_attr
+ (const unsigned char *bus, const unsigned char *drv,
+ const unsigned char *attrib)
+-------------------------------------------------------------------------------
+
+
+7. Navigating a dlist
+---------------------
+
+Libsysfs uses (yet another) list implementation thanks to Eric J Bohm.
+
+Some library functions return a dlist of devices/drivers/attributes, etc.
+To navigate the list returned the macro "dlist_for_each_data" is to be used.
+
+------------------------------------------------------------------------------
+Function/Macro name: dlist_for_each_data
+
+Description: Walk the given list, returning a known data type/
+ structure in each iteration.
+
+Arguments: struct dlist *list List pointer
+ data_iterator Data type/structure variable
+ contained in the list
+ datatype Data type/structure contained
+ in the list
+
+Returns: On each iteration, "data_iterator" will contain a list
+ element of "datatype"
+
+Usage example: The function sysfs_get_classdev_attributes() returns a
+ dlist of attributes. To navigate the list:
+
+ struct sysfs_attribute *attr = NULL;
+ struct dlist *attrlist = NULL;
+ .
+ .
+ .
+ attrlist = sysfs_get_classdev_attributes
+ (struct sysfs_class_device *cdev)
+ if (attrlist != NULL) {
+ dlist_for_each_data(attrlist, attr,
+ struct sysfs_attribute) {
+ .
+ .
+ .
+ }
+ }
-------------------------------------------------------------------------------
-7. Usage
+8. Usage
--------
Accessing devices through libsysfs is supposed to mirror accessing devices
@@ -1397,7 +1424,7 @@ in the filesystem it represents. Here's a typical order of operation:
- "close" sysfs category
-8. Conclusion
+9. Conclusion
-------------
Libsysfs is meant to provide a stable application programming interface to
diff --git a/include/libsysfs.h b/include/libsysfs.h
index d9403ea..f7e989e 100644
--- a/include/libsysfs.h
+++ b/include/libsysfs.h
@@ -32,8 +32,11 @@
#define SYSFS_FSTYPE_NAME "sysfs"
#define SYSFS_PROC_MNTS "/proc/mounts"
#define SYSFS_BUS_DIR "/bus"
+#define SYSFS_BUS_NAME "bus"
#define SYSFS_CLASS_DIR "/class"
+#define SYSFS_CLASS_NAME "class"
#define SYSFS_BLOCK_DIR "/block"
+#define SYSFS_BLOCK_NAME "block"
#define SYSFS_DEVICES_DIR "/devices"
#define SYSFS_DEVICES_NAME "devices"
#define SYSFS_DRIVERS_DIR "/drivers"
@@ -85,8 +88,9 @@ struct sysfs_device {
struct dlist *children;
unsigned char name[SYSFS_NAME_LEN];
unsigned char bus_id[SYSFS_NAME_LEN];
- unsigned char path[SYSFS_PATH_MAX];
+ unsigned char bus[SYSFS_NAME_LEN];
unsigned char driver_name[SYSFS_NAME_LEN];
+ unsigned char path[SYSFS_PATH_MAX];
/* for internal use only */
struct sysfs_directory *directory;
@@ -182,10 +186,8 @@ 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 int sysfs_write_driver_attr(unsigned char *drv, unsigned char *attrib,
- unsigned char *value, size_t len);
-extern int sysfs_read_driver_attr(unsigned char *drv, unsigned char *attrib,
- unsigned char *value, size_t len);
+extern struct sysfs_attribute *sysfs_open_driver_attr(const unsigned char *bus,
+ const unsigned char *drv, const unsigned char *attrib);
/* generic sysfs device access */
extern void sysfs_close_root_device(struct sysfs_root_device *root);
@@ -198,10 +200,8 @@ extern struct sysfs_attribute *sysfs_get_device_attr
extern struct dlist *sysfs_get_device_attributes(struct sysfs_device *device);
extern struct sysfs_device *sysfs_open_device_by_id
(const unsigned char *bus_id, const unsigned char *bus, size_t bsize);
-extern int sysfs_write_device_attr(unsigned char *dev, unsigned char *attrib,
- unsigned char *value, size_t len);
-extern int sysfs_read_device_attr(unsigned char *dev, unsigned char *attrib,
- unsigned char *value, size_t len);
+extern struct sysfs_attribute *sysfs_open_device_attr(const unsigned char *bus,
+ const unsigned char *bus_id, const unsigned char *attrib);
/* generic sysfs bus access */
extern void sysfs_close_bus(struct sysfs_bus *bus);
@@ -215,8 +215,6 @@ extern struct sysfs_attribute *sysfs_get_bus_attribute(struct sysfs_bus *bus,
unsigned char *attrname);
extern struct sysfs_device *sysfs_open_bus_device(unsigned char *busname,
unsigned char *dev_id);
-extern int sysfs_find_device_bus(const unsigned char *dev_id,
- unsigned char *busname, size_t bsize);
extern int sysfs_find_driver_bus(const unsigned char *driver,
unsigned char *busname, size_t bsize);
@@ -229,17 +227,14 @@ 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
- (const unsigned char *class, unsigned char *name);
+ (const unsigned char *class, const unsigned char *name);
extern struct dlist *sysfs_get_classdev_attributes
(struct sysfs_class_device *cdev);
-extern int sysfs_find_device_class(const unsigned char *bus_id,
- unsigned char *classname, size_t bsize);
extern struct sysfs_attribute *sysfs_get_classdev_attr
(struct sysfs_class_device *clsdev, const unsigned char *name);
-extern int sysfs_write_classdev_attr(unsigned char *dev, unsigned char *attrib,
- unsigned char *value, size_t len);
-extern int sysfs_read_classdev_attr(unsigned char *dev, unsigned char *attrib,
- unsigned char *value, size_t len);
+extern struct sysfs_attribute *sysfs_open_classdev_attr
+ (const unsigned char *classname, const unsigned char *dev,
+ const unsigned char *attrib);
#ifdef __cplusplus
}
diff --git a/lib/sysfs_bus.c b/lib/sysfs_bus.c
index 19fc275..3111154 100644
--- a/lib/sysfs_bus.c
+++ b/lib/sysfs_bus.c
@@ -25,12 +25,12 @@
static void sysfs_close_dev(void *dev)
{
- sysfs_close_device((struct sysfs_device *)dev);
+ sysfs_close_device((struct sysfs_device *)dev);
}
static void sysfs_close_drv(void *drv)
{
- sysfs_close_driver((struct sysfs_driver *)drv);
+ sysfs_close_driver((struct sysfs_driver *)drv);
}
/*
@@ -424,48 +424,6 @@ struct sysfs_device *sysfs_open_bus_device(unsigned char *busname,
}
/**
- * sysfs_find_device_bus: locates the bus a device is on.
- * @dev_id: device id.
- * @busname: buffer to copy name to
- * @bsize: buffer size
- * returns 0 with success or -1 with error
- */
-int sysfs_find_device_bus(const unsigned char *dev_id, unsigned char *busname,
- size_t bsize)
-{
- unsigned char subsys[SYSFS_NAME_LEN], *bus = NULL, *curdev = NULL;
- struct dlist *buslist = NULL, *device_list = NULL;
-
- if (dev_id == NULL || busname == NULL) {
- errno = EINVAL;
- return -1;
- }
-
- strcpy(subsys, SYSFS_BUS_DIR); /* subsys = /bus */
- buslist = sysfs_open_subsystem_list(subsys);
- if (buslist != NULL) {
- dlist_for_each_data(buslist, bus, char) {
- device_list = sysfs_open_bus_devices_list(bus);
- if (device_list != NULL) {
- dlist_for_each_data(device_list,
- curdev, char) {
- if (strcmp(dev_id, curdev) == 0) {
- strncpy(busname,
- bus, bsize);
- sysfs_close_list(device_list);
- sysfs_close_list(buslist);
- return 0;
- }
- }
- sysfs_close_list(device_list);
- }
- }
- sysfs_close_list(buslist);
- }
- return -1;
-}
-
-/**
* sysfs_find_driver_bus: locates the bus the driver is on.
* @driver: name of the driver to locate
* @busname: buffer to copy name to
diff --git a/lib/sysfs_class.c b/lib/sysfs_class.c
index f44c7aa..d7521df 100644
--- a/lib/sysfs_class.c
+++ b/lib/sysfs_class.c
@@ -116,9 +116,17 @@ static struct sysfs_directory *open_class_dir(const unsigned char *name)
return NULL;
}
- strcat(classpath, SYSFS_CLASS_DIR);
- strcat(classpath, "/");
- strcat(classpath, name);
+ /*
+ * We shall now treat "block" also as a class. Hence, check here
+ * if "name" is "block" and proceed accordingly
+ */
+ if (strcmp(name, SYSFS_BLOCK_NAME) == 0) {
+ strcat(classpath, SYSFS_BLOCK_DIR);
+ } else {
+ strcat(classpath, SYSFS_CLASS_DIR);
+ strcat(classpath, "/");
+ strcat(classpath, name);
+ }
classdir = sysfs_open_directory(classpath);
if (classdir == NULL) {
errno = EINVAL;
@@ -338,46 +346,72 @@ struct sysfs_class_device *sysfs_get_class_device(struct sysfs_class *class,
}
/**
+ * get_classdev_path: given the class and a device in the class, return the
+ * absolute path to the device
+ * @classname: name of the class
+ * @clsdev: the class device
+ * @path: buffer to return path
+ * @psize: size of "path"
+ * Returns 0 on SUCCESS or -1 on error
+ */
+static int get_classdev_path(const unsigned char *classname,
+ const unsigned char *clsdev, unsigned char *path, size_t len)
+{
+ if (classname == NULL || clsdev == NULL || path == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+ if (sysfs_get_mnt_path(path, len) != 0) {
+ dprintf("Error getting sysfs mount path\n");
+ return -1;
+ }
+ if (strcmp(classname, SYSFS_BLOCK_NAME) == 0) {
+ strcat(path, SYSFS_BLOCK_DIR);
+ } else {
+ strcat(path, SYSFS_CLASS_DIR);
+ strcat(path, "/");
+ strcat(path, classname);
+ }
+ strcat(path, "/");
+ strcat(path, clsdev);
+ return 0;
+}
+
+/**
* 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
+ *
+ * NOTE:
+ * Call sysfs_close_class_device() to close the class device
*/
struct sysfs_class_device *sysfs_open_class_device_by_name
- (const unsigned char *classname, unsigned char *name)
+ (const unsigned char *classname, const unsigned char *name)
{
- struct sysfs_class *class = NULL;
- struct sysfs_class_device *cdev = NULL, *rcdev = NULL;
+ unsigned char devpath[SYSFS_PATH_MAX];
+ struct sysfs_class_device *cdev = 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);
+ memset(devpath, 0, SYSFS_PATH_MAX);
+ if ((get_classdev_path(classname, name, devpath,
+ SYSFS_PATH_MAX)) != 0) {
+ dprintf("Error getting to device %s on class %s\n",
+ name, classname);
return NULL;
}
-
- cdev = sysfs_get_class_device(class, name);
+
+ cdev = sysfs_open_class_device(devpath);
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;
+ return cdev;
}
/**
@@ -395,53 +429,6 @@ struct dlist *sysfs_get_classdev_attributes(struct sysfs_class_device *cdev)
}
/**
- * sysfs_find_device_class: locates the device the device is on
- * @bus_id: device to look for
- * @classname: buffer to copy class name to
- * @bsize: size of buffer
- * returns 0 with success and -1 with error
- */
-int sysfs_find_device_class(const unsigned char *bus_id,
- unsigned char *classname, size_t bsize)
-{
- unsigned char class[SYSFS_NAME_LEN], clspath[SYSFS_NAME_LEN];
- unsigned char *cls = NULL, *clsdev = NULL;
- struct dlist *clslist = NULL, *clsdev_list = NULL;
-
- if (bus_id == NULL || classname == NULL) {
- errno = EINVAL;
- return -1;
- }
-
- strcpy(class, SYSFS_CLASS_DIR);
- clslist = sysfs_open_subsystem_list(class);
- if (clslist != NULL) {
- dlist_for_each_data(clslist, cls, char) {
- memset(clspath, 0, SYSFS_NAME_LEN);
- strcpy(clspath, SYSFS_CLASS_DIR);
- strcat(clspath, "/");
- strcat(clspath, cls);
- clsdev_list = sysfs_open_subsystem_list(clspath);
- if (clsdev_list != NULL) {
- dlist_for_each_data(clsdev_list,
- clsdev, char) {
- if (strcmp(bus_id, clsdev) == 0) {
- strncpy(classname,
- cls, bsize);
- sysfs_close_list(clsdev_list);
- sysfs_close_list(clslist);
- return 0;
- }
- }
- sysfs_close_list(clsdev_list);
- }
- }
- sysfs_close_list(clslist);
- }
- return -1;
-}
-
-/**
* sysfs_get_classdev_attr: searches class device's attributes by name
* @clsdev: class device to look through
* @name: attribute name to get
@@ -467,99 +454,45 @@ struct sysfs_attribute *sysfs_get_classdev_attr
}
/**
- * sysfs_write_classdev_attr: modify writable attribute value for the given
- * class device
- * @dev: class device name for which the attribute has to be changed
- * @attrib: attribute to change
- * @value: value to change to
- * @len: size of buffer at "value"
- * Returns 0 on success and -1 on error
- */
-int sysfs_write_classdev_attr(unsigned char *dev, unsigned char *attrib,
- unsigned char *value, size_t len)
-{
- struct sysfs_class_device *clsdev = NULL;
- struct sysfs_attribute *attribute = NULL;
- unsigned char class_name[SYSFS_NAME_LEN];
-
- if (dev == NULL || attrib == NULL || value == NULL) {
- errno = EINVAL;
- return -1;
- }
-
- memset(class_name, 0, SYSFS_NAME_LEN);
- if ((sysfs_find_device_class(dev,
- class_name, SYSFS_NAME_LEN)) < 0) {
- dprintf("Class device %s not found\n", dev);
- return -1;
- }
- clsdev = sysfs_open_class_device_by_name(class_name, dev);
- if (clsdev == NULL) {
- dprintf("Error opening %s in class %s\n", dev, class_name);
- return -1;
- }
- attribute = sysfs_get_directory_attribute(clsdev->directory, attrib);
- if (attribute == NULL) {
- dprintf("Attribute %s not defined for device %s on class %s\n",
- attrib, dev, class_name);
- sysfs_close_class_device(clsdev);
- return -1;
- }
- if ((sysfs_write_attribute(attribute, value, len)) < 0) {
- dprintf("Error setting %s to %s\n", attrib, value);
- sysfs_close_class_device(clsdev);
- return -1;
- }
- sysfs_close_class_device(clsdev);
- return 0;
-}
-
-/**
- * sysfs_read_classdev_attr: read an attribute for a given class device
+ * sysfs_open_classdev_attr: read an attribute for a given class device
+ * @classname: name of the class on which to look
* @dev: class device name for which the attribute has to be read
* @attrib: attribute to read
- * @value: buffer to return value to user
- * @len: size of buffer at "value"
- * Returns 0 on success and -1 on error
+ * Returns sysfs_attribute * on SUCCESS and NULL on error
+ *
+ * NOTE:
+ * A call to sysfs_close_attribute() is required to close the
+ * attribute returned and to free memory
*/
-int sysfs_read_classdev_attr(unsigned char *dev, unsigned char *attrib,
- unsigned char *value, size_t len)
+struct sysfs_attribute *sysfs_open_classdev_attr(const unsigned char *classname,
+ const unsigned char *dev, const unsigned char *attrib)
{
- struct sysfs_class_device *clsdev = NULL;
struct sysfs_attribute *attribute = NULL;
- unsigned char class_name[SYSFS_NAME_LEN];
+ unsigned char path[SYSFS_PATH_MAX];
- if (dev == NULL || attrib == NULL || value == NULL) {
+ if (classname == NULL || dev == NULL || attrib == NULL) {
errno = EINVAL;
- return -1;
- }
-
- memset(class_name, 0, SYSFS_NAME_LEN);
- if ((sysfs_find_device_class(dev,
- class_name, SYSFS_NAME_LEN)) < 0) {
- dprintf("Class device %s not found\n", dev);
- return -1;
+ return NULL;
}
- clsdev = sysfs_open_class_device_by_name(class_name, dev);
- if (clsdev == NULL) {
- dprintf("Error opening %s in class %s\n", dev, class_name);
- return -1;
+ memset(path, 0, SYSFS_PATH_MAX);
+ if ((get_classdev_path(classname, dev, path, SYSFS_PATH_MAX)) != 0) {
+ dprintf("Error getting to device %s on class %s\n",
+ dev, classname);
+ return NULL;
}
- attribute = sysfs_get_directory_attribute(clsdev->directory, attrib);
+ strcat(path, "/");
+ strcat(path, attrib);
+ attribute = sysfs_open_attribute(path);
if (attribute == NULL) {
- dprintf("Attribute %s not defined for device %s on class %s\n",
- attrib, dev, class_name);
- sysfs_close_class_device(clsdev);
- return -1;
+ dprintf("Error opening attribute %s on class device %s\n",
+ attrib, dev);
+ return NULL;
}
- if (attribute->len > len) {
- dprintf("Value length %d is greater that suppled buffer %d\n",
- attribute->len, len);
- sysfs_close_class_device(clsdev);
- return -1;
+ if ((sysfs_read_attribute(attribute)) != 0) {
+ dprintf("Error reading attribute %s for class device %s\n",
+ attrib, dev);
+ sysfs_close_attribute(attribute);
+ return NULL;
}
- strncpy(value, attribute->value, attribute->len);
- value[(attribute->len)+1] = 0;
- sysfs_close_class_device(clsdev);
- return 0;
+ return attribute;
}
diff --git a/lib/sysfs_device.c b/lib/sysfs_device.c
index 89704dc..fbd046f 100644
--- a/lib/sysfs_device.c
+++ b/lib/sysfs_device.c
@@ -23,6 +23,77 @@
#include "libsysfs.h"
#include "sysfs.h"
+static int confirm_device_bus(struct sysfs_device *dev,
+ unsigned char *busname, unsigned char *bus_id)
+{
+ struct sysfs_link *devlink = NULL;
+ unsigned char devpath[SYSFS_PATH_MAX];
+ int result = 0;
+
+ if (busname == NULL || bus_id == NULL)
+ return -1;
+
+ if (sysfs_get_mnt_path(devpath, SYSFS_PATH_MAX) != 0)
+ return -1;
+
+ strcat(devpath, SYSFS_BUS_DIR);
+ strcat(devpath, "/");
+ strcat(devpath, busname);
+ strcat(devpath, SYSFS_DEVICES_DIR);
+ strcat(devpath, "/");
+ strcat(devpath, bus_id);
+
+ devlink = sysfs_open_link(devpath);
+ if (devlink == NULL)
+ return -1;
+
+ if (strcmp(devlink->target, dev->path) == 0)
+ result++;
+ sysfs_close_link(devlink);
+ return result;
+}
+
+/**
+ * get_device_bus: retrieves the bus name the device is on, checks path to
+ * bus' link to make sure it has correct device.
+ * @dev: device to get busname.
+ * returns 0 with success and -1 with error.
+ */
+static int get_device_bus(struct sysfs_device *dev)
+{
+ unsigned char subsys[SYSFS_NAME_LEN], *bus = NULL, *curdev = NULL;
+ struct dlist *buslist = NULL, *device_list = NULL;
+
+ if (dev == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ strcpy(subsys, SYSFS_BUS_DIR); /* subsys = /bus */
+ buslist = sysfs_open_subsystem_list(subsys);
+ if (buslist != NULL) {
+ dlist_for_each_data(buslist, bus, char) {
+ device_list = sysfs_open_bus_devices_list(bus);
+ if (device_list != NULL) {
+ dlist_for_each_data(device_list,
+ curdev, char) {
+ if (strcmp(dev->bus_id, curdev) == 0
+ && confirm_device_bus(dev, bus,
+ curdev) > 0) {
+ strcpy(dev->bus, bus);
+ sysfs_close_list(device_list);
+ sysfs_close_list(buslist);
+ return 0;
+ }
+ }
+ sysfs_close_list(device_list);
+ }
+ }
+ sysfs_close_list(buslist);
+ }
+ return -1;
+}
+
/**
* sysfs_close_device_tree: closes every device in the supplied tree,
* closing children only.
@@ -150,6 +221,9 @@ struct sysfs_device *sysfs_open_device(const unsigned char *path)
* implies that the dev->name and dev->bus_id contain same data.
*/
strncpy(dev->name, sdir->name, SYSFS_NAME_LEN);
+
+ if (get_device_bus(dev) != 0)
+ strcpy(dev->bus, SYSFS_UNKNOWN);
return dev;
}
@@ -339,55 +413,6 @@ struct dlist *sysfs_get_device_attributes(struct sysfs_device *device)
}
/**
- * sysfs_open_device_by_id: open a device by id (use the "bus" subsystem)
- * @bus_id: bus_id of the device to open - has to be the "bus_id" in
- * /sys/bus/xxx/devices
- * @bus: bus the device belongs to
- * @bsize: size of the bus buffer
- * returns struct sysfs_device if found, NULL otherwise
- * NOTE:
- * 1. Use sysfs_close_device to close the device
- * 2. Bus the device is on must be supplied
- * Use sysfs_find_device_bus to get the bus name
- */
-struct sysfs_device *sysfs_open_device_by_id(const unsigned char *bus_id,
- const unsigned char *bus, size_t bsize)
-{
- char sysfs_path[SYSFS_PATH_MAX], device_path[SYSFS_PATH_MAX];
- struct sysfs_device *device = NULL;
-
- if (bus_id == NULL || bus == NULL) {
- errno = EINVAL;
- return NULL;
- }
- memset(sysfs_path, 0, SYSFS_PATH_MAX);
- if ((sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX)) != 0) {
- dprintf("Error getting sysfs mount path\n");
- return NULL;
- }
- strcat(sysfs_path, SYSFS_BUS_DIR);
- strcat(sysfs_path, "/");
- strncat(sysfs_path, bus, bsize);
- strcat(sysfs_path, SYSFS_DEVICES_DIR);
- strcat(sysfs_path, "/");
- strcat(sysfs_path, bus_id);
-
- /* devices under /sys/bus/xxx/devices are links to devices subsystem */
- if ((sysfs_get_link(sysfs_path, device_path, SYSFS_PATH_MAX)) < 0) {
- dprintf("Error getting device path\n");
- return NULL;
- }
-
- device = sysfs_open_device(device_path);
- if (device == NULL) {
- dprintf("Error opening device %s\n", bus_id);
- return NULL;
- }
-
- return device;
-}
-
-/**
* get_device_absolute_path: looks up the bus the device is on, gets
* absolute path to the device
* @device: device for which path is needed
@@ -395,29 +420,24 @@ struct sysfs_device *sysfs_open_device_by_id(const unsigned char *bus_id,
* @psize: size of "path"
* Returns 0 on success -1 on failure
*/
-static int get_device_absolute_path(const unsigned char *device,
- unsigned char *path, size_t psize)
+static int get_device_absolute_path(const unsigned char *device,
+ const unsigned char *bus, unsigned char *path, size_t psize)
{
- unsigned char bus_name[SYSFS_NAME_LEN], bus_path[SYSFS_PATH_MAX];
+ unsigned char bus_path[SYSFS_NAME_LEN];
if (device == NULL || path == NULL) {
errno = EINVAL;
return -1;
}
- memset(bus_name, 0, SYSFS_NAME_LEN);
memset(bus_path, 0, SYSFS_NAME_LEN);
- if ((sysfs_find_device_bus(device, bus_name, SYSFS_NAME_LEN)) != 0) {
- dprintf("Device %s not found\n", device);
- return -1;
- }
if (sysfs_get_mnt_path(bus_path, SYSFS_PATH_MAX) != 0) {
dprintf ("Sysfs not supported on this system\n");
return -1;
}
strcat(bus_path, SYSFS_BUS_DIR);
strcat(bus_path, "/");
- strcat(bus_path, bus_name);
+ strcat(bus_path, bus);
strcat(bus_path, SYSFS_DEVICES_DIR);
strcat(bus_path, "/");
strcat(bus_path, device);
@@ -433,106 +453,85 @@ static int get_device_absolute_path(const unsigned char *device,
}
/**
- * sysfs_write_device_attr: modify a "writable" attribute for the given device
- * @dev: device bus_id for which attribute has to be changed
- * @attrib: attribute to change
- * @value: value to change to
- * @len: "value" length to write
- * Returns 0 on success -1 on error
- */
-int sysfs_write_device_attr(unsigned char *dev, unsigned char *attrib,
- unsigned char *value, size_t len)
+ * sysfs_open_device_by_id: open a device by id (use the "bus" subsystem)
+ * @bus_id: bus_id of the device to open - has to be the "bus_id" in
+ * /sys/bus/xxx/devices
+ * @bus: bus the device belongs to
+ * @bsize: size of the bus buffer
+ * returns struct sysfs_device if found, NULL otherwise
+ * NOTE:
+ * 1. Use sysfs_close_device to close the device
+ * 2. Bus the device is on must be supplied
+ * Use sysfs_find_device_bus to get the bus name
+ */
+struct sysfs_device *sysfs_open_device_by_id(const unsigned char *bus_id,
+ const unsigned char *bus, size_t bsize)
{
- struct sysfs_attribute *attribute = NULL;
- unsigned char devpath[SYSFS_PATH_MAX];
+ char sysfs_path[SYSFS_PATH_MAX];
+ struct sysfs_device *device = NULL;
- if (dev == NULL || attrib == NULL || value == NULL) {
+ if (bus_id == NULL || bus == NULL) {
errno = EINVAL;
- return -1;
- }
-
- memset(devpath, 0, SYSFS_PATH_MAX);
- if ((get_device_absolute_path(dev, devpath, SYSFS_PATH_MAX)) != 0) {
- dprintf("Error finding absolute path to device %s\n", dev);
- return -1;
- }
- strcat(devpath, "/");
- strcat(devpath, attrib);
- attribute = sysfs_open_attribute(devpath);
- if (attribute == NULL) {
- dprintf("Attribute %s could not be retrieved for device %s\n",
- attrib, dev);
- return -1;
+ return NULL;
}
- if (attribute->method & SYSFS_METHOD_SHOW) {
- if ((sysfs_read_attribute(attribute)) != 0) {
- dprintf("Error reading attribute %s for device %s\n",
- attrib, dev);
- sysfs_close_attribute(attribute);
- return -1;
- }
+ memset(sysfs_path, 0, SYSFS_PATH_MAX);
+ if ((get_device_absolute_path(bus_id, bus, sysfs_path,
+ SYSFS_PATH_MAX)) != 0) {
+ dprintf("Error getting to device %s\n", bus_id);
+ return NULL;
}
- if ((sysfs_write_attribute(attribute, value, len)) < 0) {
- dprintf("Error setting %s to %s\n", attrib, value);
- sysfs_close_attribute(attribute);
- return -1;
+
+ device = sysfs_open_device(sysfs_path);
+ if (device == NULL) {
+ dprintf("Error opening device %s\n", bus_id);
+ return NULL;
}
- sysfs_close_attribute(attribute);
- return 0;
+
+ return device;
}
-/**
- * sysfs_read_device_attr: read an attribute of the given device
- * @dev: device bus_id for which attribute has to be changed
- * @attrib: attribute to read
- * @value: buffer to return value in
- * @len: size of buffer available
- * Returns 0 on success -1 on error
- */
-int sysfs_read_device_attr(unsigned char *dev, unsigned char *attrib,
- unsigned char *value, size_t len)
+/*
+ * sysfs_open_device_attr: open the given device's attribute
+ * @bus: Bus on which to look
+ * @dev_id: device for which attribute is required
+ * @attrname: name of the attribute to look for
+ * Returns struct sysfs_attribute on success and NULL on failure
+ *
+ * NOTE:
+ * A call to sysfs_close_attribute() is required to close
+ * the attribute returned and free memory.
+ */
+struct sysfs_attribute *sysfs_open_device_attr(const unsigned char *bus,
+ const unsigned char *bus_id, const unsigned char *attrib)
{
struct sysfs_attribute *attribute = NULL;
unsigned char devpath[SYSFS_PATH_MAX];
-
- if (dev == NULL || attrib == NULL || value == NULL) {
+
+ if (bus == NULL || bus_id == NULL || attrib == NULL) {
errno = EINVAL;
- return -1;
+ return NULL;
}
-
+
memset(devpath, 0, SYSFS_PATH_MAX);
- if ((get_device_absolute_path(dev, devpath, SYSFS_PATH_MAX)) != 0) {
- dprintf("Error finding absolute path to device %s\n", dev);
- return -1;
+ if ((get_device_absolute_path(bus_id, bus, devpath,
+ SYSFS_PATH_MAX)) != 0) {
+ dprintf("Error getting to device %s\n", bus_id);
+ return NULL;
}
strcat(devpath, "/");
strcat(devpath, attrib);
attribute = sysfs_open_attribute(devpath);
if (attribute == NULL) {
dprintf("Error opening attribute %s for device %s\n",
- attrib, dev);
- return -1;
- }
- if (!(attribute->method & SYSFS_METHOD_SHOW)) {
- dprintf("Show method not supported for attribute %s\n",
- attrib);
- sysfs_close_attribute(attribute);
- return -1;
+ attrib, bus_id);
+ return NULL;
}
if ((sysfs_read_attribute(attribute)) != 0) {
dprintf("Error reading attribute %s for device %s\n",
- attrib, dev);
+ attrib, bus_id);
sysfs_close_attribute(attribute);
- return -1;
- }
- if (attribute->len > len) {
- dprintf("Value length %d is larger than supplied buffer %d\n",
- attribute->len, len);
- sysfs_close_attribute(attribute);
- return -1;
+ return NULL;
}
- strncpy(value, attribute->value, attribute->len);
- value[(attribute->len)+1] = 0;
- sysfs_close_attribute(attribute);
- return 0;
+ return attribute;
}
+
diff --git a/lib/sysfs_driver.c b/lib/sysfs_driver.c
index 9d331cc..0011177 100644
--- a/lib/sysfs_driver.c
+++ b/lib/sysfs_driver.c
@@ -163,6 +163,35 @@ struct dlist *sysfs_get_driver_links(struct sysfs_driver *driver)
}
/**
+ * 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_by_name: open a driver by name and return the bus
* the driver is on.
* @drv_name: driver to open
@@ -188,16 +217,10 @@ struct sysfs_driver *sysfs_open_driver_by_name(const unsigned char *drv_name,
}
memset(path, 0, SYSFS_PATH_MAX);
- if (sysfs_get_mnt_path(path, SYSFS_PATH_MAX) != 0) {
- dprintf("Error getting sysfs mount path\n");
+ if (get_driver_path(bus, drv_name, path, SYSFS_PATH_MAX) != 0) {
+ dprintf("Error getting to driver %s\n", drv_name);
return NULL;
}
- strcat(path, SYSFS_BUS_DIR);
- strcat(path, "/");
- strcat(path, bus);
- strcat(path, SYSFS_DRIVERS_DIR);
- strcat(path, "/");
- strcat(path, drv_name);
driver = sysfs_open_driver(path);
if (driver == NULL) {
dprintf("Could not open driver %s\n", drv_name);
@@ -224,114 +247,33 @@ struct sysfs_driver *sysfs_open_driver_by_name(const unsigned char *drv_name,
return driver;
}
-/**
- * get_driver_path: looks up the bus the driver is on and builds path to
- * the driver.
- * @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 *drv,
- unsigned char *path, size_t psize)
-{
- unsigned char bus_name[SYSFS_NAME_LEN];
-
- if (drv == NULL || path == NULL) {
- errno = EINVAL;
- return -1;
- }
- memset(bus_name, 0, SYSFS_NAME_LEN);
- memset(path, 0, SYSFS_PATH_MAX);
- if ((sysfs_find_driver_bus(drv, bus_name, SYSFS_NAME_LEN)) < 0) {
- dprintf("Driver %s not found\n", drv);
- return -1;
- }
- if (sysfs_get_mnt_path(path, SYSFS_PATH_MAX) != 0) {
- dprintf("Error getting sysfs mount path\n");
- return -1;
- }
- strcat(path, SYSFS_BUS_DIR);
- strcat(path, "/");
- strcat(path, bus_name);
- strcat(path, SYSFS_DRIVERS_DIR);
- strcat(path, "/");
- strcat(path, drv);
- fprintf(stdout, "get_driver_path %s\n", path);
- return 0;
-}
/**
- * sysfs_write_driver_attr: modify "writable" driver attribute
- * @drv: driver whose attribute has to be modified
- * @attrib: Attribute to be modified
- * @value: Value to change to
- * Returns 0 on success -1 on failure
- */
-int sysfs_write_driver_attr(unsigned char *drv, unsigned char *attrib,
- unsigned char *value, size_t len)
-{
- struct sysfs_attribute *attribute = NULL;
- unsigned char path[SYSFS_PATH_MAX];
-
- if (drv == NULL || attrib == NULL || value == NULL) {
- errno = EINVAL;
- return -1;
- }
-
- memset(path, 0, SYSFS_PATH_MAX);
- if ((get_driver_path(drv, path, SYSFS_PATH_MAX)) != 0) {
- dprintf("Error getting to driver %s\n", drv);
- return -1;
- }
- strcat(path, "/");
- strcat(path, attrib);
- attribute = sysfs_open_attribute(path);
- if (attribute == NULL) {
- dprintf("Attribute %s could not be retrieved for driver %s\n",
- attrib, drv);
- return -1;
- }
- if (attribute->method & SYSFS_METHOD_SHOW) {
- if ((sysfs_read_attribute(attribute)) != 0) {
- dprintf("Error reading attribute %s for driver %s\n",
- attrib, drv);
- sysfs_close_attribute(attribute);
- return -1;
- }
- }
- if ((sysfs_write_attribute(attribute, value, len)) < 0) {
- dprintf("Error setting %s to %s\n", attrib, value);
- sysfs_close_attribute(attribute);
- return -1;
- }
- sysfs_close_attribute(attribute);
- return 0;
-}
-
-/**
- * sysfs_read_driver_attr: read the user supplied driver attribute
+ * sysfs_open_driver_attr: read the user supplied driver attribute
+ * @bus: bus on which to look
* @drv: driver whose attribute has to be read
* @attrib: Attribute to be read
- * @value: Buffer to return the read value
- * @len: Length of the buffer "value"
- * Returns 0 on success -1 on failure
+ * Returns struct sysfs_attribute on success and NULL on failure
+ *
+ * NOTE:
+ * A call to sysfs_close_attribute() is required to close the
+ * attribute returned and to free memory
*/
-int sysfs_read_driver_attr(unsigned char *drv, unsigned char *attrib,
- unsigned char *value, size_t len)
+struct sysfs_attribute *sysfs_open_driver_attr(const unsigned char *bus,
+ const unsigned char *drv, const unsigned char *attrib)
{
struct sysfs_attribute *attribute = NULL;
- unsigned char busname[SYSFS_NAME_LEN], path[SYSFS_PATH_MAX];
+ unsigned char path[SYSFS_PATH_MAX];
- if (drv == NULL || attrib == NULL || value == NULL) {
+ if (bus == NULL || drv == NULL || attrib == NULL) {
errno = EINVAL;
- return -1;
+ return NULL;
}
memset(path, 0, SYSFS_NAME_LEN);
- if ((get_driver_path(drv, path, SYSFS_PATH_MAX)) != 0) {
+ if ((get_driver_path(bus, drv, path, SYSFS_PATH_MAX)) != 0) {
dprintf("Error getting to driver %s\n", drv);
- return -1;
+ return NULL;
}
strcat(path, "/");
strcat(path, attrib);
@@ -339,29 +281,14 @@ int sysfs_read_driver_attr(unsigned char *drv, unsigned char *attrib,
if (attribute == NULL) {
dprintf("Error opening attribute %s for driver %s\n",
attrib, drv);
- return -1;
- }
- if (!(attribute->method & SYSFS_METHOD_SHOW)) {
- dprintf("Show method not supported for attribute %s\n",
- attrib);
- sysfs_close_attribute(attribute);
- return -1;
+ return NULL;
}
if ((sysfs_read_attribute(attribute)) != 0) {
dprintf("Error reading attribute %s for driver %s\n",
attrib, drv);
sysfs_close_attribute(attribute);
- return -1;
- }
- if (attribute->len > len) {
- dprintf("Value length %d is larger than supplied buffer %d\n",
- attribute->len, len);
- sysfs_close_attribute(attribute);
- return -1;
+ return NULL;
}
- strncpy(value, attribute->value, attribute->len);
- value[(attribute->len)+1] = 0;
- sysfs_close_attribute(attribute);
- return 0;
+ return attribute;
}
diff --git a/lib/sysfs_utils.c b/lib/sysfs_utils.c
index 2465eb0..7563dff 100644
--- a/lib/sysfs_utils.c
+++ b/lib/sysfs_utils.c
@@ -205,8 +205,10 @@ void sysfs_close_list(struct dlist *list)
struct dlist *sysfs_open_subsystem_list(unsigned char *name)
{
unsigned char sysfs_path[SYSFS_PATH_MAX], *subsys_name = NULL;
+ unsigned char *c = NULL;
struct sysfs_directory *dir = NULL, *cur = NULL;
struct dlist *list = NULL;
+ struct stat astats;
if (name == NULL)
return NULL;
@@ -246,6 +248,27 @@ struct dlist *sysfs_open_subsystem_list(unsigned char *name)
}
}
sysfs_close_directory(dir);
+ /*
+ * We are now considering "block" as a "class". Hence, if the subsys
+ * name requested here is "class", verify if "block" is supported on
+ * this system and return the same.
+ */
+ if (strcmp(name, SYSFS_CLASS_DIR) == 0) {
+ c = strstr(sysfs_path, SYSFS_CLASS_NAME);
+ if (c == NULL)
+ goto out;
+ strcpy(c, SYSFS_BLOCK_NAME);
+ if ((lstat(sysfs_path, &astats)) != 0) {
+ dprintf("stat() failed\n");
+ goto out;
+ }
+ if (S_ISDIR(astats.st_mode)) {
+ subsys_name = (char *)calloc(1, SYSFS_NAME_LEN);
+ strcpy(subsys_name, SYSFS_BLOCK_NAME);
+ dlist_unshift(list, subsys_name);
+ }
+ }
+out:
return list;
}
diff --git a/test/Makefile.am b/test/Makefile.am
index ad9325d..e2deb5b 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,10 +1,10 @@
-bin_PROGRAMS = dlist_test get_dev_bus get_dev_class get_device get_driver \
- get_bus_devices_list
+bin_PROGRAMS = dlist_test get_class_dev get_device get_driver \
+ get_bus_devices_list write_attr
dlist_test_SOURCES = dlist_test.c
-get_dev_bus_SOURCES = get_dev_bus.c
-get_dev_class_SOURCES = get_dev_class.c
+get_class_dev_SOURCES = get_class_dev.c
get_device_SOURCES = get_device.c
get_driver_SOURCES = get_driver.c
get_bus_devices_list_SOURCES = get_bus_devices_list.c
+write_attr_SOURCES = write_attr.c
INCLUDES = -I../include
LDADD = ../lib/libsysfs.la
diff --git a/test/Makefile.in b/test/Makefile.in
index 0f89af0..ceeccaa 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -83,24 +83,24 @@ VERSION = @VERSION@
am__include = @am__include@
am__quote = @am__quote@
install_sh = @install_sh@
-bin_PROGRAMS = dlist_test get_dev_bus get_dev_class get_device get_driver \
- get_bus_devices_list
+bin_PROGRAMS = dlist_test get_class_dev get_device get_driver \
+ get_bus_devices_list write_attr
dlist_test_SOURCES = dlist_test.c
-get_dev_bus_SOURCES = get_dev_bus.c
-get_dev_class_SOURCES = get_dev_class.c
+get_class_dev_SOURCES = get_class_dev.c
get_device_SOURCES = get_device.c
get_driver_SOURCES = get_driver.c
get_bus_devices_list_SOURCES = get_bus_devices_list.c
+write_attr_SOURCES = write_attr.c
INCLUDES = -I../include
LDADD = ../lib/libsysfs.la
subdir = test
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
-bin_PROGRAMS = dlist_test$(EXEEXT) get_dev_bus$(EXEEXT) \
- get_dev_class$(EXEEXT) get_device$(EXEEXT) get_driver$(EXEEXT) \
- get_bus_devices_list$(EXEEXT)
+bin_PROGRAMS = dlist_test$(EXEEXT) get_class_dev$(EXEEXT) \
+ get_device$(EXEEXT) get_driver$(EXEEXT) \
+ get_bus_devices_list$(EXEEXT) write_attr$(EXEEXT)
PROGRAMS = $(bin_PROGRAMS)
am_dlist_test_OBJECTS = dlist_test.$(OBJEXT)
@@ -113,16 +113,11 @@ get_bus_devices_list_OBJECTS = $(am_get_bus_devices_list_OBJECTS)
get_bus_devices_list_LDADD = $(LDADD)
get_bus_devices_list_DEPENDENCIES = ../lib/libsysfs.la
get_bus_devices_list_LDFLAGS =
-am_get_dev_bus_OBJECTS = get_dev_bus.$(OBJEXT)
-get_dev_bus_OBJECTS = $(am_get_dev_bus_OBJECTS)
-get_dev_bus_LDADD = $(LDADD)
-get_dev_bus_DEPENDENCIES = ../lib/libsysfs.la
-get_dev_bus_LDFLAGS =
-am_get_dev_class_OBJECTS = get_dev_class.$(OBJEXT)
-get_dev_class_OBJECTS = $(am_get_dev_class_OBJECTS)
-get_dev_class_LDADD = $(LDADD)
-get_dev_class_DEPENDENCIES = ../lib/libsysfs.la
-get_dev_class_LDFLAGS =
+am_get_class_dev_OBJECTS = get_class_dev.$(OBJEXT)
+get_class_dev_OBJECTS = $(am_get_class_dev_OBJECTS)
+get_class_dev_LDADD = $(LDADD)
+get_class_dev_DEPENDENCIES = ../lib/libsysfs.la
+get_class_dev_LDFLAGS =
am_get_device_OBJECTS = get_device.$(OBJEXT)
get_device_OBJECTS = $(am_get_device_OBJECTS)
get_device_LDADD = $(LDADD)
@@ -133,6 +128,11 @@ get_driver_OBJECTS = $(am_get_driver_OBJECTS)
get_driver_LDADD = $(LDADD)
get_driver_DEPENDENCIES = ../lib/libsysfs.la
get_driver_LDFLAGS =
+am_write_attr_OBJECTS = write_attr.$(OBJEXT)
+write_attr_OBJECTS = $(am_write_attr_OBJECTS)
+write_attr_LDADD = $(LDADD)
+write_attr_DEPENDENCIES = ../lib/libsysfs.la
+write_attr_LDFLAGS =
DEFS = @DEFS@
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
@@ -143,9 +143,9 @@ depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/dlist_test.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/get_bus_devices_list.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/get_dev_bus.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/get_dev_class.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/get_device.Po ./$(DEPDIR)/get_driver.Po
+@AMDEP_TRUE@ ./$(DEPDIR)/get_class_dev.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/get_device.Po ./$(DEPDIR)/get_driver.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/write_attr.Po
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \
@@ -155,10 +155,10 @@ LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
CFLAGS = @CFLAGS@
DIST_SOURCES = $(dlist_test_SOURCES) $(get_bus_devices_list_SOURCES) \
- $(get_dev_bus_SOURCES) $(get_dev_class_SOURCES) \
- $(get_device_SOURCES) $(get_driver_SOURCES)
+ $(get_class_dev_SOURCES) $(get_device_SOURCES) \
+ $(get_driver_SOURCES) $(write_attr_SOURCES)
DIST_COMMON = Makefile.am Makefile.in
-SOURCES = $(dlist_test_SOURCES) $(get_bus_devices_list_SOURCES) $(get_dev_bus_SOURCES) $(get_dev_class_SOURCES) $(get_device_SOURCES) $(get_driver_SOURCES)
+SOURCES = $(dlist_test_SOURCES) $(get_bus_devices_list_SOURCES) $(get_class_dev_SOURCES) $(get_device_SOURCES) $(get_driver_SOURCES) $(write_attr_SOURCES)
all: all-am
@@ -204,18 +204,18 @@ dlist_test$(EXEEXT): $(dlist_test_OBJECTS) $(dlist_test_DEPENDENCIES)
get_bus_devices_list$(EXEEXT): $(get_bus_devices_list_OBJECTS) $(get_bus_devices_list_DEPENDENCIES)
@rm -f get_bus_devices_list$(EXEEXT)
$(LINK) $(get_bus_devices_list_LDFLAGS) $(get_bus_devices_list_OBJECTS) $(get_bus_devices_list_LDADD) $(LIBS)
-get_dev_bus$(EXEEXT): $(get_dev_bus_OBJECTS) $(get_dev_bus_DEPENDENCIES)
- @rm -f get_dev_bus$(EXEEXT)
- $(LINK) $(get_dev_bus_LDFLAGS) $(get_dev_bus_OBJECTS) $(get_dev_bus_LDADD) $(LIBS)
-get_dev_class$(EXEEXT): $(get_dev_class_OBJECTS) $(get_dev_class_DEPENDENCIES)
- @rm -f get_dev_class$(EXEEXT)
- $(LINK) $(get_dev_class_LDFLAGS) $(get_dev_class_OBJECTS) $(get_dev_class_LDADD) $(LIBS)
+get_class_dev$(EXEEXT): $(get_class_dev_OBJECTS) $(get_class_dev_DEPENDENCIES)
+ @rm -f get_class_dev$(EXEEXT)
+ $(LINK) $(get_class_dev_LDFLAGS) $(get_class_dev_OBJECTS) $(get_class_dev_LDADD) $(LIBS)
get_device$(EXEEXT): $(get_device_OBJECTS) $(get_device_DEPENDENCIES)
@rm -f get_device$(EXEEXT)
$(LINK) $(get_device_LDFLAGS) $(get_device_OBJECTS) $(get_device_LDADD) $(LIBS)
get_driver$(EXEEXT): $(get_driver_OBJECTS) $(get_driver_DEPENDENCIES)
@rm -f get_driver$(EXEEXT)
$(LINK) $(get_driver_LDFLAGS) $(get_driver_OBJECTS) $(get_driver_LDADD) $(LIBS)
+write_attr$(EXEEXT): $(write_attr_OBJECTS) $(write_attr_DEPENDENCIES)
+ @rm -f write_attr$(EXEEXT)
+ $(LINK) $(write_attr_LDFLAGS) $(write_attr_OBJECTS) $(write_attr_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT) core *.core
@@ -225,10 +225,10 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dlist_test.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_bus_devices_list.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_dev_bus.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_dev_class.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_class_dev.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_device.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_driver.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/write_attr.Po@am__quote@
distclean-depend:
-rm -rf ./$(DEPDIR)
diff --git a/test/get_dev_class.c b/test/get_class_dev.c
index 4c5df16..7d20686 100644
--- a/test/get_dev_class.c
+++ b/test/get_class_dev.c
@@ -1,5 +1,5 @@
/*
- * get_dev_class.c
+ * get_class_dev.c
*
* Utility to find the class a given device is on
*
@@ -27,29 +27,41 @@
void print_usage(void)
{
- fprintf(stdout, "Usage: get_dev_class [class_device]\n");
+ fprintf(stdout, "Usage: get_class_dev [class name] [class_device]\n");
}
int main(int argc, char *argv[])
{
- char *classname = NULL;
- int rc;
+ struct sysfs_class_device *cdev = NULL;
+ struct sysfs_attribute *attr = NULL;
+ struct dlist *attrlist = NULL;
- if (argc != 2) {
+ if (argc != 3) {
print_usage();
return 1;
}
- classname = (char *)calloc(1, SYSFS_NAME_LEN);
- rc = sysfs_find_device_class(argv[1], classname, SYSFS_NAME_LEN);
- if (rc == -1) {
- fprintf(stdout, "Device %s not found\n", argv[1]);
- free(classname);
+ cdev = sysfs_open_class_device_by_name(argv[1], argv[2]);
+ if (cdev == NULL) {
+ fprintf(stdout, "Device %s not found\n", argv[2]);
return 1;
}
- fprintf(stdout, "Device %s is a member of class %s\n",
- argv[1], classname);
- free(classname);
+
+ fprintf(stdout, "Class device %s\n", cdev->name);
+
+ attrlist = sysfs_get_classdev_attributes(cdev);
+ if (attrlist != NULL) {
+ dlist_for_each_data(attrlist, attr, struct sysfs_attribute)
+ fprintf(stdout, "\t%s : %s", attr->name, attr->value);
+ }
+ fprintf(stdout, "\n");
+
+ if (cdev->sysdevice)
+ fprintf(stdout, "\tDevice : %s\n", cdev->sysdevice->bus_id);
+ if (cdev->driver)
+ fprintf(stdout, "\tDriver : %s\n", cdev->driver->name);
+
+ sysfs_close_class_device(cdev);
return 0;
}
diff --git a/test/get_dev_bus.c b/test/get_dev_bus.c
deleted file mode 100644
index 6a0379e..0000000
--- a/test/get_dev_bus.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * get_dev_bus.c
- *
- * Utility to get bus on which device is present
- *
- * Copyright (C) IBM Corp. 2003
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 of the License.
- *
- * This program 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
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "libsysfs.h"
-
-void print_usage(void)
-{
- fprintf(stdout, "Usage: get_dev_bus [device]\n");
-}
-
-int main(int argc, char *argv[])
-{
- char *busname = NULL;
- int rc;
-
- if (argc != 2) {
- print_usage();
- return 1;
- }
-
- busname = (char *)calloc(1, SYSFS_NAME_LEN);
- rc = sysfs_find_device_bus(argv[1], busname, SYSFS_NAME_LEN);
- if (rc != 0) {
- fprintf(stdout, "Device %s not found\n", argv[1]);
- free(busname);
- return 1;
- }
- fprintf(stdout, "Device %s is on bus %s\n", argv[1], busname);
- free(busname);
- return 0;
-}
-
diff --git a/test/get_device.c b/test/get_device.c
index 7e20608..9d13d9f 100644
--- a/test/get_device.c
+++ b/test/get_device.c
@@ -27,42 +27,36 @@
void print_usage(void)
{
- fprintf(stdout, "Usage: get_device [device]\n");
+ fprintf(stdout, "Usage: get_device [bus] [device]\n");
}
int main(int argc, char *argv[])
{
- char *bus = NULL;
struct sysfs_device *device = NULL;
struct sysfs_attribute *attr = NULL;
+ struct dlist *attrlist = NULL;
- if (argc != 2) {
+ if (argc != 3) {
print_usage();
return 1;
}
- bus = (char *)calloc(1, SYSFS_NAME_LEN);
- if ((sysfs_find_device_bus(argv[1], bus, SYSFS_NAME_LEN)) < 0) {
- fprintf(stdout, "Device %s not found\n", argv[1]);
- free (bus);
- return 1;
- }
- fprintf(stdout, "Device %s is a member of bus %s\n",
- argv[1], bus);
- device = sysfs_open_device_by_id(argv[1], bus, SYSFS_NAME_LEN);
+ device = sysfs_open_device_by_id(argv[2], argv[1], strlen(argv[1]));
if (device == NULL) {
- fprintf(stdout, "Device %s not found\n", argv[1]);
- free(bus);
+ fprintf(stdout, "Device %s not found on bus %s\n",
+ argv[2], argv[1]);
return 1;
}
- dlist_for_each_data(device->directory->attributes, attr,
- struct sysfs_attribute) {
- fprintf(stdout, "\t%s : %s", attr->name, attr->value);
+
+ attrlist = sysfs_get_device_attributes(device);
+ if (attrlist != NULL) {
+ dlist_for_each_data(attrlist, attr,
+ struct sysfs_attribute)
+ fprintf(stdout, "\t%s : %s", attr->name, attr->value);
}
fprintf(stdout, "\n");
sysfs_close_device(device);
- free(bus);
return 0;
}
diff --git a/test/write_attr.c b/test/write_attr.c
index ab9e6b6..25a10c5 100644
--- a/test/write_attr.c
+++ b/test/write_attr.c
@@ -1,63 +1,60 @@
-/* write attribute support for the given device */
+/*
+ * write_attr.c
+ *
+ * Utility to modify the value of a given class device attribute
+ *
+ * Copyright (C) IBM Corp. 2003
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2 of the License.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
#include <stdio.h>
#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <mntent.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <ctype.h>
#include "libsysfs.h"
+void print_usage(void)
+{
+ fprintf(stdout, "Usage: write_attr [classname] [device] [attribute] [new_value]\n");
+}
+
int main(int argc, char *argv[])
{
- char *bus = NULL;
- struct sysfs_device *device = NULL;
- struct sysfs_attribute *attribute = NULL;
-
- /*
- * need args: device, attribute and value to be changed to
- * eg: ./fn_name <device> <attribute> <val to change to>
- */
- if (argc != 4) {
- fprintf(stdout, "Need 4 args\n");
- return 1;
- }
+ struct sysfs_attribute *attr = NULL;
- bus = (char *)calloc(1, SYSFS_NAME_LEN);
- device = sysfs_open_device_by_name(argv[1], bus, SYSFS_NAME_LEN);
- if (device == NULL) {
- fprintf(stdout, "Device %s not found\n", argv[1]);
- free(bus);
+ if (argc != 5) {
+ print_usage();
return 1;
}
- fprintf(stdout, "Device %s is a member of bus %s\n",
- argv[1], bus);
- fprintf(stdout, "\t\t%s\n", device->bus_id);
-
- attribute = sysfs_get_device_attr(device, argv[2]);
- if (attribute == NULL) {
- fprintf(stdout, "Attribute %s not defined for device %s\n",
- argv[2], argv[1]);
- sysfs_close_device(device);
- free(bus);
+
+ attr = sysfs_open_classdev_attr(argv[1], argv[2], argv[3]);
+ if (attr == NULL) {
+ fprintf(stdout, "Attribute %s not defined for classdev %s\n",
+ argv[3], argv[2]);
return 1;
}
- if ((sysfs_write_attribute_value(attribute->path, argv[2])) < 0) {
- fprintf(stdout, "Write attribute failed\n");
- sysfs_close_device(device);
- free(bus);
+ fprintf(stdout, "Attribute %s presently has a value %s\n",
+ attr->name, attr->value);
+ if ((sysfs_write_attribute(attr, argv[4], strlen(argv[4]))) != 0) {
+ fprintf(stdout, "Error writing attribute value\n");
+ sysfs_close_attribute(attr);
return 1;
}
-
- fprintf(stdout, "Write succeeded\n");
- sysfs_close_device(device);
- free(bus);
+ fprintf(stdout, "Attribute value after write is %s\n", attr->value);
+ sysfs_close_attribute(attr);
return 0;
}
diff --git a/test/write_attr_2.c b/test/write_attr_2.c
deleted file mode 100644
index ac2fcd7..0000000
--- a/test/write_attr_2.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/* write attribute support for the given device */
-
-#include <stdio.h>
-
-#include "libsysfs.h"
-
-int main(int argc, char *argv[])
-{
- /*
- * need args: device, attribute and value to be changed to
- * eg: ./fn_name <device> <attribut> <val to change to>
- */
- if (argc != 4) {
- fprintf(stdout, "Need 4 args\n");
- return 1;
- }
-/* if ((sysfs_change_attribute_value(argv[1], argv[2], argv[3])) < 0) {*/
- if ((sysfs_write_device_attr(argv[1], argv[2], argv[3], strlen(argv[3]))) < 0) {
-/* if ((sysfs_write_classdev_attr(argv[1], argv[2], argv[3])) < 0) {*/
-/* if ((sysfs_write_driver_attr(argv[1], argv[2], argv[3])) < 0) {*/
- fprintf(stdout, "Write attribute error\n");
- return 1;
- }
- fprintf(stdout, "Write succeeded\n");
- return 0;
-}
-