In include/blk.h, Simon suggested:
===>
/*
 * These functions should take struct udevice instead of struct blk_desc,
 * but this is convenient for migration to driver model. Add a 'd' prefix
 * to the function operations, so that blk_read(), etc. can be reserved for
 * functions with the correct arguments.
 */
unsigned long blk_dread(struct blk_desc *block_dev, lbaint_t start,
                        lbaint_t blkcnt, void *buffer);
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);
<===

So new interfaces are provided with this patch.

They are expected to be used everywhere in U-Boot at the end.
The exceptions are block device drivers, partition drivers and efi_disk
which should know details of blk_desc structure.

Signed-off-by: AKASHI Takahiro <takahiro.aka...@linaro.org>
---
 disk/disk-uclass.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++
 include/part.h     |  7 ++++
 2 files changed, 101 insertions(+)

diff --git a/disk/disk-uclass.c b/disk/disk-uclass.c
index 4918a2f72d1e..72ff62ebf581 100644
--- a/disk/disk-uclass.c
+++ b/disk/disk-uclass.c
@@ -146,6 +146,100 @@ U_BOOT_DRIVER(blk_partition) = {
        .ops            = &blk_part_ops,
 };
 
+/*
+ * BLOCK IO APIs
+ */
+static struct blk_desc *dev_get_blk(struct udevice *dev)
+{
+       struct blk_desc *block_dev;
+
+       switch (device_get_uclass_id(dev)) {
+       /*
+        * We won't support UCLASS_BLK with dev_* interfaces.
+        */
+       case UCLASS_PARTITION:
+               block_dev = dev_get_uclass_plat(dev_get_parent(dev));
+               break;
+       default:
+               block_dev = NULL;
+               break;
+       }
+
+       return block_dev;
+}
+
+unsigned long dev_read(struct udevice *dev, lbaint_t start,
+                      lbaint_t blkcnt, void *buffer)
+{
+       struct blk_desc *block_dev;
+       const struct blk_ops *ops;
+       struct disk_part *part;
+       lbaint_t start_in_disk;
+       ulong blks_read;
+
+       block_dev = dev_get_blk(dev);
+       if (!block_dev)
+               return -ENOSYS;
+
+       ops = blk_get_ops(dev);
+       if (!ops->read)
+               return -ENOSYS;
+
+       start_in_disk = start;
+       if (device_get_uclass_id(dev) == UCLASS_PARTITION) {
+               part = dev_get_uclass_plat(dev);
+               start_in_disk += part->gpt_part_info.start;
+       }
+
+       if (blkcache_read(block_dev->if_type, block_dev->devnum,
+                         start_in_disk, blkcnt, block_dev->blksz, buffer))
+               return blkcnt;
+       blks_read = ops->read(dev, start, blkcnt, buffer);
+       if (blks_read == blkcnt)
+               blkcache_fill(block_dev->if_type, block_dev->devnum,
+                             start_in_disk, blkcnt, block_dev->blksz, buffer);
+
+       return blks_read;
+}
+
+unsigned long dev_write(struct udevice *dev, lbaint_t start,
+                       lbaint_t blkcnt, const void *buffer)
+{
+       struct blk_desc *block_dev;
+       const struct blk_ops *ops;
+
+       block_dev = dev_get_blk(dev);
+       if (!block_dev)
+               return -ENOSYS;
+
+       ops = blk_get_ops(dev);
+       if (!ops->write)
+               return -ENOSYS;
+
+       blkcache_invalidate(block_dev->if_type, block_dev->devnum);
+
+       return ops->write(dev, start, blkcnt, buffer);
+}
+
+unsigned long dev_erase(struct udevice *dev, lbaint_t start,
+                       lbaint_t blkcnt)
+{
+       struct blk_desc *block_dev;
+       const struct blk_ops *ops;
+
+       block_dev = dev_get_blk(dev);
+       if (!block_dev)
+               return -ENOSYS;
+
+       ops = blk_get_ops(dev);
+       if (!ops->erase)
+               return -ENOSYS;
+
+       blkcache_invalidate(block_dev->if_type, block_dev->devnum);
+
+       return ops->erase(dev, start, blkcnt);
+}
+
 UCLASS_DRIVER(partition) = {
        .id             = UCLASS_PARTITION,
        .per_device_plat_auto   = sizeof(struct disk_part),
diff --git a/include/part.h b/include/part.h
index 95e30e60af10..d4e5cd921db1 100644
--- a/include/part.h
+++ b/include/part.h
@@ -264,6 +264,13 @@ struct udevice;
  */
 int part_create_block_devices(struct udevice *blk_dev);
 
+unsigned long dev_read(struct udevice *dev, lbaint_t start,
+                      lbaint_t blkcnt, void *buffer);
+unsigned long dev_write(struct udevice *dev, lbaint_t start,
+                       lbaint_t blkcnt, const void *buffer);
+unsigned long dev_erase(struct udevice *dev, lbaint_t start,
+                       lbaint_t blkcnt);
+
 #else
 static inline struct blk_desc *blk_get_dev(const char *ifname, int dev)
 { return NULL; }
-- 
2.33.0

Reply via email to