mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Ahmad Fatoum <a.fatoum@pengutronix.de>
To: barebox@lists.infradead.org
Cc: Ahmad Fatoum <a.fatoum@pengutronix.de>
Subject: [PATCH v2 04/10] block: allow block devices to implement the cdev erase operation
Date: Wed, 31 Jul 2024 10:05:04 +0200	[thread overview]
Message-ID: <20240731080510.364706-5-a.fatoum@pengutronix.de> (raw)
In-Reply-To: <20240731080510.364706-1-a.fatoum@pengutronix.de>

We mainly implement cdev erase for raw flashes. Many block devices, like
NVMe, SSD or SD/MMC are also flash-based and expose a mechanism or
multiple to trigger an erase on hardware or flash translation layer
level without an accompanied write.

To make it possible to use this functionality elsewhere in barebox,
let's have the common block device layer pass through the erase
operation, so it may be implemented in a device-specific manner.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
v1 -> v2:
  - use newly added region_overlap_size helper in range.h
---
 common/block.c  | 34 ++++++++++++++++++++++++++++++++++
 include/block.h |  1 +
 2 files changed, 35 insertions(+)

diff --git a/common/block.c b/common/block.c
index f55da775a797..eaec454ecbb2 100644
--- a/common/block.c
+++ b/common/block.c
@@ -11,6 +11,7 @@
 #include <linux/err.h>
 #include <linux/list.h>
 #include <dma.h>
+#include <range.h>
 #include <file-list.h>
 
 LIST_HEAD(block_device_list);
@@ -380,10 +381,35 @@ static int block_op_discard_range(struct cdev *cdev, loff_t count, loff_t offset
 	return 0;
 }
 
+static __maybe_unused int block_op_erase(struct cdev *cdev, loff_t count, loff_t offset)
+{
+	struct block_device *blk = cdev->priv;
+	struct chunk *chunk, *tmp;
+	int ret;
+
+	if (!blk->ops->erase)
+		return -EOPNOTSUPP;
+
+	count >>= blk->blockbits;
+	offset >>= blk->blockbits;
+
+	list_for_each_entry_safe(chunk, tmp, &blk->buffered_blocks, list) {
+		if (region_overlap_size(offset, count, chunk->block_start, blk->rdbufsize)) {
+			ret = chunk_flush(blk, chunk);
+			if (ret < 0)
+				return ret;
+			list_move(&chunk->list, &blk->idle_blocks);
+		}
+	}
+
+	return blk->ops->erase(blk, offset, count);
+}
+
 static struct cdev_operations block_ops = {
 	.read	= block_op_read,
 #ifdef CONFIG_BLOCK_WRITE
 	.write	= block_op_write,
+	.erase = block_op_erase,
 #endif
 	.close	= block_op_close,
 	.flush	= block_op_flush,
@@ -429,6 +455,14 @@ int blockdevice_register(struct block_device *blk)
 		list_add_tail(&chunk->list, &blk->idle_blocks);
 	}
 
+	/* TODO: We currently set this to ignore ERASE_TO_FLASH, but it could
+	 * be useful to propagate the enum erase_type down into the erase
+	 * callbacks and then map ERASE_TO_FLASH here to a discard operation.
+	 * Before doing that though, we need to optimize the hardware drivers
+	 * (currently eMMC) to erase bigger regions at once
+	 */
+	blk->cdev.flags |= DEVFS_WRITE_AUTOERASE;
+
 	ret = devfs_create(&blk->cdev);
 	if (ret)
 		return ret;
diff --git a/include/block.h b/include/block.h
index a0f226c7649f..eb319b953d32 100644
--- a/include/block.h
+++ b/include/block.h
@@ -12,6 +12,7 @@ struct file_list;
 struct block_device_ops {
 	int (*read)(struct block_device *, void *buf, sector_t block, blkcnt_t num_blocks);
 	int (*write)(struct block_device *, const void *buf, sector_t block, blkcnt_t num_blocks);
+	int (*erase)(struct block_device *blk, sector_t block, blkcnt_t num_blocks);
 	int (*flush)(struct block_device *);
 };
 
-- 
2.39.2




  parent reply	other threads:[~2024-07-31  8:05 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-07-31  8:05 [PATCH v2 00/10] mmc: add SD/eMMC erase support Ahmad Fatoum
2024-07-31  8:05 ` [PATCH v2 01/10] fs: give erase() a new erase_type parameter Ahmad Fatoum
2024-08-01 10:51   ` Sascha Hauer
2024-08-01 10:54     ` Ahmad Fatoum
2024-07-31  8:05 ` [PATCH v2 02/10] cdev: factor out range identical/overlap check Ahmad Fatoum
2024-07-31  8:05 ` [PATCH v2 03/10] block: factor out chunk_flush helper Ahmad Fatoum
2024-07-31  8:05 ` Ahmad Fatoum [this message]
2024-07-31  8:05 ` [PATCH v2 05/10] mci: turn bool members into bitfield in struct mci Ahmad Fatoum
2024-07-31  8:05 ` [PATCH v2 06/10] mci: describe more command structure in mci.h Ahmad Fatoum
2024-07-31  8:05 ` [PATCH v2 07/10] mci: core: use CONFIG_MCI_WRITE, not CONFIG_BLOCK_WRITE Ahmad Fatoum
2024-07-31  8:05 ` [PATCH v2 08/10] mci: add support for discarding write blocks Ahmad Fatoum
2024-08-01 11:27   ` Sascha Hauer
2024-07-31  8:05 ` [PATCH v2 09/10] commands: sync: add new command to flush cached writes Ahmad Fatoum
2024-07-31  8:05 ` [PATCH v2 10/10] commands: blkstats: add command to print block device statistics Ahmad Fatoum
2024-08-01 10:49 ` [PATCH v2 00/10] mmc: add SD/eMMC erase support Sascha Hauer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240731080510.364706-5-a.fatoum@pengutronix.de \
    --to=a.fatoum@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox