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:
parent
a3cb34e9b7
commit
59da9d4782
@ -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),
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user