From: Rafał Miłecki <ra...@milecki.pl>

This code was developed 10+ years ago to support few specific devices.
It doesn't match current mtd architecture and is probably/hopefully not
needed anymore.

Problems of this code with recent kernels:
1. It assumes that parent mtd boundaries always allow accessing whole
   block data. It was true only for master MTD device and non-tree
   partitions.
2. MTD_ERASE_PARTIAL affects all partition blocks - even those fully
   accessible in a standard way. This code was probably designed for
   tiny partitions only.
3. It seems broken with subpartitions. Unintended usage of this code
   triggered by run_parsers_by_type() rewrite caused in erasing content
   of some unrelated partitions. It may be caused by incorrect offsets
   calculation.

It seems this code was originally needed by some Gateworks devices from
Avila and Cambria families using RedBoot. Those devices were supported
by ixp4xx target which was dropped recently. It's also likely that new
ixp4xx devices didn't require that code at all. Some recent examples:

1. Gateworks Avila GW2342:
0x000000000000-0x000000040000 : "RedBoot"
0x000000040000-0x000000160000 : "linux"
0x000000160000-0x000000fc0000 : "rootfs"
0x000000360000-0x000000fc0000 : "rootfs_data"
0x000000fc0000-0x000000fc1000 : "RedBoot config"
0x000000fe0000-0x000001000000 : "FIS directory"

2. Gateworks Cambria GW2350:
0x000000000000-0x000000080000 : "RedBoot"
0x000000080000-0x000000180000 : "linux"
0x000000180000-0x000001fe0000 : "rootfs"
0x000000320000-0x000001fe0000 : "rootfs_data"
0x000001fe0000-0x000001fff000 : "FIS directory"
0x000001fff000-0x000002000000 : "RedBoot config"

All above partitions seem to be aligned properly.

Signed-off-by: Rafał Miłecki <ra...@milecki.pl>
---
 .../411-mtd-partial_eraseblock_write.patch    | 131 ------------------
 .../412-mtd-partial_eraseblock_unlock.patch   |  40 ------
 .../411-mtd-partial_eraseblock_write.patch    | 131 ------------------
 .../412-mtd-partial_eraseblock_unlock.patch   |  40 ------
 4 files changed, 342 deletions(-)
 delete mode 100644 
target/linux/generic/pending-4.19/411-mtd-partial_eraseblock_write.patch
 delete mode 100644 
target/linux/generic/pending-4.19/412-mtd-partial_eraseblock_unlock.patch
 delete mode 100644 
target/linux/generic/pending-5.4/411-mtd-partial_eraseblock_write.patch
 delete mode 100644 
target/linux/generic/pending-5.4/412-mtd-partial_eraseblock_unlock.patch

