static int diagcharmdm_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { int err, pkt_type; int payload_size; #if defined(CONFIG_MACH_MECHA) int ret = 0; unsigned char *tmp_buf = NULL; #endif #ifdef DIAG_DEBUG DIAG_INFO("%s:%s(parent:%s): tgid=%d\n", __func__, current->comm, current->parent->comm, current->tgid); #endif #if defined(CONFIG_MACH_MECHA) if (!sdio_diag_initialized) { DIAG_INFO("sdio diag isn't in embedded mode \n"); return 0; } if (driver->logging_mode == MEMORY_DEVICE_MODE) { /* Get the packet type F3/log/event/Pkt response */ err = copy_from_user((&pkt_type), buf, 4); /*First 4 bytes indicate the type of payload - ignore these */ payload_size = count - 4; if (pkt_type == MEMORY_DEVICE_LOG_TYPE) { if (!mask_request_validate((unsigned char *)buf)) { DIAG_ERR("mask request Invalid ..cannot send to modem \n"); return -EFAULT; } buf = buf + 4; tmp_buf = kzalloc(IN_BUF_SIZE, GFP_KERNEL); memcpy(tmp_buf, buf, payload_size); msm_sdio_diag_write((void *)tmp_buf, payload_size); tmp_buf = NULL; return 0; } } return ret; #else #ifdef CONFIG_DIAG_OVER_USB if (((driver->logging_mode == USB_MODE) && (!driver->usb_connected)) || (driver->logging_mode == NO_LOGGING_MODE)) { /*Drop the diag payload */ return -EIO; } #endif /* DIAG over USB */ /* Get the packet type F3/log/event/Pkt response */ err = copy_from_user((&pkt_type), buf, 4); /*First 4 bytes indicate the type of payload - ignore these */ payload_size = count - 4; if (pkt_type == MEMORY_DEVICE_LOG_TYPE) { DIAGFWD_INFO("writing mask file\n"); if (!mask_request_validate((unsigned char *)buf)) { DIAG_ERR("mask request Invalid ..cannot send to modem \n"); return -EFAULT; } buf = buf + 4; if (driver->sdio_ch) { memcpy(buf_9k, buf, payload_size); sdio_write(driver->sdio_ch, buf_9k, payload_size); } return count; } else if(pkt_type == USERMODE_DIAGFWD) { buf += 4; if (driver->sdio_ch) { memcpy(buf_9k, buf, payload_size); sdio_write(driver->sdio_ch, buf_9k,payload_size); } return count; } return 0; #endif }
void diag_process_hdlc(void *data, unsigned len) { struct diag_hdlc_decode_type hdlc; int ret, type = 0; #if HPST_FUN unsigned char *buf_9k = NULL; int path; #endif #ifdef DIAG_DEBUG int i; printk(KERN_INFO "\n HDLC decode function, len of data %d\n", len); #endif hdlc.dest_ptr = driver->hdlc_buf; hdlc.dest_size = USB_MAX_OUT_BUF; hdlc.src_ptr = data; hdlc.src_size = len; hdlc.src_idx = 0; hdlc.dest_idx = 0; hdlc.escaping = 0; ret = diag_hdlc_decode(&hdlc); if (ret) { type = diag_process_apps_pkt(driver->hdlc_buf, hdlc.dest_idx - 3); } else if (driver->debug_flag) { printk(KERN_ERR "Packet dropped due to bad HDLC coding/CRC" " errors or partial packet received, packet" " length = %d\n", len); print_hex_dump(KERN_DEBUG, "Dropped Packet Data: ", 16, 1, DUMP_PREFIX_ADDRESS, data, len, 1); driver->debug_flag = 0; } #ifdef DIAG_DEBUG printk(KERN_INFO "\n hdlc.dest_idx = %d \n", hdlc.dest_idx); for (i = 0; i < hdlc.dest_idx; i++) printk(KERN_DEBUG "\t%x", *(((unsigned char *) driver->hdlc_buf)+i)); #endif /* ignore 2 bytes for CRC, one for 7E and send */ if ((driver->ch) && (ret) && (type) && (hdlc.dest_idx > 3)) { APPEND_DEBUG('g'); #if HPST_FUN /* check for hpst*/ path = checkcmd_modem_hpst(data); switch (path) { case DM7K9K: printk(KERN_INFO "%s:DM7K9K\n", __func__); print_hex_dump(KERN_DEBUG, "HPST:DM Packet Data" " write to radio ", 16, 1, DUMP_PREFIX_ADDRESS, data, 16, 1); smd_write(driver->ch, data, len); buf_9k = kzalloc(len, GFP_KERNEL); memcpy(buf_9k, data, len); msm_sdio_diag_write((void *)buf_9k, len); buf_9k = NULL; break; case DM9KONLY: printk(KERN_INFO "%s:DM9KONLY\n", __func__); print_hex_dump(KERN_DEBUG, "HPST:DM Packet Data" " write to radio ", 16, 1, DUMP_PREFIX_ADDRESS, data, 16, 1); buf_9k = kzalloc(len, GFP_KERNEL); memcpy(buf_9k, data, len); msm_sdio_diag_write((void *)buf_9k, len); buf_9k = NULL; break; case DM7K9KDIFF: printk(KERN_INFO "%s:DM7K9KDIFF", __func__); print_hex_dump(KERN_DEBUG, "HPST:DM Packet Data" " write to radio ", 16, 1, DUMP_PREFIX_ADDRESS, data, 16, 1); if (((*(((uint8_t *)data)+3)) & 0xC0) == 0xC0) { printk(KERN_INFO "%s:DM7K9KDIFF to 9K\n", __func__); buf_9k = kzalloc(len, GFP_KERNEL); memcpy(buf_9k, data, len); msm_sdio_diag_write((void *)buf_9k, len); buf_9k = NULL; } else { printk(KERN_INFO "%s:DM7K9KDIFF to 7K\n", __func__); smd_write(driver->ch, data, len); } break; case DM7KONLY: printk(KERN_INFO "%s:DM7KONLY\n", __func__); print_hex_dump(KERN_DEBUG, "HPST:DM Packet Data" " write to radio ", 16, 1, DUMP_PREFIX_ADDRESS, data, 16, 1); smd_write(driver->ch, data, len); break; case NO_PST: smd_write(driver->ch, data, len); break; case NO_DEF_ID: case NO_DEF_ITEM: default: print_hex_dump(KERN_DEBUG, "HPST:DM Packet Data" " can't write to radio ", 16, 1, DUMP_PREFIX_ADDRESS, data, 16, 1); } #else smd_write(driver->ch, data, len); #endif APPEND_DEBUG('h'); #ifdef DIAG_DEBUG printk(KERN_INFO "writing data to SMD, pkt length %d \n", len); print_hex_dump(KERN_DEBUG, "Written Packet Data to SMD: ", 16, 1, DUMP_PREFIX_ADDRESS, data, len, 1); #endif } }