static void lge_dump_kernel_log() { extern int log_buf_copy(char *dest, int idx, int len); char log_buf[1024]; int idx = 0; int cnt; int h_file = 0; mm_segment_t oldfs = get_fs(); set_fs(KERNEL_DS); h_file = sys_open("/data/panic.txt", O_RDWR|O_CREAT,0644); if(h_file >= 0) { for (;;) { cnt = log_buf_copy(log_buf, idx, 1023); if (cnt <= 0) break; // WBT 20110314 [START] log_buf[cnt] = 0; // WBT 20110314 [END] sys_write(h_file,log_buf,cnt); idx += cnt; } sys_close(h_file); } else { printk("Can't open log file ret = %d.\n",h_file); } sys_sync(); set_fs(oldfs); }
/* * Extract a single character from the log buffer. */ int log_buf_read(int idx) { char ret; if (log_buf_copy(&ret, idx, 1) == 1) return ret; else return -1; }
void emergency_msg_outlog(void *handle) { struct emergency_msg *emsg = (struct emergency_msg *)handle; unsigned long flags; int len,idx,i; spin_lock_irqsave(&emsg->lock,flags); idx = 0; while(1) { len = log_buf_copy(emsg->msg,idx,emsg->len); if(len <= 0) break; for(i = 0;i < len;i++) { if(emsg->msg[i] == '\n') putchar('\r'); putchar(emsg->msg[i]); } idx += len; } spin_unlock_irqrestore(&emsg->lock,flags); }
/* * Writes the contents of the console to the specified offset in mmc. * Returns number of bytes written */ static int apanic_write_console_mmc(unsigned int off) { struct apanic_data *ctx = &drv_ctx; int saved_oip; int idx = 0; int rc, rc2; unsigned int last_chunk = 0; if (!ctx->hd || !ctx->mmc_panic_ops) return -EBUSY; while (!last_chunk) { saved_oip = oops_in_progress; oops_in_progress = 1; rc = log_buf_copy(ctx->bounce, idx, PAGE_SIZE); if (rc < 0) break; if (rc != PAGE_SIZE) last_chunk = rc; oops_in_progress = saved_oip; if (rc <= 0) break; if (rc != PAGE_SIZE) memset(ctx->bounce + rc, 0, PAGE_SIZE - rc); rc2 = ctx->mmc_panic_ops->panic_write(ctx->hd, ctx->bounce, off, rc); if (rc2 <= 0) { pr_emerg("apanic: Flash write failed (%d)\n", rc2); return idx; } if (!last_chunk) idx += rc2; else idx += last_chunk; off += rc2; } return idx; }
static void dump_kernel_log(void) { char buf[1024]; int idx = 0; int ret; int saved_oip; saved_oip = oops_in_progress; oops_in_progress = 1; for (;;) { ret = log_buf_copy(buf, idx, 1023); if (ret <= 0) break; buf[ret] = 0; debug_puts(buf); idx += ret; } oops_in_progress = saved_oip; }
static void dump_kernel_log(void) { char buf[1024]; int idx = 0; int ret; int saved_oip; /* setting oops_in_progress prevents log_buf_copy() * from trying to take a spinlock which will make it * very unhappy in some cases... */ saved_oip = oops_in_progress; oops_in_progress = 1; for (;;) { ret = log_buf_copy(buf, idx, 1023); if (ret <= 0) break; buf[ret] = 0; debug_puts(buf); idx += ret; } oops_in_progress = saved_oip; }
exit1: return -ENOMEM; } int log_buf_copy(char *dest, int idx, int len); static int dump_kernel_logs(struct notifier_block *this, unsigned long event, void *ptr) { struct last_logs *buffer; int size; int log_length = (1 << CONFIG_LOG_BUF_SHIFT); buffer = (struct last_logs *)kmsg_base; size = log_buf_copy(buffer->data, 0, log_length); if (size < 0) goto exit; buffer->sig = KMSGLOG_SIG; buffer->size = size; exit: return NOTIFY_DONE; } static struct notifier_block lastlogs_panic_block = { .notifier_call = dump_kernel_logs, }; static int lastlogs_driver_probe(struct platform_device *pdev)
/* * Writes the contents of the console to the specified offset in flash. * Returns number of bytes written */ static int apanic_write_console_mmc(unsigned long off) { struct apanic_data *ctx = &drv_ctx; int saved_oip; int idx = 0; int rc, rc2; unsigned int last_chunk = 0; unsigned long num = 0; unsigned long start; start = off; while (!last_chunk) { saved_oip = oops_in_progress; oops_in_progress = 1; /* * bounce buffer is reserved during init time. * Now copy 'writable' amount of data from __log_buf * to the bounce buffer */ rc = log_buf_copy(ctx->bounce, idx, ctx->mmc->write_bl_len); if (rc < 0) break; if (rc != ctx->mmc->write_bl_len) last_chunk = rc; oops_in_progress = saved_oip; if (rc <= 0) break; if (rc != ctx->mmc->write_bl_len) memset(ctx->bounce + rc, 0, ctx->mmc->write_bl_len - rc); /* Write the bounce buffer to eMMC */ rc2 = ctx->mmc->block_dev.block_write(ctx->mmc_poll_dev_num, off, 1, ctx->bounce); if (rc2 <= 0) { printk(KERN_EMERG "apanic: MMC write failed (%d)\n", rc2); return idx; } ++num; /* idx is a byte offset used to copy from log buf */ if (!last_chunk) idx += (rc2 * ctx->mmc->write_bl_len); else idx += last_chunk; /* * off is in terms of block count to tell the mmc driver where * to start the next write from, while idx is in terms of * bytes to tell the lob_buf_copy where to start the read * from. Note that the block_write function of mmc also * returns the number of blocks written. */ off += rc2; } pr_debug("%s: wrote %ld pages from %ld returned %ld\r\n", __func__, num, start, off); return num; }