int ccci_df_to_ccci_send_msg(CCCI_CHANNEL_T ch, unsigned int msg, unsigned int reserv){ struct sk_buff *new_skb; CCCI_BUFF_T *pccci_h; KAL_UINT32 port_id; KAL_INT32 ret; DEBUG_LOG_FUNCTION_ENTRY; if ((check_device_state() != EEMCS_BOOTING_DONE) || md_wdt_timeout_isr) {//modem not ready DBGLOG(CCCI, ERR, "CH%d send ccci msg(%d) fail when modem not ready", ch, msg); return -ENODEV; } new_skb = ccci_cdev_mem_alloc(sizeof(CCCI_BUFF_T), GFP_ATOMIC); if(new_skb == NULL){ DBGLOG(CCCI, ERR, "[TX]CH%d alloc skb fail", ch); return -ENOMEM; } pccci_h = (CCCI_BUFF_T *)skb_put(new_skb, sizeof(CCCI_BUFF_T)) ; memset(pccci_h, 0, sizeof(CCCI_BUFF_T)); pccci_h->data[0] = CCCI_MAGIC_NUM; pccci_h->data[1] = msg; pccci_h->reserved = reserv; #if defined (DBG_FEATURE_ADD_CCCI_SEQNO) if (ch == CCCI_FORCE_RESET_MODEM_CHANNEL) { pccci_h->channel = (CCCI_FORCE_RESET_MODEM_CHANNEL&0xFFFF); pccci_h->seq_num = (CCCI_FORCE_RESET_MODEM_CHANNEL&0x7FFF0000) >> 16; pccci_h->assert_bit = (CCCI_FORCE_RESET_MODEM_CHANNEL&0x80000000) >> 31; }
static void eemcs_cdev_write_force_md_rst(void) { struct sk_buff *new_skb; CCCI_BUFF_T *ccci_header; int ret; new_skb = ccci_cdev_mem_alloc(CCCI_CDEV_HEADER_ROOM); while(NULL == new_skb) { new_skb = ccci_cdev_mem_alloc(CCCI_CDEV_HEADER_ROOM); } /* reserve SDIO_H header room */ skb_reserve(new_skb, sizeof(SDIO_H)); ccci_header = (CCCI_BUFF_T *)skb_put(new_skb, sizeof(CCCI_BUFF_T)) ; ccci_header->data[0]= CCCI_MAGIC_NUM; /* message box magic */ ccci_header->data[1]= 0; /* message ID */ ccci_header->channel = CCCI_FORCE_RESET_MODEM_CHANNEL; /* reset channel number */ ret = ccci_cdev_write_desc_to_q(CCCI_FORCE_RESET_MODEM_CHANNEL, new_skb); }
static ssize_t eemcs_cdev_write(struct file *fp, const char __user *buf, size_t in_sz, loff_t *ppos) { ssize_t ret = -EINVAL; eemcs_cdev_node_t *curr_node = (eemcs_cdev_node_t *)fp->private_data; KAL_UINT8 port_id = curr_node->eemcs_port_id; /* port_id */ KAL_UINT32 p_type, control_flag; struct sk_buff *new_skb; CCCI_BUFF_T *ccci_header; size_t count = in_sz; DEBUG_LOG_FUNCTION_ENTRY; DBGLOG(CHAR, DBG, "eemcs_cdev_write: %s(%d), len=%d",curr_node->cdev_name,port_id,count); p_type = ccci_get_port_type(port_id); if(curr_node->ccci_ch.tx == CH_DUMMY){ /* if ccci channel is assigned to CH_DUMMY means tx packets should be dropped ex. muxreport port */ DBGLOG(CHAR, ERR, "PORT%d is assigned to CH_DUMMY ccci channel !!PKT DROP!!", port_id); ret = -EINVAL; goto _exit; } if(p_type != EX_T_USER) { DBGLOG(CHAR, ERR, "PORT%d refuse p_type(%d) access user port", port_id, p_type); ret = -EINVAL; goto _exit; } if(!eemcs_device_ready() && ((port_id==CCCI_PORT_META)||(port_id==CCCI_PORT_MD_LOG))) { ret= - ENODEV; DBGLOG(CHAR, DEF, "device not ready!"); return ret; } control_flag = ccci_get_port_cflag(port_id); if((control_flag & EXPORT_CCCI_H) && (count < sizeof(CCCI_BUFF_T))) { DBGLOG(CHAR, WAR, "PORT%d wirte len not support(%d) by emcs!", port_id, count); ret = -EINVAL; goto _exit; } if(control_flag & EXPORT_CCCI_H){ if(count > (MAX_TX_BYTE+sizeof(CCCI_BUFF_T))){ DBGLOG(CHAR, WAR, "PORT%d wirte_len(%d) > MTU(%d)!", port_id, count, MAX_TX_BYTE); count = MAX_TX_BYTE+sizeof(CCCI_BUFF_T); } }else{ if(count > MAX_TX_BYTE){ DBGLOG(CHAR, WAR, "PORT%d wirte_len(%d) > MTU(%d)!", port_id, count, MAX_TX_BYTE); count = MAX_TX_BYTE; } } __blocking_IO: if (ccci_cdev_write_space_alloc(curr_node->ccci_ch.tx)==0){ if (fp->f_flags & O_NONBLOCK) { ret = -EAGAIN; DBGLOG(CHAR, WAR, "PORT%d ccci_cdev_write_space_alloc return 0)", port_id); goto _exit; }else{ // Blocking IO DBGLOG(CHAR, TRA, "PORT%d Enter Blocking I/O wait", port_id); ret = ccci_cdev_write_wait(curr_node->ccci_ch.tx); if(ret == -ERESTARTSYS) { DBGLOG(CHAR, WAR, "PORT%d Interrupted,return ERESTARTSYS", port_id); ret = -EINTR; goto _exit; } goto __blocking_IO; } } new_skb = ccci_cdev_mem_alloc(count + CCCI_CDEV_HEADER_ROOM); if(NULL == new_skb) { ret = -ENOMEM; DBGLOG(CHAR, ERR, "PORT%d alloct tx memory fail(%d)", port_id, ret); goto _exit; } /* reserve SDIO_H header room */ skb_reserve(new_skb, sizeof(SDIO_H)); if(control_flag & EXPORT_CCCI_H){ ccci_header = (CCCI_BUFF_T *)new_skb->data; }else{ ccci_header = (CCCI_BUFF_T *)skb_put(new_skb, sizeof(CCCI_BUFF_T)) ; } if(copy_from_user(skb_put(new_skb, count), buf, count)) { DBGLOG(CHAR, ERR, "PORT%d fail copy data from user space(%d)", port_id, count); dev_kfree_skb(new_skb); ret=-EFAULT; goto _exit; } if(control_flag & EXPORT_CCCI_H) { /* user bring down the ccci header */ if(count == sizeof(CCCI_BUFF_T)){ DBGLOG(CHAR, DBG, "eemcs_cdev_write: PORT%d, CCCI_MSG(0x%x, 0x%x, 0x%x, 0x%x)", port_id, ccci_header->data[0], ccci_header->data[1], ccci_header->channel, ccci_header->reserved); ccci_header->data[0]= CCCI_MAGIC_NUM; }else{ ccci_header->data[1]= count; } if(ccci_header->channel != curr_node->ccci_ch.tx){ DBGLOG(CHAR, WAR, "PORT%d Tx CCCI channel not match (%d) vs (%d)!! will correct by char_dev",\ port_id, ccci_header->channel, curr_node->ccci_ch.tx); } } else { /* user bring down the payload only */ ccci_header->data[1] = count + sizeof(CCCI_BUFF_T); ccci_header->reserved = 0; } ccci_header->channel = curr_node->ccci_ch.tx; DBGLOG(CHAR, DBG, "eemcs_cdev_write: PORT%d, CCCI_MSG(0x%x, 0x%x, 0x%x, 0x%x)", port_id, ccci_header->data[0], ccci_header->data[1], ccci_header->channel, ccci_header->reserved); /* 20130816 ian add aud dump */ { char *ptr = (char *)new_skb->data; ptr+=sizeof(CCCI_BUFF_T); /* dump 32 byte of the !!!CCCI DATA!!! part */ CDEV_LOG(port_id, CHAR, INF, "[DUMP]PORT%d eemcs_cdev_write\n\ [00..07](0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)\n\ [08..15](0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)\n\ [16..23](0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)\n\ [24..31](0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)",\ port_id,\ (int)*(ptr+0),(int)*(ptr+1),(int)*(ptr+2),(int)*(ptr+3),(int)*(ptr+4),(int)*(ptr+5),(int)*(ptr+6),(int)*(ptr+7),\ (int)*(ptr+8),(int)*(ptr+9),(int)*(ptr+10),(int)*(ptr+11),(int)*(ptr+12),(int)*(ptr+13),(int)*(ptr+14),(int)*(ptr+15),\ (int)*(ptr+16),(int)*(ptr+17),(int)*(ptr+18),(int)*(ptr+19),(int)*(ptr+20),(int)*(ptr+21),(int)*(ptr+22),(int)*(ptr+23),\ (int)*(ptr+24),(int)*(ptr+25),(int)*(ptr+26),(int)*(ptr+27),(int)*(ptr+28),(int)*(ptr+29),(int)*(ptr+30),(int)*(ptr+31)); } ret = ccci_cdev_write_desc_to_q(curr_node->ccci_ch.tx, new_skb); if (KAL_SUCCESS != ret) { DBGLOG(CHAR, ERR, "Pkt drop of ch%d!",curr_node->ccci_ch.tx); dev_kfree_skb(new_skb); ret = -EAGAIN; } else { atomic_inc(&curr_node->tx_pkt_cnt); //wake_up(&curr_node->tx_waitq); /* wake up tx_waitq for notify poll_wait of state change */ } #if 0 20130102 note that ret = que_wakeup_transfer(port->txq_id); if(ret) { DBGLOG(PORT,ERR,"PORT(%d) fail wake when write(%d)", port->id, ret); goto _exit; } ret = wait_event_interruptible(port->write_waitq, port->tx_pkt_id == port->tx_pkt_id_done); if(ret == -ERESTARTSYS) { // TODO: error handling ..... DBGLOG(PORT,ERR,"PORT(%d) fail wait write done event successfully", port->id); } #endif _exit: DEBUG_LOG_FUNCTION_LEAVE; if(!ret){ return count; } ccci_cdev_write_space_release(curr_node->ccci_ch.tx); return ret; }