X-Git-Url: http://git.openwrt.org/?a=blobdiff_plain;f=target%2Flinux%2Fgeneric%2Fpending-5.4%2F411-mtd-partial_eraseblock_write.patch;fp=target%2Flinux%2Fgeneric%2Fpending-5.4%2F411-mtd-partial_eraseblock_write.patch;h=0000000000000000000000000000000000000000;hb=3a14580411adfb75f9a44eded9f41245b9e44606;hp=c48a144d3de66437b8c6f0f03bfd9d7bf98a5666;hpb=9f9477b2751231d57cdd8c227149b88c93491d93;p=openwrt%2Fopenwrt.git 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 c48a144d3d..0000000000 --- a/target/linux/generic/pending-5.4/411-mtd-partial_eraseblock_write.patch +++ /dev/null @@ -1,130 +0,0 @@ -From: Felix Fietkau -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 ---- - 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,11 +208,77 @@ 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); - if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) - instr->fail_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); -+ } -+ - instr->addr -= part->offset; - - return ret; -@@ -525,19 +593,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);