static int mtd_ipanic_block_read(struct mtd_ipanic_data *ctx, off_t file_offset, int file_length, void *buf)
{
#if 0
	xlog_printk(ANDROID_LOG_INFO, IPANIC_LOG_TAG, "%s: ctx:%p file_offset:%d file_length:%lu\n", __func__, ctx, file_offset, file_length);
#endif
	while (file_length > 0) {
		unsigned int page_no;
		off_t page_offset;
		int rc;
		size_t count = file_length;

		/* We only support reading a maximum of a flash page */
		if (count > ctx->mtd->writesize)
			count = ctx->mtd->writesize;
		page_no = file_offset / ctx->mtd->writesize;
		page_offset = file_offset % ctx->mtd->writesize;

		rc = mtd_ipanic_block_read_single(ctx, page_no * ctx->mtd->writesize);
		if (rc < 0) {
			xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "aee-ipanic(%s): mtd read error page_no(%d) error(%d)\n", __func__, page_no, rc);
			goto error_return;
		}
		if (page_offset)
			count -= page_offset;
		memcpy(buf, ctx->bounce + page_offset, count);

		file_length -= count;
		buf += count;
		file_offset += count;
	}
	return 0;
error_return:
	return -1;
}
static void mtd_panic_notify_add(struct mtd_info *mtd)
{
	struct mtd_ipanic_data *ctx = &mtd_drv_ctx;
	struct ipanic_header *hdr;
	int rc;

	if (strcmp(mtd->name, AEE_IPANIC_PLABEL))
		return;

	ctx->mtd = mtd;

	ctx->bounce = kzalloc(ctx->mtd->writesize, GFP_KERNEL);
	if (ctx->bounce == NULL)
	  xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "%s: mtd buffer kzalloc failed, %d \n", __func__, ctx->mtd->writesize);
	  
        hdr = ctx->bounce;  
	if (!mtd_ipanic_block_scan(ctx))
		goto out_err;

	rc = mtd_ipanic_block_read_single(ctx, 0);
	if (rc < 0) {
		xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "aee-ipanic: Error reading block 0 (%d)\n", rc);
		mtd_ipanic_block_erase();
		goto out_err;
	}

	xlog_printk(ANDROID_LOG_INFO, IPANIC_LOG_TAG, "aee-ipanic: Bound to mtd partition '%s', write size(%d), write size shift(%d)\n", mtd->name, mtd->writesize, mtd->writesize_shift);
	switch (ipanic_header_check(hdr)) {
	case 0:
		break;
	case 1:
		return;
	case 2:
		mtd_ipanic_block_erase();
		return;
	}

	memcpy(&ctx->curr, hdr, sizeof(struct ipanic_header));
	ipanic_header_dump(hdr);

	ctx->oops = create_proc_read_entry("aee_ipanic_oops", 
					   0444, NULL, 
					   mtd_ipanic_proc_oops,
					   NULL);
	if (ctx->oops == NULL) {
		xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, " %s: failed to create proc file apanic_oops\n", __func__);
	}

	/*it will free the ctx->curr assigne during bootup. then 
     open the ke device will return NULL. so lose db
    */
    //mtd_ipanic_oops_dump();
	
    return;

out_err:
	ctx->mtd = NULL;
}