Skip to content

Commit

Permalink
dm: disk: add read/write interfaces with udevice
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
AKASHI Takahiro authored and xypron committed Apr 23, 2022
1 parent a3cb34e commit 59da9d4
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 0 deletions.
94 changes: 94 additions & 0 deletions disk/disk-uclass.c
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
7 changes: 7 additions & 0 deletions include/part.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit 59da9d4

Please sign in to comment.