@@ -146,6 +146,102 @@ 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)) {
+#if 0 /* FIXME */
+ case UCLASS_BLK:
+ block_dev = dev_get_uclass_plat(dev);
+ break;
+#endif
+ 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),
@@ -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; }
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.akashi@linaro.org> --- disk/disk-uclass.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++ include/part.h | 7 ++++ 2 files changed, 103 insertions(+)