/*
 * @brief Callback function which is registerd to DF layer
 * @param
 *     msg_id    [in] Exception ID
 * @return
 *     None
 */
void ccci_df_to_ccci_exception_callback(KAL_UINT32 msg_id)
{
    DEBUG_LOG_FUNCTION_ENTRY;
    DBGLOG(EXPT, TRA, "CCCI Exception Callback (%d)", msg_id);
    switch (msg_id) {
        case EX_INIT:
        {
            //reset exception statistics
            eemcs_expt_reset_statistics();
            
            //set eemcs state to EEMCS_EXCEPTION
            change_device_state(EEMCS_EXCEPTION);

            //set a 5s timer to check if exception flow complete
            mod_timer(&g_except_inst.md_ex_monitor, jiffies+EE_INIT_TIMER);

            //update eemcs_exception state : EEMCS_EX_NONE -> EEMCS_EX_INIT or EEMCS_EX_INIT_DONE-> EEMCS_EX_INIT
            set_exception_mode(EEMCS_EX_INIT);

            //indicate state change to upper layer
            eemcs_exec_expt_callback(EEMCS_EX_INIT);

            //Send message to mdinit
            eemcs_cdev_msg(CCCI_PORT_CTRL, CCCI_MD_MSG_EXCEPTION, 0);

            //snapeshot traffic
            eemcs_ccci_expt_log_df_q_pkts();

            break;
        }
        case EX_DHL_DL_RDY:
            //1. update eemcs_exception state : EEMCS_EX_INIT -> EEMCS_EX_DHL_DL_RDY
            set_exception_mode(EEMCS_EX_DHL_DL_RDY);

            //2. indicate state change to upper layer
            eemcs_exec_expt_callback(EEMCS_EX_DHL_DL_RDY);
            break;
        case EX_INIT_DONE:
            //1. update eemcs_exception state : EEMCS_EX_DHL_DL_RDY -> EEMCS_EX_INIT_DONE
            set_exception_mode(EEMCS_EX_INIT_DONE);

            //2. set up timer for waiting MD_EX msg
            mod_timer(&g_except_inst.md_ex_monitor, jiffies+EE_HS1_TIMER);

            //3. flush all pkts in exception list
            eemcs_expt_flush();
            
            //4. indicate state change to upper layer
            eemcs_exec_expt_callback(EEMCS_EX_INIT_DONE);
            break;
        default:
            DBGLOG(EXPT, ERR, "Unknown exception callback id %d", msg_id);
    }
	
    DEBUG_LOG_FUNCTION_LEAVE;
    return;
}
Exemplo n.º 2
0
static long eemcs_cdev_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
{
    eemcs_cdev_node_t *curr_node = (eemcs_cdev_node_t *)fp->private_data;
    KAL_UINT8 port_id = curr_node->eemcs_port_id; /* port_id */
    int ret = 0;
    unsigned int sim_type;
    unsigned int enable_sim_type;

    DEBUG_LOG_FUNCTION_ENTRY;
    if(port_id > END_OF_CCCI_CDEV)
    {
        DBGLOG(CHAR, ERR, "ccci ioctl fail: unknown Port id=%d", port_id);
        ret = -ENOTTY;
        goto _exit;                    
    }

    switch(cmd)
    {
        case CCCI_IOC_GET_MD_STATE:
        {
            KAL_UINT32  eemcs_state, md_state;

            eemcs_state = check_device_state();
            if(eemcs_state == EEMCS_BOOTING_DONE ){
				md_state = MD_STATE_READY;
            }else if(eemcs_state == EEMCS_EXCEPTION){
				md_state = MD_STATE_EXPT;
            }else if(eemcs_state <= EEMCS_INIT){
				md_state = MD_STATE_INVALID;
            }else{
				 md_state = MD_STATE_INIT;
            }
            ret = put_user((unsigned int)md_state, (unsigned int __user *)arg);
            DBGLOG(CHAR, DBG, "CCCI_IOC_GET_MD_STATE(md_s=%d, eemcs_s=%d) by %s(%d)", md_state, eemcs_state, \
				ccci_cdev_name[PORT2IDX(port_id)], port_id);
            }
            break;

        case CCCI_IOC_SET_EXCEPTION_DATA:
        {
            DBGLOG(CHAR, ERR, "CCCI_IOC_SET_EXCEPTION_DATA by %s(%d)", ccci_cdev_name[PORT2IDX(port_id)], port_id);
#if 0
            extern EX_LOG_T md_ex_log;
            void __user *argp = (void __user *)arg;
            if(copy_from_user(&md_ex_log,argp,MD_EX_LOG_SIZE))
            {
                 DBGLOG(PORT,ERR,"copy_from_user failed.");
                 return -EFAULT;
            }
            md_exception(&md_ex_log);
#endif		
        }
        break;

        case CCCI_IOC_SET_HEADER:
        {
            KAL_UINT32 ori_port_flag = 0;
            KAL_UINT32 new_port_flag = 0;
            //port->control_flag |=PORT_EXPORT_CCIF_BUFFER;
            ori_port_flag = ccci_get_port_cflag(port_id);
            ccci_set_port_type(port_id, (ori_port_flag|EXPORT_CCCI_H));
            new_port_flag = ccci_get_port_cflag(port_id);
            DBGLOG(CHAR, DBG, "CCCI_IOC_SET_HEADER(%d, %d) by %s(%d)", ori_port_flag, new_port_flag,\
				ccci_cdev_name[PORT2IDX(port_id)], port_id);
        }
        break;

        case CCCI_IOC_CLR_HEADER:
        {
            //port->control_flag &=(~PORT_EXPORT_CCIF_BUFFER);
            KAL_UINT32 ori_port_flag = 0;
            KAL_UINT32 new_port_flag = 0;

            ori_port_flag = ccci_get_port_cflag(port_id);
            ccci_set_port_type(port_id, (ori_port_flag&(~EXPORT_CCCI_H)));
            new_port_flag = ccci_get_port_cflag(port_id);
            DBGLOG(CHAR, DBG, "CCCI_IOC_CLR_HEADER(%d, %d) by %s(%d)", ori_port_flag, new_port_flag, \
				ccci_cdev_name[PORT2IDX(port_id)], port_id);
            
        }
        break;

        /* This ioctl will be issued from RILD */
        case CCCI_IOC_ENTER_DEEP_FLIGHT:
        case CCCI_IOC_SEND_STOP_MD_REQUEST: 
        {
            DBGLOG(CHAR, INF, "IOTCL CCCI_IOC_ENTER_DEEP_FLIGHT by %s(%d)", ccci_cdev_name[PORT2IDX(port_id)], port_id); 
            change_device_state(EEMCS_GATE);
            eemcs_power_off_md(0, 0);
            /* mtlte_sys_sdio_remove */
            eemcs_cdev_msg(CCCI_PORT_CTRL, CCCI_MD_MSG_ENTER_FLIGHT_MODE, 0);
           
        }
        break;

        case CCCI_IOC_LEAVE_DEEP_FLIGHT:
        case CCCI_IOC_SEND_START_MD_REQUEST:
        {
            DBGLOG(CHAR, INF, "CCCI_IOC_LEAVE_DEEP_FLIGHT by %s(%d)", ccci_cdev_name[PORT2IDX(port_id)], port_id); 
            eemcs_cdev_msg(CCCI_PORT_CTRL, CCCI_MD_MSG_LEAVE_FLIGHT_MODE, 0);
        }
        break;

        case CCCI_IOC_FORCE_MD_ASSERT:
        {
            DBGLOG(CHAR, INF, "CCCI_IOC_FORCE_MD_ASSERT by %s(%d)", ccci_cdev_name[PORT2IDX(port_id)], port_id); 
            /* force md assert channel is 20090215 */
            eemcs_cdev_write_force_md_rst();
            //CCCI_INIT_MAILBOX(&buff, 0);
            //ret = ccci_write_force(CCCI_FORCE_RESET_MODEM_CHANNEL, &buff);
        }
        break;

        case CCCI_IOC_MD_RESET:
        {
            DBGLOG(CHAR, INF, "CCCI_IOC_MD_RESET by %s(%d)", ccci_cdev_name[PORT2IDX(port_id)], port_id); 
            eemcs_md_reset();
        }
        break;

        case CCCI_IOC_CHECK_STATE:
        {
            KAL_UINT32  state;
            state = check_device_state();
            DBGLOG(CHAR, INF, "CCCI_IOC_CHECK_STATE(%d) by %s(%d)", state, ccci_cdev_name[PORT2IDX(port_id)], port_id); 
            ret = put_user((unsigned int)state, (unsigned int __user *)arg);
        }
        break;
         
#ifdef IT_TESTING_PURPOSE   
        case CCCI_IOC_PURGE_SKBQ:
        {
            struct sk_buff *skb;
            while ((skb = skb_dequeue(&eemcs_cdev_inst.cdev_node[PORT2IDX(port_id)].rx_skb_list)) != NULL) {
				dev_kfree_skb(skb);	
				eemcs_ccci_release_rx_skb(port_id, 1, skb);
            }
            atomic_set(&eemcs_cdev_inst.cdev_node[PORT2IDX(port_id)].rx_pkt_cnt, 0);
            DBGLOG(CHAR, INF, "CCCI_IOC_PURGE_SKBQ by %s(%d)", ccci_cdev_name[PORT2IDX(port_id)], port_id);         
        }
        break;
#endif

        case CCCI_IOC_GET_EXT_MD_POST_FIX:
        {
            eemcs_boot_get_ext_md_post_fix((char*) arg);
            DBGLOG(CHAR, INF, "CCCI_IOC_GET_MD_POSTFIX(%s) by %s(%d)", (char*)arg, \
				ccci_cdev_name[PORT2IDX(port_id)], port_id);
        }
        break;

        case CCCI_IOC_SET_BOOT_STATE:
        {
            KAL_UINT32  state = 0;
            get_user(state, (unsigned int __user *)arg);
            state = eemcs_boot_reset_test(state);
            DBGLOG(CHAR, INF, "CCCI_IOC_SET_BOOT_STATE(%d) by %s(%d)", state, \
				ccci_cdev_name[PORT2IDX(port_id)], port_id);
        }
        break;

        case CCCI_IOC_GET_BOOT_STATE:
        {
            KAL_UINT32  state = 0;
            
            state = eemcs_boot_get_state();
            ret = put_user((unsigned int)state, (unsigned int __user *)arg);
            DBGLOG(CHAR, INF, "CCCI_IOC_GET_BOOT_STATE(%d) by %s(%d)", state, \
				ccci_cdev_name[PORT2IDX(port_id)], port_id);
        }
        break;
       
        case CCCI_IOC_GET_MD_IMG_EXIST:
        {
            unsigned int *md_img_exist_list = eemcs_get_md_img_exist_list();
            DBGLOG(CHAR, INF,"CCCI_IOC_GET_MD_IMG_EXIST by %s(%d)", ccci_cdev_name[PORT2IDX(port_id)], port_id);
            if (copy_to_user((void __user *)arg, md_img_exist_list,(unsigned int)eemcs_get_md_img_exist_list_size())) {
				DBGLOG(CHAR, ERR, "CCCI_IOC_GET_MD_IMG_EXIST: copy_to_user fail");
				ret= -EFAULT;
            }
        }
        break;
            
        case CCCI_IOC_GET_MD_TYPE:
        {
            int md_type = get_ext_modem_support(eemcs_get_md_id());
            DBGLOG(CHAR, INF, "CCCI_IOC_GET_MD_TYPE(%d) by %s(%d)", md_type, \
				ccci_cdev_name[PORT2IDX(port_id)], port_id);
            ret = put_user((unsigned int)md_type, (unsigned int __user *)arg);
        }
        break;
            
        case CCCI_IOC_RELOAD_MD_TYPE:
        {
            int md_type = 0;
    		if(copy_from_user(&md_type, (void __user *)arg, sizeof(unsigned int))) {
				DBGLOG(CHAR, ERR, "CCCI_IOC_RELOAD_MD_TYPE: copy_from_user fail!");
				ret = -EFAULT;
                break;
			} 
            
            if (md_type >= modem_lwg && md_type <= modem_ltg){
                DBGLOG(CHAR, INF, "CCCI_IOC_RELOAD_MD_TYPE(%d) by %s(%d)", md_type, \
					ccci_cdev_name[PORT2IDX(port_id)], port_id);
			    ret = set_ext_modem_support(eemcs_get_md_id(), md_type);
            }
            else{
                DBGLOG(CHAR, ERR, "CCCI_IOC_RELOAD_MD_TYPE fail: invalid md type(%d)", md_type);
                ret = -EFAULT;
            }
            eemcs_set_reload_image(true);
	    }
        break;

        case CCCI_IOC_STORE_MD_TYPE:
        {
            unsigned int md_type_saving = 0;
			//DBGLOG(CHAR, INF, "IOC_STORE_MD_TYPE ioctl by %s!",  current->comm);
			if(copy_from_user(&md_type_saving, (void __user *)arg, sizeof(unsigned int))) {
				DBGLOG(CHAR, ERR, "CCCI_IOC_STORE_MD_TYPE: copy_from_user fail!");
				ret = -EFAULT;
                break;
			}
			
			DBGLOG(CHAR, DBG, "CCCI_IOC_STORE_MD_TYPE(%d) by %s(%s,%d)", md_type_saving, current->comm,\
				ccci_cdev_name[PORT2IDX(port_id)], port_id);
			if (md_type_saving >= modem_lwg && md_type_saving <= modem_ltg){
				if (md_type_saving != get_ext_modem_support(eemcs_get_md_id())){
					DBGLOG(CHAR, INF, "CCCI_IOC_STORE_MD_TYPE(%d->%d)", md_type_saving, get_ext_modem_support(eemcs_get_md_id()));
				}
				//Notify md_init daemon to store md type in nvram
				eemcs_cdev_msg(CCCI_PORT_CTRL, CCCI_MD_MSG_STORE_NVRAM_MD_TYPE, md_type_saving);
			}
			else {
				DBGLOG(CHAR, ERR, "CCCI_IOC_STORE_MD_TYPE fail: invalid md type(%d)", md_type_saving);
                ret = -EFAULT;
			}
			
	    }
		break;
           
        case CCCI_IOC_GET_MD_EX_TYPE:
        {
            int md_expt_type = get_md_expt_type();
            DBGLOG(CHAR, INF, "CCCI_IOC_GET_MD_EX_TYPE(%d) by %s(%d)", md_expt_type, \
				ccci_cdev_name[PORT2IDX(port_id)], port_id);
			ret = put_user((unsigned int)md_expt_type, (unsigned int __user *)arg);
        }
        break;
		
        case CCCI_IOC_DL_TRAFFIC_CONTROL:
        {
            unsigned int traffic_control = 0;
            
            if(copy_from_user(&traffic_control, (void __user *)arg, sizeof(unsigned int))) {
                DBGLOG(CHAR, ERR, "CCCI_IOC_DL_TRAFFIC_CONTROL: copy_from_user fail!");
                ret = -EFAULT;
                break;
            }
			
            DBGLOG(CHAR, INF, "CCCI_IOC_DL_TRAFFIC_CONTROL(%d) by %s(%d)", traffic_control,\
				ccci_cdev_name[PORT2IDX(port_id)], port_id);
            if(traffic_control == 1)
            {
                ccci_cdev_turn_on_dl_q(port_id);
            }
            else if(traffic_control == 0)
            {
                ccci_cdev_turn_off_dl_q(port_id);
            }
            else 
            {
                DBGLOG(CHAR, ERR, "CCCI_IOC_DL_TRAFFIC_CONTROL fail: Unknown value(0x%x)", traffic_control);
                ret = -EFAULT;
            }
	    }
        break;    

		case CCCI_IOC_GET_SIM_TYPE: 		//for regional phone boot animation
		{
			get_sim_type(eemcs_get_md_id(), &sim_type);
			ret = put_user((unsigned int)sim_type, (unsigned int __user *)arg);
		}
		break;
		
		case CCCI_IOC_ENABLE_GET_SIM_TYPE:	//for regional phone boot animation
		{
			if(copy_from_user(&enable_sim_type, (void __user *)arg, sizeof(unsigned int))) {
				DBGLOG(CHAR, ERR, "CCCI_IOC_ENABLE_GET_SIM_TYPE: copy_from_user fail!\n");
				ret = -EFAULT;
			} else {
				enable_get_sim_type(eemcs_get_md_id(), enable_sim_type);
			}
		}
		break;          

        default:
            DBGLOG(CHAR, ERR, "Unknown ioctl(0x%x) by %s(%d)", cmd, ccci_cdev_name[PORT2IDX(port_id)], port_id);
            ret = -EFAULT;
        	break;
    }

_exit:
    DEBUG_LOG_FUNCTION_LEAVE;
    return ret;
}