Example #1
0
static void ipanic_oops_done(struct aee_oops *oops, int erase)
{
	if (oops)
		aee_oops_free(oops);
	if (erase)
		ipanic_erase();
}
/*erase is no longer used. erase from user space*/
static void mtd_ipanic_oops_free(struct aee_oops *oops, int erase)
{
	if (oops) {
		struct mtd_ipanic_data *ctx = &mtd_drv_ctx;

		aee_oops_free(oops);
	
       /*After this, open ke device returns null*/
       memset(&ctx->curr, 0, sizeof(struct ipanic_header));
		
	}
}
static void ke_destroy_log(void)
{
	xlog_printk(ANDROID_LOG_DEBUG, AEK_LOG_TAG, "%s\n", __func__);
	msg_destroy(&aed_dev.kerec.msg);

	if(aed_dev.kerec.lastlog)
	{
		if (strncmp(aed_dev.kerec.lastlog->module, IPANIC_MODULE_TAG, strlen(IPANIC_MODULE_TAG)) == 0) {
			ipanic_oops_free(aed_dev.kerec.lastlog, 0);
		}
		else {
			aee_oops_free(aed_dev.kerec.lastlog);
		}

		aed_dev.kerec.lastlog = NULL;
	}
}
static void ke_gen_ind_msg(struct aee_oops *oops)
{
    unsigned long flags = 0;

    xlog_printk(ANDROID_LOG_DEBUG, AEK_LOG_TAG, "%s oops %p\n", __func__, oops);
    if (oops == NULL) {
        return;
    }	
    
    spin_lock_irqsave(&aed_device_lock, flags); 
    if (aed_dev.kerec.lastlog == NULL) {
        aed_dev.kerec.lastlog = oops;
    }
    else {
        /*
         *  waaa..   Two ke api at the same time 
         *  or ke api during aed process is still busy at ke
         *  discard the new oops!
         */

        xlog_printk(ANDROID_LOG_WARN, AEK_LOG_TAG, "%s: More than on kernel message queued\n", __func__);
        aee_oops_free(oops);
        spin_unlock_irqrestore(&aed_device_lock, flags);

        return;
    }
    spin_unlock_irqrestore(&aed_device_lock, flags);

    if (aed_dev.kerec.lastlog != NULL) {
        AE_Msg *rep_msg;
        rep_msg = msg_create(&aed_dev.kerec.msg, 0);
        if(rep_msg == NULL)
            return;	

        rep_msg->cmdType = AE_IND;
        switch (oops->attr) {
            case AE_DEFECT_REMINDING:
                rep_msg->cmdId = AE_IND_REM_RAISED;
                break;
            case AE_DEFECT_WARNING:
                rep_msg->cmdId = AE_IND_WRN_RAISED;
                break;
            case AE_DEFECT_EXCEPTION:
                rep_msg->cmdId = AE_IND_EXP_RAISED;
                break;
            case AE_DEFECT_FATAL:
                rep_msg->cmdId = AE_IND_FATAL_RAISED;
                break;
            default:
                /* Huh... something wrong, just go to exception */
                rep_msg->cmdId = AE_IND_EXP_RAISED;
                break;
        }

        rep_msg->arg = oops->clazz;
        rep_msg->len = 0;
        rep_msg->dbOption = oops->dump_option;

        wake_up(&aed_dev.kewait);
    }

}
static struct aee_oops *emmc_ipanic_oops_copy(void)
{
	struct aee_oops *oops = NULL;
	struct ipanic_header *hdr = NULL;
	int hdr_size = ALIGN(sizeof(struct ipanic_header), EMMC_BLOCK_SIZE);

