/* Modem_request command */ static int lge_dm_tty_modem_request(struct dm_tty *lge_dm_tty_drv, const unsigned char *buf, int count) { short modem_chip = Primary_modem_chip; int length; if(lge_dm_tty_drv->logging_mode == DM_APP_SDM) { length = dm_modem_request_header_length + sizeof(modem_chip); if (modem_chip == Primary_modem_chip) { /* send masks to modem */ if(buf != NULL) diag_process_hdlc((void *)buf + length, count - length); else pr_info("[DM_APP]buf is null , lge_dm_tty_modem_request \n"); } else if (modem_chip == Secondary_modem_chip) { /* send masks to 9k */ //TBD } else { pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_write" "modem_number %d " "error count = %d length = %d\n", __func__, modem_chip, count, length); } } else if(lge_dm_tty_drv->logging_mode == DM_APP_ODM) { diag_process_hdlc((void *)buf, count); } return count; }
void diag_process_hdlc_fn(struct work_struct *work) { APPEND_DEBUG('D'); diag_process_hdlc(driver->usb_buf_out, driver->read_len_legacy); diag_read_work_fn(work); APPEND_DEBUG('E'); }
/* Modem_request command */ static int lge_dm_tty_modem_request(const unsigned char *buf, int count) { short modem_chip = 0; int length = 0; memcpy(&modem_chip, buf + dm_modem_request_header_length, sizeof(modem_chip)); length = dm_modem_request_header_length + sizeof(modem_chip); if (modem_chip == Primary_modem_chip) { /* send masks to modem */ diag_process_hdlc((void *)buf + length, count - length); } else if (modem_chip == Secondary_modem_chip) { /* send masks to 9k */ //TBD } else { pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_write" "modem_number %d " "error count = %d length = %d\n", __func__, modem_chip, count, length); } return count; }
void lge_dm_dload_fn(struct work_struct *work) { #ifdef CONFIG_DIAGFWD_BRIDGE_CODE short modem_chip = Secondary_modem_chip; int err = 0; int index = 0; #else short modem_chip = Primary_modem_chip; #endif /*CONFIG_DIAGFWD_BRIDGE_CODE*/ int count = 0, length = 0; int size = sizeof(empty_mask_buff)/sizeof(char); char mask_buf[20]; while (count < size) { mask_buf[length++] = empty_mask_buff[count]; if (empty_mask_buff[count] == CONTROL_CHAR) { if (modem_chip == Primary_modem_chip) { diag_process_hdlc((unsigned char *)mask_buf, length); } else if (modem_chip == Secondary_modem_chip) { #ifdef CONFIG_DIAGFWD_BRIDGE_CODE /* send masks to All 9k */ for (index = 0; index < MAX_HSIC_DATA_CH; index++) { if (diag_hsic[index].hsic_ch && (count > 0)){ /* wait sending mask updates * if HSIC ch not ready */ if (diag_hsic[index].in_busy_hsic_write) wait_event_interruptible(driver->wait_q, (diag_hsic[index]. in_busy_hsic_write != 1)); diag_hsic[index].in_busy_hsic_write = 1; diag_hsic[index].in_busy_hsic_read_on_device = 0; err = diag_bridge_write(index, (unsigned char *)mask_buf, length); if (err) { pr_err("diag: err sending mask to MDM: %d\n", err); /* * If the error is recoverable, then * clear the write flag, so we will * resubmit a write on the next frame. * Otherwise, don't resubmit a write * on the next frame. */ if ((-ESHUTDOWN) != err) diag_hsic[index].in_busy_hsic_write = 0; } } } #endif /*CONFIG_DIAGFWD_BRIDGE_CODE*/ } length = 0; } count++; } }
/* Modem_request command */ static int lge_dm_dev_tty_modem_request(const unsigned char *buf, int count) { /* send masks to modem */ diag_process_hdlc((void *)buf, count); // pr_info(DM_DEV_TTY_MODULE_NAME ": %s:" // "count = %d\n",__func__, count); #if 0 else {
void diag_read_work_fn(struct work_struct *work) { APPEND_DEBUG('d'); diag_process_hdlc(driver->usb_buf_out, driver->read_len); driver->usb_read_ptr->buf = driver->usb_buf_out; driver->usb_read_ptr->length = USB_MAX_OUT_BUF; APPEND_DEBUG('e'); diag_read(driver->usb_read_ptr); APPEND_DEBUG('f'); }
/* Modem_request command */ static int lge_dm_tty_modem_request(const unsigned char *buf, int count) { short modem_chip; int length; memcpy(&modem_chip, buf + dm_modem_request_header_length, sizeof(modem_chip)); length = dm_modem_request_header_length + sizeof(modem_chip); if (modem_chip == Primary_modem_chip) { /* send masks to modem */ diag_process_hdlc((void *)buf + length, count - length); } else if (modem_chip == Secondary_modem_chip) { #ifdef CONFIG_DIAG_SDIO_PIPE /* send masks to 9k */ if (driver->sdio_ch) { wait_event_interruptible(driver->wait_q, (sdio_write_avail(driver->sdio_ch) >= (count - length))); if (driver->sdio_ch && ((count - length) > 0)) { sdio_write(driver->sdio_ch, (void *)buf + length, count - length); } } #endif } else { pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_write" "modem_number %d " "error count = %d length = %d\n", __func__, modem_chip, count, length); } return count; }
static int diagchar_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { int err, ret = 0, pkt_type; #ifdef DIAG_DEBUG int length = 0, i; #endif struct diag_send_desc_type send = { NULL, NULL, DIAG_STATE_START, 0 }; struct diag_hdlc_dest_type enc = { NULL, NULL, 0 }; void *buf_copy = NULL; int payload_size; #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 == USER_SPACE_LOG_TYPE) { err = copy_from_user(driver->user_space_data, buf + 4, payload_size); /* Check masks for On-Device logging */ if (driver->mask_check) { if (!mask_request_validate(driver->user_space_data)) { pr_alert("diag: mask request Invalid\n"); return -EFAULT; } } buf = buf + 4; #ifdef DIAG_DEBUG pr_debug("diag: user space data %d\n", payload_size); for (i = 0; i < payload_size; i++) pr_debug("\t %x", *((driver->user_space_data)+i)); #endif #ifdef CONFIG_DIAG_SDIO_PIPE /* send masks to 9k too */ if (driver->sdio_ch) { wait_event_interruptible(driver->wait_q, (sdio_write_avail(driver->sdio_ch) >= payload_size)); if (driver->sdio_ch && (payload_size > 0)) { sdio_write(driver->sdio_ch, (void *) (driver->user_space_data), payload_size); } } #endif /* send masks to modem now */ diag_process_hdlc((void *)(driver->user_space_data), payload_size); return 0; } buf_copy = diagmem_alloc(driver, payload_size, POOL_TYPE_COPY); if (!buf_copy) { driver->dropped_count++; return -ENOMEM; } err = copy_from_user(buf_copy, buf + 4, payload_size); if (err) { printk(KERN_INFO "diagchar : copy_from_user failed\n"); ret = -EFAULT; goto fail_free_copy; } #ifdef DIAG_DEBUG printk(KERN_DEBUG "data is -->\n"); for (i = 0; i < payload_size; i++) printk(KERN_DEBUG "\t %x \t", *(((unsigned char *)buf_copy)+i)); #endif send.state = DIAG_STATE_START; send.pkt = buf_copy; send.last = (void *)(buf_copy + payload_size - 1); send.terminate = 1; #ifdef DIAG_DEBUG pr_debug("diag: Already used bytes in buffer %d, and" " incoming payload size is %d\n", driver->used, payload_size); printk(KERN_DEBUG "hdlc encoded data is -->\n"); for (i = 0; i < payload_size + 8; i++) { printk(KERN_DEBUG "\t %x \t", *(((unsigned char *)buf_hdlc)+i)); if (*(((unsigned char *)buf_hdlc)+i) != 0x7e) length++; } #endif mutex_lock(&driver->diagchar_mutex); if (!buf_hdlc) buf_hdlc = diagmem_alloc(driver, HDLC_OUT_BUF_SIZE, POOL_TYPE_HDLC); if (!buf_hdlc) { ret = -ENOMEM; goto fail_free_hdlc; } if (HDLC_OUT_BUF_SIZE - driver->used <= (2*payload_size) + 3) { err = diag_device_write(buf_hdlc, APPS_DATA, NULL); if (err) { /*Free the buffer right away if write failed */ diagmem_free(driver, buf_hdlc, POOL_TYPE_HDLC); diagmem_free(driver, (unsigned char *)driver-> write_ptr_svc, POOL_TYPE_WRITE_STRUCT); ret = -EIO; goto fail_free_hdlc; } buf_hdlc = NULL; driver->used = 0; buf_hdlc = diagmem_alloc(driver, HDLC_OUT_BUF_SIZE, POOL_TYPE_HDLC); if (!buf_hdlc) { ret = -ENOMEM; goto fail_free_hdlc; } } enc.dest = buf_hdlc + driver->used; enc.dest_last = (void *)(buf_hdlc + driver->used + 2*payload_size + 3); diag_hdlc_encode(&send, &enc); /* This is to check if after HDLC encoding, we are still within the limits of aggregation buffer. If not, we write out the current buffer and start aggregation in a newly allocated buffer */ if ((unsigned int) enc.dest >= (unsigned int)(buf_hdlc + HDLC_OUT_BUF_SIZE)) { err = diag_device_write(buf_hdlc, APPS_DATA, NULL); if (err) { /*Free the buffer right away if write failed */ diagmem_free(driver, buf_hdlc, POOL_TYPE_HDLC); diagmem_free(driver, (unsigned char *)driver-> write_ptr_svc, POOL_TYPE_WRITE_STRUCT); ret = -EIO; goto fail_free_hdlc; } buf_hdlc = NULL; driver->used = 0; buf_hdlc = diagmem_alloc(driver, HDLC_OUT_BUF_SIZE, POOL_TYPE_HDLC); if (!buf_hdlc) { ret = -ENOMEM; goto fail_free_hdlc; } enc.dest = buf_hdlc + driver->used; enc.dest_last = (void *)(buf_hdlc + driver->used + (2*payload_size) + 3); diag_hdlc_encode(&send, &enc); } driver->used = (uint32_t) enc.dest - (uint32_t) buf_hdlc; if (pkt_type == DATA_TYPE_RESPONSE) { err = diag_device_write(buf_hdlc, APPS_DATA, NULL); if (err) { /*Free the buffer right away if write failed */ diagmem_free(driver, buf_hdlc, POOL_TYPE_HDLC); diagmem_free(driver, (unsigned char *)driver-> write_ptr_svc, POOL_TYPE_WRITE_STRUCT); ret = -EIO; goto fail_free_hdlc; } buf_hdlc = NULL; driver->used = 0; } mutex_unlock(&driver->diagchar_mutex); diagmem_free(driver, buf_copy, POOL_TYPE_COPY); if (!timer_in_progress) { timer_in_progress = 1; ret = mod_timer(&drain_timer, jiffies + msecs_to_jiffies(500)); } return 0; fail_free_hdlc: buf_hdlc = NULL; driver->used = 0; diagmem_free(driver, buf_copy, POOL_TYPE_COPY); mutex_unlock(&driver->diagchar_mutex); return ret; fail_free_copy: diagmem_free(driver, buf_copy, POOL_TYPE_COPY); return ret; }
/* Modem_request command */ static int lge_dm_tty_modem_request(struct dm_tty *lge_dm_tty_drv, const unsigned char *buf, int count) { int length; #ifdef CONFIG_DIAGFWD_BRIDGE_CODE short modem_chip = Secondary_modem_chip; int err = 0; int index = 0; #else short modem_chip = Primary_modem_chip; #endif /*CONFIG_DIAGFWD_BRIDGE_CODE*/ if(lge_dm_tty_drv->logging_mode == DM_APP_SDM) { length = dm_modem_request_header_length + sizeof(modem_chip); if (modem_chip == Primary_modem_chip) { /* send masks to modem */ if(buf != NULL) diag_process_hdlc((void *)buf + length, count - length); else pr_info("[DM_APP]buf is null , lge_dm_tty_modem_request \n"); } else if (modem_chip == Secondary_modem_chip) { /* send masks to 9k */ #ifdef CONFIG_DIAGFWD_BRIDGE_CODE /* send masks to All 9k */ for (index = 0; index < MAX_HSIC_CH; index++) { // if (diag_hsic[index].hsic_ch && (payload_size > 0) && // (remote_proc == MDM)) { if (diag_hsic[index].hsic_ch && (count > 0)){ /* wait sending mask updates * if HSIC ch not ready */ if (diag_hsic[index].in_busy_hsic_write) wait_event_interruptible(driver->wait_q, (diag_hsic[index]. in_busy_hsic_write != 1)); diag_hsic[index].in_busy_hsic_write = 1; diag_hsic[index].in_busy_hsic_read_on_device = 0; // err = diag_bridge_write(index, // driver->user_space_data + // token_offset, payload_size); err = diag_bridge_write(index, (void *)buf + length, count - length); if (err) { pr_err("diag: err sending mask to MDM: %d\n", err); /* * If the error is recoverable, then * clear the write flag, so we will * resubmit a write on the next frame. * Otherwise, don't resubmit a write * on the next frame. */ if ((-ESHUTDOWN) != err) diag_hsic[index].in_busy_hsic_write = 0; } } } #endif /*CONFIG_DIAGFWD_BRIDGE_CODE*/ } else { pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_write" "modem_number %d " "error count = %d length = %d\n", __func__, modem_chip, count, length); } } else if(lge_dm_tty_drv->logging_mode == DM_APP_ODM) { if (modem_chip == Primary_modem_chip) { diag_process_hdlc((void *)buf, count); } else if (modem_chip == Secondary_modem_chip) { #ifdef CONFIG_DIAGFWD_BRIDGE_CODE /* send masks to All 9k */ for (index = 0; index < MAX_HSIC_CH; index++) { // if (diag_hsic[index].hsic_ch && (payload_size > 0) && // (remote_proc == MDM)) { if (diag_hsic[index].hsic_ch && (count > 0)){ /* wait sending mask updates * if HSIC ch not ready */ if (diag_hsic[index].in_busy_hsic_write) wait_event_interruptible(driver->wait_q, (diag_hsic[index]. in_busy_hsic_write != 1)); diag_hsic[index].in_busy_hsic_write = 1; diag_hsic[index].in_busy_hsic_read_on_device = 0; // err = diag_bridge_write(index, // driver->user_space_data + // token_offset, payload_size); // err = diag_bridge_write(index, (void *)buf + length, count - length); err = diag_bridge_write(index, (void *)buf, count); if (err) { pr_err("diag: err sending mask to MDM: %d\n", err); /* * If the error is recoverable, then * clear the write flag, so we will * resubmit a write on the next frame. * Otherwise, don't resubmit a write * on the next frame. */ if ((-ESHUTDOWN) != err) diag_hsic[index].in_busy_hsic_write = 0; } } } #endif /*CONFIG_DIAGFWD_BRIDGE_CODE*/ } } return count; }
static int diagchar_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { int err, ret = 0, pkt_type; #ifdef DIAG_DEBUG int length = 0, i; #endif struct diag_send_desc_type send = { NULL, NULL, DIAG_STATE_START, 0 }; struct diag_hdlc_dest_type enc = { NULL, NULL, 0 }; void *buf_copy = NULL; int payload_size; unsigned char is_encoded = 0; void *large_buf_hdlc; #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 == -3) { //-DIAG_DATA_TYPE_RESPONSE => no hdlc encode is_encoded = 1; } else { is_encoded = 0; } if(is_encoded) { large_buf_hdlc = diagmem_alloc(driver, HDLC_OUT_BUF_SIZE, POOL_TYPE_HDLC); if (!large_buf_hdlc) { driver->dropped_count++; return -ENOMEM; } err = copy_from_user(large_buf_hdlc, buf + 4, payload_size); if (err) { diagmem_free(driver, large_buf_hdlc, POOL_TYPE_HDLC); printk(KERN_INFO "diagchar : copy_from_user failed \n"); ret = -EFAULT; return ret; } mutex_lock(&driver->diagchar_mutex); driver->write_ptr_svc = (struct diag_request *) (diagmem_alloc(driver, sizeof(struct diag_request), POOL_TYPE_WRITE_STRUCT)); driver->write_ptr_svc->buf = large_buf_hdlc; driver->used = payload_size; driver->write_ptr_svc->length = driver->used; err = usb_diag_write(driver->legacy_ch, driver->write_ptr_svc); if (err) { printk(KERN_INFO "\n size written length[%d] error[%d] \n", driver->used, err); diagmem_free(driver, large_buf_hdlc, POOL_TYPE_HDLC); ret = -EIO; mutex_unlock(&driver->diagchar_mutex); return -EIO; } #ifdef DIAG_DEBUG printk(KERN_INFO "\n LARGE_size written is %d \n", driver->used); #endif driver->used = 0; mutex_unlock(&driver->diagchar_mutex); return 0; } if (pkt_type == MEMORY_DEVICE_LOG_TYPE) { if (!mask_request_validate((unsigned char *)buf)) { printk(KERN_ALERT "mask request Invalid ..cannot send to modem \n"); return -EFAULT; } buf = buf + 4; #ifdef DIAG_DEBUG printk(KERN_INFO "\n I got the masks: %d\n", payload_size); for (i = 0; i < payload_size; i++) printk(KERN_DEBUG "\t %x", *(((unsigned char *)buf)+i)); #endif diag_process_hdlc((void *)buf, payload_size); return 0; } buf_copy = diagmem_alloc(driver, payload_size, POOL_TYPE_COPY); if (!buf_copy) { driver->dropped_count++; return -ENOMEM; } err = copy_from_user(buf_copy, buf + 4, payload_size); if (err) { printk(KERN_INFO "diagchar : copy_from_user failed\n"); ret = -EFAULT; goto fail_free_copy; } #ifdef DIAG_DEBUG printk(KERN_DEBUG "data is -->\n"); for (i = 0; i < payload_size; i++) printk(KERN_DEBUG "\t %x \t", *(((unsigned char *)buf_copy)+i)); #endif send.state = DIAG_STATE_START; send.pkt = buf_copy; send.last = (void *)(buf_copy + payload_size - 1); send.terminate = 1; #ifdef DIAG_DEBUG printk(KERN_INFO "\n Already used bytes in buffer %d, and" " incoming payload size is %d\n", driver->used, payload_size); printk(KERN_DEBUG "hdlc encoded data is -->\n"); for (i = 0; i < payload_size + 8; i++) { printk(KERN_DEBUG "\t %x \t", *(((unsigned char *)buf_hdlc)+i)); if (*(((unsigned char *)buf_hdlc)+i) != 0x7e) length++; } #endif mutex_lock(&driver->diagchar_mutex); if (!buf_hdlc) buf_hdlc = diagmem_alloc(driver, HDLC_OUT_BUF_SIZE, POOL_TYPE_HDLC); if (!buf_hdlc) { ret = -ENOMEM; goto fail_free_hdlc; } if (HDLC_OUT_BUF_SIZE - driver->used <= (2*payload_size) + 3) { err = diag_device_write(buf_hdlc, APPS_DATA, NULL); if (err) { /*Free the buffer right away if write failed */ diagmem_free(driver, buf_hdlc, POOL_TYPE_HDLC); diagmem_free(driver, (unsigned char *)driver-> write_ptr_svc, POOL_TYPE_WRITE_STRUCT); ret = -EIO; goto fail_free_hdlc; } buf_hdlc = NULL; #ifdef DIAG_DEBUG printk(KERN_INFO "\n size written is %d\n", driver->used); #endif driver->used = 0; buf_hdlc = diagmem_alloc(driver, HDLC_OUT_BUF_SIZE, POOL_TYPE_HDLC); if (!buf_hdlc) { ret = -ENOMEM; goto fail_free_hdlc; } } enc.dest = buf_hdlc + driver->used; enc.dest_last = (void *)(buf_hdlc + driver->used + 2*payload_size + 3); diag_hdlc_encode(&send, &enc); /* This is to check if after HDLC encoding, we are still within the limits of aggregation buffer. If not, we write out the current buffer and start aggregation in a newly allocated buffer */ if ((unsigned int) enc.dest >= (unsigned int)(buf_hdlc + HDLC_OUT_BUF_SIZE)) { err = diag_device_write(buf_hdlc, APPS_DATA, NULL); if (err) { /*Free the buffer right away if write failed */ diagmem_free(driver, buf_hdlc, POOL_TYPE_HDLC); diagmem_free(driver, (unsigned char *)driver-> write_ptr_svc, POOL_TYPE_WRITE_STRUCT); ret = -EIO; goto fail_free_hdlc; } buf_hdlc = NULL; #ifdef DIAG_DEBUG printk(KERN_INFO "\n size written is %d\n", driver->used); #endif driver->used = 0; buf_hdlc = diagmem_alloc(driver, HDLC_OUT_BUF_SIZE, POOL_TYPE_HDLC); if (!buf_hdlc) { ret = -ENOMEM; goto fail_free_hdlc; } enc.dest = buf_hdlc + driver->used; enc.dest_last = (void *)(buf_hdlc + driver->used + (2*payload_size) + 3); diag_hdlc_encode(&send, &enc); } driver->used = (uint32_t) enc.dest - (uint32_t) buf_hdlc; if (pkt_type == DATA_TYPE_RESPONSE) { err = diag_device_write(buf_hdlc, APPS_DATA, NULL); if (err) { /*Free the buffer right away if write failed */ diagmem_free(driver, buf_hdlc, POOL_TYPE_HDLC); diagmem_free(driver, (unsigned char *)driver-> write_ptr_svc, POOL_TYPE_WRITE_STRUCT); ret = -EIO; goto fail_free_hdlc; } buf_hdlc = NULL; #ifdef DIAG_DEBUG printk(KERN_INFO "\n size written is %d\n", driver->used); #endif driver->used = 0; } mutex_unlock(&driver->diagchar_mutex); diagmem_free(driver, buf_copy, POOL_TYPE_COPY); if (!timer_in_progress) { timer_in_progress = 1; ret = mod_timer(&drain_timer, jiffies + msecs_to_jiffies(500)); } return 0; fail_free_hdlc: buf_hdlc = NULL; driver->used = 0; diagmem_free(driver, buf_copy, POOL_TYPE_COPY); mutex_unlock(&driver->diagchar_mutex); return ret; fail_free_copy: diagmem_free(driver, buf_copy, POOL_TYPE_COPY); return ret; }
static int diagchar_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { int err, ret = 0, pkt_type; #ifdef CONFIG_LGE_DM_APP char *buf_cmp; #endif #ifdef DIAG_DEBUG int length = 0, i; #endif struct diag_send_desc_type send = { NULL, NULL, DIAG_STATE_START, 0 }; struct diag_hdlc_dest_type enc = { NULL, NULL, 0 }; void *buf_copy = NULL; int payload_size; #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; #ifdef CONFIG_LGE_DM_APP if (driver->logging_mode == DM_APP_MODE) { /* only diag cmd #250 for supporting testmode tool */ buf_cmp = (char *)buf + 4; if (*(buf_cmp) != 0xFA) return 0; } #endif if (payload_size > USER_SPACE_DATA) { pr_err("diag: Dropping packet, packet payload size crosses 8KB limit. Current payload size %d\n", payload_size); driver->dropped_count++; return -EBADMSG; } if (pkt_type == DCI_DATA_TYPE) { err = copy_from_user(driver->user_space_data, buf + 4, payload_size); if (err) { pr_alert("diag: copy failed for DCI data\n"); return DIAG_DCI_SEND_DATA_FAIL; } err = diag_process_dci_client(driver->user_space_data, payload_size); return err; } if (pkt_type == USER_SPACE_LOG_TYPE) { err = copy_from_user(driver->user_space_data, buf + 4, payload_size); /* Check masks for On-Device logging */ if (driver->mask_check) { if (!mask_request_validate(driver->user_space_data)) { pr_alert("diag: mask request Invalid\n"); return -EFAULT; } } buf = buf + 4; #ifdef DIAG_DEBUG pr_debug("diag: user space data %d\n", payload_size); for (i = 0; i < payload_size; i++) pr_debug("\t %x", *((driver->user_space_data)+i)); #endif #ifdef CONFIG_DIAG_SDIO_PIPE /* send masks to 9k too */ if (driver->sdio_ch) { wait_event_interruptible(driver->wait_q, (sdio_write_avail(driver->sdio_ch) >= payload_size)); if (driver->sdio_ch && (payload_size > 0)) { sdio_write(driver->sdio_ch, (void *) (driver->user_space_data), payload_size); } } #endif #ifdef CONFIG_DIAG_BRIDGE_CODE /* send masks to 9k too */ if (driver->hsic_ch && (payload_size > 0)) { /* wait sending mask updates if HSIC ch not ready */ if (driver->in_busy_hsic_write) wait_event_interruptible(driver->wait_q, (driver->in_busy_hsic_write != 1)); driver->in_busy_hsic_write = 1; driver->in_busy_hsic_read_on_device = 0; err = diag_bridge_write(driver->user_space_data, payload_size); if (err) { pr_err("diag: err sending mask to MDM: %d\n", err); /* * If the error is recoverable, then clear * the write flag, so we will resubmit a * write on the next frame. Otherwise, don't * resubmit a write on the next frame. */ if ((-ESHUTDOWN) != err) driver->in_busy_hsic_write = 0; } } #endif /* send masks to 8k now */ diag_process_hdlc((void *)(driver->user_space_data), payload_size); return 0; } if (payload_size > itemsize) { pr_err("diag: Dropping packet, packet payload size crosses" "4KB limit. Current payload size %d\n", payload_size); driver->dropped_count++; return -EBADMSG; } buf_copy = diagmem_alloc(driver, payload_size, POOL_TYPE_COPY); if (!buf_copy) { driver->dropped_count++; return -ENOMEM; } err = copy_from_user(buf_copy, buf + 4, payload_size); if (err) { printk(KERN_INFO "diagchar : copy_from_user failed\n"); ret = -EFAULT; goto fail_free_copy; } #ifdef DIAG_DEBUG printk(KERN_DEBUG "data is -->\n"); for (i = 0; i < payload_size; i++) printk(KERN_DEBUG "\t %x \t", *(((unsigned char *)buf_copy)+i)); #endif send.state = DIAG_STATE_START; send.pkt = buf_copy; send.last = (void *)(buf_copy + payload_size - 1); send.terminate = 1; #ifdef DIAG_DEBUG pr_debug("diag: Already used bytes in buffer %d, and" " incoming payload size is %d\n", driver->used, payload_size); printk(KERN_DEBUG "hdlc encoded data is -->\n"); for (i = 0; i < payload_size + 8; i++) { printk(KERN_DEBUG "\t %x \t", *(((unsigned char *)buf_hdlc)+i)); if (*(((unsigned char *)buf_hdlc)+i) != 0x7e) length++; } #endif mutex_lock(&driver->diagchar_mutex); if (!buf_hdlc) buf_hdlc = diagmem_alloc(driver, HDLC_OUT_BUF_SIZE, POOL_TYPE_HDLC); if (!buf_hdlc) { ret = -ENOMEM; goto fail_free_hdlc; } if (HDLC_OUT_BUF_SIZE - driver->used <= (2*payload_size) + 3) { err = diag_device_write(buf_hdlc, APPS_DATA, NULL); if (err) { /*Free the buffer right away if write failed */ diagmem_free(driver, buf_hdlc, POOL_TYPE_HDLC); diagmem_free(driver, (unsigned char *)driver-> write_ptr_svc, POOL_TYPE_WRITE_STRUCT); ret = -EIO; goto fail_free_hdlc; } buf_hdlc = NULL; driver->used = 0; buf_hdlc = diagmem_alloc(driver, HDLC_OUT_BUF_SIZE, POOL_TYPE_HDLC); if (!buf_hdlc) { ret = -ENOMEM; goto fail_free_hdlc; } } enc.dest = buf_hdlc + driver->used; enc.dest_last = (void *)(buf_hdlc + driver->used + 2*payload_size + 3); diag_hdlc_encode(&send, &enc); /* This is to check if after HDLC encoding, we are still within the limits of aggregation buffer. If not, we write out the current buffer and start aggregation in a newly allocated buffer */ if ((unsigned int) enc.dest >= (unsigned int)(buf_hdlc + HDLC_OUT_BUF_SIZE)) { err = diag_device_write(buf_hdlc, APPS_DATA, NULL); if (err) { /*Free the buffer right away if write failed */ diagmem_free(driver, buf_hdlc, POOL_TYPE_HDLC); diagmem_free(driver, (unsigned char *)driver-> write_ptr_svc, POOL_TYPE_WRITE_STRUCT); ret = -EIO; goto fail_free_hdlc; } buf_hdlc = NULL; driver->used = 0; buf_hdlc = diagmem_alloc(driver, HDLC_OUT_BUF_SIZE, POOL_TYPE_HDLC); if (!buf_hdlc) { ret = -ENOMEM; goto fail_free_hdlc; } enc.dest = buf_hdlc + driver->used; enc.dest_last = (void *)(buf_hdlc + driver->used + (2*payload_size) + 3); diag_hdlc_encode(&send, &enc); } driver->used = (uint32_t) enc.dest - (uint32_t) buf_hdlc; if (pkt_type == DATA_TYPE_RESPONSE) { err = diag_device_write(buf_hdlc, APPS_DATA, NULL); if (err) { /*Free the buffer right away if write failed */ diagmem_free(driver, buf_hdlc, POOL_TYPE_HDLC); diagmem_free(driver, (unsigned char *)driver-> write_ptr_svc, POOL_TYPE_WRITE_STRUCT); ret = -EIO; goto fail_free_hdlc; } buf_hdlc = NULL; driver->used = 0; } mutex_unlock(&driver->diagchar_mutex); diagmem_free(driver, buf_copy, POOL_TYPE_COPY); if (!timer_in_progress) { timer_in_progress = 1; ret = mod_timer(&drain_timer, jiffies + msecs_to_jiffies(500)); } return 0; fail_free_hdlc: buf_hdlc = NULL; driver->used = 0; diagmem_free(driver, buf_copy, POOL_TYPE_COPY); mutex_unlock(&driver->diagchar_mutex); return ret; fail_free_copy: diagmem_free(driver, buf_copy, POOL_TYPE_COPY); return ret; }
/* Modem_request command */ static int lge_dm_tty_modem_request(const unsigned char *buf, int count) { short modem_chip; int length; #ifdef CONFIG_DIAG_HSIC_PIPE int err = 0; #endif memcpy(&modem_chip, buf + dm_modem_request_header_length, sizeof(modem_chip)); length = dm_modem_request_header_length + sizeof(modem_chip); if (modem_chip == Primary_modem_chip) { /* send masks to modem */ diag_process_hdlc((void *)buf + length, count - length); } else if (modem_chip == Secondary_modem_chip) { #ifdef CONFIG_DIAG_SDIO_PIPE /* send masks to 9k */ if (driver->sdio_ch) { wait_event_interruptible(driver->wait_q, (sdio_write_avail(driver->sdio_ch) >= (count - length))); if (driver->sdio_ch && ((count - length) > 0)) { sdio_write(driver->sdio_ch, (void *)buf + length, count - length); } } #endif #ifdef CONFIG_DIAG_HSIC_PIPE /* send masks to 9k too */ if (driver->hsic_ch && (count - length > 0)) { /* wait sending mask updates if HSIC ch not ready */ if (driver->in_busy_hsic_write) wait_event_interruptible(driver->wait_q, (driver->in_busy_hsic_write != 1)); driver->in_busy_hsic_write = 1; driver->in_busy_hsic_read_on_device = 0; err = diag_bridge_write((void *)buf + length, count - length); if (err) { pr_err("diag: err sending mask to MDM: %d\n", err); /* * If the error is recoverable, then clear * the write flag, so we will resubmit a * write on the next frame. Otherwise, don't * resubmit a write on the next frame. */ if ((-ESHUTDOWN) != err) driver->in_busy_hsic_write = 0; } } #endif } else { pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_write" "modem_number %d " "error count = %d length = %d\n", __func__, modem_chip, count, length); } return count; }