Openwrt recently adds Qihoo [NYSE:QIHU] C301 router support.
However, this router has a backup firmware in the second flash and the
current trunk can only boot 3 times before u-boot boots into that backup
firmware. This is a stratgy for unbricking. 

This patch makes u-boot happy.

Signed-off-by: Xungneg li <swigger at gmail.com>

===============================================================
diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-qihoo-c301.c
b/target/linux/ar71xx/files/arch/mips/ath79/mach-qihoo-c301.c
index 08a602f..774356f 100644
--- a/target/linux/ar71xx/files/arch/mips/ath79/mach-qihoo-c301.c
+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-qihoo-c301.c
@@ -14,6 +14,8 @@
 #include <linux/gpio.h>
 #include <linux/platform_device.h>
 #include <linux/ath9k_platform.h>
+#include <linux/crc32.h>
+#include <linux/mtd/mtd.h>
 
 #include <asm/mach-ath79/ar71xx_regs.h>
 
@@ -79,6 +81,7 @@ static struct gpio_keys_button qihoo_c301_gpio_keys[]
__initdata = {
        },
 };
 
+static int qihoo_c301_board = 0;
 struct flash_platform_data flash __initdata = {NULL, NULL, 0};
 
 static void qihoo_c301_get_mac(const char *name, char *mac) @@ -98,6 +101,7
@@ static void __init qihoo_c301_setup(void)
        u8 tmpmac[ETH_ALEN];
 
        ath79_register_m25p80_multi(&flash);
+       qihoo_c301_board = 1;
 
        ath79_gpio_function_enable(AR934X_GPIO_FUNC_JTAG_DISABLE);
 
@@ -164,3 +168,86 @@ static void __init qihoo_c301_setup(void)
 
 MIPS_MACHINE(ATH79_MACH_QIHOO_C301, "QIHOO-C301", "Qihoo 360 C301",
             qihoo_c301_setup);
+
+
+//the following code stops qihoo's uboot booting into the backup system.
+static void erase_callback(struct erase_info *erase) {
+       char * buf = (char*) erase->priv;
+       int ret;
+       size_t nb=0;
+
+       if (erase->state == MTD_ERASE_DONE)
+       {
+               ret = mtd_write(erase->mtd, 0, 0x10000, &nb, buf);
+       }
+       kfree(erase);
+       kfree(buf);
+}
+
+static int qihoo_reset_trynum(void)
+{
+       size_t nb = 0;
+       char *buf=0, *p;
+       const char * match = "image1trynum=";
+       size_t matchlen = strlen(match);
+       struct erase_info *erase;
+       struct mtd_info * mtd;
+       unsigned int newcrc;
+       int ret;
+
+       if (! qihoo_c301_board)
+               return 0;
+
+       mtd = get_mtd_device_nm("action_image_config");
+       if (IS_ERR(mtd))
+       {
+               return PTR_ERR(mtd);
+       }
+       if (mtd->size!=0x10000)
+       {
+               return -1;
+       }
+       buf = kzalloc(0x10000+4, GFP_KERNEL);
+       ret = mtd_read(mtd, 0, 0x10000, &nb, buf);
+       if (nb != 0x10000)
+       {
+               kfree(buf);
+               return -1;
+       }
+       for (p=buf+4; *p; p+=strlen(p)+1)
+       {
+               if (strncmp(p, match, matchlen)==0)
+               {
+                       p += matchlen;
+                       while (*p)
+                               *p++ = '0';
+                       break;
+               }
+       }
+
+       newcrc = crc32(~0, buf+4, 0xfffc)^0xffffffff;
+       memcpy(buf, &newcrc, 4);
+
+       erase = kzalloc(sizeof(struct erase_info), GFP_KERNEL);
+       if (!erase)
+       {
+               kfree(buf);
+               return -1;
+       }
+       erase->mtd      = mtd;
+       erase->callback = erase_callback;
+       erase->addr     = 0;
+       erase->len      = 0x10000;
+       erase->priv     = (u_long) buf;
+       ret = mtd_erase(mtd, erase);
+
+       if (ret) {
+               kfree(buf);
+               kfree(erase);
+               return ret;
+       }
+
+       return 0;
+}
+late_initcall(qihoo_reset_trynum);
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel

Reply via email to