void _queue_loop_in(struct queue *q, void *element, unsigned int len)
{
    unsigned int copy = min((q->max - q->head), len);
    unsigned int omit = len;
    unsigned int left = 0;

    /*left room*/
    left = q->max - (MOD_SUB(q->head, q->tail, q->max));
    if (left > (len + 1)){
        omit = 0;
    }

    /*update tail index*/
    q->tail = MOD_ADD(q->tail, omit, q->max);

    /*copy data*/
    hisi_io_memcpy(&(q->data[q->head]), element, copy);
    if (len > copy){
        hisi_io_memcpy(&(q->data[0]), element + copy, len - copy);
    }
    q->head = MOD_ADD(q->head, len, q->max);
    q->in += len;

    return;
}
int _queue_leftroom(struct queue *q)
{
    unsigned int left = 0;

    /*left room*/
    left = (q->max - (MOD_SUB(q->head, q->tail, q->max))) - 1;

    return left;
}
int _queue_in(struct queue *q, void *element, unsigned int len)
{
    unsigned int copy = min((q->max - q->head), len);
    unsigned int left = 0;

    /*left room*/
    left = q->max - (MOD_SUB(q->head, q->tail, q->max));
    if ((len + 1) > left){
        return -1;
    }

    hisi_io_memcpy(&(q->data[q->head]), element, copy);
    if (len > copy){
        hisi_io_memcpy(&(q->data[0]), element + copy, len - copy);
    }

    q->head = MOD_ADD(q->head, len, q->max);

    return 0;
}
int _queue_out(struct queue *q, void *element, unsigned int len)
{
    unsigned int valid;
    unsigned int copy;

    valid = MOD_SUB(q->head, q->tail, q->max);
    if (len > valid){
        return -1;
    }

    copy = min((q->max - q->tail), len);
    hisi_io_memcpy(element, &q->data[q->tail], copy);
    if (len > copy){
        hisi_io_memcpy(element + copy, &q->data[0], len - copy);
    }

    q->tail = MOD_ADD(q->tail, len, q->max);
    q->out += len;

    return 0;
}
static int __init dump_info_init(void)
{
	void * __iomem mem = NULL;
	struct dump_log *dump = NULL;
	struct queue *task_queue[NR_CPUS] = {0};
	struct queue *irq_queue[NR_CPUS] = {0};
	unsigned int i = 0;
	int irq_flag = 0, task_flag = 0;
	unsigned int saved_length = 0;
	u32 count = num_online_cpus();

	printk("%s ANDROID_DUMP_LOG_ADDR = %#x\n", __func__, ANDROID_DUMP_LOG_ADDR);
	mem = (void *)ioremap(ANDROID_DUMP_LOG_ADDR, ANDROID_DUMP_LOG_SIZE);
	if (NULL == mem) {
		printk(KERN_ERR "%s : failed to ioremap memory\n", __func__);
		return 0;
	}

	dump = (struct dump_log *)mem;

	for (i=0; i<count; i++) {
		irq_queue[i] = (struct queue*)(dump->irq_trace + g_irq_record_offset[i]);
		if (strncmp(irq_queue[i]->name, g_irq_trace_name[i], strlen(g_irq_trace_name[i]))) {
			printk(KERN_ERR "%s : irq trace cpu[%d] section header incorrect\n", __func__, i);
			printk(KERN_ERR "irq g:%s\n", g_irq_trace_name[i]);
			goto unmap;
		}
		/* 判断max值,防止队列头长度变换*/
		if (irq_queue[i]->max != (g_irq_record_len[i] - sizeof(struct queue))) {
			printk(KERN_ERR "%s : irq trace cpu[%d] section header, max length incorrect\n", __func__, i);
			goto unmap;
		}
		/* 判断head/tail值是否异常 */
		saved_length = MOD_SUB(irq_queue[i]->head, irq_queue[i]->tail, irq_queue[i]->max);
		if (saved_length%sizeof(struct irq_info) != 0) {
			printk(KERN_ERR "%s : irq trace cpu[%d] section header, head/tail incorrect\n", __func__, i);
			goto unmap;
		}
		if (irq_queue[i]->head != irq_queue[i]->tail) {
			irq_flag++;
		}

		task_queue[i] = (struct queue*)(dump->task_trace + g_task_record_offset[i]);
		if (strncmp(task_queue[i]->name, g_task_trace_name[i], strlen(g_task_trace_name[i]))) {
			printk(KERN_ERR "%s : task trace cpu[%d] section header incorrect\n", __func__, i);
			printk(KERN_ERR "task g:%s\n", g_task_trace_name[i]);
			goto unmap;
		}
		/* 判断max值,防止队列头长度变换*/
		if (task_queue[i]->max !=  (g_task_record_len[i] - sizeof(struct queue))) {
			printk(KERN_ERR "%s : task trace cpu[%d] section header, max length incorrect\n", __func__, i);
			goto unmap;
		}
		/* 判断head/tail值是否异常 */
		saved_length = MOD_SUB(task_queue[i]->head, task_queue[i]->tail, task_queue[i]->max);
		if (saved_length%sizeof(struct task_info) != 0) {
			printk(KERN_ERR "%s : task trace cpu[%d] section header, head/tail incorrect\n", __func__, i);
			goto unmap;
		}
		if (task_queue[i]->head != task_queue[i]->tail) {
			task_flag++;
		}
	}

	if (irq_flag) {
		last_kirq = (char *)vmalloc(EXCH_INT_SWITCH_SIZE);
		if (last_kirq) {
			hisi_io_memcpy(last_kirq, &dump->irq_trace[0], EXCH_INT_SWITCH_SIZE);
		}
	}

	if (task_flag) {
		last_ktask = (char *)vmalloc(EXCH_TASK_SWITCH_SIZE);
		if (last_ktask) {
			hisi_io_memcpy(last_ktask, &dump->task_trace[0], EXCH_TASK_SWITCH_SIZE);
		}
	}

unmap:
	iounmap(mem);
	return 0;
}