aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/bcm63xxpart.c
diff options
context:
space:
mode:
authorJonas Gorski <jonas.gorski@gmail.com>2012-04-19 07:15:57 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2012-05-13 23:55:03 -0400
commit5329d67cc32c0306426dc4bc4b5e66a36cb87ce0 (patch)
tree51e5c892f9c22ac145f12fc1ad54233ed91f4dde /drivers/mtd/bcm63xxpart.c
parenta9c465f07c2dcd515d20b96f93470762f9ae08b6 (diff)
mtd: bcm63xxpart: handle Broadcom partition order
The original Broadcom partition order has the root fs in front of the kernel, which resulted in miscalculated partition sizes. Detect when such an image is on the flash and also reorder the partitions accordingly. Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> Acked-by: Florian Fainelli <florian@openwrt.org> Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@linux.intel.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd/bcm63xxpart.c')
-rw-r--r--drivers/mtd/bcm63xxpart.c41
1 files changed, 30 insertions, 11 deletions
diff --git a/drivers/mtd/bcm63xxpart.c b/drivers/mtd/bcm63xxpart.c
index 608321ee056e..63d2a64331f7 100644
--- a/drivers/mtd/bcm63xxpart.c
+++ b/drivers/mtd/bcm63xxpart.c
@@ -4,7 +4,7 @@
4 * Copyright © 2006-2008 Florian Fainelli <florian@openwrt.org> 4 * Copyright © 2006-2008 Florian Fainelli <florian@openwrt.org>
5 * Mike Albon <malbon@openwrt.org> 5 * Mike Albon <malbon@openwrt.org>
6 * Copyright © 2009-2010 Daniel Dickinson <openwrt@cshore.neomailbox.net> 6 * Copyright © 2009-2010 Daniel Dickinson <openwrt@cshore.neomailbox.net>
7 * Copyright © 2011 Jonas Gorski <jonas.gorski@gmail.com> 7 * Copyright © 2011-2012 Jonas Gorski <jonas.gorski@gmail.com>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
@@ -82,6 +82,7 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
82 int namelen = 0; 82 int namelen = 0;
83 int i; 83 int i;
84 u32 computed_crc; 84 u32 computed_crc;
85 bool rootfs_first = false;
85 86
86 if (bcm63xx_detect_cfe(master)) 87 if (bcm63xx_detect_cfe(master))
87 return -EINVAL; 88 return -EINVAL;
@@ -109,6 +110,7 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
109 char *boardid = &(buf->board_id[0]); 110 char *boardid = &(buf->board_id[0]);
110 char *tagversion = &(buf->tag_version[0]); 111 char *tagversion = &(buf->tag_version[0]);
111 112
113 sscanf(buf->flash_image_start, "%u", &rootfsaddr);
112 sscanf(buf->kernel_address, "%u", &kerneladdr); 114 sscanf(buf->kernel_address, "%u", &kerneladdr);
113 sscanf(buf->kernel_length, "%u", &kernellen); 115 sscanf(buf->kernel_length, "%u", &kernellen);
114 sscanf(buf->total_length, "%u", &totallen); 116 sscanf(buf->total_length, "%u", &totallen);
@@ -117,10 +119,19 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
117 tagversion, boardid); 119 tagversion, boardid);
118 120
119 kerneladdr = kerneladdr - BCM63XX_EXTENDED_SIZE; 121 kerneladdr = kerneladdr - BCM63XX_EXTENDED_SIZE;
120 rootfsaddr = kerneladdr + kernellen; 122 rootfsaddr = rootfsaddr - BCM63XX_EXTENDED_SIZE;
121 spareaddr = roundup(totallen, master->erasesize) + cfelen; 123 spareaddr = roundup(totallen, master->erasesize) + cfelen;
122 sparelen = master->size - spareaddr - nvramlen; 124 sparelen = master->size - spareaddr - nvramlen;
123 rootfslen = spareaddr - rootfsaddr; 125
126 if (rootfsaddr < kerneladdr) {
127 /* default Broadcom layout */
128 rootfslen = kerneladdr - rootfsaddr;
129 rootfs_first = true;
130 } else {
131 /* OpenWrt layout */
132 rootfsaddr = kerneladdr + kernellen;
133 rootfslen = spareaddr - rootfsaddr;
134 }
124 } else { 135 } else {
125 pr_warn("CFE boot tag CRC invalid (expected %08x, actual %08x)\n", 136 pr_warn("CFE boot tag CRC invalid (expected %08x, actual %08x)\n",
126 buf->header_crc, computed_crc); 137 buf->header_crc, computed_crc);
@@ -156,18 +167,26 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
156 curpart++; 167 curpart++;
157 168
158 if (kernellen > 0) { 169 if (kernellen > 0) {
159 parts[curpart].name = "kernel"; 170 int kernelpart = curpart;
160 parts[curpart].offset = kerneladdr; 171
161 parts[curpart].size = kernellen; 172 if (rootfslen > 0 && rootfs_first)
173 kernelpart++;
174 parts[kernelpart].name = "kernel";
175 parts[kernelpart].offset = kerneladdr;
176 parts[kernelpart].size = kernellen;
162 curpart++; 177 curpart++;
163 } 178 }
164 179
165 if (rootfslen > 0) { 180 if (rootfslen > 0) {
166 parts[curpart].name = "rootfs"; 181 int rootfspart = curpart;
167 parts[curpart].offset = rootfsaddr; 182
168 parts[curpart].size = rootfslen; 183 if (kernellen > 0 && rootfs_first)
169 if (sparelen > 0) 184 rootfspart--;
170 parts[curpart].size += sparelen; 185 parts[rootfspart].name = "rootfs";
186 parts[rootfspart].offset = rootfsaddr;
187 parts[rootfspart].size = rootfslen;
188 if (sparelen > 0 && !rootfs_first)
189 parts[rootfspart].size += sparelen;
171 curpart++; 190 curpart++;
172 } 191 }
173 192