summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBastian Stender <bst@pengutronix.de>2016-03-11 11:28:46 +0100
committerMarc Kleine-Budde <mkl@pengutronix.de>2016-03-15 13:37:23 +0100
commit6e912489417b93528d1e963f47e1f5d4773a3775 (patch)
tree8c45a3fa5259196a845e702b8b1da0722c2ee3f7 /src
parentfb48280edcede9b97bf913654a19ea3b0ec45fac (diff)
downloaddt-utils-6e912489417b93528d1e963f47e1f5d4773a3775.tar.gz
dt-utils-6e912489417b93528d1e963f47e1f5d4773a3775.tar.xz
libdt: add block devicepath extraction
This allows barebox state to find the backend node on block devices. Signed-off-by: Bastian Stender <bst@pengutronix.de> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'src')
-rw-r--r--src/libdt.c69
1 files changed, 65 insertions, 4 deletions
diff --git a/src/libdt.c b/src/libdt.c
index 7a1fb55..1fc3677 100644
--- a/src/libdt.c
+++ b/src/libdt.c
@@ -2028,6 +2028,61 @@ static struct udev_device *device_find_mtd_partition(struct udev_device *dev,
}
/*
+ * device_find_block_device - extract device path from udev block device
+ *
+ * @dev: the udev_device to extract information from
+ * @devpath: returns the devicepath under which the block device is accessible
+ *
+ * returns 0 for success or negative error value on failure.
+ */
+int device_find_block_device(struct udev_device *dev,
+ char **devpath)
+{
+
+ struct udev *udev;
+ struct udev_enumerate *enumerate;
+ struct udev_list_entry *devices, *dev_list_entry;
+ struct udev_device *part;
+ const char *outpath;
+ int ret;
+
+ udev = udev_new();
+ if (!udev) {
+ fprintf(stderr, "Can't create udev\n");
+ return -ENODEV;
+ }
+
+ enumerate = udev_enumerate_new(udev);
+ /* block device and partitions get identified by subsystem in subtree */
+ udev_enumerate_add_match_parent(enumerate, dev);
+ udev_enumerate_add_match_subsystem(enumerate, "block");
+ udev_enumerate_scan_devices(enumerate);
+ devices = udev_enumerate_get_list_entry(enumerate);
+ udev_list_entry_foreach(dev_list_entry, devices) {
+ const char *path, *devtype;
+ path = udev_list_entry_get_name(dev_list_entry);
+ part = udev_device_new_from_syspath(udev, path);
+ /* distinguish device (disk) from partitions */
+ devtype = udev_device_get_devtype(part);
+ if (!devtype)
+ continue;
+ if (!strcmp(devtype, "disk")) {
+ outpath = udev_device_get_devnode(part);
+ *devpath = strdup(outpath);
+ ret = 0;
+ goto out;
+ }
+ }
+ ret = -ENODEV;
+
+out:
+ udev_enumerate_unref(enumerate);
+ udev_unref(udev);
+
+ return ret;
+}
+
+/*
* of_parse_partition - extract offset and size from a partition device_node
*
* returns true for success, negative error code otherwise
@@ -2209,10 +2264,11 @@ out:
* This function takes a device_node which represents a partition.
* For this partition the function returns the device path and the offset
* and size in the device. For mtd devices the path will be /dev/mtdx, for
- * EEPROMs it will be /sys/.../eeprom. For mtd devices the device path returned
- * will be the partition itself. Since EEPROMs do not have partitions under
- * Linux @offset and @size will describe the offset and size inside the full
- * device.
+ * EEPROMs it will be /sys/.../eeprom and for block devices it will be /dev/...
+ * For mtd devices the device path returned will be the partition itself.
+ * Since EEPROMs do not have partitions under Linux @offset and @size will
+ * describe the offset and size inside the full device. The same applies to
+ * block devices.
*
* returns 0 for success or negative error value on failure.
*/
@@ -2227,6 +2283,11 @@ int of_get_devicepath(struct device_node *partition_node, char **devpath, off_t
*offset = 0;
*size = 0;
+ /* try to find a block device */
+ ret = device_find_block_device(dev, devpath);
+ if (!ret)
+ return of_parse_partition(partition_node, offset, size);
+
/*
* simplest case: This nodepath can directly be translated into
* a mtd or eeprom device. A mtd device requires that the mtd