void phudiagfwd_read_data_from_smd(void) { int r = smd_read_avail(phudriver->ch); if (r > PHU_MAX_BUF_SIZE) { printk(KERN_ALERT "\n diag: SMD sending in " "packets more than %d bytes", PHU_MAX_BUF_SIZE); return; } if(r > 0) { if(r == phudiagfwd_ring_buf_set_data_before_process(phudriver->in_buf, r)) { smd_read(phudriver->ch, phudriver->in_buf->end, r); phudriver->in_buf->end += r; } else { printk(KERN_INFO "phudiagfwd_read_data_from_smd write out of memory !\n"); } } }
int phudiagfwd_user_set_data(const char __user * data,int data_length) { struct phudiag_data *pdata; int total_data_length = 0; int ret = 0; if(NULL == phudriver->out_buf || NULL == data ||data_length <= 0 ) { printk(KERN_INFO "phudiagfwd_copy_from_user_data fatal error: parameter invalid! \n"); return -1; } mutex_lock(&phudriver->diagchar_mutex); total_data_length = data_length + sizeof(int); ret = phudiagfwd_ring_buf_set_data_before_process(phudriver->out_buf,total_data_length); if(ret <= 0) { printk(KERN_INFO "phudiagfwd_copy_from_user_data fatal error! \n"); mutex_unlock(&phudriver->diagchar_mutex); return ret; } pdata = (struct phudiag_data *)phudriver->out_buf->end; pdata->length = data_length; if(copy_from_user(pdata->data,data,data_length)) { printk(KERN_INFO "phudiagfwd_user_set_data copy_from_user failed!\n"); mutex_unlock(&phudriver->diagchar_mutex); return -1; } phudriver->out_buf->end += total_data_length; mutex_unlock(&phudriver->diagchar_mutex); return data_length; }
void __diag_smd_send_req(void) { void *buf = NULL; int *in_busy_ptr = NULL; struct diag_request *write_ptr_modem = NULL; if (!driver->in_busy_1) { buf = driver->buf_in_1; write_ptr_modem = driver->write_ptr_1; in_busy_ptr = &(driver->in_busy_1); } else if (!driver->in_busy_2) { buf = driver->buf_in_2; write_ptr_modem = driver->write_ptr_2; in_busy_ptr = &(driver->in_busy_2); } if (driver->ch && buf) { int r = smd_read_avail(driver->ch); if (r > IN_BUF_SIZE) { if (r < MAX_IN_BUF_SIZE) { pr_err("diag: SMD sending in " "packets upto %d bytes", r); buf = krealloc(buf, r, GFP_KERNEL); } else { pr_err("diag: SMD sending in " "packets more than %d bytes", MAX_IN_BUF_SIZE); return; } } if (r > 0) { if (!buf) pr_info("Out of diagmem for Modem\n"); else { #ifdef CONFIG_HUAWEI_FEATURE_PHUDIAG mutex_lock(&phudriver->diagchar_mutex); if(phudriver->opened) { if(r != phudiagfwd_ring_buf_set_data_before_process(phudriver->in_buf, r)) { printk(KERN_INFO "__diag_smd_send_req write in_buf out of memory !\n"); mutex_unlock(&phudriver->diagchar_mutex); return; } } #endif APPEND_DEBUG('i'); smd_read(driver->ch, buf, r); APPEND_DEBUG('j'); #ifdef CONFIG_HUAWEI_FEATURE_PHUDIAG if(phudriver->opened) { memcpy(phudriver->in_buf->end,buf,r); phudriver->in_buf->end += r; } mutex_unlock(&phudriver->diagchar_mutex); #endif write_ptr_modem->length = r; *in_busy_ptr = 1; diag_device_write(buf, MODEM_DATA, write_ptr_modem); } } } #ifdef CONFIG_HUAWEI_FEATURE_PHUDIAG phudiagfwd_usb_diag_suspend_packet_num++; mutex_lock(&phudriver->diagchar_mutex); if(phudriver->opened && NULL == buf && phudiagfwd_usb_diag_suspend_packet_num > 10 ) { phudiagfwd_usb_diag_suspend_packet_num = 10; phudiagfwd_read_data_from_smd(); } mutex_unlock(&phudriver->diagchar_mutex); #endif }