+ /* find the sysfs_device for this class device */
+ /* Wouldn't it really be nice if libsysfs could do this for us? */
+ if (class_dev->sysdevice) {
+ sysfs_device = class_dev->sysdevice;
+ } else {
+ /* bah, let's go backwards up a level to see if the device is there,
+ * as block partitions don't point to the physical device. Need to fix that
+ * up in the kernel...
+ */
+ if (strstr(class_dev->path, "block")) {
+ dbg_parse("looking at block device");
+ if (isdigit(class_dev->path[strlen(class_dev->path)-1])) {
+ char path[SYSFS_PATH_MAX];
+
+ dbg_parse("really is a partition");
+ strfieldcpy(path, class_dev->path);
+ temp = strrchr(path, '/');
+ *temp = 0x00;
+ dbg_parse("looking for a class device at '%s'", path);
+ class_dev_parent = sysfs_open_class_device(path);
+ if (class_dev_parent == NULL) {
+ dbg("sysfs_open_class_device at '%s' failed", path);
+ } else {
+ dbg_parse("class_dev_parent->name='%s'", class_dev_parent->name);
+ if (class_dev_parent->sysdevice)
+ sysfs_device = class_dev_parent->sysdevice;
+ }
+ }
+ }
+ }
+
+ if (sysfs_device) {
+ dbg_parse("sysfs_device->path='%s'", sysfs_device->path);
+ dbg_parse("sysfs_device->bus_id='%s'", sysfs_device->bus_id);
+ dbg_parse("sysfs_device->bus='%s'", sysfs_device->bus);
+ strfieldcpy(udev->bus_id, sysfs_device->bus_id);
+ } else {
+ dbg_parse("class_dev->name = '%s'", class_dev->name);
+ }
+
+ build_kernel_number(class_dev, udev);
+
+ /* rules are looked at in priority order */
+ retval = do_callout(class_dev, udev, sysfs_device);
+ if (retval == 0)
+ goto found;
+
+ retval = do_label(class_dev, udev, sysfs_device);
+ if (retval == 0)
+ goto found;
+
+ retval = do_number(class_dev, udev, sysfs_device);
+ if (retval == 0)
+ goto found;
+
+ retval = do_topology(class_dev, udev, sysfs_device);
+ if (retval == 0)
+ goto found;
+
+ retval = do_replace(class_dev, udev, sysfs_device);
+ if (retval == 0)
+ goto found;
+
+ do_kernelname(class_dev, udev);
+ goto done;
+
+found:
+ /* substitute placeholder in NAME */
+ apply_format(udev, udev->name);
+
+done:
+ /* mode was never set above */
+ if (!udev->mode) {
+ udev->mode = get_default_mode(class_dev);
+ udev->owner[0] = 0x00;
+ udev->group[0] = 0x00;
+ }
+
+ if (class_dev_parent)
+ sysfs_close_class_device(class_dev_parent);
+
+ return 0;