aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/mtdoops.c
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2008-10-22 14:34:09 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2008-10-22 14:34:09 -0400
commitf20e3b5fe7ead0615309433260b9784d8da0bbbd (patch)
treeeabb2e47a0355ac4e8024b7087b4e7cb9f324358 /drivers/mtd/mtdoops.c
parentbcbfe664e7af019e698cef2feb85ac2b4f1ac11d (diff)
parentf030d7b65e4e6399f23de2a41a58d1b607b6bd89 (diff)
Merge branch 'for-rmk' of git://git.android.com/kernel into devel
Diffstat (limited to 'drivers/mtd/mtdoops.c')
-rw-r--r--drivers/mtd/mtdoops.c42
1 files changed, 22 insertions, 20 deletions
diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c
index 5a680e1e61f1..aebb3b27edbd 100644
--- a/drivers/mtd/mtdoops.c
+++ b/drivers/mtd/mtdoops.c
@@ -33,6 +33,7 @@
33#include <linux/interrupt.h> 33#include <linux/interrupt.h>
34#include <linux/mtd/mtd.h> 34#include <linux/mtd/mtd.h>
35 35
36#define MTDOOPS_KERNMSG_MAGIC 0x5d005d00
36#define OOPS_PAGE_SIZE 4096 37#define OOPS_PAGE_SIZE 4096
37 38
38static struct mtdoops_context { 39static struct mtdoops_context {
@@ -99,7 +100,7 @@ static void mtdoops_inc_counter(struct mtdoops_context *cxt)
99 int ret; 100 int ret;
100 101
101 cxt->nextpage++; 102 cxt->nextpage++;
102 if (cxt->nextpage > cxt->oops_pages) 103 if (cxt->nextpage >= cxt->oops_pages)
103 cxt->nextpage = 0; 104 cxt->nextpage = 0;
104 cxt->nextcount++; 105 cxt->nextcount++;
105 if (cxt->nextcount == 0xffffffff) 106 if (cxt->nextcount == 0xffffffff)
@@ -141,7 +142,7 @@ static void mtdoops_workfunc_erase(struct work_struct *work)
141 mod = (cxt->nextpage * OOPS_PAGE_SIZE) % mtd->erasesize; 142 mod = (cxt->nextpage * OOPS_PAGE_SIZE) % mtd->erasesize;
142 if (mod != 0) { 143 if (mod != 0) {
143 cxt->nextpage = cxt->nextpage + ((mtd->erasesize - mod) / OOPS_PAGE_SIZE); 144 cxt->nextpage = cxt->nextpage + ((mtd->erasesize - mod) / OOPS_PAGE_SIZE);
144 if (cxt->nextpage > cxt->oops_pages) 145 if (cxt->nextpage >= cxt->oops_pages)
145 cxt->nextpage = 0; 146 cxt->nextpage = 0;
146 } 147 }
147 148
@@ -158,7 +159,7 @@ badblock:
158 cxt->nextpage * OOPS_PAGE_SIZE); 159 cxt->nextpage * OOPS_PAGE_SIZE);
159 i++; 160 i++;
160 cxt->nextpage = cxt->nextpage + (mtd->erasesize / OOPS_PAGE_SIZE); 161 cxt->nextpage = cxt->nextpage + (mtd->erasesize / OOPS_PAGE_SIZE);
161 if (cxt->nextpage > cxt->oops_pages) 162 if (cxt->nextpage >= cxt->oops_pages)
162 cxt->nextpage = 0; 163 cxt->nextpage = 0;
163 if (i == (cxt->oops_pages / (mtd->erasesize / OOPS_PAGE_SIZE))) { 164 if (i == (cxt->oops_pages / (mtd->erasesize / OOPS_PAGE_SIZE))) {
164 printk(KERN_ERR "mtdoops: All blocks bad!\n"); 165 printk(KERN_ERR "mtdoops: All blocks bad!\n");
@@ -224,40 +225,40 @@ static void find_next_position(struct mtdoops_context *cxt)
224{ 225{
225 struct mtd_info *mtd = cxt->mtd; 226 struct mtd_info *mtd = cxt->mtd;
226 int ret, page, maxpos = 0; 227 int ret, page, maxpos = 0;
227 u32 count, maxcount = 0xffffffff; 228 u32 count[2], maxcount = 0xffffffff;
228 size_t retlen; 229 size_t retlen;
229 230
230 for (page = 0; page < cxt->oops_pages; page++) { 231 for (page = 0; page < cxt->oops_pages; page++) {
231 ret = mtd->read(mtd, page * OOPS_PAGE_SIZE, 4, &retlen, (u_char *) &count); 232 ret = mtd->read(mtd, page * OOPS_PAGE_SIZE, 8, &retlen, (u_char *) &count[0]);
232 if ((retlen != 4) || ((ret < 0) && (ret != -EUCLEAN))) { 233 if ((retlen != 8) || ((ret < 0) && (ret != -EUCLEAN))) {
233 printk(KERN_ERR "mtdoops: Read failure at %d (%td of 4 read)" 234 printk(KERN_ERR "mtdoops: Read failure at %d (%td of 8 read)"
234 ", err %d.\n", page * OOPS_PAGE_SIZE, retlen, ret); 235 ", err %d.\n", page * OOPS_PAGE_SIZE, retlen, ret);
235 continue; 236 continue;
236 } 237 }
237 238
238 if (count == 0xffffffff) 239 if (count[1] != MTDOOPS_KERNMSG_MAGIC)
240 continue;
241 if (count[0] == 0xffffffff)
239 continue; 242 continue;
240 if (maxcount == 0xffffffff) { 243 if (maxcount == 0xffffffff) {
241 maxcount = count; 244 maxcount = count[0];
242 maxpos = page; 245 maxpos = page;
243 } else if ((count < 0x40000000) && (maxcount > 0xc0000000)) { 246 } else if ((count[0] < 0x40000000) && (maxcount > 0xc0000000)) {
244 maxcount = count; 247 maxcount = count[0];
245 maxpos = page; 248 maxpos = page;
246 } else if ((count > maxcount) && (count < 0xc0000000)) { 249 } else if ((count[0] > maxcount) && (count[0] < 0xc0000000)) {
247 maxcount = count; 250 maxcount = count[0];
248 maxpos = page; 251 maxpos = page;
249 } else if ((count > maxcount) && (count > 0xc0000000) 252 } else if ((count[0] > maxcount) && (count[0] > 0xc0000000)
250 && (maxcount > 0x80000000)) { 253 && (maxcount > 0x80000000)) {
251 maxcount = count; 254 maxcount = count[0];
252 maxpos = page; 255 maxpos = page;
253 } 256 }
254 } 257 }
255 if (maxcount == 0xffffffff) { 258 if (maxcount == 0xffffffff) {
256 cxt->nextpage = 0; 259 cxt->nextpage = 0;
257 cxt->nextcount = 1; 260 cxt->nextcount = 1;
258 cxt->ready = 1; 261 schedule_work(&cxt->work_erase);
259 printk(KERN_DEBUG "mtdoops: Ready %d, %d (first init)\n",
260 cxt->nextpage, cxt->nextcount);
261 return; 262 return;
262 } 263 }
263 264
@@ -358,8 +359,9 @@ mtdoops_console_write(struct console *co, const char *s, unsigned int count)
358 359
359 if (cxt->writecount == 0) { 360 if (cxt->writecount == 0) {
360 u32 *stamp = cxt->oops_buf; 361 u32 *stamp = cxt->oops_buf;
361 *stamp = cxt->nextcount; 362 *stamp++ = cxt->nextcount;
362 cxt->writecount = 4; 363 *stamp = MTDOOPS_KERNMSG_MAGIC;
364 cxt->writecount = 8;
363 } 365 }
364 366
365 if ((count + cxt->writecount) > OOPS_PAGE_SIZE) 367 if ((count + cxt->writecount) > OOPS_PAGE_SIZE)