void from_hifi_mailbox_readcb(void *usr_handle, void *mail_handle, unsigned int mail_len)/*lint !e438 */ { unsigned long ret = 0; unsigned int msg_len = (unsigned int)sizeof(HIFI_AP_CCPU_RESET_CNF_STRU); HIFI_AP_CCPU_RESET_CNF_STRU msg_hifi = {0}; ret = DRV_MAILBOX_READMAILDATA(mail_handle, (unsigned char *)(&msg_hifi), &msg_len); reset_print_debug("ret=%lu, uhwMsgId=%d, uhwResult=%d\n", ret, msg_hifi.uhwMsgId, msg_hifi.uhwResult); if (ID_HIFI_AP_CCPU_RESET_CNF == msg_hifi.uhwMsgId && 0 == msg_hifi.uhwResult) { up(&(g_modem_reset_ctrl.wait_hifi_reply_sem)); } else { up(&(g_modem_reset_ctrl.wait_hifi_reply_sem)); reset_print_err("unkown msg from hifi\n"); reset_reboot_system(RESET_TYPE_RECV_HIFI_MSG_FAIL); } }
/***************************************************************************** 函 数 名 : hifi_misc_handle_mail 功能描述 : Hifi MISC 设备双核通信接收中断处理函数 约定收到HIIF邮箱消息的首4个字节是MSGID 输入参数 : void *usr_para : 注册时传递的参数 void *mail_handle : 邮箱数据参数 unsigned int mail_len : 邮箱数据长度 输出参数 : 无 返 回 值 : void 调用函数 : 被调函数 : 修改历史 : 1.日 期 : 2012年8月1日 作 者 : 夏青 00195127 修改内容 : 新生成函数 *****************************************************************************/ static void hifi_misc_handle_mail(void *usr_para, void *mail_handle, unsigned int mail_len) { unsigned int ret_mail = 0; struct recv_request *recv = NULL; HIFI_CHN_CMD *cmd_para = NULL; IN_FUNCTION; if (NULL == mail_handle) { loge("mail_handle is NULL.\n"); goto END; } if (mail_len <= SIZE_CMD_ID) { loge("mail_len is less than SIZE_CMD_ID(%d).\n", mail_len); goto END; } recv = (struct recv_request *)kmalloc(sizeof(struct recv_request), GFP_ATOMIC); if (NULL == recv) { loge("recv kmalloc failed.\n"); goto ERR; } memset(recv, 0, sizeof(struct recv_request)); /* 设定SIZE */ recv->rev_msg.mail_buff_len = mail_len; /* 分配总的空间 */ recv->rev_msg.mail_buff = (unsigned char *)kmalloc(SIZE_LIMIT_PARAM, GFP_ATOMIC); if (NULL == recv->rev_msg.mail_buff) { loge("recv->rev_msg.mail_buff kmalloc failed.\n"); goto ERR; } memset(recv->rev_msg.mail_buff, 0, SIZE_LIMIT_PARAM); /* 将剩余内容copy透传到buff中 */ #ifdef PLATFORM_HI3XXX ret_mail = mailbox_read_msg_data(mail_handle, (char*)(recv->rev_msg.mail_buff), (unsigned int *)(&(recv->rev_msg.mail_buff_len))); #endif #ifdef PLATFORM_HI6XXX ret_mail = DRV_MAILBOX_READMAILDATA(mail_handle, (char*)recv->rev_msg.mail_buff, (unsigned int *)&recv->rev_msg.mail_buff_len); #endif if ((ret_mail != MAILBOX_OK) || (recv->rev_msg.mail_buff_len <= 0)) { loge("Empty point or data length error! ret=0x%x, mail_size: %d.\n", (unsigned int)ret_mail, recv->rev_msg.mail_buff_len); goto ERR; } logd("ret_mail=%d, mail_buff_len=%d, msgID=0x%x.\n", ret_mail, recv->rev_msg.mail_buff_len, *((unsigned int *)(recv->rev_msg.mail_buff + mail_len - SIZE_CMD_ID))); if (recv->rev_msg.mail_buff_len > mail_len) { loge("ReadMailData mail_size(%d) > mail_len(%d).\n", recv->rev_msg.mail_buff_len, mail_len); goto ERR; } /* 约定,前4个字节是cmd_id */ cmd_para = (HIFI_CHN_CMD *)(recv->rev_msg.mail_buff + mail_len - SIZE_CMD_ID); /* 赋予不同的接收指针,由接收者释放分配空间 */ if (HIFI_CHN_SYNC_CMD == cmd_para->cmd_type) { if (s_misc_data.sn == cmd_para->sn) { #ifdef PLATFORM_HI6XXX wake_lock_timeout(&s_misc_data.hifi_misc_wakelock, HZ / 2); #endif spin_lock_bh(&s_misc_data.recv_sync_lock); list_add_tail(&recv->recv_node, &recv_sync_work_queue_head); spin_unlock_bh(&s_misc_data.recv_sync_lock); complete(&s_misc_data.completion); } else { loge("s_misc_data.sn !== cmd_para->sn: %d, %d.\n", s_misc_data.sn, cmd_para->sn); } goto END; } else if ((HIFI_CHN_READNOTICE_CMD == cmd_para->cmd_type) && (ACPU_TO_HIFI_ASYNC_CMD == cmd_para->sn)) { #ifdef PLATFORM_HI3XXX if (HIFI_CHN_READNOTICE_CMD == cmd_para->cmd_type) { wake_lock_timeout(&s_misc_data.hifi_misc_wakelock, 5*HZ); } #endif #ifdef PLATFORM_HI6XXX wake_lock_timeout(&s_misc_data.hifi_misc_wakelock, HZ); #endif spin_lock_bh(&s_misc_data.recv_proc_lock); list_add_tail(&recv->recv_node, &recv_proc_work_queue_head); s_misc_data.wait_flag++; spin_unlock_bh(&s_misc_data.recv_proc_lock); wake_up(&s_misc_data.proc_waitq); goto END; } else { loge("unknown msg comed from hifi .\n"); } ERR: if (recv) { if (recv->rev_msg.mail_buff) { kfree(recv->rev_msg.mail_buff); } kfree(recv); } END: OUT_FUNCTION; return; }