|
|
@@ -27,6 +27,7 @@
|
|
|
#define char_to_num(c) ((c >= '0' && c <= '9') ? (c - '0') : (0))
|
|
|
|
|
|
#define BCM_WFI_PARTS 3
|
|
|
+#define BCM_WFI_SPLIT_PARTS 2
|
|
|
|
|
|
#define CFERAM_NAME "cferam"
|
|
|
#define CFERAM_NAME_LEN (sizeof(CFERAM_NAME) - 1)
|
|
|
@@ -46,6 +47,11 @@
|
|
|
#define SERCOMM_MAGIC "eRcOmM.000"
|
|
|
#define SERCOMM_MAGIC_LEN (sizeof(SERCOMM_MAGIC) - 1)
|
|
|
|
|
|
+#define PART_CFERAM "cferam"
|
|
|
+#define PART_FIRMWARE "firmware"
|
|
|
+#define PART_IMAGE_1 "img1"
|
|
|
+#define PART_IMAGE_2 "img2"
|
|
|
+
|
|
|
static u32 jffs2_dirent_crc(struct jffs2_raw_dirent *node)
|
|
|
{
|
|
|
return crc32(0, node, sizeof(struct jffs2_raw_dirent) - 8);
|
|
|
@@ -187,14 +193,14 @@ static int parse_bcm_wfi(struct mtd_info *master,
|
|
|
return -ENOMEM;
|
|
|
|
|
|
if (cfe_part) {
|
|
|
- parts[cur_part].name = "cferam";
|
|
|
+ parts[cur_part].name = PART_CFERAM;
|
|
|
parts[cur_part].mask_flags = MTD_WRITEABLE;
|
|
|
parts[cur_part].offset = cfe_off;
|
|
|
parts[cur_part].size = kernel_off - cfe_off;
|
|
|
cur_part++;
|
|
|
}
|
|
|
|
|
|
- parts[cur_part].name = "firmware";
|
|
|
+ parts[cur_part].name = PART_FIRMWARE;
|
|
|
parts[cur_part].offset = kernel_off;
|
|
|
parts[cur_part].size = size - (kernel_off - off);
|
|
|
cur_part++;
|
|
|
@@ -273,6 +279,7 @@ static int mtdsplit_parse_bcm_wfi_split(struct mtd_info *master,
|
|
|
const struct mtd_partition **pparts,
|
|
|
struct mtd_part_parser_data *data)
|
|
|
{
|
|
|
+ struct mtd_partition *parts;
|
|
|
loff_t cfe_off;
|
|
|
loff_t img1_off = 0;
|
|
|
loff_t img2_off = master->size / 2;
|
|
|
@@ -280,6 +287,7 @@ static int mtdsplit_parse_bcm_wfi_split(struct mtd_info *master,
|
|
|
loff_t img2_size = (master->size - img2_off);
|
|
|
loff_t active_off, inactive_off;
|
|
|
loff_t active_size, inactive_size;
|
|
|
+ const char *inactive_name;
|
|
|
uint8_t *buf;
|
|
|
char *cfe1_name = NULL, *cfe2_name = NULL;
|
|
|
size_t cfe1_size = 0, cfe2_size = 0;
|
|
|
@@ -314,11 +322,13 @@ static int mtdsplit_parse_bcm_wfi_split(struct mtd_info *master,
|
|
|
active_size = img1_size;
|
|
|
inactive_off = img2_off;
|
|
|
inactive_size = img2_size;
|
|
|
+ inactive_name = PART_IMAGE_2;
|
|
|
} else {
|
|
|
active_off = img2_off;
|
|
|
active_size = img2_size;
|
|
|
inactive_off = img1_off;
|
|
|
inactive_size = img1_size;
|
|
|
+ inactive_name = PART_IMAGE_1;
|
|
|
}
|
|
|
|
|
|
ret = parse_bcm_wfi(master, pparts, buf, active_off, active_size, true);
|
|
|
@@ -326,8 +336,6 @@ static int mtdsplit_parse_bcm_wfi_split(struct mtd_info *master,
|
|
|
kfree(buf);
|
|
|
|
|
|
if (ret > 0) {
|
|
|
- struct mtd_partition *parts;
|
|
|
-
|
|
|
parts = kzalloc((ret + 1) * sizeof(*parts), GFP_KERNEL);
|
|
|
if (!parts)
|
|
|
return -ENOMEM;
|
|
|
@@ -335,11 +343,23 @@ static int mtdsplit_parse_bcm_wfi_split(struct mtd_info *master,
|
|
|
memcpy(parts, *pparts, ret * sizeof(*parts));
|
|
|
kfree(*pparts);
|
|
|
|
|
|
- parts[ret].name = "img2";
|
|
|
+ parts[ret].name = inactive_name;
|
|
|
parts[ret].offset = inactive_off;
|
|
|
parts[ret].size = inactive_size;
|
|
|
ret++;
|
|
|
|
|
|
+ *pparts = parts;
|
|
|
+ } else {
|
|
|
+ parts = kzalloc(BCM_WFI_SPLIT_PARTS * sizeof(*parts), GFP_KERNEL);
|
|
|
+
|
|
|
+ parts[0].name = PART_IMAGE_1;
|
|
|
+ parts[0].offset = img1_off;
|
|
|
+ parts[0].size = img1_size;
|
|
|
+
|
|
|
+ parts[1].name = PART_IMAGE_2;
|
|
|
+ parts[1].offset = img2_off;
|
|
|
+ parts[1].size = img2_size;
|
|
|
+
|
|
|
*pparts = parts;
|
|
|
}
|
|
|
|
|
|
@@ -387,14 +407,15 @@ static int mtdsplit_parse_ser_wfi(struct mtd_info *master,
|
|
|
const struct mtd_partition **pparts,
|
|
|
struct mtd_part_parser_data *data)
|
|
|
{
|
|
|
+ struct mtd_partition *parts;
|
|
|
struct mtd_info *mtd_bf1, *mtd_bf2;
|
|
|
- struct erase_info bf_erase;
|
|
|
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;
|
|
|
+ const char *inactive_name;
|
|
|
uint8_t *buf;
|
|
|
int bf1, bf2;
|
|
|
int ret;
|
|
|
@@ -420,6 +441,8 @@ static int mtdsplit_parse_ser_wfi(struct mtd_info *master,
|
|
|
printk("sercomm: bootflag2=%d\n", bf2);
|
|
|
|
|
|
if (bf1 == bf2 && bf2 >= 0) {
|
|
|
+ struct erase_info bf_erase;
|
|
|
+
|
|
|
bf2 = -ENOENT;
|
|
|
bf_erase.addr = 0;
|
|
|
bf_erase.len = mtd_bf2->size;
|
|
|
@@ -431,11 +454,13 @@ static int mtdsplit_parse_ser_wfi(struct mtd_info *master,
|
|
|
active_size = img1_size;
|
|
|
inactive_off = img2_off;
|
|
|
inactive_size = img2_size;
|
|
|
+ inactive_name = PART_IMAGE_2;
|
|
|
} else {
|
|
|
active_off = img2_off;
|
|
|
active_size = img2_size;
|
|
|
inactive_off = img1_off;
|
|
|
inactive_size = img1_size;
|
|
|
+ inactive_name = PART_IMAGE_1;
|
|
|
}
|
|
|
|
|
|
ret = parse_bcm_wfi(master, pparts, buf, active_off, active_size, false);
|
|
|
@@ -443,8 +468,6 @@ static int mtdsplit_parse_ser_wfi(struct mtd_info *master,
|
|
|
kfree(buf);
|
|
|
|
|
|
if (ret > 0) {
|
|
|
- struct mtd_partition *parts;
|
|
|
-
|
|
|
parts = kzalloc((ret + 1) * sizeof(*parts), GFP_KERNEL);
|
|
|
if (!parts)
|
|
|
return -ENOMEM;
|
|
|
@@ -452,11 +475,23 @@ static int mtdsplit_parse_ser_wfi(struct mtd_info *master,
|
|
|
memcpy(parts, *pparts, ret * sizeof(*parts));
|
|
|
kfree(*pparts);
|
|
|
|
|
|
- parts[ret].name = "img2";
|
|
|
+ parts[ret].name = inactive_name;
|
|
|
parts[ret].offset = inactive_off;
|
|
|
parts[ret].size = inactive_size;
|
|
|
ret++;
|
|
|
|
|
|
+ *pparts = parts;
|
|
|
+ } else {
|
|
|
+ parts = kzalloc(BCM_WFI_SPLIT_PARTS * sizeof(*parts), GFP_KERNEL);
|
|
|
+
|
|
|
+ parts[0].name = PART_IMAGE_1;
|
|
|
+ parts[0].offset = img1_off;
|
|
|
+ parts[0].size = img1_size;
|
|
|
+
|
|
|
+ parts[1].name = PART_IMAGE_2;
|
|
|
+ parts[1].offset = img2_off;
|
|
|
+ parts[1].size = img2_size;
|
|
|
+
|
|
|
*pparts = parts;
|
|
|
}
|
|
|
|