[][OpenWrt Dev][Add option for NMBM to support running in read-only mode]
[Description]
Add an option to allow NMBM running in read-only where only read operation
is accepted, and write/erase operation will be rejected.
With this option turned on, NMBM will write no signature block nor any
information table into NAND flash, which allows lower write/erase API
not being provided.
[Release-log]
N/A
Change-Id: Ia6931b073d2d56f722284c0b894e30551cd7c359
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/4672347
diff --git a/target/linux/generic/files-5.4/drivers/mtd/nmbm/nmbm-core.c b/target/linux/generic/files-5.4/drivers/mtd/nmbm/nmbm-core.c
index 009b82e..18dfb6a 100644
--- a/target/linux/generic/files-5.4/drivers/mtd/nmbm/nmbm-core.c
+++ b/target/linux/generic/files-5.4/drivers/mtd/nmbm/nmbm-core.c
@@ -238,6 +238,11 @@
{
int tries, ret;
+ if (ni->lower.flags & NMBM_F_READ_ONLY) {
+ nlog_err(ni, "%s called with NMBM_F_READ_ONLY set\n", addr);
+ return false;
+ }
+
for (tries = 0; tries < NMBM_TRY_COUNT; tries++) {
ret = ni->lower.write_page(ni->lower.arg, addr, data, oob, mode);
if (!ret)
@@ -262,6 +267,11 @@
{
int tries, ret;
+ if (ni->lower.flags & NMBM_F_READ_ONLY) {
+ nlog_err(ni, "%s called with NMBM_F_READ_ONLY set\n", addr);
+ return false;
+ }
+
for (tries = 0; tries < NMBM_TRY_COUNT; tries++) {
ret = ni->lower.erase_block(ni->lower.arg, addr);
if (!ret)
@@ -309,6 +319,11 @@
enum nmbm_log_category level;
uint32_t off;
+ if (ni->lower.flags & NMBM_F_READ_ONLY) {
+ nlog_err(ni, "%s called with NMBM_F_READ_ONLY set\n", addr);
+ return false;
+ }
+
nlog_info(ni, "Block %u [0x%08llx] will be marked bad\n", ba, addr);
if (ni->lower.mark_bad_block)
@@ -1684,6 +1699,11 @@
ni->signature.max_try_count = NMBM_TRY_COUNT;
nmbm_update_checksum(&ni->signature.header);
+ if (ni->lower.flags & NMBM_F_READ_ONLY) {
+ nlog_info(ni, "NMBM has been initialized in read-only mode\n");
+ return true;
+ }
+
success = nmbm_write_signature(ni, ni->mgmt_start_ba,
&ni->signature, &ni->signature_ba);
if (!success) {
@@ -1985,6 +2005,9 @@
/* Regenerate the info table cache from the final selected info table */
nmbm_generate_info_table_cache(ni);
+ if (ni->lower.flags & NMBM_F_READ_ONLY)
+ return true;
+
/*
* If only one table exists, try to write another table.
* If two tables have different write count, try to update info table
@@ -2037,7 +2060,8 @@
success = nmbm_load_info_table(ni, ni->mgmt_start_ba,
ni->signature_ba);
if (success) {
- nlog_info(ni, "NMBM has been successfully attached\n");
+ nlog_info(ni, "NMBM has been successfully attached %s\n",
+ (ni->lower.flags & NMBM_F_READ_ONLY) ? "in read-only mode" : "");
return true;
}
@@ -2048,6 +2072,11 @@
nmbm_scan_badblocks(ni);
nmbm_build_mapping_table(ni);
+ if (ni->lower.flags & NMBM_F_READ_ONLY) {
+ nlog_info(ni, "NMBM has been initialized in read-only mode\n");
+ return true;
+ }
+
/* Write info table(s) */
success = nmbm_create_info_table(ni);
if (success) {
@@ -2166,9 +2195,14 @@
return false;
}
+ if (!nld->read_page) {
+ nmbm_log_lower(nld, NMBM_LOG_ERR, "read_page() is required\n");
+ return false;
+ }
+
- if (!nld->read_page || !nld->write_page || !nld->erase_block) {
+ if (!(nld->flags & NMBM_F_READ_ONLY) && (!nld->write_page || !nld->erase_block)) {
nmbm_log_lower(nld, NMBM_LOG_ERR,
- "read_page(), write_page() and erase_block() are required\n");
+ "write_page() and erase_block() are required\n");
return false;
}
@@ -2355,7 +2389,8 @@
if (!ni)
return -EINVAL;
- nmbm_update_info_table(ni);
+ if (!(ni->lower.flags & NMBM_F_READ_ONLY))
+ nmbm_update_info_table(ni);
nmbm_mark_block_color_normal(ni, 0, ni->block_count - 1);
@@ -2443,7 +2478,7 @@
return -EINVAL;
/* Sanity check */
- if (ni->protected) {
+ if (ni->protected || (ni->lower.flags & NMBM_F_READ_ONLY)) {
nlog_debug(ni, "Device is forced read-only\n");
return -EROFS;
}
@@ -2710,7 +2745,7 @@
return -EINVAL;
/* Sanity check */
- if (ni->protected) {
+ if (ni->protected || (ni->lower.flags & NMBM_F_READ_ONLY)) {
nlog_debug(ni, "Device is forced read-only\n");
return -EROFS;
}
@@ -2745,7 +2780,7 @@
return -EINVAL;
/* Sanity check */
- if (ni->protected) {
+ if (ni->protected || (ni->lower.flags & NMBM_F_READ_ONLY)) {
nlog_debug(ni, "Device is forced read-only\n");
return -EROFS;
}
@@ -2843,6 +2878,12 @@
if (!ni)
return -EINVAL;
+ /* Sanity check */
+ if (ni->protected || (ni->lower.flags & NMBM_F_READ_ONLY)) {
+ nlog_debug(ni, "Device is forced read-only\n");
+ return -EROFS;
+ }
+
if (addr >= ba2addr(ni, ni->data_block_count)) {
nlog_err(ni, "Address 0x%llx is invalid\n", addr);
return -EINVAL;