dm: disk: add read/write interfaces with udevice

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>
This commit is contained in:
AKASHI Takahiro 2022-04-19 10:05:16 +09:00 committed by Heinrich Schuchardt
parent a3cb34e9b7
commit 59da9d4782
2 changed files with 101 additions and 0 deletions

View File

@ -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),

View File

@ -313,6 +313,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);
/*
* We don't support printing partition information in SPL and only support
* getting partition information in a few cases.