From: Denis Mukhin <[email protected]> Add generic flush operations for committing dirty data to the storage device.
This provides a common block-layer interface for flushing pending writes, allowing callers to ensure that data buffered by the block device or its backing implementation is written out to the underlying storage. Signed-off-by: Denis Mukhin <[email protected]> --- Changes since v1: - new patch --- disk/disk-uclass.c | 6 ++++++ drivers/block/blk-uclass.c | 18 ++++++++++++++++++ include/blk.h | 28 ++++++++++++++++++++++++++++ include/part.h | 8 ++++++++ 4 files changed, 60 insertions(+) diff --git a/disk/disk-uclass.c b/disk/disk-uclass.c index ee3cc4407d76..1a87f7dffa7c 100644 --- a/disk/disk-uclass.c +++ b/disk/disk-uclass.c @@ -122,6 +122,11 @@ unsigned long disk_blk_erase(struct udevice *dev, lbaint_t start, blkcnt); } +unsigned long disk_blk_flush(struct udevice *dev) +{ + return blk_flush(dev_get_parent(dev)); +} + UCLASS_DRIVER(partition) = { .id = UCLASS_PARTITION, .per_device_plat_auto = sizeof(struct disk_part), @@ -132,6 +137,7 @@ static const struct blk_ops blk_part_ops = { .read = disk_blk_read, .write = disk_blk_write, .erase = disk_blk_erase, + .flush = disk_blk_flush, }; U_BOOT_DRIVER(blk_partition) = { diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c index 73c24fd91763..0be1fdab1ba5 100644 --- a/drivers/block/blk-uclass.c +++ b/drivers/block/blk-uclass.c @@ -514,6 +514,19 @@ long blk_erase(struct udevice *dev, lbaint_t start, lbaint_t blkcnt) return ops->erase(dev, start, blkcnt); } +long blk_flush(struct udevice *dev) +{ + struct blk_desc *desc = dev_get_uclass_plat(dev); + const struct blk_ops *ops = blk_get_ops(dev); + + if (!ops->flush) + return -ENOSYS; + + blkcache_invalidate(desc->uclass_id, desc->devnum); + + return ops->flush(dev); +} + ulong blk_dread(struct blk_desc *desc, lbaint_t start, lbaint_t blkcnt, void *buffer) { @@ -531,6 +544,11 @@ ulong blk_derase(struct blk_desc *desc, lbaint_t start, lbaint_t blkcnt) return blk_erase(desc->bdev, start, blkcnt); } +ulong blk_dflush(struct blk_desc *desc) +{ + return blk_flush(desc->bdev); +} + int blk_find_from_parent(struct udevice *parent, struct udevice **devp) { struct udevice *dev; diff --git a/include/blk.h b/include/blk.h index 8d1b70cabd31..98e1db7a58f1 100644 --- a/include/blk.h +++ b/include/blk.h @@ -99,6 +99,7 @@ struct blk_desc { unsigned long (*block_erase)(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt); + unsigned long (*block_flush)(struct blk_desc *block_dev); void *priv; /* driver private struct pointer */ #endif }; @@ -275,6 +276,14 @@ struct blk_ops { */ int (*buffer_aligned)(struct udevice *dev, struct bounce_buffer *state); #endif /* CONFIG_BOUNCE_BUFFER */ + + /** + * flush() - commit all dirty data to storage + * + * @dev: Device to flush + * @return 0 if OK, -ve on error + */ + unsigned long (*flush)(struct udevice *dev); }; #if CONFIG_IS_ENABLED(BLK) @@ -291,6 +300,7 @@ unsigned long blk_dwrite(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt, const void *buffer); unsigned long blk_derase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt); +unsigned long blk_dflush(struct blk_desc *block_dev); #endif /* BLK */ @@ -331,6 +341,14 @@ long blk_write(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, */ long blk_erase(struct udevice *dev, lbaint_t start, lbaint_t blkcnt); +/** + * blk_flush() - Commit data to a block device + * + * @dev: Device to flush + * @return 0 if operation succeeded, or -ve on error. + */ +long blk_flush(struct udevice *dev); + /** * blk_find_device() - Find a block device * @@ -559,6 +577,16 @@ static inline ulong blk_derase(struct blk_desc *block_dev, lbaint_t start, return block_dev->block_erase(block_dev, start, blkcnt); } +static inline ulong blk_dflush(struct blk_desc *block_dev) +{ + if (!block_dev->block_flush) + return -ENOSYS; + + blkcache_invalidate(block_dev->uclass_id, block_dev->devnum); + + return block_dev->block_flush(block_dev); +} + /** * struct blk_driver - Driver for block interface types * diff --git a/include/part.h b/include/part.h index 15daacd7faaa..63982d7b9370 100644 --- a/include/part.h +++ b/include/part.h @@ -454,6 +454,14 @@ ulong disk_blk_write(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, */ ulong disk_blk_erase(struct udevice *dev, lbaint_t start, lbaint_t blkcnt); +/** + * disk_blk_flush() - commit data to a disk + * + * @dev: Device to flush + * Return: 0 success, or -ve error number (see the IS_ERR_VALUE() macro + */ +ulong disk_blk_flush(struct udevice *dev); + /* * We don't support printing partition information in SPL and only support * getting partition information in a few cases. -- 2.54.0

