aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/bcm63xxpart.c
diff options
context:
space:
mode:
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