From ecd5b3102322011610a2521c389ab5804c811837 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sat, 26 Jul 2008 09:17:41 +0100 Subject: [MTD] mtdoops: Fix an off by one error Fix an off by one error in the mtdoops driver Signed-off-by: Richard Purdie Signed-off-by: David Woodhouse --- drivers/mtd/mtdoops.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/mtd/mtdoops.c') diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c index 5a680e1e61f1..f40e45727aed 100644 --- a/drivers/mtd/mtdoops.c +++ b/drivers/mtd/mtdoops.c @@ -99,7 +99,7 @@ static void mtdoops_inc_counter(struct mtdoops_context *cxt) int ret; cxt->nextpage++; - if (cxt->nextpage > cxt->oops_pages) + if (cxt->nextpage >= cxt->oops_pages) cxt->nextpage = 0; cxt->nextcount++; if (cxt->nextcount == 0xffffffff) @@ -141,7 +141,7 @@ static void mtdoops_workfunc_erase(struct work_struct *work) mod = (cxt->nextpage * OOPS_PAGE_SIZE) % mtd->erasesize; if (mod != 0) { cxt->nextpage = cxt->nextpage + ((mtd->erasesize - mod) / OOPS_PAGE_SIZE); - if (cxt->nextpage > cxt->oops_pages) + if (cxt->nextpage >= cxt->oops_pages) cxt->nextpage = 0; } @@ -158,7 +158,7 @@ badblock: cxt->nextpage * OOPS_PAGE_SIZE); i++; cxt->nextpage = cxt->nextpage + (mtd->erasesize / OOPS_PAGE_SIZE); - if (cxt->nextpage > cxt->oops_pages) + if (cxt->nextpage >= cxt->oops_pages) cxt->nextpage = 0; if (i == (cxt->oops_pages / (mtd->erasesize / OOPS_PAGE_SIZE))) { printk(KERN_ERR "mtdoops: All blocks bad!\n"); -- cgit v1.2.2 From f0482ee3669a78bdb1e15b9f9c58a9f1ffc5a997 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sat, 26 Jul 2008 09:22:45 +0100 Subject: [MTD] mtdoops: Add a magic number to logged kernel oops Add a magic number to logged kernel oops messages so that they can be more accurately detected rather than just having to rely on the sequence number. This also allows easier detection of saved crashes by userspace. Signed-off-by: Richard Purdie Signed-off-by: David Woodhouse --- drivers/mtd/mtdoops.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) (limited to 'drivers/mtd/mtdoops.c') diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c index f40e45727aed..6f6b2f3c70df 100644 --- a/drivers/mtd/mtdoops.c +++ b/drivers/mtd/mtdoops.c @@ -33,6 +33,7 @@ #include #include +#define MTDOOPS_KERNMSG_MAGIC 0x5d005d00 #define OOPS_PAGE_SIZE 4096 static struct mtdoops_context { @@ -224,31 +225,33 @@ static void find_next_position(struct mtdoops_context *cxt) { struct mtd_info *mtd = cxt->mtd; int ret, page, maxpos = 0; - u32 count, maxcount = 0xffffffff; + u32 count[2], maxcount = 0xffffffff; size_t retlen; for (page = 0; page < cxt->oops_pages; page++) { - ret = mtd->read(mtd, page * OOPS_PAGE_SIZE, 4, &retlen, (u_char *) &count); - if ((retlen != 4) || ((ret < 0) && (ret != -EUCLEAN))) { - printk(KERN_ERR "mtdoops: Read failure at %d (%td of 4 read)" + ret = mtd->read(mtd, page * OOPS_PAGE_SIZE, 8, &retlen, (u_char *) &count[0]); + if ((retlen != 8) || ((ret < 0) && (ret != -EUCLEAN))) { + printk(KERN_ERR "mtdoops: Read failure at %d (%td of 8 read)" ", err %d.\n", page * OOPS_PAGE_SIZE, retlen, ret); continue; } - if (count == 0xffffffff) + if (count[1] != MTDOOPS_KERNMSG_MAGIC) + continue; + if (count[0] == 0xffffffff) continue; if (maxcount == 0xffffffff) { - maxcount = count; + maxcount = count[0]; maxpos = page; - } else if ((count < 0x40000000) && (maxcount > 0xc0000000)) { - maxcount = count; + } else if ((count[0] < 0x40000000) && (maxcount > 0xc0000000)) { + maxcount = count[0]; maxpos = page; - } else if ((count > maxcount) && (count < 0xc0000000)) { - maxcount = count; + } else if ((count[0] > maxcount) && (count[0] < 0xc0000000)) { + maxcount = count[0]; maxpos = page; - } else if ((count > maxcount) && (count > 0xc0000000) + } else if ((count[0] > maxcount) && (count[0] > 0xc0000000) && (maxcount > 0x80000000)) { - maxcount = count; + maxcount = count[0]; maxpos = page; } } @@ -358,8 +361,9 @@ mtdoops_console_write(struct console *co, const char *s, unsigned int count) if (cxt->writecount == 0) { u32 *stamp = cxt->oops_buf; - *stamp = cxt->nextcount; - cxt->writecount = 4; + *stamp++ = cxt->nextcount; + *stamp = MTDOOPS_KERNMSG_MAGIC; + cxt->writecount = 8; } if ((count + cxt->writecount) > OOPS_PAGE_SIZE) -- cgit v1.2.2 From 43b5693d404127697d62962def8c1bfe3a89811a Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sat, 26 Jul 2008 09:25:18 +0100 Subject: [MTD] mtdoops: Fix a bug where block may not be erased This makes the driver erase a block when it doesn't find any existing saved log messages which is safer than assuming the flash was already erased. Signed-off-by: Richard Purdie Signed-off-by: David Woodhouse --- drivers/mtd/mtdoops.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/mtd/mtdoops.c') diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c index 6f6b2f3c70df..aebb3b27edbd 100644 --- a/drivers/mtd/mtdoops.c +++ b/drivers/mtd/mtdoops.c @@ -258,9 +258,7 @@ static void find_next_position(struct mtdoops_context *cxt) if (maxcount == 0xffffffff) { cxt->nextpage = 0; cxt->nextcount = 1; - cxt->ready = 1; - printk(KERN_DEBUG "mtdoops: Ready %d, %d (first init)\n", - cxt->nextpage, cxt->nextcount); + schedule_work(&cxt->work_erase); return; } -- cgit v1.2.2