diff --git 
a/target/linux/generic/pending-4.19/411-mtd-partial_eraseblock_write.patch 
b/target/linux/generic/pending-4.19/411-mtd-partial_eraseblock_write.patch
deleted file mode 100644
index f3a314ae02..0000000000
--- a/target/linux/generic/pending-4.19/411-mtd-partial_eraseblock_write.patch
+++ /dev/null
@@ -1,131 +0,0 @@
-From: Felix Fietkau <n...@nbd.name>
-Subject: mtd: implement write support for partitions covering only a part of 
an eraseblock (buffer data that would otherwise be erased)
-
-lede-commit: 87a8e8ac1067f58ba831c4aae443f3655c31cd80
-Signed-off-by: Felix Fietkau <n...@nbd.name>
----
- drivers/mtd/mtdpart.c   | 90 ++++++++++++++++++++++++++++++++++++++++++++-----
- include/linux/mtd/mtd.h |  4 +++
- 2 files changed, 85 insertions(+), 9 deletions(-)
-
---- a/drivers/mtd/mtdpart.c
-+++ b/drivers/mtd/mtdpart.c
-@@ -36,6 +36,8 @@
- #include "mtdcore.h"
- #include "mtdsplit/mtdsplit.h"
- 
-+#define MTD_ERASE_PARTIAL     0x8000 /* partition only covers parts of an 
erase block */
-+
- /* Our partition linked list */
- static LIST_HEAD(mtd_partitions);
- static DEFINE_MUTEX(mtd_partitions_mutex);
-@@ -220,6 +222,53 @@ static int part_erase(struct mtd_info *m
- {
-       struct mtd_part *part = mtd_to_part(mtd);
-       int ret;
-+      size_t wrlen = 0;
-+      u8 *erase_buf = NULL;
-+      u32 erase_buf_ofs = 0;
-+      bool partial_start = false;
-+
-+      if (mtd->flags & MTD_ERASE_PARTIAL) {
-+              size_t readlen = 0;
-+              u64 mtd_ofs;
-+
-+              erase_buf = kmalloc(part->parent->erasesize, GFP_ATOMIC);
-+              if (!erase_buf)
-+                      return -ENOMEM;
-+
-+              mtd_ofs = part->offset + instr->addr;
-+              erase_buf_ofs = do_div(mtd_ofs, part->parent->erasesize);
-+
-+              if (erase_buf_ofs > 0) {
-+                      instr->addr -= erase_buf_ofs;
-+                      ret = mtd_read(part->parent,
-+                              instr->addr + part->offset,
-+                              part->parent->erasesize,
-+                              &readlen, erase_buf);
-+
-+                      instr->len += erase_buf_ofs;
-+                      partial_start = true;
-+              } else {
-+                      mtd_ofs = part->offset + part->mtd.size;
-+                      erase_buf_ofs = part->parent->erasesize -
-+                              do_div(mtd_ofs, part->parent->erasesize);
-+
-+                      if (erase_buf_ofs > 0) {
-+                              instr->len += erase_buf_ofs;
-+                              ret = mtd_read(part->parent,
-+                                      part->offset + instr->addr +
-+                                      instr->len - part->parent->erasesize,
-+                                      part->parent->erasesize, &readlen,
-+                                      erase_buf);
-+                      } else {
-+                              ret = 0;
-+                      }
-+              }
-+              if (ret < 0) {
-+                      kfree(erase_buf);
-+                      return ret;
-+              }
-+
-+      }
- 
-       instr->addr += part->offset;
-       ret = part->parent->_erase(part->parent, instr);
-@@ -227,6 +276,24 @@ static int part_erase(struct mtd_info *m
-               instr->fail_addr -= part->offset;
-       instr->addr -= part->offset;
- 
-+      if (mtd->flags & MTD_ERASE_PARTIAL) {
-+              if (partial_start) {
-+                      part->parent->_write(part->parent,
-+                              instr->addr, erase_buf_ofs,
-+                              &wrlen, erase_buf);
-+                      instr->addr += erase_buf_ofs;
-+              } else {
-+                      instr->len -= erase_buf_ofs;
-+                      part->parent->_write(part->parent,
-+                              instr->addr + instr->len,
-+                              erase_buf_ofs, &wrlen,
-+                              erase_buf +
-+                              part->parent->erasesize -
-+                              erase_buf_ofs);
-+              }
-+              kfree(erase_buf);
-+      }
-+
-       return ret;
- }
- 
-@@ -539,19 +606,22 @@ static struct mtd_part *allocate_partiti
-       remainder = do_div(tmp, wr_alignment);
-       if ((slave->mtd.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 */
--              slave->mtd.flags &= ~MTD_WRITEABLE;
--              printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an 
erase/write block boundary -- force read-only\n",
--                      part->name);
-+              slave->mtd.flags |= MTD_ERASE_PARTIAL;
-+              if (((u32)slave->mtd.size) > parent->erasesize)
-+                      slave->mtd.flags &= ~MTD_WRITEABLE;
-+              else
-+                      slave->mtd.erasesize = slave->mtd.size;
-       }
- 
-       tmp = part_absolute_offset(parent) + slave->offset + slave->mtd.size;
-       remainder = do_div(tmp, wr_alignment);
-       if ((slave->mtd.flags & MTD_WRITEABLE) && remainder) {
--              slave->mtd.flags &= ~MTD_WRITEABLE;
--              printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an 
erase/write block -- force read-only\n",
--                      part->name);
-+              slave->mtd.flags |= MTD_ERASE_PARTIAL;
-+
-+              if ((u32)slave->mtd.size > parent->erasesize)
-+                      slave->mtd.flags &= ~MTD_WRITEABLE;
-+              else
-+                      slave->mtd.erasesize = slave->mtd.size;
-       }
- 
-       mtd_set_ooblayout(&slave->mtd, &part_ooblayout_ops);
diff --git 
a/target/linux/generic/pending-4.19/412-mtd-partial_eraseblock_unlock.patch 
b/target/linux/generic/pending-4.19/412-mtd-partial_eraseblock_unlock.patch
deleted file mode 100644
index a54603a0f8..0000000000
--- a/target/linux/generic/pending-4.19/412-mtd-partial_eraseblock_unlock.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From: Tim Harvey <thar...@gateworks.com>
-Subject: mtd: allow partial block unlock
-
-This allows sysupgrade for devices such as the Gateworks Avila/Cambria
-product families based on the ixp4xx using the redboot bootloader with
-combined FIS directory and RedBoot config partitions on larger FLASH
-devices with larger eraseblocks.
-
-This second iteration of this patch addresses previous issues:
-- whitespace breakage fixed
-- unlock in all scenarios
-- simplification and fix logic bug
-
-[j...@phrozen.org: this should be moved to the ixp4xx folder]
-
-Signed-off-by: Tim Harvey <thar...@gateworks.com>
----
- drivers/mtd/mtdpart.c | 11 ++++++++++-
- 1 file changed, 10 insertions(+), 1 deletion(-)
-
---- a/drivers/mtd/mtdpart.c
-+++ b/drivers/mtd/mtdpart.c
-@@ -306,7 +306,16 @@ static int part_lock(struct mtd_info *mt
- static int part_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
- {
-       struct mtd_part *part = mtd_to_part(mtd);
--      return part->parent->_unlock(part->parent, ofs + part->offset, len);
-+
-+      ofs += part->offset;
-+
-+      if (mtd->flags & MTD_ERASE_PARTIAL) {
-+              /* round up len to next erasesize and round down offset to prev 
block */
-+              len = (mtd_div_by_eb(len, part->parent) + 1) * 
part->parent->erasesize;
-+              ofs &= ~(part->parent->erasesize - 1);
-+      }
-+
-+      return part->parent->_unlock(part->parent, ofs, len);
- }
- 
- static int part_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
diff --git 
a/target/linux/generic/pending-5.4/411-mtd-partial_eraseblock_write.patch 
b/target/linux/generic/pending-5.4/411-mtd-partial_eraseblock_write.patch
deleted file mode 100644
index b46c3f5ed4..0000000000
--- a/target/linux/generic/pending-5.4/411-mtd-partial_eraseblock_write.patch
+++ /dev/null
@@ -1,131 +0,0 @@
-From: Felix Fietkau <n...@nbd.name>
-Subject: mtd: implement write support for partitions covering only a part of 
an eraseblock (buffer data that would otherwise be erased)
-
-lede-commit: 87a8e8ac1067f58ba831c4aae443f3655c31cd80
-Signed-off-by: Felix Fietkau <n...@nbd.name>
----
- drivers/mtd/mtdpart.c   | 90 ++++++++++++++++++++++++++++++++++++++++++++-----
- include/linux/mtd/mtd.h |  4 +++
- 2 files changed, 85 insertions(+), 9 deletions(-)
-
---- a/drivers/mtd/mtdpart.c
-+++ b/drivers/mtd/mtdpart.c
-@@ -22,6 +22,8 @@
- #include "mtdcore.h"
- #include "mtdsplit/mtdsplit.h"
- 
-+#define MTD_ERASE_PARTIAL     0x8000 /* partition only covers parts of an 
erase block */
-+
- /* Our partition linked list */
- static LIST_HEAD(mtd_partitions);
- static DEFINE_MUTEX(mtd_partitions_mutex);
-@@ -206,6 +208,53 @@ static int part_erase(struct mtd_info *m
- {
-       struct mtd_part *part = mtd_to_part(mtd);
-       int ret;
-+      size_t wrlen = 0;
-+      u8 *erase_buf = NULL;
-+      u32 erase_buf_ofs = 0;
-+      bool partial_start = false;
-+
-+      if (mtd->flags & MTD_ERASE_PARTIAL) {
-+              size_t readlen = 0;
-+              u64 mtd_ofs;
-+
-+              erase_buf = kmalloc(part->parent->erasesize, GFP_ATOMIC);
-+              if (!erase_buf)
-+                      return -ENOMEM;
-+
-+              mtd_ofs = part->offset + instr->addr;
-+              erase_buf_ofs = do_div(mtd_ofs, part->parent->erasesize);
-+
-+              if (erase_buf_ofs > 0) {
-+                      instr->addr -= erase_buf_ofs;
-+                      ret = mtd_read(part->parent,
-+                              instr->addr + part->offset,
-+                              part->parent->erasesize,
-+                              &readlen, erase_buf);
-+
-+                      instr->len += erase_buf_ofs;
-+                      partial_start = true;
-+              } else {
-+                      mtd_ofs = part->offset + part->mtd.size;
-+                      erase_buf_ofs = part->parent->erasesize -
-+                              do_div(mtd_ofs, part->parent->erasesize);
-+
-+                      if (erase_buf_ofs > 0) {
-+                              instr->len += erase_buf_ofs;
-+                              ret = mtd_read(part->parent,
-+                                      part->offset + instr->addr +
-+                                      instr->len - part->parent->erasesize,
-+                                      part->parent->erasesize, &readlen,
-+                                      erase_buf);
-+                      } else {
-+                              ret = 0;
-+                      }
-+              }
-+              if (ret < 0) {
-+                      kfree(erase_buf);
-+                      return ret;
-+              }
-+
-+      }
- 
-       instr->addr += part->offset;
-       ret = part->parent->_erase(part->parent, instr);
-@@ -213,6 +262,24 @@ static int part_erase(struct mtd_info *m
-               instr->fail_addr -= part->offset;
-       instr->addr -= part->offset;
- 
-+      if (mtd->flags & MTD_ERASE_PARTIAL) {
-+              if (partial_start) {
-+                      part->parent->_write(part->parent,
-+                              instr->addr, erase_buf_ofs,
-+                              &wrlen, erase_buf);
-+                      instr->addr += erase_buf_ofs;
-+              } else {
-+                      instr->len -= erase_buf_ofs;
-+                      part->parent->_write(part->parent,
-+                              instr->addr + instr->len,
-+                              erase_buf_ofs, &wrlen,
-+                              erase_buf +
-+                              part->parent->erasesize -
-+                              erase_buf_ofs);
-+              }
-+              kfree(erase_buf);
-+      }
-+
-       return ret;
- }
- 
-@@ -525,19 +592,22 @@ static struct mtd_part *allocate_partiti
-       remainder = do_div(tmp, wr_alignment);
-       if ((slave->mtd.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 */
--              slave->mtd.flags &= ~MTD_WRITEABLE;
--              printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an 
erase/write block boundary -- force read-only\n",
--                      part->name);
-+              slave->mtd.flags |= MTD_ERASE_PARTIAL;
-+              if (((u32)slave->mtd.size) > parent->erasesize)
-+                      slave->mtd.flags &= ~MTD_WRITEABLE;
-+              else
-+                      slave->mtd.erasesize = slave->mtd.size;
-       }
- 
-       tmp = part_absolute_offset(parent) + slave->offset + slave->mtd.size;
-       remainder = do_div(tmp, wr_alignment);
-       if ((slave->mtd.flags & MTD_WRITEABLE) && remainder) {
--              slave->mtd.flags &= ~MTD_WRITEABLE;
--              printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an 
erase/write block -- force read-only\n",
--                      part->name);
-+              slave->mtd.flags |= MTD_ERASE_PARTIAL;
-+
-+              if ((u32)slave->mtd.size > parent->erasesize)
-+                      slave->mtd.flags &= ~MTD_WRITEABLE;
-+              else
-+                      slave->mtd.erasesize = slave->mtd.size;
-       }
- 
-       mtd_set_ooblayout(&slave->mtd, &part_ooblayout_ops);
diff --git 
a/target/linux/generic/pending-5.4/412-mtd-partial_eraseblock_unlock.patch 
b/target/linux/generic/pending-5.4/412-mtd-partial_eraseblock_unlock.patch
deleted file mode 100644
index 348fb9a842..0000000000
--- a/target/linux/generic/pending-5.4/412-mtd-partial_eraseblock_unlock.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From: Tim Harvey <thar...@gateworks.com>
-Subject: mtd: allow partial block unlock
-
-This allows sysupgrade for devices such as the Gateworks Avila/Cambria
-product families based on the ixp4xx using the redboot bootloader with
-combined FIS directory and RedBoot config partitions on larger FLASH
-devices with larger eraseblocks.
-
-This second iteration of this patch addresses previous issues:
-- whitespace breakage fixed
-- unlock in all scenarios
-- simplification and fix logic bug
-
-[j...@phrozen.org: this should be moved to the ixp4xx folder]
-
-Signed-off-by: Tim Harvey <thar...@gateworks.com>
----
- drivers/mtd/mtdpart.c | 11 ++++++++++-
- 1 file changed, 10 insertions(+), 1 deletion(-)
-
---- a/drivers/mtd/mtdpart.c
-+++ b/drivers/mtd/mtdpart.c
-@@ -292,7 +292,16 @@ static int part_lock(struct mtd_info *mt
- static int part_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
- {
-       struct mtd_part *part = mtd_to_part(mtd);
--      return part->parent->_unlock(part->parent, ofs + part->offset, len);
-+
-+      ofs += part->offset;
-+
-+      if (mtd->flags & MTD_ERASE_PARTIAL) {
-+              /* round up len to next erasesize and round down offset to prev 
block */
-+              len = (mtd_div_by_eb(len, part->parent) + 1) * 
part->parent->erasesize;
-+              ofs &= ~(part->parent->erasesize - 1);
-+      }
-+
-+      return part->parent->_unlock(part->parent, ofs, len);
- }
- 
- static int part_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
-- 
2.25.0


_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to