[PATCH 2/2] ath79: mikrotik: Change the moment of routerboot partition parser init

Denis K denis281089 at gmail.com
Fri Nov 12 07:25:35 PST 2021


> OK, let’s do that as a workaround and hope that deferred probes won’t overlap past late_initcall()
What about using register_mtd_user function: routerboot can call
rb_hardconfig_init and rb_softconfig_init when mtd subsystem notifies
it about a new mtd device? It works.

---
 .../drivers/platform/mikrotik/rb_hardconfig.c | 12 ++++------
 .../drivers/platform/mikrotik/rb_softconfig.c | 12 ++++------
 .../drivers/platform/mikrotik/routerboot.c    | 24 +++++++++++++------
 .../drivers/platform/mikrotik/routerboot.h    |  5 ++--
 4 files changed, 30 insertions(+), 23 deletions(-)

diff --git a/target/linux/generic/files/drivers/platform/mikrotik/rb_hardconfig.c
b/target/linux/generic/files/drivers/platform/mikrotik/rb_hardconfig.c
index e6a6928896..724851474e 100644
--- a/target/linux/generic/files/drivers/platform/mikrotik/rb_hardconfig.c
+++ b/target/linux/generic/files/drivers/platform/mikrotik/rb_hardconfig.c
@@ -676,10 +676,9 @@ static ssize_t hc_wlan_data_bin_read(struct file
*filp, struct kobject *kobj,
     return count;
 }

