From c16517d26de30c90dabce1e456615fd7fbdce07c Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sun, 23 Feb 2020 13:20:11 +0100 Subject: kernel: copy kernel 4.19 code to 5.4 No changes were done to the patches while coping them. Currently they do not apply on top of kernel 5.4. Signed-off-by: Hauke Mehrtens --- .../411-mtd-partial_eraseblock_write.patch | 132 +++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 target/linux/generic/pending-5.4/411-mtd-partial_eraseblock_write.patch (limited to 'target/linux/generic/pending-5.4/411-mtd-partial_eraseblock_write.patch') 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 new file mode 100644 index 0000000000..bf9822fda8 --- /dev/null +++ b/target/linux/generic/pending-5.4/411-mtd-partial_eraseblock_write.patch @@ -0,0 +1,132 @@ +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 +@@ -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->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); -- cgit v1.2.3