diff options
Diffstat (limited to 'drivers/mtd/bcm63xxpart.c')
-rw-r--r-- | drivers/mtd/bcm63xxpart.c | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/drivers/mtd/bcm63xxpart.c b/drivers/mtd/bcm63xxpart.c index 9933b347a555..17e137080a6b 100644 --- a/drivers/mtd/bcm63xxpart.c +++ b/drivers/mtd/bcm63xxpart.c | |||
@@ -36,6 +36,9 @@ | |||
36 | 36 | ||
37 | #define BCM63XX_EXTENDED_SIZE 0xBFC00000 /* Extended flash address */ | 37 | #define BCM63XX_EXTENDED_SIZE 0xBFC00000 /* Extended flash address */ |
38 | 38 | ||
39 | #define BCM63XX_MIN_CFE_SIZE 0x10000 /* always at least 64KiB */ | ||
40 | #define BCM63XX_MIN_NVRAM_SIZE 0x10000 /* always at least 64KiB */ | ||
41 | |||
39 | #define BCM63XX_CFE_MAGIC_OFFSET 0x4e0 | 42 | #define BCM63XX_CFE_MAGIC_OFFSET 0x4e0 |
40 | 43 | ||
41 | static int bcm63xx_detect_cfe(struct mtd_info *master) | 44 | static int bcm63xx_detect_cfe(struct mtd_info *master) |
@@ -74,6 +77,7 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, | |||
74 | size_t retlen; | 77 | size_t retlen; |
75 | unsigned int rootfsaddr, kerneladdr, spareaddr; | 78 | unsigned int rootfsaddr, kerneladdr, spareaddr; |
76 | unsigned int rootfslen, kernellen, sparelen, totallen; | 79 | unsigned int rootfslen, kernellen, sparelen, totallen; |
80 | unsigned int cfelen, nvramlen; | ||
77 | int namelen = 0; | 81 | int namelen = 0; |
78 | int i; | 82 | int i; |
79 | char *boardid; | 83 | char *boardid; |
@@ -82,14 +86,18 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, | |||
82 | if (bcm63xx_detect_cfe(master)) | 86 | if (bcm63xx_detect_cfe(master)) |
83 | return -EINVAL; | 87 | return -EINVAL; |
84 | 88 | ||
89 | cfelen = max_t(uint32_t, master->erasesize, BCM63XX_MIN_CFE_SIZE); | ||
90 | nvramlen = max_t(uint32_t, master->erasesize, BCM63XX_MIN_NVRAM_SIZE); | ||
91 | |||
85 | /* Allocate memory for buffer */ | 92 | /* Allocate memory for buffer */ |
86 | buf = vmalloc(sizeof(struct bcm_tag)); | 93 | buf = vmalloc(sizeof(struct bcm_tag)); |
87 | if (!buf) | 94 | if (!buf) |
88 | return -ENOMEM; | 95 | return -ENOMEM; |
89 | 96 | ||
90 | /* Get the tag */ | 97 | /* Get the tag */ |
91 | ret = master->read(master, master->erasesize, sizeof(struct bcm_tag), | 98 | ret = master->read(master, cfelen, sizeof(struct bcm_tag), &retlen, |
92 | &retlen, (void *)buf); | 99 | (void *)buf); |
100 | |||
93 | if (retlen != sizeof(struct bcm_tag)) { | 101 | if (retlen != sizeof(struct bcm_tag)) { |
94 | vfree(buf); | 102 | vfree(buf); |
95 | return -EIO; | 103 | return -EIO; |
@@ -106,8 +114,8 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, | |||
106 | 114 | ||
107 | kerneladdr = kerneladdr - BCM63XX_EXTENDED_SIZE; | 115 | kerneladdr = kerneladdr - BCM63XX_EXTENDED_SIZE; |
108 | rootfsaddr = kerneladdr + kernellen; | 116 | rootfsaddr = kerneladdr + kernellen; |
109 | spareaddr = roundup(totallen, master->erasesize) + master->erasesize; | 117 | spareaddr = roundup(totallen, master->erasesize) + cfelen; |
110 | sparelen = master->size - spareaddr - master->erasesize; | 118 | sparelen = master->size - spareaddr - nvramlen; |
111 | rootfslen = spareaddr - rootfsaddr; | 119 | rootfslen = spareaddr - rootfsaddr; |
112 | 120 | ||
113 | /* Determine number of partitions */ | 121 | /* Determine number of partitions */ |
@@ -131,7 +139,7 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, | |||
131 | /* Start building partition list */ | 139 | /* Start building partition list */ |
132 | parts[curpart].name = "CFE"; | 140 | parts[curpart].name = "CFE"; |
133 | parts[curpart].offset = 0; | 141 | parts[curpart].offset = 0; |
134 | parts[curpart].size = master->erasesize; | 142 | parts[curpart].size = cfelen; |
135 | curpart++; | 143 | curpart++; |
136 | 144 | ||
137 | if (kernellen > 0) { | 145 | if (kernellen > 0) { |
@@ -151,8 +159,8 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, | |||
151 | } | 159 | } |
152 | 160 | ||
153 | parts[curpart].name = "nvram"; | 161 | parts[curpart].name = "nvram"; |
154 | parts[curpart].offset = master->size - master->erasesize; | 162 | parts[curpart].offset = master->size - nvramlen; |
155 | parts[curpart].size = master->erasesize; | 163 | parts[curpart].size = nvramlen; |
156 | 164 | ||
157 | /* Global partition "linux" to make easy firmware upgrade */ | 165 | /* Global partition "linux" to make easy firmware upgrade */ |
158 | curpart++; | 166 | curpart++; |