static void mtdoops_console_sync(void) { struct mtdoops_context *cxt = &oops_cxt; struct mtd_info *mtd = cxt->mtd; unsigned long flags; if (!cxt->ready || !mtd || cxt->writecount == 0) return; spin_lock_irqsave(&cxt->writecount_lock, flags); if (!cxt->ready) { spin_unlock_irqrestore(&cxt->writecount_lock, flags); return; } cxt->ready = 0; spin_unlock_irqrestore(&cxt->writecount_lock, flags); if (mtd->panic_write && in_interrupt()) mtdoops_write(cxt, 1); else schedule_work(&cxt->work_write); }
static void mtdoops_do_dump(struct kmsg_dumper *dumper, enum kmsg_dump_reason reason, const char *s1, unsigned long l1, const char *s2, unsigned long l2) { struct mtdoops_context *cxt = container_of(dumper, struct mtdoops_context, dump); unsigned long s1_start, s2_start; unsigned long l1_cpy, l2_cpy; char *dst; /* Only dump oopses if dump_oops is set */ if (reason == KMSG_DUMP_OOPS && !dump_oops) return; dst = cxt->oops_buf + MTDOOPS_HEADER_SIZE; /* Skip the header */ l2_cpy = min(l2, record_size - MTDOOPS_HEADER_SIZE); l1_cpy = min(l1, record_size - MTDOOPS_HEADER_SIZE - l2_cpy); s2_start = l2 - l2_cpy; s1_start = l1 - l1_cpy; memcpy(dst, s1 + s1_start, l1_cpy); memcpy(dst + l1_cpy, s2 + s2_start, l2_cpy); /* Panics must be written immediately */ if (reason != KMSG_DUMP_OOPS) { if (!cxt->mtd->panic_write) printk(KERN_ERR "mtdoops: Cannot write from panic without panic_write\n"); else mtdoops_write(cxt, 1); return; } /* For other cases, schedule work to write it "nicely" */ schedule_work(&cxt->work_write); }