From 804f7d63f26c00a64e2945fced4841abf200c0c0 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 14 Aug 2023 01:46:47 +0200 Subject: disk: Move part_create_block_devices() to blk uclass Move part_create_block_devices() to blk uclass and unexpose the function. This can now be internal to the block uclass. Signed-off-by: Marek Vasut --- drivers/block/blk-uclass.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'drivers/block/blk-uclass.c') diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c index 614b975e25c..9521b3eb878 100644 --- a/drivers/block/blk-uclass.c +++ b/drivers/block/blk-uclass.c @@ -766,6 +766,54 @@ int blk_unbind_all(int uclass_id) return 0; } +static int part_create_block_devices(struct udevice *blk_dev) +{ + int part, count; + struct blk_desc *desc = dev_get_uclass_plat(blk_dev); + struct disk_partition info; + struct disk_part *part_data; + char devname[32]; + struct udevice *dev; + int ret; + + if (!CONFIG_IS_ENABLED(PARTITIONS) || !blk_enabled()) + return 0; + + if (device_get_uclass_id(blk_dev) != UCLASS_BLK) + return 0; + + /* Add devices for each partition */ + for (count = 0, part = 1; part <= MAX_SEARCH_PARTITIONS; part++) { + if (part_get_info(desc, part, &info)) + continue; + snprintf(devname, sizeof(devname), "%s:%d", blk_dev->name, + part); + + ret = device_bind_driver(blk_dev, "blk_partition", + strdup(devname), &dev); + if (ret) + return ret; + + part_data = dev_get_uclass_plat(dev); + part_data->partnum = part; + part_data->gpt_part_info = info; + count++; + + ret = device_probe(dev); + if (ret) { + debug("Can't probe\n"); + count--; + device_unbind(dev); + + continue; + } + } + debug("%s: %d partitions found in %s\n", __func__, count, + blk_dev->name); + + return 0; +} + static int blk_post_probe(struct udevice *dev) { if (CONFIG_IS_ENABLED(PARTITIONS) && blk_enabled()) { -- cgit v1.2.3 From 7f0fba9fb08fb7d31060848c719ffad3739e9d58 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 14 Aug 2023 01:46:48 +0200 Subject: disk: Make blk_get_ops() internal to blk uclass Move the macro into blk-uclass.c , since it is only used there. Signed-off-by: Marek Vasut Reviewed-by: Simon Glass --- drivers/block/blk-uclass.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/block/blk-uclass.c') diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c index 9521b3eb878..6aac92d9962 100644 --- a/drivers/block/blk-uclass.c +++ b/drivers/block/blk-uclass.c @@ -17,6 +17,8 @@ #include #include +#define blk_get_ops(dev) ((struct blk_ops *)(dev)->driver->ops) + static struct { enum uclass_id id; const char *name; -- cgit v1.2.3 From 75191f75bce45f3b9aff607c88f17778d3805c61 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 14 Aug 2023 01:49:59 +0200 Subject: blk: Add bounce buffer support to read/write operations Some devices have limited DMA capabilities and require that the buffers passed to them fit specific properties. Add new optional callback which can be used at driver level to indicate whether a buffer alignment is suitable for the device DMA or not, and trigger use of generic bounce buffer implementation to help use of unsuitable buffers at the expense of performance degradation. Signed-off-by: Marek Vasut --- drivers/block/blk-uclass.c | 62 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) (limited to 'drivers/block/blk-uclass.c') diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c index 6aac92d9962..885513893f6 100644 --- a/drivers/block/blk-uclass.c +++ b/drivers/block/blk-uclass.c @@ -446,6 +446,26 @@ int blk_get_device(int uclass_id, int devnum, struct udevice **devp) return device_probe(*devp); } +struct blk_bounce_buffer { + struct udevice *dev; + struct bounce_buffer state; +}; + +static int blk_buffer_aligned(struct bounce_buffer *state) +{ +#if IS_ENABLED(CONFIG_BOUNCE_BUFFER) + struct blk_bounce_buffer *bbstate = + container_of(state, struct blk_bounce_buffer, state); + struct udevice *dev = bbstate->dev; + const struct blk_ops *ops = blk_get_ops(dev); + + if (ops->buffer_aligned) + return ops->buffer_aligned(dev, state); +#endif /* CONFIG_BOUNCE_BUFFER */ + + return 1; /* Default, any buffer is OK */ +} + long blk_read(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, void *buf) { struct blk_desc *desc = dev_get_uclass_plat(dev); @@ -458,7 +478,25 @@ long blk_read(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, void *buf) if (blkcache_read(desc->uclass_id, desc->devnum, start, blkcnt, desc->blksz, buf)) return blkcnt; - blks_read = ops->read(dev, start, blkcnt, buf); + + if (IS_ENABLED(CONFIG_BOUNCE_BUFFER)) { + struct blk_bounce_buffer bbstate = { .dev = dev }; + int ret; + + ret = bounce_buffer_start_extalign(&bbstate.state, buf, + blkcnt * desc->blksz, + GEN_BB_WRITE, desc->blksz, + blk_buffer_aligned); + if (ret) + return ret; + + blks_read = ops->read(dev, start, blkcnt, bbstate.state.bounce_buffer); + + bounce_buffer_stop(&bbstate.state); + } else { + blks_read = ops->read(dev, start, blkcnt, buf); + } + if (blks_read == blkcnt) blkcache_fill(desc->uclass_id, desc->devnum, start, blkcnt, desc->blksz, buf); @@ -471,13 +509,33 @@ long blk_write(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, { struct blk_desc *desc = dev_get_uclass_plat(dev); const struct blk_ops *ops = blk_get_ops(dev); + long blks_written; if (!ops->write) return -ENOSYS; blkcache_invalidate(desc->uclass_id, desc->devnum); - return ops->write(dev, start, blkcnt, buf); + if (IS_ENABLED(CONFIG_BOUNCE_BUFFER)) { + struct blk_bounce_buffer bbstate = { .dev = dev }; + int ret; + + ret = bounce_buffer_start_extalign(&bbstate.state, (void *)buf, + blkcnt * desc->blksz, + GEN_BB_READ, desc->blksz, + blk_buffer_aligned); + if (ret) + return ret; + + blks_written = ops->write(dev, start, blkcnt, + bbstate.state.bounce_buffer); + + bounce_buffer_stop(&bbstate.state); + } else { + blks_written = ops->write(dev, start, blkcnt, buf); + } + + return blks_written; } long blk_erase(struct udevice *dev, lbaint_t start, lbaint_t blkcnt) -- cgit v1.2.3