+ char devpath[SYSFS_PATH_MAX];
+ char subsys[SYSFS_NAME_LEN];
+ char path[SYSFS_PATH_MAX];
+ char target[SYSFS_PATH_MAX];
+ char *bus = NULL, *c;
+ struct dlist *buslist;
+
+ if (!dev) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ memset(path, 0, SYSFS_PATH_MAX);
+ memset(devpath, 0, SYSFS_PATH_MAX);
+ safestrcpymax(path, dev->path, SYSFS_PATH_MAX);
+ safestrcatmax(path, "/bus", SYSFS_PATH_MAX);
+ if (!sysfs_path_is_link(path)) {
+ if (!sysfs_get_link(path, devpath, SYSFS_PATH_MAX)) {
+ if (sysfs_get_name_from_path(devpath,
+ dev->bus, SYSFS_NAME_LEN))
+ return -1;
+ }
+ return 0;
+ }
+
+ /*
+ * Devices on on earlier kernels do not have the "bus" link.
+ * Look it up in the bus directory.
+ */
+ memset(subsys, 0, SYSFS_NAME_LEN);
+ safestrcpy(subsys, dev->path);
+ c = strstr(subsys, SYSFS_DEVICES_NAME);
+ if (c == NULL) {
+ dprintf("Invalid path to device - %s\n", dev->path);
+ return -1;
+ } else
+ *c = '\0';
+ safestrcat(subsys, SYSFS_BUS_NAME);
+ buslist = sysfs_open_directory_list(subsys);
+ if (buslist) {
+ dlist_for_each_data(buslist, bus, char) {
+ memset(path, 0, SYSFS_PATH_MAX);
+ safestrcpy(path, subsys);
+ safestrcat(path, "/");
+ safestrcat(path, bus);
+ safestrcat(path, "/");
+ safestrcat(path, SYSFS_DEVICES_NAME);
+ safestrcat(path, "/");
+ safestrcat(path, dev->bus_id);
+ if ((sysfs_path_is_link(path)) == 0) {
+ memset(target, 0, SYSFS_PATH_MAX);
+ if (sysfs_get_link(path, target,
+ SYSFS_PATH_MAX)) {
+ dprintf("Error getting link target\n");
+ sysfs_close_list(buslist);
+ return -1;
+ }
+ if (!(strncmp(target, dev->path,
+ SYSFS_PATH_MAX))) {
+ safestrcpy(dev->bus, bus);
+ sysfs_close_list(buslist);
+ return 0;
+ }
+ }
+ }
+ sysfs_close_list(buslist);
+ }
+ return -1;