ar71xx: rb91x-nand: rewrite to use GPIO API
[oweals/openwrt.git] / target / linux / ar71xx / files / drivers / mtd / tplinkpart.c
index 7b2ac7e40dc3ce649bf078198569cd8cfbfe16f5..cabb96033d6cbdfe14bbe6ba2ad3facda8d39c90 100644 (file)
@@ -8,8 +8,10 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
+#include <linux/magic.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
@@ -58,8 +60,8 @@ tplink_read_header(struct mtd_info *mtd, size_t offset)
                goto err;
 
        header_len = sizeof(struct tplink_fw_header);
-       ret = mtd->read(mtd, offset, header_len, &retlen,
-                       (unsigned char *) header);
+       ret = mtd_read(mtd, offset, header_len, &retlen,
+                      (unsigned char *) header);
        if (ret)
                goto err_free_header;
 
@@ -83,9 +85,30 @@ err:
        return NULL;
 }
 
+static int tplink_check_rootfs_magic(struct mtd_info *mtd, size_t offset)
+{
+       u32 magic;
+       size_t retlen;
+       int ret;
+
+       ret = mtd_read(mtd, offset, sizeof(magic), &retlen,
+                      (unsigned char *) &magic);
+       if (ret)
+               return ret;
+
+       if (retlen != sizeof(magic))
+               return -EIO;
+
+       if (le32_to_cpu(magic) != SQUASHFS_MAGIC &&
+           magic != 0x19852003)
+               return -EINVAL;
+
+       return 0;
+}
+
 static int tplink_parse_partitions(struct mtd_info *master,
                                   struct mtd_partition **pparts,
-                                  unsigned long origin)
+                                  struct mtd_part_parser_data *data)
 {
        struct mtd_partition *parts;
        struct tplink_fw_header *header;
@@ -93,6 +116,7 @@ static int tplink_parse_partitions(struct mtd_info *master,
        size_t offset;
        size_t art_offset;
        size_t rootfs_offset;
+       size_t squashfs_offset;
        int ret;
 
        nr_parts = TPLINK_NUM_PARTS;
@@ -111,7 +135,15 @@ static int tplink_parse_partitions(struct mtd_info *master,
                goto err_free_parts;
        }
 
-       rootfs_offset = offset + be32_to_cpu(header->rootfs_ofs);
+       squashfs_offset = offset + sizeof(struct tplink_fw_header) +
+                         be32_to_cpu(header->kernel_len);
+
+       ret = tplink_check_rootfs_magic(master, squashfs_offset);
+       if (ret == 0)
+               rootfs_offset = squashfs_offset;
+       else
+               rootfs_offset = offset + be32_to_cpu(header->rootfs_ofs);
+
        art_offset = master->size - TPLINK_ART_LEN;
 
        parts[0].name = "u-boot";