From 6e912489417b93528d1e963f47e1f5d4773a3775 Mon Sep 17 00:00:00 2001 From: Bastian Stender Date: Fri, 11 Mar 2016 11:28:46 +0100 Subject: libdt: add block devicepath extraction This allows barebox state to find the backend node on block devices. Signed-off-by: Bastian Stender Signed-off-by: Marc Kleine-Budde --- src/libdt.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 65 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/libdt.c b/src/libdt.c index 7a1fb55..1fc3677 100644 --- a/src/libdt.c +++ b/src/libdt.c @@ -2027,6 +2027,61 @@ static struct udev_device *device_find_mtd_partition(struct udev_device *dev, return NULL; } +/* + * 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 * @@ -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 -- cgit v1.2.3