+/**
+ * get_dev_driver: fills in the dev->driver_name field, but searches by
+ * opening subsystem. Only to be used if no driver link exists in
+ * device directory.
+ *
+ * Returns 0 on SUCCESS and 1 on error
+ */
+static int get_dev_driver(struct sysfs_device *dev)
+{
+ struct dlist *drvlist = NULL;
+ char path[SYSFS_PATH_MAX], devpath[SYSFS_PATH_MAX];
+ char *drv = NULL, *c = NULL;
+
+ if (dev == NULL) {
+ errno = EINVAL;
+ return 1;
+ }
+ if (dev->bus[0] == '\0')
+ return 1;
+ memset(path, 0, SYSFS_PATH_MAX);
+ memset(devpath, 0, SYSFS_PATH_MAX);
+ safestrcpy(path, SYSFS_BUS_NAME);
+ safestrcat(path, "/");
+ safestrcat(path, dev->bus);
+ safestrcat(path, "/");
+ safestrcat(path, SYSFS_DRIVERS_NAME);
+
+ safestrcpy(devpath, dev->path);
+ c = strstr(devpath, SYSFS_DEVICES_NAME);
+ if (c == NULL)
+ return 1;
+ *c = '\0';
+ safestrcatmax(c, path, (sizeof(devpath) - strlen(devpath)));
+
+ drvlist = sysfs_open_subsystem_list(path);
+ if (drvlist != NULL) {
+ dlist_for_each_data(drvlist, drv, char) {
+ safestrcpy(path, devpath);
+ safestrcat(path, "/");
+ safestrcat(path, drv);
+ safestrcat(path, "/");
+ safestrcat(path, dev->bus_id);
+ if (sysfs_path_is_link(path) == 0) {
+ safestrcpy(dev->driver_name, drv);
+ sysfs_close_list(drvlist);
+ return 0;
+ }
+ }
+ sysfs_close_list(drvlist);
+ }
+ return 1;
+}
+
+/*
+ * get_device_driver_name: gets device's driver name, searches for driver
+ * link first before going the brute force route.
+ * @dev: device to retrieve driver
+ * returns 0 with success and 1 with error
+ */
+static int get_device_driver_name(struct sysfs_device *dev)
+{
+ char devpath[SYSFS_PATH_MAX], drvpath[SYSFS_PATH_MAX];
+
+ if (dev == NULL) {
+ errno = EINVAL;
+ return 1;
+ }
+ memset(devpath, 0, SYSFS_PATH_MAX);
+ memset(drvpath, 0, SYSFS_PATH_MAX);
+ safestrcpy(devpath, dev->path);
+ safestrcat(devpath, "/driver");
+
+ if ((sysfs_get_link(devpath, drvpath, SYSFS_PATH_MAX)) != 0)
+ return(get_dev_driver(dev));
+
+ return (sysfs_get_name_from_path(drvpath, dev->driver_name,
+ SYSFS_NAME_LEN));
+}
+