+static struct sysfs_device *get_sysfs_device(struct sysfs_class_device *class_dev)
+{
+ struct sysfs_device *sysfs_device;
+ struct sysfs_class_device *class_dev_parent;
+ struct timespec tspec;
+ int loop;
+
+ /* Figure out where the device symlink is at. For char devices this will
+ * always be in the class_dev->path. But for block devices, it's different.
+ * The main block device will have the device symlink in it's path, but
+ * all partitions have the symlink in its parent directory.
+ * But we need to watch out for block devices that do not have parents, yet
+ * look like a partition (fd0, loop0, etc.) They all do not have a device
+ * symlink yet. We do sit and spin on waiting for them right now, we should
+ * possibly have a whitelist for these devices here...
+ */
+ class_dev_parent = sysfs_get_classdev_parent(class_dev);
+ if (class_dev_parent)
+ dbg("Really a partition");
+
+ tspec.tv_sec = 0;
+ tspec.tv_nsec = 10000000; /* sleep 10 millisec */
+ loop = 10;
+ while (loop--) {
+ if (udev_sleep)
+ nanosleep(&tspec, NULL);
+ if (class_dev_parent)
+ sysfs_device = sysfs_get_classdev_device(class_dev_parent);
+ else
+ sysfs_device = sysfs_get_classdev_device(class_dev);
+
+ if (sysfs_device != NULL)
+ goto device_found;
+ }
+ dbg("timed out waiting for device symlink, continuing on anyway...");
+
+device_found:
+ /* We have another issue with just the wait above - the sysfs part of
+ * the kernel may not be quick enough to have created the link to the
+ * device under the "bus" subsystem. Due to this, the sysfs_device->bus
+ * will not contain the actual bus name :(
+ *
+ * Libsysfs now provides a new API sysfs_get_device_bus(), so use it
+ * if needed
+ */
+ if (sysfs_device) {
+ if (sysfs_device->bus[0] != '\0')
+ goto bus_found;
+
+ loop = 10;
+ tspec.tv_nsec = 10000000;
+ while (loop--) {
+ if (udev_sleep)
+ nanosleep(&tspec, NULL);
+ sysfs_get_device_bus(sysfs_device);
+
+ if (sysfs_device->bus[0] != '\0')
+ goto bus_found;
+ }
+ dbg("timed out waiting to find the device bus, continuing on anyway");
+ goto exit;
+bus_found:
+ dbg("device %s is registered with bus '%s'",
+ sysfs_device->name, sysfs_device->bus);
+ }
+exit:
+ return sysfs_device;
+}