diff mbox series

[RFC,10/22] dm: blk: add read/write interfaces with udevice

Message ID 20211001050228.55183-20-takahiro.akashi@linaro.org
State Superseded
Headers show
Series efi_loader: more tightly integrate UEFI disks to device model | expand

Commit Message

AKASHI Takahiro Oct. 1, 2021, 5:02 a.m. UTC
In include/blk.h, Simon suggested:
-- 
2.33.0

Comments

Simon Glass Oct. 10, 2021, 2:14 p.m. UTC | #1
Hi Takahiro,

On Thu, 30 Sept 2021 at 23:03, AKASHI Takahiro
<takahiro.akashi@linaro.org> wrote:
>

> 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>

> ---

>  drivers/block/blk-uclass.c | 91 ++++++++++++++++++++++++++++++++++++++

>  include/blk.h              |  6 +++

>  2 files changed, 97 insertions(+)

>

> diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c

> index 6ba11a8fa7f7..8fbec8779e1e 100644

> --- a/drivers/block/blk-uclass.c

> +++ b/drivers/block/blk-uclass.c

> @@ -482,6 +482,97 @@ unsigned long blk_derase(struct blk_desc *block_dev, lbaint_t start,

>         return ops->erase(dev, start, blkcnt);

>  }

>

> +static struct blk_desc *dev_get_blk(struct udevice *dev)

> +{

> +       struct blk_desc *block_dev;

> +

> +       switch (device_get_uclass_id(dev)) {

> +       case UCLASS_BLK:

> +               block_dev = dev_get_uclass_plat(dev);

> +               break;

> +       case UCLASS_PARTITION:

> +               block_dev = dev_get_uclass_plat(dev_get_parent(dev));

> +               break;

> +       default:

> +               block_dev = NULL;

> +               break;

> +       }

> +

> +       return block_dev;

> +}

> +

> +unsigned long blk_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;


IMO blk_read() should take a block device. That is how all other DM
APIs work. I think it is too confusing to use the parent device here.

So how about changing these functions to take a blk device, then
adding new ones for what you want here, e.g.

int media_read(struct udevice *dev...
{
   struct udevice *blk;

       blk = dev_get_blk(dev);
       if (!blk)
               return -ENOSYS;

   ret = blk_read(blk, ...
}

Also can we use blk instead of block_dev?

> +

> +       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 blk_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 blk_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);

> +}

> +

>  int blk_get_from_parent(struct udevice *parent, struct udevice **devp)

>  {

>         struct udevice *dev;

> diff --git a/include/blk.h b/include/blk.h

> index 3d883eb1db64..f5fdd6633a09 100644

> --- a/include/blk.h

> +++ b/include/blk.h

> @@ -284,6 +284,12 @@ unsigned long blk_dwrite(struct blk_desc *block_dev, lbaint_t start,

>  unsigned long blk_derase(struct blk_desc *block_dev, lbaint_t start,

>                          lbaint_t blkcnt);

>

> +unsigned long blk_read(struct udevice *dev, lbaint_t start,

> +                      lbaint_t blkcnt, void *buffer);

> +unsigned long blk_write(struct udevice *dev, lbaint_t start,

> +                       lbaint_t blkcnt, const void *buffer);

> +unsigned long blk_erase(struct udevice *dev, lbaint_t start,

> +                       lbaint_t blkcnt);


Please add full comments to these.

>  /**

>   * blk_find_device() - Find a block device

>   *

> --

> 2.33.0

>


Regards,
Simon
diff mbox series

Patch

===>
/*
 * 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>
---
 drivers/block/blk-uclass.c | 91 ++++++++++++++++++++++++++++++++++++++
 include/blk.h              |  6 +++
 2 files changed, 97 insertions(+)

diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c
index 6ba11a8fa7f7..8fbec8779e1e 100644
--- a/drivers/block/blk-uclass.c
+++ b/drivers/block/blk-uclass.c
@@ -482,6 +482,97 @@  unsigned long blk_derase(struct blk_desc *block_dev, lbaint_t start,
 	return ops->erase(dev, start, blkcnt);
 }
 
+static struct blk_desc *dev_get_blk(struct udevice *dev)
+{
+	struct blk_desc *block_dev;
+
+	switch (device_get_uclass_id(dev)) {
+	case UCLASS_BLK:
+		block_dev = dev_get_uclass_plat(dev);
+		break;
+	case UCLASS_PARTITION:
+		block_dev = dev_get_uclass_plat(dev_get_parent(dev));
+		break;
+	default:
+		block_dev = NULL;
+		break;
+	}
+
+	return block_dev;
+}
+
+unsigned long blk_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 blk_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 blk_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);
+}
+
 int blk_get_from_parent(struct udevice *parent, struct udevice **devp)
 {
 	struct udevice *dev;
diff --git a/include/blk.h b/include/blk.h
index 3d883eb1db64..f5fdd6633a09 100644
--- a/include/blk.h
+++ b/include/blk.h
@@ -284,6 +284,12 @@  unsigned long blk_dwrite(struct blk_desc *block_dev, lbaint_t start,
 unsigned long blk_derase(struct blk_desc *block_dev, lbaint_t start,
 			 lbaint_t blkcnt);
 
+unsigned long blk_read(struct udevice *dev, lbaint_t start,
+		       lbaint_t blkcnt, void *buffer);
+unsigned long blk_write(struct udevice *dev, lbaint_t start,
+			lbaint_t blkcnt, const void *buffer);
+unsigned long blk_erase(struct udevice *dev, lbaint_t start,
+			lbaint_t blkcnt);
 /**
  * blk_find_device() - Find a block device
  *