static void mtdoops_workfunc_erase(struct work_struct *work) { struct mtdoops_context *cxt = container_of(work, struct mtdoops_context, work_erase); struct mtd_info *mtd = cxt->mtd; int i = 0, j, ret, mod; if (!mtd) return; 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) cxt->nextpage = 0; } while (mtd->block_isbad) { ret = mtd->block_isbad(mtd, cxt->nextpage * OOPS_PAGE_SIZE); if (!ret) break; if (ret < 0) { printk(KERN_ERR "mtdoops: block_isbad failed, aborting.\n"); return; } badblock: printk(KERN_WARNING "mtdoops: Bad block at %08x\n", cxt->nextpage * OOPS_PAGE_SIZE); i++; cxt->nextpage = cxt->nextpage + (mtd->erasesize / OOPS_PAGE_SIZE); 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"); return; } } for (j = 0, ret = -1; (j < 3) && (ret < 0); j++) ret = mtdoops_erase_block(mtd, cxt->nextpage * OOPS_PAGE_SIZE); if (ret >= 0) { printk(KERN_DEBUG "mtdoops: Ready %d, %d \n", cxt->nextpage, cxt->nextcount); cxt->ready = 1; return; } if (mtd->block_markbad && (ret == -EIO)) { ret = mtd->block_markbad(mtd, cxt->nextpage * OOPS_PAGE_SIZE); if (ret < 0) { printk(KERN_ERR "mtdoops: block_markbad failed, aborting.\n"); return; } } goto badblock; }
/* Scheduled work - when we can't proceed without erasing a block */ static void mtdoops_workfunc_erase(struct work_struct *work) { struct mtdoops_context *cxt = container_of(work, struct mtdoops_context, work_erase); struct mtd_info *mtd = cxt->mtd; int i = 0, j, ret, mod; /* We were unregistered */ if (!mtd) return; mod = (cxt->nextpage * record_size) % mtd->erasesize; if (mod != 0) { cxt->nextpage = cxt->nextpage + ((mtd->erasesize - mod) / record_size); if (cxt->nextpage >= cxt->oops_pages) cxt->nextpage = 0; } while (mtd_can_have_bb(mtd)) { ret = mtd_block_isbad(mtd, cxt->nextpage * record_size); if (!ret) break; if (ret < 0) { printk(KERN_ERR "mtdoops: block_isbad failed, aborting\n"); return; } badblock: printk(KERN_WARNING "mtdoops: bad block at %08lx\n", cxt->nextpage * record_size); i++; cxt->nextpage = cxt->nextpage + (mtd->erasesize / record_size); if (cxt->nextpage >= cxt->oops_pages) cxt->nextpage = 0; if (i == cxt->oops_pages / (mtd->erasesize / record_size)) { printk(KERN_ERR "mtdoops: all blocks bad!\n"); return; } } for (j = 0, ret = -1; (j < 3) && (ret < 0); j++) ret = mtdoops_erase_block(cxt, cxt->nextpage * record_size); if (ret >= 0) { printk(KERN_DEBUG "mtdoops: ready %d, %d\n", cxt->nextpage, cxt->nextcount); return; } if (mtd_can_have_bb(mtd) && ret == -EIO) { ret = mtd_block_markbad(mtd, cxt->nextpage * record_size); if (ret < 0) { printk(KERN_ERR "mtdoops: block_markbad failed, aborting\n"); return; } } goto badblock; }