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; }