4 * Generic bus utility functions for libsysfs
6 * Copyright (C) IBM Corp. 2003-2005
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 static void sysfs_close_dev(void *dev)
28 sysfs_close_device((struct sysfs_device *)dev);
31 static void sysfs_close_drv(void *drv)
33 sysfs_close_driver((struct sysfs_driver *)drv);
39 * @b: sysfs_device comparing being compared
40 * returns 1 if a==b->name or 0 not equal
42 static int name_equal(void *a, void *b)
47 if (strcmp(((char *)a), ((struct sysfs_device *)b)->name) == 0)
54 * sysfs_close_bus: close single bus
57 void sysfs_close_bus(struct sysfs_bus *bus)
61 dlist_destroy(bus->attrlist);
63 dlist_destroy(bus->devices);
65 dlist_destroy(bus->drivers);
71 * alloc_bus: mallocs new bus structure
72 * returns sysfs_bus_bus struct or NULL
74 static struct sysfs_bus *alloc_bus(void)
76 return (struct sysfs_bus *)calloc(1, sizeof(struct sysfs_bus));
80 * sysfs_get_bus_devices: gets all devices for bus
81 * @bus: bus to get devices for
82 * returns dlist of devices with success and NULL with failure
84 struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus)
86 struct sysfs_device *dev;
87 struct dlist *linklist;
88 char path[SYSFS_PATH_MAX], devpath[SYSFS_PATH_MAX];
89 char target[SYSFS_PATH_MAX];
96 memset(path, 0, SYSFS_PATH_MAX);
97 safestrcpy(path, bus->path);
98 safestrcat(path, "/");
99 safestrcat(path, SYSFS_DEVICES_NAME);
101 linklist = read_dir_links(path);
103 dlist_for_each_data(linklist, curlink, char) {
105 dev = (struct sysfs_device *)
106 dlist_find_custom(bus->devices,
107 (void *)curlink, name_equal);
111 safestrcpy(devpath, path);
112 safestrcat(devpath, "/");
113 safestrcat(devpath, curlink);
114 if (sysfs_get_link(devpath, target, SYSFS_PATH_MAX)) {
115 dprintf("Error getting link - %s\n", devpath);
118 dev = sysfs_open_device_path(target);
120 dprintf("Error opening device at %s\n",
125 bus->devices = dlist_new_with_delete
126 (sizeof(struct sysfs_device),
128 dlist_unshift_sorted(bus->devices, dev, sort_list);
130 sysfs_close_list(linklist);
132 return (bus->devices);
136 * sysfs_get_bus_drivers: gets all drivers for bus
137 * @bus: bus to get devices for
138 * returns dlist of devices with success and NULL with failure
140 struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus)
142 struct sysfs_driver *drv;
143 struct dlist *dirlist;
144 char path[SYSFS_PATH_MAX], drvpath[SYSFS_PATH_MAX];
151 memset(path, 0, SYSFS_PATH_MAX);
152 safestrcpy(path, bus->path);
153 safestrcat(path, "/");
154 safestrcat(path, SYSFS_DRIVERS_NAME);
156 dirlist = read_dir_subdirs(path);
158 dlist_for_each_data(dirlist, curdir, char) {
160 drv = (struct sysfs_driver *)
161 dlist_find_custom(bus->drivers,
162 (void *)curdir, name_equal);
166 safestrcpy(drvpath, path);
167 safestrcat(drvpath, "/");
168 safestrcat(drvpath, curdir);
169 drv = sysfs_open_driver_path(drvpath);
171 dprintf("Error opening driver at %s\n",
176 bus->drivers = dlist_new_with_delete
177 (sizeof(struct sysfs_driver),
179 dlist_unshift_sorted(bus->drivers, drv, sort_list);
181 sysfs_close_list(dirlist);
183 return (bus->drivers);
187 * sysfs_open_bus: opens specific bus and all its devices on system
188 * returns sysfs_bus structure with success or NULL with error.
190 struct sysfs_bus *sysfs_open_bus(const char *name)
192 struct sysfs_bus *bus;
193 char buspath[SYSFS_PATH_MAX];
200 memset(buspath, 0, SYSFS_PATH_MAX);
201 if (sysfs_get_mnt_path(buspath, SYSFS_PATH_MAX)) {
202 dprintf("Sysfs not supported on this system\n");
206 safestrcat(buspath, "/");
207 safestrcat(buspath, SYSFS_BUS_NAME);
208 safestrcat(buspath, "/");
209 safestrcat(buspath, name);
210 if (sysfs_path_is_dir(buspath)) {
211 dprintf("Invalid path to bus: %s\n", buspath);
216 dprintf("calloc failed\n");
219 safestrcpy(bus->name, name);
220 safestrcpy(bus->path, buspath);
221 if (sysfs_remove_trailing_slash(bus->path)) {
222 dprintf("Incorrect path to bus %s\n", bus->path);
223 sysfs_close_bus(bus);
231 * sysfs_get_bus_device: Get specific device on bus using device's id
232 * @bus: bus to find device on
233 * @id: bus_id for device
234 * returns struct sysfs_device reference or NULL if not found.
236 struct sysfs_device *sysfs_get_bus_device(struct sysfs_bus *bus,
239 struct sysfs_device *dev = NULL;
240 char devpath[SYSFS_PATH_MAX], target[SYSFS_PATH_MAX];
248 dev = (struct sysfs_device *)dlist_find_custom
249 (bus->devices, (void *)id, name_equal);
253 safestrcpy(devpath, bus->path);
254 safestrcat(devpath, "/");
255 safestrcat(devpath, SYSFS_DEVICES_NAME);
256 safestrcat(devpath, "/");
257 safestrcat(devpath, id);
258 if (sysfs_path_is_link(devpath)) {
259 dprintf("No such device %s on bus %s?\n", id, bus->name);
262 if (!sysfs_get_link(devpath, target, SYSFS_PATH_MAX)) {
263 dev = sysfs_open_device_path(target);
265 dprintf("Error opening device at %s\n", target);
269 bus->devices = dlist_new_with_delete
270 (sizeof(struct sysfs_device),
272 dlist_unshift_sorted(bus->devices, dev, sort_list);
278 * sysfs_get_bus_driver: Get specific driver on bus using driver name
279 * @bus: bus to find driver on
280 * @drvname: name of driver
281 * returns struct sysfs_driver reference or NULL if not found.
283 struct sysfs_driver *sysfs_get_bus_driver(struct sysfs_bus *bus,
286 struct sysfs_driver *drv;
287 char drvpath[SYSFS_PATH_MAX];
289 if (!bus || !drvname) {
295 drv = (struct sysfs_driver *)dlist_find_custom
296 (bus->drivers, (void *)drvname, name_equal);
300 safestrcpy(drvpath, bus->path);
301 safestrcat(drvpath, "/");
302 safestrcat(drvpath, SYSFS_DRIVERS_NAME);
303 safestrcat(drvpath, "/");
304 safestrcat(drvpath, drvname);
305 drv = sysfs_open_driver_path(drvpath);
307 dprintf("Error opening driver at %s\n", drvpath);
311 bus->drivers = dlist_new_with_delete
312 (sizeof(struct sysfs_driver),
314 dlist_unshift_sorted(bus->drivers, drv, sort_list);