mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-17 09:21:35 +00:00
132 lines
3.9 KiB
Diff
132 lines
3.9 KiB
Diff
From b4c8a1c56ad964b1946f96bcc9f3b73ed13c1ba7 Mon Sep 17 00:00:00 2001
|
|
From: Md Sadre Alam <quic_mdalam@quicinc.com>
|
|
Date: Thu, 21 Dec 2023 11:49:48 +0530
|
|
Subject: [PATCH] mtd: Handle bad block in virtual partition
|
|
|
|
This patch adds bad block management support for
|
|
NAND flash with secure storage
|
|
|
|
Change-Id: I64e578f3b02245bfba77136a578f2cbd84725c7e
|
|
Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
|
|
---
|
|
drivers/mtd/devices/block2mtd.c | 57 +++++++++++++++++++++++++++++----
|
|
1 file changed, 50 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
|
|
index 4cd37ec45762..5234fabc67b3 100644
|
|
--- a/drivers/mtd/devices/block2mtd.c
|
|
+++ b/drivers/mtd/devices/block2mtd.c
|
|
@@ -31,6 +31,8 @@
|
|
#include <linux/slab.h>
|
|
#include <linux/major.h>
|
|
|
|
+char parent_mtd_name[80];
|
|
+
|
|
/* Maximum number of comma-separated items in the 'block2mtd=' parameter */
|
|
#define BLOCK2MTD_PARAM_MAX_COUNT 3
|
|
|
|
@@ -133,6 +135,23 @@ static int block2mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
|
|
return 0;
|
|
}
|
|
|
|
+static int block2mtd_read_oob(struct mtd_info *mtd, loff_t from,
|
|
+ struct mtd_oob_ops *ops)
|
|
+{
|
|
+ struct mtd_info *parent_mtd;
|
|
+ char *ptr_mtd_name = parent_mtd_name;
|
|
+ int ret = 0;
|
|
+
|
|
+ if (ops->datbuf)
|
|
+ ret = block2mtd_read(mtd, from, ops->len, &ops->retlen,
|
|
+ ops->datbuf);
|
|
+ else if (ptr_mtd_name) {
|
|
+ parent_mtd = get_mtd_device_nm(ptr_mtd_name);
|
|
+ ret = mtd_read_oob(parent_mtd, from, ops);
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
|
|
/* write data to the underlying device */
|
|
static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf,
|
|
@@ -215,6 +234,20 @@ static void block2mtd_free_device(struct block2mtd_dev *dev)
|
|
kfree(dev);
|
|
}
|
|
|
|
+static int block2mtd_isbad(struct mtd_info *mtd, loff_t from)
|
|
+{
|
|
+ char *ptr_mtd_name = parent_mtd_name;
|
|
+ struct mtd_info *parent_mtd;
|
|
+ int ret = 0;
|
|
+
|
|
+ if (ptr_mtd_name) {
|
|
+ parent_mtd = get_mtd_device_nm(ptr_mtd_name);
|
|
+ ret = mtd_block_isbad(parent_mtd, from);
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
|
|
static struct block2mtd_dev *add_device(char *devname, int erase_size,
|
|
char *label, int timeout)
|
|
@@ -294,12 +327,13 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size,
|
|
dev->mtd.erasesize = erase_size;
|
|
dev->mtd.writesize = 1;
|
|
dev->mtd.writebufsize = PAGE_SIZE;
|
|
- dev->mtd.type = MTD_RAM;
|
|
- dev->mtd.flags = MTD_CAP_RAM;
|
|
+ dev->mtd.type = MTD_NANDFLASH;
|
|
+ dev->mtd.flags = MTD_CAP_NANDFLASH;
|
|
dev->mtd._erase = block2mtd_erase;
|
|
dev->mtd._write = block2mtd_write;
|
|
dev->mtd._sync = block2mtd_sync;
|
|
- dev->mtd._read = block2mtd_read;
|
|
+ dev->mtd._read_oob = block2mtd_read_oob;
|
|
+ dev->mtd._block_isbad = block2mtd_isbad;
|
|
dev->mtd.priv = dev;
|
|
dev->mtd.owner = THIS_MODULE;
|
|
|
|
@@ -384,10 +418,11 @@ static char block2mtd_paramline[80 + 12];
|
|
|
|
static int block2mtd_setup2(const char *val)
|
|
{
|
|
- /* 80 for device, 12 for erase size, 80 for name, 8 for timeout */
|
|
- char buf[80 + 12 + 80 + 8];
|
|
+ /* 80 for device, 12 for erase size, 80 for name,
|
|
+ * 80 for parent mtd device name, 8 for timeout */
|
|
+ char buf[80 + 12 + 80 + 80 + 8];
|
|
char *str = buf;
|
|
- char *token[BLOCK2MTD_PARAM_MAX_COUNT];
|
|
+ char *token[BLOCK2MTD_PARAM_MAX_COUNT + 1];
|
|
char *name;
|
|
char *label = NULL;
|
|
size_t erase_size = PAGE_SIZE;
|
|
@@ -402,7 +437,7 @@ static int block2mtd_setup2(const char *val)
|
|
strcpy(str, val);
|
|
kill_final_newline(str);
|
|
|
|
- for (i = 0; i < BLOCK2MTD_PARAM_MAX_COUNT; i++)
|
|
+ for (i = 0; i < BLOCK2MTD_PARAM_MAX_COUNT + 1; i++)
|
|
token[i] = strsep(&str, ",");
|
|
|
|
if (str) {
|
|
@@ -435,6 +470,14 @@ static int block2mtd_setup2(const char *val)
|
|
pr_info("Using custom MTD label '%s' for dev %s\n", label, name);
|
|
}
|
|
|
|
+ if (token[3] && (strlen(token[3]) + 1 > 80))
|
|
+ pr_err("parent mtd device name too long\n");
|
|
+
|
|
+ if (token[4] && kstrtoul(token[4], 0, &timeout))
|
|
+ pr_err("invalid timeout\n");
|
|
+
|
|
+ strlcpy(parent_mtd_name, token[3], sizeof(parent_mtd_name));
|
|
+
|
|
add_device(name, erase_size, label, timeout);
|
|
|
|
return 0;
|
|
--
|
|
2.34.1
|
|
|