int mtd_index; struct work_struct work_erase; struct work_struct work_write; struct mtd_info *mtd; int oops_pages; int nextpage; int nextcount; unsignedlong *oops_page_used;
ret = mtd_erase(mtd, &erase); if (ret) {
pr_warn("erase of region [0x%llx, 0x%llx] on \"%s\" failed\n",
(unsignedlonglong)erase.addr,
(unsignedlonglong)erase.len, mtddev); return ret;
}
/* Mark pages as unused */ for (page = start_page; page < start_page + erase_pages; page++)
mark_page_unused(cxt, page);
return 0;
}
staticvoid mtdoops_erase(struct mtdoops_context *cxt)
{ 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 ((ret = mtd_block_isbad(mtd, cxt->nextpage * record_size)) > 0) {
badblock:
pr_warn("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)) {
pr_err("all blocks bad!\n"); return;
}
}
if (ret < 0) {
pr_err("mtd_block_isbad failed, aborting\n"); return;
}
for (j = 0, ret = -1; (j < 3) && (ret < 0); j++)
ret = mtdoops_erase_block(cxt, cxt->nextpage * record_size);
if (detail->reason != KMSG_DUMP_OOPS) { /* Panics must be written immediately */
mtdoops_write(cxt, 1);
} else { /* For other cases, schedule work to write it "nicely" */
schedule_work(&cxt->work_write);
}
}
if (!strcmp(mtd->name, mtddev))
cxt->mtd_index = mtd->index;
if (mtd->index != cxt->mtd_index || cxt->mtd_index < 0) return;
if (mtd->size < mtd->erasesize * 2) {
pr_err("MTD partition %d not big enough for mtdoops\n",
mtd->index); return;
} if (mtd->erasesize < record_size) {
pr_err("eraseblock size of MTD partition %d too small\n",
mtd->index); return;
} if (mtd->size > MTDOOPS_MAX_MTD_SIZE) {
pr_err("mtd%d is too large (limit is %d MiB)\n",
mtd->index, MTDOOPS_MAX_MTD_SIZE / 1024 / 1024); return;
}
/* oops_page_used is a bit field */
cxt->oops_page_used =
vmalloc(array_size(sizeof(unsignedlong),
DIV_ROUND_UP(mtdoops_pages,
BITS_PER_LONG))); if (!cxt->oops_page_used) {
pr_err("could not allocate page array\n"); return;
}
if (strlen(mtddev) == 0) {
pr_err("mtd device (mtddev=name/number) must be supplied\n"); return -EINVAL;
} if ((record_size & 4095) != 0) {
pr_err("record_size must be a multiple of 4096\n"); return -EINVAL;
} if (record_size < 4096) {
pr_err("record_size must be over 4096 bytes\n"); return -EINVAL;
}
/* Setup the MTD device to use */
cxt->mtd_index = -1;
mtd_index = simple_strtoul(mtddev, &endp, 0); if (*endp == '\0')
cxt->mtd_index = mtd_index;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.