	hdr = kzalloc(hdr_size, GFP_KERNEL);
	if (hdr == NULL) {
		xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "%s: Cannot allocate ipanic header memory\n", __FUNCTION__);
		return NULL;
	}

	if (card_dump_func_read((unsigned char *)hdr, hdr_size, 0, EMMC_ID) < 0) {
		xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "%s: emmc panic log header read failed\n", __func__);
		return NULL;
	}
	ipanic_block_scramble((unsigned char *)hdr, hdr_size);
	if (ipanic_header_check(hdr) != 0) {
		return NULL;
	}

	oops = aee_oops_create(AE_DEFECT_FATAL, AE_KE, IPANIC_MODULE_TAG);
	if (oops != NULL) {
		struct ipanic_oops_header *oops_header = (struct ipanic_oops_header *)
                emmc_allocate_and_read(hdr->oops_header_offset, hdr->oops_header_length);
		if (oops_header == NULL) { 
			xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "%s: Can't read oops header(len:%d)\n", __FUNCTION__, hdr->oops_header_length);
			goto error_return;
		}
		aee_oops_set_process_path(oops, oops_header->process_path);
		aee_oops_set_backtrace(oops, oops_header->backtrace);
		kfree(oops_header);

        if(hdr->oops_detail_length != 0)
        {
            oops->detail = emmc_allocate_and_read(hdr->oops_detail_offset, hdr->oops_detail_length);
            oops->detail_len = hdr->oops_detail_length;

        }else {
            #define TMPDETAILSTR  "panic detail is empty"
            oops->detail = kstrdup(TMPDETAILSTR, GFP_KERNEL);
            oops->detail_len = sizeof TMPDETAILSTR;
        }
		if (oops->detail == NULL) {
			xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "%s: read detail failed(len: %d)\n", __FUNCTION__, oops->detail_len);
			goto error_return;
		}

		oops->console = emmc_allocate_and_read(hdr->console_offset, hdr->console_length);
		oops->console_len = hdr->console_length;
		if (oops->console == NULL) {
			xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "%s: read console failed(len: %d)\n", __FUNCTION__, oops->console_len);
			goto error_return;
		}

        /*If panic from kernel context, no user sapce info available. Shouldn't fail*/
        if (0 == hdr->userspace_info_length)
        {
            oops->userspace_info = NULL;
            oops->userspace_info_len = 0;
        }
        else
        {
            oops->userspace_info = emmc_allocate_and_read(hdr->userspace_info_offset, hdr->userspace_info_length);
            oops->userspace_info_len = hdr->userspace_info_length;
            if (oops->userspace_info == NULL) {
                xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "%s: read usrespace info failed\n", __FUNCTION__);
                goto error_return;
            }
        }
	

		oops->android_main = emmc_allocate_and_read(hdr->android_main_offset, hdr->android_main_length);
		oops->android_main_len  = hdr->android_main_length;
		if (oops->android_main == NULL)	{
			xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "%s: read android_main failed\n", __FUNCTION__);
			goto error_return;
		}
		
		oops->android_radio  = emmc_allocate_and_read(hdr->android_radio_offset, hdr->android_radio_length);
		oops->android_radio_len = hdr->android_radio_length;
		if (oops->android_radio == NULL) {
			xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "%s: read android_radio failed\n", __FUNCTION__);
			goto error_return;
		}		    
		
		oops->android_system = emmc_allocate_and_read(hdr->android_system_offset, hdr->android_system_length);
		oops->android_system_len = hdr->android_system_length;
		if (oops->android_system == NULL) {
			xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "%s: read android_system failed\n", __FUNCTION__);
			goto error_return;
		}		    
		
		xlog_printk(ANDROID_LOG_DEBUG, IPANIC_LOG_TAG, "ipanic_oops_copy return OK\n");
		kfree(hdr);
		return oops;
	}
	else {
		xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "%s: kmalloc failed at header\n", __FUNCTION__);
		kfree(hdr);
		return NULL;
	}
error_return:
	kfree(hdr);
	aee_oops_free(oops);
	return NULL;
}
static struct aee_oops *mtd_ipanic_oops_copy(void)
{
	struct mtd_ipanic_data *ctx = &mtd_drv_ctx;
	struct aee_oops *oops;

	if ((ctx->curr.magic != AEE_IPANIC_MAGIC) || (ctx->curr.version != AEE_IPANIC_PHDR_VERSION)) {
		return NULL;
	}

	oops = aee_oops_create(AE_DEFECT_FATAL, AE_KE, IPANIC_MODULE_TAG);
	if (oops != NULL) {
		struct ipanic_oops_header *oops_header = kzalloc(sizeof(struct ipanic_oops_header), GFP_KERNEL);
		if (oops_header == NULL)
			goto error_return;

		if (mtd_ipanic_block_read(ctx, ctx->curr.oops_header_offset, ctx->curr.oops_header_length, oops_header) != 0) {
			xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "%s: mtd read header failed\n", __FUNCTION__);
			kfree(oops_header);
			goto error_return;
		}

