diff options
-rw-r--r-- | arch/arm/mach-mxs/ocotp.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-omap/xload.c | 4 | ||||
-rw-r--r-- | common/bootm.c | 6 | ||||
-rw-r--r-- | common/efi/payload/init.c | 4 | ||||
-rw-r--r-- | common/filetype.c | 2 | ||||
-rw-r--r-- | common/partitions.c | 2 | ||||
-rw-r--r-- | common/partitions/dos.c | 3 | ||||
-rw-r--r-- | common/partitions/efi.c | 2 | ||||
-rw-r--r-- | common/partitions/parser.h | 2 | ||||
-rw-r--r-- | drivers/base/driver.c | 30 | ||||
-rw-r--r-- | drivers/misc/Kconfig | 23 | ||||
-rw-r--r-- | drivers/misc/Makefile | 1 | ||||
-rw-r--r-- | drivers/misc/storage-by-uuid.c | 199 | ||||
-rw-r--r-- | drivers/of/base.c | 2 | ||||
-rw-r--r-- | drivers/of/platform.c | 3 | ||||
-rw-r--r-- | drivers/usb/core/usb.c | 1 | ||||
-rw-r--r-- | fs/devfs-core.c | 103 | ||||
-rw-r--r-- | fs/devfs.c | 50 | ||||
-rw-r--r-- | fs/fs.c | 8 | ||||
-rw-r--r-- | include/driver.h | 22 | ||||
-rw-r--r-- | lib/bootstrap/devfs.c | 4 |
21 files changed, 397 insertions, 76 deletions
diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c index 5f78d9d773..9bcd913cc1 100644 --- a/arch/arm/mach-mxs/ocotp.c +++ b/arch/arm/mach-mxs/ocotp.c @@ -229,7 +229,7 @@ int mxs_ocotp_read(void *buf, int count, int offset) struct cdev *cdev; int ret; - cdev = cdev_open(DRIVERNAME, O_RDONLY); + cdev = cdev_open_by_name(DRIVERNAME, O_RDONLY); if (!cdev) return -ENODEV; diff --git a/arch/arm/mach-omap/xload.c b/arch/arm/mach-omap/xload.c index 0fe78883d1..af9abf38b5 100644 --- a/arch/arm/mach-omap/xload.c +++ b/arch/arm/mach-omap/xload.c @@ -38,7 +38,7 @@ static void *read_image_head(const char *name) struct cdev *cdev; int ret; - cdev = cdev_open(name, O_RDONLY); + cdev = cdev_open_by_name(name, O_RDONLY); if (!cdev) { printf("failed to open %s\n", name); return NULL; @@ -86,7 +86,7 @@ static void *read_mtd_barebox(const char *partition) to = xmalloc(size); - cdev = cdev_open(partition, O_RDONLY); + cdev = cdev_open_by_name(partition, O_RDONLY); if (!cdev) { printf("failed to open partition\n"); return NULL; diff --git a/common/bootm.c b/common/bootm.c index 89e3e93f2c..4652467448 100644 --- a/common/bootm.c +++ b/common/bootm.c @@ -709,15 +709,15 @@ int bootm_boot(struct bootm_data *bootm_data) const char *root_dev_name = devpath_to_name(bootm_data->root_dev); const struct cdev *root_cdev = cdev_by_name(root_dev_name); - if (root_cdev && root_cdev->partuuid[0] != 0) { - rootarg = basprintf("root=PARTUUID=%s", root_cdev->partuuid); + if (root_cdev && root_cdev->uuid[0] != 0) { + rootarg = basprintf("root=PARTUUID=%s", root_cdev->uuid); } else { rootarg = ERR_PTR(-EINVAL); if (!root_cdev) pr_err("no cdev found for %s, cannot set root= option\n", root_dev_name); - else if (!root_cdev->partuuid[0]) + else if (!root_cdev->uuid[0]) pr_err("%s doesn't have a PARTUUID, cannot set root= option\n", root_dev_name); } diff --git a/common/efi/payload/init.c b/common/efi/payload/init.c index 6db6b23895..1541683186 100644 --- a/common/efi/payload/init.c +++ b/common/efi/payload/init.c @@ -349,7 +349,9 @@ static int efi_late_init(void) if (IS_ERR(root)) return PTR_ERR(root); - of_set_root_node(root); + ret = barebox_register_of(root); + if (ret) + pr_warn("Failed to register device-tree: %pe\n", ERR_PTR(ret)); np = of_find_node_by_alias(root, "state"); diff --git a/common/filetype.c b/common/filetype.c index 8ffcd6adcd..2039134516 100644 --- a/common/filetype.c +++ b/common/filetype.c @@ -438,7 +438,7 @@ enum filetype cdev_detect_type(const char *name) struct cdev *cdev; void *buf; - cdev = cdev_open(name, O_RDONLY); + cdev = cdev_open_by_name(name, O_RDONLY); if (!cdev) return type; diff --git a/common/partitions.c b/common/partitions.c index b579559672..9cca5c4a15 100644 --- a/common/partitions.c +++ b/common/partitions.c @@ -51,7 +51,7 @@ static int register_one_partition(struct block_device *blk, cdev->flags |= DEVFS_PARTITION_FROM_TABLE; cdev->dos_partition_type = part->dos_partition_type; - strcpy(cdev->partuuid, part->partuuid); + strcpy(cdev->uuid, part->partuuid); free(partition_name); diff --git a/common/partitions/dos.c b/common/partitions/dos.c index 597d7bf9bc..566c8dd949 100644 --- a/common/partitions/dos.c +++ b/common/partitions/dos.c @@ -182,6 +182,9 @@ static void dos_partition(void *buf, struct block_device *blk, struct disk_signature_priv *dsp; uint32_t signature = get_unaligned_le32(buf + 0x1b8); + if (signature) + sprintf(blk->cdev.uuid, "%08x", signature); + table = (struct partition_entry *)&buffer[446]; for (i = 0; i < 4; i++) { diff --git a/common/partitions/efi.c b/common/partitions/efi.c index 6d811bfb3b..0787b93f12 100644 --- a/common/partitions/efi.c +++ b/common/partitions/efi.c @@ -445,6 +445,8 @@ static void efi_partition(void *buf, struct block_device *blk, return; } + snprintf(blk->cdev.uuid, sizeof(blk->cdev.uuid), "%pUl", &gpt->disk_guid); + nb_part = le32_to_cpu(gpt->num_partition_entries); if (nb_part > MAX_PARTITION) { diff --git a/common/partitions/parser.h b/common/partitions/parser.h index 69508932b3..d67f8e1d6a 100644 --- a/common/partitions/parser.h +++ b/common/partitions/parser.h @@ -17,7 +17,7 @@ struct partition { char name[MAX_PARTITION_NAME]; u8 dos_partition_type; - char partuuid[MAX_PARTUUID_STR]; + char partuuid[MAX_UUID_STR]; uint64_t first_sec; uint64_t size; }; diff --git a/drivers/base/driver.c b/drivers/base/driver.c index f54f4d0b37..2347b5c71f 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -270,6 +270,36 @@ int unregister_device(struct device_d *old_dev) } EXPORT_SYMBOL(unregister_device); +/** + * free_device_res - free dynamically allocated device members + * @dev: The device + * + * This frees dynamically allocated resources allocated during device + * lifetime, but not the device itself. + */ +void free_device_res(struct device_d *dev) +{ + free(dev->name); + dev->name = NULL; + free(dev->unique_name); + dev->unique_name = NULL; +} +EXPORT_SYMBOL(free_device_res); + +/** + * free_device - free a device + * @dev: The device + * + * This frees dynamically allocated resources allocated during device + * lifetime and finally the device itself. + */ +void free_device(struct device_d *dev) +{ + free_device_res(dev); + free(dev); +} +EXPORT_SYMBOL(free_device); + /* * Loop over list of deferred devices as long as at least one * device is successfully probed. Devices that again request diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 5ab0506cd9..78c9c193d8 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -47,4 +47,27 @@ config STARFIVE_PWRSEQ be accessed over /dev/mem or used from kernels which still depend on bootloader for initialization. +config STORAGE_BY_UUID + bool "storage by UUID" + depends on OFDEVICE + help + This adds a driver which matches to a "barebox,storage-by-uuid" + compatible node. The driver looks for a storage device matching the + given UUID and when found registers a new cdev for the device. + + This driver solved a very specific problem. On EFI the storage devices + are not connected to any device tree node. barebox-state however expects + a node to use as its backend. The obvious solution would be to create + a partition with a specific partuuid and use that for state, in our + special usecase though the storage device is partitioned with a MBR + which doesn't have any space left to create a new partition. As this + driver parses the of partition binding we can use that to create + a partition in an unallocated are of the disk which is then used for + state. + + This driver has the problem that it depends on storage devices which + are not described in the device tree. This means it cannot work with + deep probe. This is not a problem on EFI though. It's a special purpose + driver, it's not recommended for general use. + endmenu diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 6326e784fc..986f7b1b38 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -9,3 +9,4 @@ obj-$(CONFIG_STATE_DRV) += state.o obj-$(CONFIG_DEV_MEM) += mem.o obj-$(CONFIG_UBOOTVAR) += ubootvar.o obj-$(CONFIG_STARFIVE_PWRSEQ) += starfive-pwrseq.o +obj-$(CONFIG_STORAGE_BY_UUID) += storage-by-uuid.o diff --git a/drivers/misc/storage-by-uuid.c b/drivers/misc/storage-by-uuid.c new file mode 100644 index 0000000000..12a06076a2 --- /dev/null +++ b/drivers/misc/storage-by-uuid.c @@ -0,0 +1,199 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include <common.h> +#include <init.h> +#include <io.h> +#include <of.h> +#include <malloc.h> +#include <partition.h> +#include <envfs.h> +#include <fs.h> + +static LIST_HEAD(sbu_list); + +struct sbu { + char *uuid; + struct device_d *dev; + struct cdev *rcdev; + struct cdev cdev; + struct list_head list; +}; + +void storage_by_uuid_check_exist(struct cdev *cdev); + +static ssize_t sbu_read(struct cdev *cdev, void *buf, size_t count, loff_t offset, ulong flags) +{ + struct sbu *sbu = cdev->priv; + + return cdev_read(sbu->rcdev, buf, count, offset, flags); +} + +static ssize_t sbu_write(struct cdev *cdev, const void *buf, size_t count, loff_t offset, ulong flags) +{ + struct sbu *sbu = cdev->priv; + + return cdev_write(sbu->rcdev, buf, count, offset, flags); +} + +static int sbu_ioctl(struct cdev *cdev, int request, void *buf) +{ + struct sbu *sbu = cdev->priv; + + return cdev_ioctl(sbu->rcdev, request, buf); +} + +static int sbu_open(struct cdev *cdev, unsigned long flags) +{ + struct sbu *sbu = cdev->priv; + + return cdev_open(sbu->rcdev, flags); +} + +static int sbu_close(struct cdev *cdev) +{ + struct sbu *sbu = cdev->priv; + + cdev_close(sbu->rcdev); + + return 0; +} + +static int sbu_flush(struct cdev *cdev) +{ + struct sbu *sbu = cdev->priv; + + return cdev_flush(sbu->rcdev); +} + +static int sbu_erase(struct cdev *cdev, loff_t count, loff_t offset) +{ + struct sbu *sbu = cdev->priv; + + return cdev_erase(sbu->rcdev, count, offset); +} + +static int sbu_protect(struct cdev *cdev, size_t count, loff_t offset, int prot) +{ + struct sbu *sbu = cdev->priv; + + return cdev_protect(sbu->rcdev, count, offset, prot); +} + +static int sbu_discard_range(struct cdev *cdev, loff_t count, loff_t offset) +{ + struct sbu *sbu = cdev->priv; + + return cdev_discard_range(sbu->rcdev, count, offset); +} + +static int sbu_memmap(struct cdev *cdev, void **map, int flags) +{ + struct sbu *sbu = cdev->priv; + + return cdev_memmap(sbu->rcdev, map, flags); +} + +static int sbu_truncate(struct cdev *cdev, size_t size) +{ + struct sbu *sbu = cdev->priv; + + return cdev_truncate(sbu->rcdev, size); +} + +static struct cdev_operations sbu_ops = { + .read = sbu_read, + .write = sbu_write, + .ioctl = sbu_ioctl, + .open = sbu_open, + .close = sbu_close, + .flush = sbu_flush, + .erase = sbu_erase, + .protect = sbu_protect, + .discard_range = sbu_discard_range, + .memmap = sbu_memmap, + .truncate = sbu_truncate, +}; + +static void storage_by_uuid_add_partitions(struct sbu *sbu, struct cdev *rcdev) +{ + int ret; + + if (sbu->rcdev) + return; + + sbu->rcdev = rcdev; + sbu->cdev.name = sbu->uuid; + sbu->cdev.size = rcdev->size; + sbu->cdev.ops = &sbu_ops; + sbu->cdev.dev = sbu->dev; + sbu->cdev.priv = sbu; + + ret = devfs_create(&sbu->cdev); + if (ret) { + dev_err(sbu->dev, "Failed to create cdev: %s\n", strerror(-ret)); + return; + } + + of_parse_partitions(&sbu->cdev, sbu->dev->device_node); +} + +static void check_exist(struct sbu *sbu) +{ + struct cdev *cdev; + + for_each_cdev(cdev) { + if (!strcmp(cdev->uuid, sbu->uuid)) { + dev_dbg(sbu->dev, "Found %s %s\n", cdev->name, cdev->uuid); + storage_by_uuid_add_partitions(sbu, cdev); + } + } +} + +static int sbu_detect(struct device_d *dev) +{ + struct sbu *sbu = dev->priv; + + dev_dbg(dev, "%s\n", __func__); + + check_exist(sbu); + + return 0; +} + +static int storage_by_uuid_probe(struct device_d *dev) +{ + struct sbu *sbu; + int ret; + const char *uuid; + + sbu = xzalloc(sizeof(*sbu)); + + ret = of_property_read_string(dev->device_node, "uuid", &uuid); + if (ret) + return ret; + + sbu->dev = dev; + sbu->uuid = xstrdup(uuid); + + list_add_tail(&sbu->list, &sbu_list); + + check_exist(sbu); + dev->priv = sbu; + dev->detect = sbu_detect; + + return 0; +} + +static struct of_device_id storage_by_uuid_dt_ids[] = { + { + .compatible = "barebox,storage-by-uuid", + }, { + /* sentinel */ + } +}; + +static struct driver_d storage_by_uuid_driver = { + .name = "storage-by-uuid", + .probe = storage_by_uuid_probe, + .of_compatible = storage_by_uuid_dt_ids, +}; +device_platform_driver(storage_by_uuid_driver); diff --git a/drivers/of/base.c b/drivers/of/base.c index 80465d6d50..2591610c3f 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -2383,7 +2383,7 @@ static void of_platform_device_create_root(struct device_node *np) ret = platform_device_register(dev); if (ret) - free(dev); + free_device(dev); } static const struct of_device_id reserved_mem_matches[] = { diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 3a82809cb3..0e718469db 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -155,7 +155,7 @@ struct device_d *of_platform_device_create(struct device_node *np, np->dev = NULL; - free(dev); + free_device(dev); if (num_reg) free(res); return NULL; @@ -278,6 +278,7 @@ static struct device_d *of_amba_device_create(struct device_node *np) return &dev->dev; amba_err_free: + free_device_res(&dev->dev); free(dev); return NULL; } diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 4eede13a11..34a0f004f7 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -534,6 +534,7 @@ void usb_free_device(struct usb_device *usbdev) { dma_free(usbdev->descriptor); dma_free(usbdev->setup_packet); + free_device_res(&usbdev->dev); free(usbdev); } diff --git a/fs/devfs-core.c b/fs/devfs-core.c index 2d016e0e48..38423e5d1e 100644 --- a/fs/devfs-core.c +++ b/fs/devfs-core.c @@ -37,7 +37,7 @@ int devfs_partition_complete(struct string_list *sl, char *instr) len = strlen(instr); - list_for_each_entry(cdev, &cdev_list, list) { + for_each_cdev(cdev) { if (cdev->master && !strncmp(instr, cdev->name, len)) { string_list_add_asprintf(sl, "%s ", cdev->name); @@ -62,7 +62,7 @@ struct cdev *lcdev_by_name(const char *filename) { struct cdev *cdev; - list_for_each_entry(cdev, &cdev_list, list) { + for_each_cdev(cdev) { if (!strcmp(cdev->name, filename)) return cdev; } @@ -84,7 +84,7 @@ struct cdev *cdev_by_device_node(struct device_node *node) { struct cdev *cdev; - list_for_each_entry(cdev, &cdev_list, list) { + for_each_cdev(cdev) { if (!cdev->device_node) continue; if (cdev->device_node == node) @@ -100,8 +100,22 @@ struct cdev *cdev_by_partuuid(const char *partuuid) if (!partuuid) return NULL; - list_for_each_entry(cdev, &cdev_list, list) { - if (!strcasecmp(cdev->partuuid, partuuid)) + for_each_cdev(cdev) { + if (cdev->master && !strcasecmp(cdev->uuid, partuuid)) + return cdev; + } + return NULL; +} + +struct cdev *cdev_by_diskuuid(const char *diskuuid) +{ + struct cdev *cdev; + + if (!diskuuid) + return NULL; + + for_each_cdev(cdev) { + if (!cdev->master && !strcasecmp(cdev->uuid, diskuuid)) return cdev; } return NULL; @@ -155,7 +169,15 @@ int cdev_find_free_index(const char *basename) return -EBUSY; /* all indexes are used */ } -struct cdev *cdev_open(const char *name, unsigned long flags) +int cdev_open(struct cdev *cdev, unsigned long flags) +{ + if (cdev->ops->open) + return cdev->ops->open(cdev, flags); + + return 0; +} + +struct cdev *cdev_open_by_name(const char *name, unsigned long flags) { struct cdev *cdev; int ret; @@ -164,11 +186,9 @@ struct cdev *cdev_open(const char *name, unsigned long flags) if (!cdev) return NULL; - if (cdev->ops->open) { - ret = cdev->ops->open(cdev, flags); - if (ret) - return NULL; - } + ret = cdev_open(cdev, flags); + if (ret) + return NULL; return cdev; } @@ -219,6 +239,67 @@ int cdev_erase(struct cdev *cdev, loff_t count, loff_t offset) return cdev->ops->erase(cdev, count, cdev->offset + offset); } +int cdev_lseek(struct cdev *cdev, loff_t pos) +{ + int ret; + + if (cdev->ops->lseek) { + ret = cdev->ops->lseek(cdev, pos + cdev->offset); + if (ret < 0) + return ret; + } + + return 0; +} + +int cdev_protect(struct cdev *cdev, size_t count, loff_t offset, int prot) +{ + if (!cdev->ops->protect) + return -ENOSYS; + + return cdev->ops->protect(cdev, count, offset + cdev->offset, prot); +} + +int cdev_discard_range(struct cdev *cdev, loff_t count, loff_t offset) +{ + if (!cdev->ops->discard_range) + return -ENOSYS; + + if (cdev->flags & DEVFS_PARTITION_READONLY) + return -EPERM; + + if (offset >= cdev->size) + return 0; + + if (count + offset > cdev->size) + count = cdev->size - offset; + + return cdev->ops->discard_range(cdev, count, offset + cdev->offset); +} + +int cdev_memmap(struct cdev *cdev, void **map, int flags) +{ + int ret = -ENOSYS; + + if (!cdev->ops->memmap) + return -EINVAL; + + ret = cdev->ops->memmap(cdev, map, flags); + + if (!ret) + *map = (void *)((unsigned long)*map + (unsigned long)cdev->offset); + + return ret; +} + +int cdev_truncate(struct cdev *cdev, size_t size) +{ + if (cdev->ops->truncate) + return cdev->ops->truncate(cdev, size); + + return -EPERM; +} + int devfs_create(struct cdev *new) { struct cdev *cdev; diff --git a/fs/devfs.c b/fs/devfs.c index df229cca48..deb244feea 100644 --- a/fs/devfs.c +++ b/fs/devfs.c @@ -35,8 +35,6 @@ struct devfs_inode { struct cdev *cdev; }; -extern struct list_head cdev_list; - static int devfs_read(struct device_d *_dev, FILE *f, void *buf, size_t size) { struct cdev *cdev = f->priv; @@ -57,15 +55,8 @@ static int devfs_write(struct device_d *_dev, FILE *f, const void *buf, size_t s static int devfs_lseek(struct device_d *_dev, FILE *f, loff_t pos) { struct cdev *cdev = f->priv; - int ret; - - if (cdev->ops->lseek) { - ret = cdev->ops->lseek(cdev, pos + cdev->offset); - if (ret < 0) - return ret; - } - return 0; + return cdev_lseek(cdev, pos); } static int devfs_erase(struct device_d *_dev, FILE *f, loff_t count, loff_t offset) @@ -81,14 +72,11 @@ static int devfs_erase(struct device_d *_dev, FILE *f, loff_t count, loff_t offs return cdev_erase(cdev, count, offset); } -static int devfs_protect(struct device_d *_dev, FILE *f, size_t count, loff_t offset, int prot) +static int devfs_protect(struct device_d *dev, FILE *f, size_t count, loff_t offset, int prot) { struct cdev *cdev = f->priv; - if (!cdev->ops->protect) - return -ENOSYS; - - return cdev->ops->protect(cdev, count, offset + cdev->offset, prot); + return cdev_protect(cdev, count, offset, prot); } static int devfs_discard_range(struct device_d *dev, FILE *f, loff_t count, @@ -96,35 +84,14 @@ static int devfs_discard_range(struct device_d *dev, FILE *f, loff_t count, { struct cdev *cdev = f->priv; - if (!cdev->ops->discard_range) - return -ENOSYS; - - if (cdev->flags & DEVFS_PARTITION_READONLY) - return -EPERM; - - if (offset >= cdev->size) - return 0; - - if (count + offset > cdev->size) - count = cdev->size - offset; - - return cdev->ops->discard_range(cdev, count, offset + cdev->offset); + return cdev_discard_range(cdev, count, offset); } static int devfs_memmap(struct device_d *_dev, FILE *f, void **map, int flags) { struct cdev *cdev = f->priv; - int ret = -ENOSYS; - - if (!cdev->ops->memmap) - return -EINVAL; - - ret = cdev->ops->memmap(cdev, map, flags); - if (!ret) - *map = (void *)((unsigned long)*map + (unsigned long)cdev->offset); - - return ret; + return cdev_memmap(cdev, map, flags); } static int devfs_open(struct device_d *_dev, FILE *f, const char *filename) @@ -183,10 +150,7 @@ static int devfs_truncate(struct device_d *dev, FILE *f, loff_t size) { struct cdev *cdev = f->priv; - if (cdev->ops->truncate) - return cdev->ops->truncate(cdev, size); - - return -EPERM; + return cdev_truncate(cdev, size); } static struct inode *devfs_alloc_inode(struct super_block *sb) @@ -213,7 +177,7 @@ static int devfs_iterate(struct file *file, struct dir_context *ctx) dir_emit_dots(file, ctx); - list_for_each_entry(cdev, &cdev_list, list) { + for_each_cdev(cdev) { dir_emit(ctx, cdev->name, strlen(cdev->name), 1 /* FIXME */, DT_REG); } @@ -800,7 +800,7 @@ int fsdev_open_cdev(struct fs_device_d *fsdev) fsdev->cdev = cdev_create_loop(fsdev->backingstore, O_RDWR, offset); } else { - fsdev->cdev = cdev_open(fsdev->backingstore, O_RDWR); + fsdev->cdev = cdev_open_by_name(fsdev->backingstore, O_RDWR); } if (!fsdev->cdev) { path_put(&path); @@ -2999,8 +2999,8 @@ int mount(const char *device, const char *fsname, const char *pathname, cdev_is_mci_main_part_dev(fsdev->cdev->master)) str = get_linux_mmcblkdev(fsdev); - if (!str && fsdev->cdev->partuuid[0] != 0) - str = basprintf("root=PARTUUID=%s", fsdev->cdev->partuuid); + if (!str && fsdev->cdev->uuid[0] != 0) + str = basprintf("root=PARTUUID=%s", fsdev->cdev->uuid); if (str) fsdev_set_linux_rootarg(fsdev, str); @@ -3048,7 +3048,7 @@ int umount(const char *pathname) path_put(&path); if (!fsdev) { - struct cdev *cdev = cdev_open(pathname, O_RDWR); + struct cdev *cdev = cdev_open_by_name(pathname, O_RDWR); if (cdev) { cdev_close(cdev); diff --git a/include/driver.h b/include/driver.h index 1215a2d57a..a787f985a0 100644 --- a/include/driver.h +++ b/include/driver.h @@ -141,6 +141,10 @@ void device_detect_all(void); */ int unregister_device(struct device_d *); +void free_device_res(struct device_d *dev); +void free_device(struct device_d *dev); + + /* Iterate over a devices children */ #define device_for_each_child(dev, child) \ @@ -451,7 +455,7 @@ struct cdev_operations { int (*truncate)(struct cdev*, size_t size); }; -#define MAX_PARTUUID_STR sizeof("00112233-4455-6677-8899-AABBCCDDEEFF") +#define MAX_UUID_STR sizeof("00112233-4455-6677-8899-AABBCCDDEEFF") struct cdev { const struct cdev_operations *ops; @@ -464,7 +468,7 @@ struct cdev { char *partname; /* the partition name, usually the above without the * device part, i.e. name = "nand0.barebox" -> partname = "barebox" */ - char partuuid[MAX_PARTUUID_STR]; + char uuid[MAX_UUID_STR]; loff_t offset; loff_t size; unsigned int flags; @@ -488,18 +492,28 @@ struct cdev *lcdev_by_name(const char *filename); struct cdev *cdev_readlink(struct cdev *cdev); struct cdev *cdev_by_device_node(struct device_node *node); struct cdev *cdev_by_partuuid(const char *partuuid); -struct cdev *cdev_open(const char *name, unsigned long flags); +struct cdev *cdev_by_diskuuid(const char *partuuid); +struct cdev *cdev_open_by_name(const char *name, unsigned long flags); struct cdev *cdev_create_loop(const char *path, ulong flags, loff_t offset); void cdev_remove_loop(struct cdev *cdev); -int cdev_do_open(struct cdev *, unsigned long flags); +int cdev_open(struct cdev *, unsigned long flags); void cdev_close(struct cdev *cdev); int cdev_flush(struct cdev *cdev); ssize_t cdev_read(struct cdev *cdev, void *buf, size_t count, loff_t offset, ulong flags); ssize_t cdev_write(struct cdev *cdev, const void *buf, size_t count, loff_t offset, ulong flags); int cdev_ioctl(struct cdev *cdev, int cmd, void *buf); int cdev_erase(struct cdev *cdev, loff_t count, loff_t offset); +int cdev_lseek(struct cdev*, loff_t); +int cdev_protect(struct cdev*, size_t count, loff_t offset, int prot); +int cdev_discard_range(struct cdev*, loff_t count, loff_t offset); +int cdev_memmap(struct cdev*, void **map, int flags); +int cdev_truncate(struct cdev*, size_t size); loff_t cdev_unallocated_space(struct cdev *cdev); +extern struct list_head cdev_list; +#define for_each_cdev(c) \ + list_for_each_entry(cdev, &cdev_list, list) + #define DEVFS_PARTITION_FIXED (1U << 0) #define DEVFS_PARTITION_READONLY (1U << 1) #define DEVFS_IS_CHARACTER_DEV (1U << 3) diff --git a/lib/bootstrap/devfs.c b/lib/bootstrap/devfs.c index 6d28b1cb4d..873c4b0170 100644 --- a/lib/bootstrap/devfs.c +++ b/lib/bootstrap/devfs.c @@ -32,7 +32,7 @@ static void *read_image_head(const char *name) struct cdev *cdev; int ret; - cdev = cdev_open(name, O_RDONLY); + cdev = cdev_open_by_name(name, O_RDONLY); if (!cdev) { bootstrap_err("failed to open partition\n"); goto free_header; @@ -124,7 +124,7 @@ void* bootstrap_read_devfs(char *devname, bool use_bb, int offset, to = xmalloc(size); - cdev = cdev_open(partname, O_RDONLY); + cdev = cdev_open_by_name(partname, O_RDONLY); if (!cdev) { bootstrap_err("%s: failed to open %s\n", devname, partname); goto free_memory; |