diff options
-rw-r--r-- | target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_bcm_wfi.c | 151 |
1 files changed, 69 insertions, 82 deletions
diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_bcm_wfi.c b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_bcm_wfi.c index 4e46ded587..cf57f59a58 100644 --- a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_bcm_wfi.c +++ b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_bcm_wfi.c @@ -130,54 +130,37 @@ static int ubifs_find(struct mtd_info *mtd, loff_t *offs, loff_t size) return -ENOENT; } -static int mtdsplit_parse_bcm_wfi(struct mtd_info *master, - const struct mtd_partition **pparts, - struct mtd_part_parser_data *data) +static int parse_bcm_wfi(struct mtd_info *master, + const struct mtd_partition **pparts, + uint8_t *buf, loff_t off, loff_t size, bool cfe_part) { struct mtd_partition *parts; - struct device_node *mtd_node; loff_t cfe_off, kernel_off, rootfs_off; - bool cfe_part = true; unsigned int num_parts = BCM_WFI_PARTS, cur_part = 0; - uint8_t *buf; int ret; - buf = kzalloc(master->erasesize, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - mtd_node = mtd_get_of_node(master); - if (!mtd_node) - return -EINVAL; - - if (of_property_read_bool(mtd_node, "brcm,no-cferam")) - cfe_part = false; - if (cfe_part) { num_parts++; - cfe_off = 0; + cfe_off = off; ret = jffs2_find_file(master, buf, CFERAM_NAME, CFERAM_NAME_LEN, &cfe_off, - master->size); - if (ret) { - kfree(buf); + size - (cfe_off - off)); + if (ret) return ret; - } kernel_off = cfe_off + master->erasesize; } else { - kernel_off = 0; + kernel_off = off; } ret = jffs2_find_file(master, buf, KERNEL_NAME, KERNEL_NAME_LEN, - &kernel_off, master->size); - kfree(buf); + &kernel_off, size - (kernel_off - off)); if (ret) return ret; rootfs_off = kernel_off + master->erasesize; - ret = ubifs_find(master, &rootfs_off, master->size); + ret = ubifs_find(master, &rootfs_off, size - (rootfs_off - off)); if (ret) return ret; @@ -188,14 +171,14 @@ static int mtdsplit_parse_bcm_wfi(struct mtd_info *master, if (cfe_part) { parts[cur_part].name = "cferam"; parts[cur_part].mask_flags = MTD_WRITEABLE; - parts[cur_part].offset = 0; - parts[cur_part].size = kernel_off; + parts[cur_part].offset = cfe_off; + parts[cur_part].size = kernel_off - cfe_off; cur_part++; } parts[cur_part].name = "firmware"; parts[cur_part].offset = kernel_off; - parts[cur_part].size = master->size - kernel_off; + parts[cur_part].size = size - (kernel_off - off); cur_part++; parts[cur_part].name = KERNEL_PART_NAME; @@ -205,7 +188,7 @@ static int mtdsplit_parse_bcm_wfi(struct mtd_info *master, parts[cur_part].name = UBI_PART_NAME; parts[cur_part].offset = rootfs_off; - parts[cur_part].size = master->size - rootfs_off; + parts[cur_part].size = size - (rootfs_off - off); cur_part++; *pparts = parts; @@ -213,6 +196,33 @@ static int mtdsplit_parse_bcm_wfi(struct mtd_info *master, return num_parts; } +static int mtdsplit_parse_bcm_wfi(struct mtd_info *master, + const struct mtd_partition **pparts, + struct mtd_part_parser_data *data) +{ + struct device_node *mtd_node; + bool cfe_part = true; + uint8_t *buf; + int ret; + + mtd_node = mtd_get_of_node(master); + if (!mtd_node) + return -EINVAL; + + buf = kzalloc(master->erasesize, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + if (of_property_read_bool(mtd_node, "brcm,no-cferam")) + cfe_part = false; + + ret = parse_bcm_wfi(master, pparts, buf, 0, master->size, cfe_part); + + kfree(buf); + + return ret; +} + static const struct of_device_id mtdsplit_bcm_wfi_of_match[] = { { .compatible = "brcm,wfi" }, { }, @@ -256,10 +266,12 @@ static int mtdsplit_parse_ser_wfi(struct mtd_info *master, { struct mtd_info *mtd_bf1, *mtd_bf2; struct erase_info bf_erase; - struct mtd_partition *parts; - loff_t kernel_off, rootfs_off, img_size; - loff_t img2_off, img2_size = 0; - unsigned int num_parts = BCM_WFI_PARTS, cur_part = 0; + loff_t img1_off = 0; + loff_t img2_off = master->size / 2; + loff_t img1_size = (img2_off - img1_off); + loff_t img2_size = (master->size - img2_off); + loff_t active_off, inactive_off; + loff_t active_size, inactive_size; uint8_t *buf; int bf1, bf2; int ret; @@ -292,65 +304,40 @@ static int mtdsplit_parse_ser_wfi(struct mtd_info *master, } if (bf1 >= bf2) { - kernel_off = 0; - if (bf2 >= 0) { - img_size = master->size / 2; - - img2_off = img_size; - img2_size = master->size - img2_off; - num_parts++; - } else { - img_size = master->size; - } + active_off = img1_off; + active_size = img1_size; + inactive_off = img2_off; + inactive_size = img2_size; } else { - kernel_off = master->size / 2; - img_size = master->size; - - img2_off = 0; - img2_size = kernel_off; - num_parts++; + active_off = img2_off; + active_size = img2_size; + inactive_off = img1_off; + inactive_size = img1_size; } - ret = jffs2_find_file(master, buf, KERNEL_NAME, KERNEL_NAME_LEN, - &kernel_off, img_size); - kfree(buf); - if (ret) - return ret; + ret = parse_bcm_wfi(master, pparts, buf, active_off, active_size, false); - rootfs_off = kernel_off + master->erasesize; - ret = ubifs_find(master, &rootfs_off, img_size); - if (ret) - return ret; + kfree(buf); - parts = kzalloc(num_parts * sizeof(*parts), GFP_KERNEL); - if (!parts) - return -ENOMEM; + if (ret > 0) { + struct mtd_partition *parts; - parts[cur_part].name = "firmware"; - parts[cur_part].offset = kernel_off; - parts[cur_part].size = img_size - kernel_off; - cur_part++; + parts = kzalloc((ret + 1) * sizeof(*parts), GFP_KERNEL); + if (!parts) + return -ENOMEM; - parts[cur_part].name = KERNEL_PART_NAME; - parts[cur_part].offset = kernel_off; - parts[cur_part].size = rootfs_off - kernel_off; - cur_part++; + memcpy(parts, *pparts, ret * sizeof(*parts)); + kfree(*pparts); - parts[cur_part].name = UBI_PART_NAME; - parts[cur_part].offset = rootfs_off; - parts[cur_part].size = img_size - rootfs_off; - cur_part++; + parts[ret].name = "img2"; + parts[ret].offset = inactive_off; + parts[ret].size = inactive_size; + ret++; - if (img2_size) { - parts[cur_part].name = "img2"; - parts[cur_part].offset = img2_off; - parts[cur_part].size = img2_size; - cur_part++; + *pparts = parts; } - *pparts = parts; - - return num_parts; + return ret; } static const struct of_device_id mtdsplit_ser_wfi_of_match[] = { |