-int __init rb_hardconfig_init(struct kobject *rb_kobj)
+int __init rb_hardconfig_init(struct kobject *rb_kobj, struct mtd_info *mtd)
 {
     struct kobject *hc_wlan_kobj;
-    struct mtd_info *mtd;
     size_t bytes_read, buflen, outlen;
     const u8 *buf;
     void *outbuf;
@@ -690,20 +689,19 @@ int __init rb_hardconfig_init(struct kobject *rb_kobj)
     hc_kobj = NULL;
     hc_wlan_kobj = NULL;

-    // TODO allow override
-    mtd = get_mtd_device_nm(RB_MTD_HARD_CONFIG);
-    if (IS_ERR(mtd))
+    ret = __get_mtd_device(mtd);
+    if (IS_ERR(ret))
         return -ENODEV;

     hc_buflen = mtd->size;
     hc_buf = kmalloc(hc_buflen, GFP_KERNEL);
     if (!hc_buf) {
-        put_mtd_device(mtd);
+        __put_mtd_device(mtd);
         return -ENOMEM;
     }

     ret = mtd_read(mtd, 0, hc_buflen, &bytes_read, hc_buf);
-    put_mtd_device(mtd);
+    __put_mtd_device(mtd);

     if (ret)
         goto fail;
diff --git a/target/linux/generic/files/drivers/platform/mikrotik/rb_softconfig.c
b/target/linux/generic/files/drivers/platform/mikrotik/rb_softconfig.c
index 070bd32d5a..59c42e4cf4 100644
--- a/target/linux/generic/files/drivers/platform/mikrotik/rb_softconfig.c
+++ b/target/linux/generic/files/drivers/platform/mikrotik/rb_softconfig.c
@@ -705,9 +705,8 @@ mtdfail:

 static struct kobj_attribute sc_kattrcommit = __ATTR(commit,
RB_SC_RMODE|RB_SC_WMODE, sc_commit_show, sc_commit_store);

-int __init rb_softconfig_init(struct kobject *rb_kobj)
+int __init rb_softconfig_init(struct kobject *rb_kobj, struct mtd_info *mtd)
 {
-    struct mtd_info *mtd;
     size_t bytes_read, buflen;
     const u8 *buf;
     int i, ret;
@@ -716,20 +715,19 @@ int __init rb_softconfig_init(struct kobject *rb_kobj)
     sc_buf = NULL;
     sc_kobj = NULL;

-    // TODO allow override
-    mtd = get_mtd_device_nm(RB_MTD_SOFT_CONFIG);
-    if (IS_ERR(mtd))
+    ret = __get_mtd_device(mtd);
+    if (IS_ERR(ret))
         return -ENODEV;

     sc_buflen = mtd->size;
     sc_buf = kmalloc(sc_buflen, GFP_KERNEL);
     if (!sc_buf) {
-        put_mtd_device(mtd);
+        __put_mtd_device(mtd);
         return -ENOMEM;
     }

     ret = mtd_read(mtd, 0, sc_buflen, &bytes_read, sc_buf);
-    put_mtd_device(mtd);
+    __put_mtd_device(mtd);

     if (ret)
         goto fail;
diff --git a/target/linux/generic/files/drivers/platform/mikrotik/routerboot.c
b/target/linux/generic/files/drivers/platform/mikrotik/routerboot.c
index 4c8c0bfac5..77f39709ce 100644
--- a/target/linux/generic/files/drivers/platform/mikrotik/routerboot.c
+++ b/target/linux/generic/files/drivers/platform/mikrotik/routerboot.c
@@ -160,25 +160,35 @@ fail:
     return ret;
 }

+static void routerboot_mtd_notifier_add(struct mtd_info *mtd)
+{
+    if (mtd->type != MTD_NORFLASH)
+        return;
+    if (!strcmp(mtd->name, RB_MTD_HARD_CONFIG)) {
+        rb_hardconfig_init(rb_kobj, mtd);
+    } else if (!strcmp(mtd->name, RB_MTD_SOFT_CONFIG)) {
+        rb_softconfig_init(rb_kobj, mtd);
+    }
+}
+
+static struct mtd_notifier routerboot_mtd_notifier = {
+        .add = routerboot_mtd_notifier_add,
+};
+
 static int __init routerboot_init(void)
 {
     rb_kobj = kobject_create_and_add("mikrotik", firmware_kobj);
     if (!rb_kobj)
         return -ENOMEM;

-    /*
-     * We ignore the following return values and always register.
-     * These init() routines are designed so that their failed state is
-     * always manageable by the corresponding exit() calls.
-     */
-    rb_hardconfig_init(rb_kobj);
-    rb_softconfig_init(rb_kobj);
+    register_mtd_user(&routerboot_mtd_notifier);

     return 0;
 }

 static void __exit routerboot_exit(void)
 {
+    unregister_mtd_user(&routerboot_mtd_notifier);
     rb_softconfig_exit();
     rb_hardconfig_exit();
     kobject_put(rb_kobj);    // recursive afaict
diff --git a/target/linux/generic/files/drivers/platform/mikrotik/routerboot.h
b/target/linux/generic/files/drivers/platform/mikrotik/routerboot.h
index 67d89808d5..5277a3cd94 100644
--- a/target/linux/generic/files/drivers/platform/mikrotik/routerboot.h
+++ b/target/linux/generic/files/drivers/platform/mikrotik/routerboot.h
@@ -10,6 +10,7 @@
 #define _ROUTERBOOT_H_

 #include <linux/types.h>
+#include <linux/mtd/mtd.h>

 // these magic values are stored in cpu-endianness on flash
 #define RB_MAGIC_HARD    (('H') | ('a' << 8) | ('r' << 16) | ('d' << 24))
@@ -25,10 +26,10 @@
 int routerboot_tag_find(const u8 *bufhead, const size_t buflen, const
u16 tag_id, u16 *pld_ofs, u16 *pld_len);
 int routerboot_rle_decode(const u8 *in, size_t inlen, u8 *out, size_t *outlen);

-int __init rb_hardconfig_init(struct kobject *rb_kobj);
+int __init rb_hardconfig_init(struct kobject *rb_kobj, struct mtd_info *mtd);
 void __exit rb_hardconfig_exit(void);

-int __init rb_softconfig_init(struct kobject *rb_kobj);
+int __init rb_softconfig_init(struct kobject *rb_kobj, struct mtd_info *mtd);
 void __exit rb_softconfig_exit(void);

 ssize_t routerboot_tag_show_string(const u8 *pld, u16 pld_len, char *buf);
--

Regards, Denis
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-routerboot-fix-mtd-nodev-error.patch
Type: text/x-patch
Size: 5884 bytes
Desc: not available
URL: <http://lists.openwrt.org/pipermail/openwrt-devel/attachments/20211112/03607a56/attachment.bin>


More information about the openwrt-devel mailing list