]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/mtd/mtdoops.c
Staging: comedi: add pcl711 driver
[linux-2.6-omap-h63xx.git] / drivers / mtd / mtdoops.c
index 5a680e1e61f14dbc2ba684482792f2f40aabbee9..1a6b3beabe8d04f70762f9aa3e470160a8e7c653 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/interrupt.h>
 #include <linux/mtd/mtd.h>
 
+#define MTDOOPS_KERNMSG_MAGIC 0x5d005d00
 #define OOPS_PAGE_SIZE 4096
 
 static struct mtdoops_context {
@@ -79,9 +80,9 @@ static int mtdoops_erase_block(struct mtd_info *mtd, int offset)
        if (ret) {
                set_current_state(TASK_RUNNING);
                remove_wait_queue(&wait_q, &wait);
-               printk (KERN_WARNING "mtdoops: erase of region [0x%x, 0x%x] "
+               printk (KERN_WARNING "mtdoops: erase of region [0x%llx, 0x%llx] "
                                     "on \"%s\" failed\n",
-                       erase.addr, erase.len, mtd->name);
+                       (unsigned long long)erase.addr, (unsigned long long)erase.len, mtd->name);
                return ret;
        }
 
@@ -99,7 +100,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 +142,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 +159,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");
@@ -224,40 +225,40 @@ 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;
                }
        }
        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;
        }
 
@@ -288,7 +289,10 @@ static void mtdoops_notify_add(struct mtd_info *mtd)
        }
 
        cxt->mtd = mtd;
-       cxt->oops_pages = mtd->size / OOPS_PAGE_SIZE;
+       if (mtd->size > INT_MAX)
+               cxt->oops_pages = INT_MAX / OOPS_PAGE_SIZE;
+       else
+               cxt->oops_pages = (int)mtd->size / OOPS_PAGE_SIZE;
 
        find_next_position(cxt);
 
@@ -358,8 +362,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)