diff options
Diffstat (limited to 'drivers/mtd/bcm63xxpart.c')
-rw-r--r-- | drivers/mtd/bcm63xxpart.c | 41 |
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 | ||