		aee_oops_set_process_path(oops, oops_header->process_path);
		aee_oops_set_backtrace(oops, oops_header->backtrace);
		kfree(oops_header);
        if(ctx->curr.oops_detail_length != 0)
        {
            oops->detail = kmalloc(ctx->curr.oops_detail_length, GFP_KERNEL);
            oops->detail_len = ctx->curr.oops_detail_length;
            if (oops->detail != NULL) {
                if (mtd_ipanic_block_read(ctx, ctx->curr.oops_detail_offset, ctx->curr.oops_detail_length, oops->detail) != 0) {
                    xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "%s: mtd read detail failed\n", __FUNCTION__);
                    kfree(oops->detail);
                    goto error_return;
                }
            }
        }else {
           #define TMPDETAILSTR  "panic detail is empty"
            oops->detail = kstrdup(TMPDETAILSTR,GFP_KERNEL);
            oops->detail_len = sizeof TMPDETAILSTR; 
        }

        if(oops->detail == NULL)
        {
            xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "%s: kmalloc failed at detail\n", __FUNCTION__);
            kfree(oops);
            return NULL;
        }

		oops->console = kmalloc(ctx->curr.console_length, GFP_KERNEL);
		oops->console_len = ctx->curr.console_length;
		if (oops->console != NULL) {
			if (mtd_ipanic_block_read(ctx, ctx->curr.console_offset, ctx->curr.console_length, oops->console) != 0) {
				xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "%s: mtd read console failed\n", __FUNCTION__);
				kfree(oops->detail);
				goto error_return;
			}
		}
		else {
			xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "%s: kmalloc failed at detail\n", __FUNCTION__);
			kfree(oops);
			return NULL;
		}
		
		/* Android log */
		oops->android_main = kmalloc(ctx->curr.android_main_length, GFP_KERNEL);
		oops->android_main_len = ctx->curr.android_main_length;
		if (oops->android_main)	{
			if (mtd_ipanic_block_read(ctx, ctx->curr.android_main_offset, ctx->curr.android_main_length, oops->android_main) != 0) {
				xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "%s: mtd read android_main failed\n", __FUNCTION__);
				kfree(oops->detail);
				kfree(oops->console);
				goto error_return;
			}
		}
		else {
			xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "%s: kmalloc failed at android_main\n", __FUNCTION__);
			aee_oops_free(oops);
			return NULL;
		}

		oops->android_radio = kmalloc(ctx->curr.android_radio_length, GFP_KERNEL);
		oops->android_radio_len = ctx->curr.android_radio_length;
		if (oops->android_radio) {
			if (mtd_ipanic_block_read(ctx, ctx->curr.android_radio_offset, ctx->curr.android_radio_length, oops->android_radio) != 0) {
				xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "%s: mtd read android_radio failed\n", __FUNCTION__);
				kfree(oops->detail);
				kfree(oops->console);
				kfree(oops->android_main);
				goto error_return;
			}		    
		}
		else {
			xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "%s: kmalloc failed at android_radio\n", __FUNCTION__);
			aee_oops_free(oops);
			return NULL;
		}
		
		oops->android_system = kmalloc(ctx->curr.android_system_length, GFP_KERNEL);
		oops->android_system_len = ctx->curr.android_system_length;
		if (oops->android_system) {
			if (mtd_ipanic_block_read(ctx, ctx->curr.android_system_offset, ctx->curr.android_system_length, oops->android_system) != 0) {
				xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "%s: mtd read android_system failed\n", __FUNCTION__);
				kfree(oops->detail);
				kfree(oops->console);
				kfree(oops->android_main);
				kfree(oops->android_radio);
				goto error_return;
			}		    
		}
		else {
			xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "%s: kmalloc failed at android_system\n", __FUNCTION__);
			aee_oops_free(oops);
			return NULL;
		}

#if 0		
		xlog_printk(ANDROID_LOG_INFO, IPANIC_LOG_TAG, "android log length, 0x%x, 0x%x, 0x%x, 0x%x\n",
			    oops->android_main_len,oops->android_event_len,oops->android_radio_len,oops->android_system_len);
#endif
		/* Process dump */
		oops->userspace_info = kmalloc(ctx->curr.userspace_info_length, GFP_KERNEL);
		oops->userspace_info_len = ctx->curr.userspace_info_length;
		if (oops->userspace_info) {
			if (mtd_ipanic_block_read(ctx, ctx->curr.userspace_info_offset, ctx->curr.userspace_info_length, oops->userspace_info) != 0) {
				xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "%s: mtd read usrespace info failed\n", __FUNCTION__);
				kfree(oops->detail);
				kfree(oops->console);
				kfree(oops->android_main);
				kfree(oops->android_radio);
				kfree(oops->userspace_info);
				goto error_return;
			}		    
		}
		else {
			xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "%s: kmalloc failed at userspace info failed\n", __FUNCTION__);
			aee_oops_free(oops);
			return NULL;
		}
		
		xlog_printk(ANDROID_LOG_DEBUG, IPANIC_LOG_TAG, "ipanic_oops_copy return OK\n");
		return oops;
	}
	else {
		xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "%s: kmalloc failed at header\n", __FUNCTION__);
		return NULL;
	}
error_return:
	kfree(oops);
	memset(&ctx->curr, 0, sizeof(struct ipanic_header));
	mtd_ipanic_block_erase();
	return NULL;
}