From: "Thibaut VARÈNE" <hacks+kernel@slashdirt.org>
To: linux-mtd@lists.infradead.org
Cc: miquel.raynal@bootlin.com, richard@nod.at, vigneshr@ti.com,
tudor.ambarus@microchip.com, p.yadav@ti.com, michael@walle.cc,
git@johnthomson.fastmail.com.au,
"Thibaut VARÈNE" <hacks+kernel@slashdirt.org>
Subject: [PATCH v3 1/3] mtd: mtdpart: write support for minor-aligned partitions
Date: Fri, 29 Jul 2022 11:16:34 +0200 [thread overview]
Message-ID: <20220729091636.59287-2-hacks+kernel@slashdirt.org> (raw)
In-Reply-To: <20220729091636.59287-1-hacks+kernel@slashdirt.org>
This patch enables writing to mtd partitions where a partition boundary
sits on a "minor" erasesize boundary.
This patch adds a uint32_t `erasesize_minor` to struct mtd_info: the
smallest erasesize supported by the device, also exposed in sysfs.
This patch is a no-op if erasesize_minor is unset (0) and has no
userspace-visible side effect (in particular the reported erasesize in
/proc/mtd is unchanged). This new feature is only enabled for single
eraseregion devices, where it makes most sense.
This patch addresses an outstanding mtdpart.c FIXME that has been
present since the start of the linux git history.
Signed-off-by: John Thomson <git@johnthomson.fastmail.com.au>
Signed-off-by: Thibaut VARÈNE <hacks+kernel@slashdirt.org>
---
Documentation/ABI/testing/sysfs-class-mtd | 8 ++++++
drivers/mtd/mtdcore.c | 10 +++++++
drivers/mtd/mtdpart.c | 35 ++++++++++++++++-------
include/linux/mtd/mtd.h | 2 ++
4 files changed, 45 insertions(+), 10 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-class-mtd b/Documentation/ABI/testing/sysfs-class-mtd
index 3bc7c0a95..786068f63 100644
--- a/Documentation/ABI/testing/sysfs-class-mtd
+++ b/Documentation/ABI/testing/sysfs-class-mtd
@@ -240,3 +240,11 @@ Contact: linux-mtd@lists.infradead.org
Description:
Number of bytes available for a client to place data into
the out of band area.
+
+What: /sys/class/mtd/mtdX/erasesize_minor
+Date: July 2022
+KernelVersion: 5.20
+Contact: linux-mtd@lists.infradead.org
+Description:
+ "Minor" erase size for the device. If supported, this is
+ the smallest eraseblock size for the device.
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 9eb0680db..ccb80197d 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -168,6 +168,15 @@ static ssize_t mtd_erasesize_show(struct device *dev,
}
MTD_DEVICE_ATTR_RO(erasesize);
+static ssize_t mtd_erasesize_minor_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mtd_info *mtd = dev_get_drvdata(dev);
+
+ return sysfs_emit(buf, "%lu\n", (unsigned long)mtd->erasesize_minor);
+}
+MTD_DEVICE_ATTR_RO(erasesize_minor);
+
static ssize_t mtd_writesize_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -313,6 +322,7 @@ static struct attribute *mtd_attrs[] = {
&dev_attr_flags.attr,
&dev_attr_size.attr,
&dev_attr_erasesize.attr,
+ &dev_attr_erasesize_minor.attr,
&dev_attr_writesize.attr,
&dev_attr_subpagesize.attr,
&dev_attr_oobsize.attr,
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index d442fa94c..6bf21567f 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -39,6 +39,7 @@ static struct mtd_info *allocate_partition(struct mtd_info *parent,
struct mtd_info *master = mtd_get_master(parent);
int wr_alignment = (parent->flags & MTD_NO_ERASE) ?
master->writesize : master->erasesize;
+ int wr_alignment_minor = 0;
u64 parent_size = mtd_is_partition(parent) ?
parent->part.size : parent->size;
struct mtd_info *child;
@@ -163,6 +164,7 @@ static struct mtd_info *allocate_partition(struct mtd_info *parent,
} else {
/* Single erase size */
child->erasesize = master->erasesize;
+ child->erasesize_minor = master->erasesize_minor;
}
/*
@@ -170,26 +172,39 @@ static struct mtd_info *allocate_partition(struct mtd_info *parent,
* exposes several regions with different erasesize. Adjust
* wr_alignment accordingly.
*/
- if (!(child->flags & MTD_NO_ERASE))
+ if (!(child->flags & MTD_NO_ERASE)) {
wr_alignment = child->erasesize;
+ wr_alignment_minor = child->erasesize_minor;
+ }
tmp = mtd_get_master_ofs(child, 0);
remainder = do_div(tmp, wr_alignment);
if ((child->flags & MTD_WRITEABLE) && remainder) {
- /* Doesn't start on a boundary of major erase size */
- /* FIXME: Let it be writable if it is on a boundary of
- * _minor_ erase size though */
- child->flags &= ~MTD_WRITEABLE;
- printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase/write block boundary -- force read-only\n",
- part->name);
+ if (wr_alignment_minor) {
+ /* rely on minor being a factor of major erasesize */
+ tmp = remainder;
+ remainder = do_div(tmp, wr_alignment_minor);
+ }
+ if (remainder) {
+ child->flags &= ~MTD_WRITEABLE;
+ pr_warn("mtd: partition \"%s\" doesn't start on an erase/write block boundary -- force read-only\n",
+ part->name);
+ }
}
tmp = mtd_get_master_ofs(child, 0) + child->part.size;
remainder = do_div(tmp, wr_alignment);
if ((child->flags & MTD_WRITEABLE) && remainder) {
- child->flags &= ~MTD_WRITEABLE;
- printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase/write block -- force read-only\n",
- part->name);
+ if (wr_alignment_minor) {
+ tmp = remainder;
+ remainder = do_div(tmp, wr_alignment_minor);
+ }
+
+ if (remainder) {
+ child->flags &= ~MTD_WRITEABLE;
+ pr_warn("mtd: partition \"%s\" doesn't end on an erase/write block boundary -- force read-only\n",
+ part->name);
+ }
}
child->size = child->part.size;
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 955aee14b..8efbc929e 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -238,6 +238,8 @@ struct mtd_info {
* information below if they desire
*/
uint32_t erasesize;
+ /* "Minor" (smallest) erase size supported by the whole device */
+ uint32_t erasesize_minor;
/* Minimal writable flash unit size. In case of NOR flash it is 1 (even
* though individual bits can be cleared), in case of NAND flash it is
* one NAND page (or half, or one-fourths of it), in case of ECC-ed NOR
--
2.30.2
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
next prev parent reply other threads:[~2022-07-29 9:19 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-07-29 9:16 [PATCH v3 0/3] mtd: write support for minor-aligned partitions Thibaut VARÈNE
2022-07-29 9:16 ` Thibaut VARÈNE [this message]
2022-07-29 9:16 ` [PATCH v3 2/3] mtd: spi-nor: set erasesize_minor for non-uniform erase Thibaut VARÈNE
2022-07-29 9:16 ` [PATCH v3 3/3] mtd: spi-nor: allow overriding uniform erase Thibaut VARÈNE
2022-08-09 9:23 ` [PATCH v3 0/3] mtd: write support for minor-aligned partitions Thibaut VARÈNE
2022-08-09 15:45 ` Tudor.Ambarus
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=20220729091636.59287-2-hacks+kernel@slashdirt.org \
--to=hacks+kernel@slashdirt.org \
--cc=git@johnthomson.fastmail.com.au \
--cc=linux-mtd@lists.infradead.org \
--cc=michael@walle.cc \
--cc=miquel.raynal@bootlin.com \
--cc=p.yadav@ti.com \
--cc=richard@nod.at \
--cc=tudor.ambarus@microchip.com \
--cc=vigneshr@ti.com \
/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;
as well as URLs for NNTP newsgroup(s).