static long diagcharmdm_ioctl(struct file *filp, unsigned int iocmd, unsigned long ioarg) { int success = -1; if (iocmd == DIAG_IOCTL_SWITCH_LOGGING) { mutex_lock(&driver->diagcharmdm_mutex); driver->logging_mode = (int)ioarg; driver->logging_process_id = current->tgid; mutex_unlock(&driver->diagcharmdm_mutex); if (driver->logging_mode == MEMORY_DEVICE_MODE) { DIAG_INFO("diagcharmdm_ioctl enable\n"); diagfwd_disconnect(); driver->qxdm2sd_drop = 0; driver->in_busy_sdio_1 = 0; driver->in_busy_sdio_2 = 0; buf_9k = kzalloc(USB_MAX_OUT_BUF, GFP_KERNEL); if (driver->sdio_ch) queue_work(driver->diag_sdio_wq, &(driver->diag_read_sdio_work)); } else if (driver->logging_mode == USB_MODE) { DIAG_INFO("diagcharmdm_ioctl disable\n"); diagfwd_connect(); driver->qxdm2sd_drop = 1; kfree(buf_9k); } success = 1; } return success; }
static int diagcharmdm_ioctl(struct inode *inode, struct file *filp, unsigned int iocmd, unsigned long ioarg) { int success = -1; #if defined(CONFIG_MACH_MECHA) if (!sdio_diag_initialized) { DIAG_INFO("sdio diag isn't in embedded mode \n"); return 0; } #endif if (iocmd == DIAG_IOCTL_SWITCH_LOGGING) { mutex_lock(&driver->diagcharmdm_mutex); driver->logging_mode = (int)ioarg; driver->logging_process_id = current->tgid; mutex_unlock(&driver->diagcharmdm_mutex); if (driver->logging_mode == MEMORY_DEVICE_MODE) { DIAG_INFO("diagcharmdm_ioctl enable\n"); diagfwd_disconnect(); driver->qxdm2sd_drop = 0; #if defined(CONFIG_MACH_MECHA) driver->in_busy_mdm_1 = 0; driver->in_busy_mdm_2 = 0; /* Poll SMD channels to check for data*/ queue_work(driver->mdm_diag_workqueue, &(driver->diag_read_smd_mdm_work)); #endif #if defined(CONFIG_ARCH_MSM8X60_LTE) driver->in_busy_sdio_1 = 0; driver->in_busy_sdio_2 = 0; buf_9k = kzalloc(USB_MAX_OUT_BUF, GFP_KERNEL); if (driver->sdio_ch) queue_work(driver->diag_sdio_wq, &(driver->diag_read_sdio_work)); #endif } else if (driver->logging_mode == USB_MODE) { DIAG_INFO("diagcharmdm_ioctl disable\n"); diagfwd_connect(); driver->qxdm2sd_drop = 1; #if defined(CONFIG_MACH_MECHA) driver->in_busy_mdm_1 = 1; driver->in_busy_mdm_2 = 1; #endif #if defined(CONFIG_ARCH_MSM8X60_LTE) kfree(buf_9k); #endif } success = 1; } return success; return 0; }
void diag_usb_legacy_notifier(void *priv, unsigned event, struct diag_request *d_req) { switch (event) { case USB_DIAG_CONNECT: diagfwd_connect(); break; case USB_DIAG_DISCONNECT: diagfwd_disconnect(); break; case USB_DIAG_READ_DONE: diagfwd_read_complete(d_req); break; case USB_DIAG_WRITE_DONE: diagfwd_write_complete(d_req); break; default: DIAGFWD_ERR("Unknown event from USB diag\n"); break; } }
static int diagchar_ioctl(struct inode *inode, struct file *filp, unsigned int iocmd, unsigned long ioarg) { int i, j, count_entries = 0, temp; int success = -1; if (iocmd == DIAG_IOCTL_COMMAND_REG) { struct bindpkt_params_per_process *pkt_params = (struct bindpkt_params_per_process *) ioarg; for (i = 0; i < diag_max_registration; i++) { if (driver->table[i].process_id == 0) { success = 1; driver->table[i].cmd_code = pkt_params->params->cmd_code; driver->table[i].subsys_id = pkt_params->params->subsys_id; driver->table[i].cmd_code_lo = pkt_params->params->cmd_code_hi; driver->table[i].cmd_code_hi = pkt_params->params->cmd_code_lo; driver->table[i].process_id = current->tgid; count_entries++; if (pkt_params->count > count_entries) pkt_params->params++; else return success; } } if (i < diag_threshold_registration) { /* Increase table size by amount required */ diag_max_registration += pkt_params->count - count_entries; /* Make sure size doesnt go beyond threshold */ if (diag_max_registration > diag_threshold_registration) diag_max_registration = diag_threshold_registration; driver->table = krealloc(driver->table, diag_max_registration*sizeof(struct diag_master_table), GFP_KERNEL); for (j = i; j < diag_max_registration; j++) { success = 1; driver->table[j].cmd_code = pkt_params-> params->cmd_code; driver->table[j].subsys_id = pkt_params-> params->subsys_id; driver->table[j].cmd_code_lo = pkt_params-> params->cmd_code_hi; driver->table[j].cmd_code_hi = pkt_params-> params->cmd_code_lo; driver->table[j].process_id = current->tgid; count_entries++; if (pkt_params->count > count_entries) pkt_params->params++; else return success; } } else pr_err("Max size reached, Pkt Registration failed for" " Process %d", current->tgid); success = 0; } else if (iocmd == DIAG_IOCTL_GET_DELAYED_RSP_ID) { struct diagpkt_delay_params *delay_params = (struct diagpkt_delay_params *) ioarg; if ((delay_params->rsp_ptr) && (delay_params->size == sizeof(delayed_rsp_id)) && (delay_params->num_bytes_ptr)) { *((uint16_t *)delay_params->rsp_ptr) = DIAGPKT_NEXT_DELAYED_RSP_ID(delayed_rsp_id); *(delay_params->num_bytes_ptr) = sizeof(delayed_rsp_id); success = 0; } } else if (iocmd == DIAG_IOCTL_LSM_DEINIT) { for (i = 0; i < driver->num_clients; i++) if (driver->client_map[i].pid == current->tgid) break; if (i == -1) return -EINVAL; driver->data_ready[i] |= DEINIT_TYPE; wake_up_interruptible(&driver->wait_q); success = 1; } else if (iocmd == DIAG_IOCTL_SWITCH_LOGGING) { mutex_lock(&driver->diagchar_mutex); temp = driver->logging_mode; driver->logging_mode = (int)ioarg; driver->logging_process_id = current->tgid; mutex_unlock(&driver->diagchar_mutex); if (temp == USB_MODE && driver->logging_mode == NO_LOGGING_MODE) diagfwd_disconnect(); else if (temp == NO_LOGGING_MODE && driver->logging_mode == USB_MODE) diagfwd_connect(); else if (temp == MEMORY_DEVICE_MODE && driver->logging_mode == NO_LOGGING_MODE) { driver->in_busy_1 = 1; driver->in_busy_2 = 1; driver->in_busy_qdsp = 1; } else if (temp == NO_LOGGING_MODE && driver->logging_mode == MEMORY_DEVICE_MODE) { driver->in_busy_1 = 0; driver->in_busy_2 = 0; driver->in_busy_qdsp = 0; /* Poll SMD channels to check for data*/ if (driver->ch) queue_work(driver->diag_wq, &(driver->diag_read_smd_work)); if (driver->chqdsp) queue_work(driver->diag_wq, &(driver->diag_read_smd_qdsp_work)); } else if (temp == USB_MODE && driver->logging_mode == MEMORY_DEVICE_MODE) { diagfwd_disconnect(); driver->in_busy_1 = 0; driver->in_busy_2 = 0; driver->in_busy_qdsp = 0; /* Poll SMD channels to check for data*/ if (driver->ch) queue_work(driver->diag_wq, &(driver->diag_read_smd_work)); if (driver->chqdsp) queue_work(driver->diag_wq, &(driver->diag_read_smd_qdsp_work)); } else if (temp == MEMORY_DEVICE_MODE && driver->logging_mode == USB_MODE) diagfwd_connect(); success = 1; } return success; }
static int lge_dm_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { short result; #ifdef CONFIG_DIAGFWD_BRIDGE_CODE short modem_number = Secondary_modem_chip; #else short modem_number = Primary_modem_chip; #endif /*CONFIG_DIAGFWD_BRIDGE_CODE*/ struct dm_tty *lge_dm_tty_drv = NULL; int status = 0; /* */ int i; int index=MODEM_DATA; #ifdef CONFIG_DIAGFWD_BRIDGE_CODE unsigned long spin_lock_flags; #endif result = 0; lge_dm_tty_drv = lge_dm_tty; tty->driver_data = lge_dm_tty_drv; lge_dm_tty_drv->tty_str = tty; if (_IOC_TYPE(cmd) != DM_TTY_IOCTL_MAGIC) return -EINVAL; switch (cmd) { case DM_TTY_MODEM_OPEN_SDM: if(lge_dm_tty_drv->logging_mode == DM_APP_SDM) { pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "already DM_TTY_MODEM_OPEN_SDM\n", __func__); result = TRUE; if (copy_to_user((void *)arg, (const void *)&result, sizeof(result)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "already DM_TTY_MODEM_OPEN_SDM" "result = %d\n", __func__, result); break; } lge_dm_tty_drv->logging_mode = DM_APP_SDM; pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_MODEM_OPEN_SDM\n", __func__); #ifdef CONFIG_DIAGFWD_BRIDGE_CODE if ((diag_bridge[index].usb_connected == 1) && (diag_hsic[index].count_hsic_pool == N_MDM_WRITE)) { spin_lock_irqsave(&diag_hsic[HSIC].hsic_spinlock,spin_lock_flags); diag_hsic[index].count_hsic_pool = 0; spin_unlock_irqrestore(&diag_hsic[HSIC].hsic_spinlock,spin_lock_flags); } diag_hsic[index].num_hsic_buf_tbl_entries = 0; for (i = 0; i < diag_hsic[index].poolsize_hsic_write; i++) { if (diag_hsic[index].hsic_buf_tbl[index].buf) { /* Return the buffer to the pool */ diagmem_free(driver, (unsigned char *) (diag_hsic[index].hsic_buf_tbl[index].buf), POOL_TYPE_HSIC); diag_hsic[index].hsic_buf_tbl[index].buf = 0; } diag_hsic[index].hsic_buf_tbl[index].length = 0; } diagfwd_disconnect_bridge(1); diagfwd_cancel_hsic(REOPEN_HSIC); // QCT 161032 migration - NEED TO CHECK diagfwd_connect_bridge(0); #endif /* CONFIG_DIAGFWD_BRIDGE_CODE */ /* change path to DM APP */ mutex_lock(&driver->diagchar_mutex); driver->logging_mode = DM_APP_MODE; mutex_unlock(&driver->diagchar_mutex); if (modem_number == Primary_modem_chip) { for (i = 0; i < NUM_SMD_DATA_CHANNELS; i++) { driver->smd_data[i].in_busy_1 = 0; driver->smd_data[i].in_busy_2 = 0; /* Poll SMD channels to check for data*/ if (driver->smd_data[i].ch) queue_work(driver->diag_wq, &(driver->smd_data[i]. diag_read_smd_work)); }// end of for loop } else if (modem_number == Secondary_modem_chip) { #ifdef CONFIG_DIAGFWD_BRIDGE_CODE /* Read data from the hsic */ if (diag_hsic[index].hsic_ch) queue_work(diag_bridge[index].wq, &(diag_hsic[index]. diag_read_hsic_work)); #endif /* CONFIG_DIAGFWD_BRIDGE_CODE */ } else { pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_MODEM_OPEN_SDM" "error modem_number = %d\n", __func__, modem_number); } result = TRUE; if (copy_to_user((void *)arg, (const void *)&result, sizeof(result)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_MODEM_OPEN_SDM" "result = %d\n", __func__, result); break; case DM_TTY_MODEM_CLOSE_SDM: lge_dm_tty_drv->logging_mode = DM_APP_ODM; pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_MODEM_CLOSE_SDM, modem_number = %d\n", __func__, modem_number); lge_dm_tty_drv->set_logging = 0; /* change path to USB driver */ mutex_lock(&driver->diagchar_mutex); driver->logging_mode = USB_MODE; mutex_unlock(&driver->diagchar_mutex); if (driver->usb_connected == 0) diagfwd_disconnect(); else diagfwd_connect(); result = TRUE; #ifdef CONFIG_DIAGFWD_BRIDGE_CODE diag_hsic[index].num_hsic_buf_tbl_entries = 0; for (i = 0; i < diag_hsic[index].poolsize_hsic_write; i++) { if (diag_hsic[index].hsic_buf_tbl[index].buf) { /* Return the buffer to the pool */ diagmem_free(driver, (unsigned char *) (diag_hsic[index].hsic_buf_tbl[index].buf), POOL_TYPE_HSIC); diag_hsic[index].hsic_buf_tbl[index].buf = 0; } diag_hsic[index].hsic_buf_tbl[index].length = 0; } diagfwd_cancel_hsic(REOPEN_HSIC); // QCT 161032 migration - NEED TO CHECK diagfwd_connect_bridge(0); #endif if (copy_to_user((void *)arg, (const void *)&result, sizeof(result)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_MODEM_CLOSE_SDM" "result = %d\n", __func__, result); break; case DM_TTY_MODEM_OPEN_ODM: lge_dm_tty_drv->logging_mode = DM_APP_ODM; pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_MODEM_OPEN_ODM\n", __func__); #ifdef CONFIG_DIAGFWD_BRIDGE_CODE if ((diag_bridge[index].usb_connected == 1) && (diag_hsic[index].count_hsic_pool == N_MDM_WRITE)) { spin_lock_irqsave(&diag_hsic[HSIC].hsic_spinlock,spin_lock_flags); diag_hsic[index].count_hsic_pool = 0; spin_unlock_irqrestore(&diag_hsic[HSIC].hsic_spinlock,spin_lock_flags); } diag_hsic[index].num_hsic_buf_tbl_entries = 0; for (i = 0; i < diag_hsic[index].poolsize_hsic_write; i++) { if (diag_hsic[index].hsic_buf_tbl[index].buf) { /* Return the buffer to the pool */ diagmem_free(driver, (unsigned char *) (diag_hsic[index].hsic_buf_tbl[index].buf), POOL_TYPE_HSIC); diag_hsic[index].hsic_buf_tbl[index].buf = 0; } diag_hsic[index].hsic_buf_tbl[index].length = 0; } diagfwd_disconnect_bridge(1); diagfwd_cancel_hsic(REOPEN_HSIC); // QCT 161032 migration - NEED TO CHECK diagfwd_connect_bridge(0); #endif /* CONFIG_DIAGFWD_BRIDGE_CODE */ /* change path to DM DEV */ mutex_lock(&driver->diagchar_mutex); driver->logging_mode = DM_APP_MODE; mutex_unlock(&driver->diagchar_mutex); if (modem_number == Primary_modem_chip) { for (i = 0; i < NUM_SMD_DATA_CHANNELS; i++) { driver->smd_data[i].in_busy_1 = 0; driver->smd_data[i].in_busy_2 = 0; /* Poll SMD channels to check for data*/ if (driver->smd_data[i].ch) queue_work(driver->diag_wq, &(driver->smd_data[i]. diag_read_smd_work)); }// end of for loop } else if (modem_number == Secondary_modem_chip) { #ifdef CONFIG_DIAGFWD_BRIDGE_CODE /* Read data from the hsic */ if (diag_hsic[index].hsic_ch) queue_work(diag_bridge[index].wq, &(diag_hsic[index]. diag_read_hsic_work)); #endif /* CONFIG_DIAGFWD_BRIDGE_CODE */ } else { pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_MODEM_OPEN_ODM" "error modem_number = %d\n", __func__, modem_number); } result = TRUE; if (copy_to_user((void *)arg, (const void *)&result, sizeof(result)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_MODEM_OPEN_ODM" "result = %d\n", __func__, result); break; case DM_TTY_MODEM_CLOSE_ODM: lge_dm_tty_drv->logging_mode = DM_APP_ODM; pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_MODEM_CLOSE_ODM, modem_number = %d\n", __func__, modem_number); lge_dm_tty_drv->set_logging = 0; /* change path to USB driver */ mutex_lock(&driver->diagchar_mutex); driver->logging_mode = USB_MODE; mutex_unlock(&driver->diagchar_mutex); if (driver->usb_connected == 0) diagfwd_disconnect(); else diagfwd_connect(); result = TRUE; #ifdef CONFIG_DIAGFWD_BRIDGE_CODE diag_hsic[index].num_hsic_buf_tbl_entries = 0; for (i = 0; i < diag_hsic[index].poolsize_hsic_write; i++) { if (diag_hsic[index].hsic_buf_tbl[index].buf) { /* Return the buffer to the pool */ diagmem_free(driver, (unsigned char *) (diag_hsic[index].hsic_buf_tbl[index].buf), POOL_TYPE_HSIC); diag_hsic[index].hsic_buf_tbl[index].buf = 0; } diag_hsic[index].hsic_buf_tbl[index].length = 0; } diagfwd_cancel_hsic(REOPEN_HSIC); // QCT 161032 migration - NEED TO CHECK diagfwd_connect_bridge(0); #endif if (copy_to_user((void *)arg, (const void *)&result, sizeof(result)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_MODEM_CLOSE_ODM" "result = %d\n", __func__, result); break; case DM_TTY_MODEM_RESET: // not supported //status = subsys_modem_restart(); result = TRUE; if (copy_to_user((void *)arg, (const void *)&status, sizeof(result)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_MODEM_RESET" "result = %d\n", __func__, result); break; case DM_TTY_MODEM_CRASH: #ifdef CONFIG_DIAG_BRIDGE_CODE status = subsys_modem_restart(); result = TRUE; #else subsystem_restart("modem"); result = TRUE; #endif if (copy_to_user((void *)arg, (const void *)&result, sizeof(result)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_MODEM_CRASH" "result = %d\n", __func__, result); break; case DM_TTY_MODEM_DEBUGGER: /* */ break; default: pr_info(DM_TTY_MODULE_NAME ": %s:" "lge_dm_tty_ioctl error\n", __func__); break; } return 0; }
static int lge_dm_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { short modem_number, result; struct dm_tty *lge_dm_tty_drv = NULL; int status = 0; int is_all_closed, i; result = 0; lge_dm_tty_drv = lge_dm_tty; tty->driver_data = lge_dm_tty_drv; lge_dm_tty_drv->tty_str = tty; if (_IOC_TYPE(cmd) != DM_TTY_IOCTL_MAGIC) return -EINVAL; switch (cmd) { case DM_TTY_MODEM_OPEN: if (copy_from_user((void *)&modem_number, (const void *)arg, sizeof(modem_number)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_MODEM_OPEN modem_number = %d\n", __func__, modem_number); if (lge_dm_tty_drv->is_modem_open[modem_number] == FALSE) lge_dm_tty_drv->is_modem_open[modem_number] = TRUE; else pr_err(DM_TTY_MODULE_NAME ": %s: already open " "modem_number = %d", __func__, modem_number); /* change path to DM APP */ mutex_lock(&driver->diagchar_mutex); driver->logging_mode = DM_APP_MODE; mutex_unlock(&driver->diagchar_mutex); if (modem_number == Primary_modem_chip) { for (i = 0; i < NUM_SMD_DATA_CHANNELS; i++) { driver->smd_data[i].in_busy_1 = 0; driver->smd_data[i].in_busy_2 = 0; /* Poll SMD channels to check for data*/ if (driver->smd_data[i].ch) queue_work(driver->diag_wq, &(driver->smd_data[i]. diag_read_smd_work)); }// end of for loop for (i = 0; i < NUM_SMD_CMD_CHANNELS; i++) { driver->smd_cmd[i].in_busy_1 = 0; driver->smd_cmd[i].in_busy_2 = 0; if (driver->smd_cmd[i].ch) queue_work(driver->diag_wq, &(driver->smd_cmd[i]. diag_read_smd_work)); } } else if (modem_number == Secondary_modem_chip) { //TBD... } else { pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_MODEM_OPEN" "error modem_number = %d\n", __func__, modem_number); } result = lge_dm_tty_drv->is_modem_open[modem_number]; if (copy_to_user((void *)arg, (const void *)&result, sizeof(result)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_MODEM_OPEN" "result = %d\n", __func__, result); break; case DM_TTY_MODEM_CLOSE: if (copy_from_user((void *)&modem_number, (const void *)arg, sizeof(modem_number)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_MODEM_CLOSE modem_number = %d\n", __func__, modem_number); if (modem_number == 0) { /* close all modem chip */ for (i = 0; i < NUM_MODEM_CHIP + 1; i++) lge_dm_tty_drv->is_modem_open[i] = FALSE; result = TRUE; pr_err(DM_TTY_MODULE_NAME ": %s: close all modem chip" , __func__); } else { if (lge_dm_tty_drv->is_modem_open[modem_number] == TRUE) lge_dm_tty_drv->is_modem_open[modem_number] = FALSE; else pr_err(DM_TTY_MODULE_NAME ": %s: " "already closed " "modem_number = %d", __func__, modem_number); /* check all modem chip closed */ is_all_closed = TRUE; for (i = 0; i < NUM_MODEM_CHIP + 1; i++) { if (lge_dm_tty_drv->is_modem_open[i] == TRUE) is_all_closed = FALSE; } result = is_all_closed; } if (result == TRUE) { lge_dm_tty->set_logging = 0; /* change path to USB driver */ mutex_lock(&driver->diagchar_mutex); driver->logging_mode = USB_MODE; mutex_unlock(&driver->diagchar_mutex); if (driver->usb_connected == 0) diagfwd_disconnect(); else diagfwd_connect(); } if (copy_to_user((void *)arg, (const void *)&result, sizeof(result)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_MODEM_CLOSE" "result = %d\n", __func__, result); break; case DM_TTY_MODEM_STATUS: if (copy_from_user((void *)&modem_number, (const void *)arg, sizeof(modem_number)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_MODEM_STATUS modem_number = %d\n", __func__, modem_number); result = lge_dm_tty_drv->is_modem_open[modem_number]; if (copy_to_user((void *)arg, (const void *)&result, sizeof(result)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_MODEM_STATUS" "result = %d\n", __func__, result); break; case DM_TTY_DATA_TO_APP: if (copy_from_user((void *)&modem_number, (const void *)arg, sizeof(modem_number)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_DATA_TO_APP modem_number = %d\n", __func__, modem_number); if (copy_to_user((void *)arg, (const void*)&result, sizeof(result)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_DATA_TO_APP" "result = %d\n", __func__, result); break; case DM_TTY_DATA_TO_USB: if (copy_from_user((void *)&modem_number, (const void *)arg, sizeof(modem_number)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_DATA_TO_USB" "modem_number = %d\n", __func__, modem_number); if (copy_to_user((void *)arg, (const void *)&result, sizeof(result)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_DATA_TO_USB" "result = %d\n", __func__, result); break; case DM_TTY_MODEM_RESET: if (copy_from_user((void *)&modem_number, (const void *)arg, sizeof(modem_number)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_MODEM_RESET" "modem_number = %d\n", __func__, modem_number); status = subsys_modem_restart(); if (copy_to_user((void *)arg, (const void *)&status, sizeof(result)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_MODEM_RESET" "result = %d\n", __func__, result); break; case DM_TTY_MODEM_CRASH: if (copy_from_user((void *)&modem_number, (const void *)arg, sizeof(modem_number)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_MODEM_CRASH" "modem_number = %d\n", __func__, modem_number); #ifdef CONFIG_DIAG_BRIDGE_CODE subsystem_restart("external_modem"); result = TRUE; #else subsystem_restart("modem"); result = TRUE; #endif if (copy_to_user((void *)arg, (const void *)&result, sizeof(result)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_MODEM_CRASH" "result = %d\n", __func__, result); break; default: pr_info(DM_TTY_MODULE_NAME ": %s:" "lge_dm_tty_ioctl error\n", __func__); break; } return 0; }
long diagchar_ioctl(struct file *filp, unsigned int iocmd, unsigned long ioarg) { int i, j, count_entries = 0, temp; int success = -1; void *temp_buf; uint16_t support_list = 0; struct dci_notification_tbl *notify_params; if (iocmd == DIAG_IOCTL_COMMAND_REG) { struct bindpkt_params_per_process *pkt_params = (struct bindpkt_params_per_process *) ioarg; mutex_lock(&driver->diagchar_mutex); for (i = 0; i < diag_max_reg; i++) { if (driver->table[i].process_id == 0) { diag_add_reg(i, pkt_params->params, &success, &count_entries); if (pkt_params->count > count_entries) { pkt_params->params++; } else { mutex_unlock(&driver->diagchar_mutex); return success; } } } if (i < diag_threshold_reg) { /* Increase table size by amount required */ diag_max_reg += pkt_params->count - count_entries; /* Make sure size doesnt go beyond threshold */ if (diag_max_reg > diag_threshold_reg) { diag_max_reg = diag_threshold_reg; pr_info("diag: best case memory allocation\n"); } temp_buf = krealloc(driver->table, diag_max_reg*sizeof(struct diag_master_table), GFP_KERNEL); if (!temp_buf) { diag_max_reg -= pkt_params->count - count_entries; pr_alert("diag: Insufficient memory for reg."); mutex_unlock(&driver->diagchar_mutex); return 0; } else { driver->table = temp_buf; } for (j = i; j < diag_max_reg; j++) { diag_add_reg(j, pkt_params->params, &success, &count_entries); if (pkt_params->count > count_entries) { pkt_params->params++; } else { mutex_unlock(&driver->diagchar_mutex); return success; } } mutex_unlock(&driver->diagchar_mutex); } else { mutex_unlock(&driver->diagchar_mutex); pr_err("Max size reached, Pkt Registration failed for" " Process %d", current->tgid); } success = 0; } else if (iocmd == DIAG_IOCTL_GET_DELAYED_RSP_ID) { struct diagpkt_delay_params *delay_params = (struct diagpkt_delay_params *) ioarg; if ((delay_params->rsp_ptr) && (delay_params->size == sizeof(delayed_rsp_id)) && (delay_params->num_bytes_ptr)) { *((uint16_t *)delay_params->rsp_ptr) = DIAGPKT_NEXT_DELAYED_RSP_ID(delayed_rsp_id); *(delay_params->num_bytes_ptr) = sizeof(delayed_rsp_id); success = 0; } } else if (iocmd == DIAG_IOCTL_DCI_REG) { if (driver->dci_state == DIAG_DCI_NO_REG) return DIAG_DCI_NO_REG; if (driver->num_dci_client >= MAX_DCI_CLIENT) return DIAG_DCI_NO_REG; notify_params = (struct dci_notification_tbl *) ioarg; mutex_lock(&driver->dci_mutex); driver->num_dci_client++; pr_debug("diag: id = %d\n", driver->dci_client_id); driver->dci_client_id++; for (i = 0; i < MAX_DCI_CLIENT; i++) { if (driver->dci_notify_tbl[i].client == NULL) { driver->dci_notify_tbl[i].client = current; driver->dci_notify_tbl[i].list = notify_params->list; driver->dci_notify_tbl[i].signal_type = notify_params->signal_type; break; } } mutex_unlock(&driver->dci_mutex); return driver->dci_client_id; } else if (iocmd == DIAG_IOCTL_DCI_DEINIT) { success = -1; /* Delete this process from DCI table */ mutex_lock(&driver->dci_mutex); for (i = 0; i < dci_max_reg; i++) { if (driver->dci_tbl[i].pid == current->tgid) { pr_debug("diag: delete %d\n", current->tgid); driver->dci_tbl[i].pid = 0; success = i; } } for (i = 0; i < MAX_DCI_CLIENT; i++) { if (driver->dci_notify_tbl[i].client == current) { driver->dci_notify_tbl[i].client = NULL; break; } } /* if any registrations were deleted successfully OR a valid client_id was sent in DEINIT call , then its DCI client */ if (success >= 0 || ioarg) driver->num_dci_client--; driver->num_dci_client--; mutex_unlock(&driver->dci_mutex); for (i = 0; i < dci_max_reg; i++) if (driver->dci_tbl[i].pid != 0) pr_debug("diag: PID = %d, UID = %d, tag = %d\n", driver->dci_tbl[i].pid, driver->dci_tbl[i].uid, driver->dci_tbl[i].tag); pr_debug("diag: complete deleting registrations\n"); return success; } else if (iocmd == DIAG_IOCTL_DCI_SUPPORT) { if (driver->ch_dci) support_list = support_list | DIAG_CON_MPSS; *(uint16_t *)ioarg = support_list; return DIAG_DCI_NO_ERROR; } else if (iocmd == DIAG_IOCTL_LSM_DEINIT) { for (i = 0; i < driver->num_clients; i++) if (driver->client_map[i].pid == current->tgid) break; if (i == -1) return -EINVAL; driver->data_ready[i] |= DEINIT_TYPE; wake_up_interruptible(&driver->wait_q); success = 1; } else if (iocmd == DIAG_IOCTL_SWITCH_LOGGING) { mutex_lock(&driver->diagchar_mutex); temp = driver->logging_mode; driver->logging_mode = (int)ioarg; if (driver->logging_mode == MEMORY_DEVICE_MODE) driver->mask_check = 1; if (driver->logging_mode == UART_MODE) { driver->mask_check = 0; driver->logging_mode = MEMORY_DEVICE_MODE; } driver->logging_process_id = current->tgid; mutex_unlock(&driver->diagchar_mutex); if (temp == MEMORY_DEVICE_MODE && driver->logging_mode == NO_LOGGING_MODE) { driver->in_busy_1 = 1; driver->in_busy_2 = 1; driver->in_busy_qdsp_1 = 1; driver->in_busy_qdsp_2 = 1; driver->in_busy_wcnss_1 = 1; driver->in_busy_wcnss_2 = 1; #ifdef CONFIG_DIAG_SDIO_PIPE driver->in_busy_sdio = 1; #endif #ifdef CONFIG_DIAG_BRIDGE_CODE diagfwd_disconnect_bridge(0); #endif } else if (temp == NO_LOGGING_MODE && driver->logging_mode == MEMORY_DEVICE_MODE) { driver->in_busy_1 = 0; driver->in_busy_2 = 0; driver->in_busy_qdsp_1 = 0; driver->in_busy_qdsp_2 = 0; driver->in_busy_wcnss_1 = 0; driver->in_busy_wcnss_2 = 0; /* Poll SMD channels to check for data*/ if (driver->ch) queue_work(driver->diag_wq, &(driver->diag_read_smd_work)); if (driver->chqdsp) queue_work(driver->diag_wq, &(driver->diag_read_smd_qdsp_work)); if (driver->ch_wcnss) queue_work(driver->diag_wq, &(driver->diag_read_smd_wcnss_work)); #ifdef CONFIG_DIAG_SDIO_PIPE driver->in_busy_sdio = 0; /* Poll SDIO channel to check for data */ if (driver->sdio_ch) queue_work(driver->diag_sdio_wq, &(driver->diag_read_sdio_work)); #endif #ifdef CONFIG_DIAG_BRIDGE_CODE diagfwd_connect_bridge(0); #endif } #ifdef CONFIG_DIAG_OVER_USB else if (temp == USB_MODE && driver->logging_mode == NO_LOGGING_MODE) { diagfwd_disconnect(); #ifdef CONFIG_DIAG_BRIDGE_CODE diagfwd_disconnect_bridge(0); #endif } else if (temp == NO_LOGGING_MODE && driver->logging_mode == USB_MODE) { diagfwd_connect(); #ifdef CONFIG_DIAG_BRIDGE_CODE diagfwd_connect_bridge(0); #endif } else if (temp == USB_MODE && driver->logging_mode == MEMORY_DEVICE_MODE) { diagfwd_disconnect(); driver->in_busy_1 = 0; driver->in_busy_2 = 0; driver->in_busy_qdsp_1 = 0; driver->in_busy_qdsp_2 = 0; driver->in_busy_wcnss_1 = 0; driver->in_busy_wcnss_2 = 0; /* Poll SMD channels to check for data*/ if (driver->ch) queue_work(driver->diag_wq, &(driver->diag_read_smd_work)); if (driver->chqdsp) queue_work(driver->diag_wq, &(driver->diag_read_smd_qdsp_work)); if (driver->ch_wcnss) queue_work(driver->diag_wq, &(driver->diag_read_smd_wcnss_work)); #ifdef CONFIG_DIAG_SDIO_PIPE driver->in_busy_sdio = 0; /* Poll SDIO channel to check for data */ if (driver->sdio_ch) queue_work(driver->diag_sdio_wq, &(driver->diag_read_sdio_work)); #endif #ifdef CONFIG_DIAG_BRIDGE_CODE diagfwd_cancel_hsic(); diagfwd_connect_bridge(0); #endif } else if (temp == MEMORY_DEVICE_MODE && driver->logging_mode == USB_MODE) { diagfwd_connect(); #ifdef CONFIG_DIAG_BRIDGE_CODE diagfwd_cancel_hsic(); diagfwd_connect_bridge(0); #endif } #endif /* DIAG over USB */ success = 1; } return success; }
static int diagchar_ioctl(struct inode *inode, struct file *filp, unsigned int iocmd, unsigned long ioarg) { int i, j, count_entries = 0, temp; int success = -1; if (iocmd == DIAG_IOCTL_COMMAND_REG) { struct bindpkt_params_per_process *pkt_params = (struct bindpkt_params_per_process *) ioarg; for (i = 0; i < diag_max_registration; i++) { if (driver->table[i].process_id == 0) { success = 1; driver->table[i].cmd_code = pkt_params->params->cmd_code; driver->table[i].subsys_id = pkt_params->params->subsys_id; driver->table[i].cmd_code_lo = pkt_params->params->cmd_code_hi; driver->table[i].cmd_code_hi = pkt_params->params->cmd_code_lo; driver->table[i].process_id = current->tgid; count_entries++; if (pkt_params->count > count_entries) pkt_params->params++; else return success; } } if (i < diag_threshold_registration) { /* Increase table size by amount required */ diag_max_registration += pkt_params->count - count_entries; /* Make sure size doesnt go beyond threshold */ if (diag_max_registration > diag_threshold_registration) diag_max_registration = diag_threshold_registration; driver->table = krealloc(driver->table, diag_max_registration*sizeof(struct diag_master_table), GFP_KERNEL); for (j = i; j < diag_max_registration; j++) { success = 1; driver->table[j].cmd_code = pkt_params-> params->cmd_code; driver->table[j].subsys_id = pkt_params-> params->subsys_id; driver->table[j].cmd_code_lo = pkt_params-> params->cmd_code_hi; driver->table[j].cmd_code_hi = pkt_params-> params->cmd_code_lo; driver->table[j].process_id = current->tgid; count_entries++; if (pkt_params->count > count_entries) pkt_params->params++; else return success; } } else pr_err("Max size reached, Pkt Registration failed for" " Process %d", current->tgid); success = 0; } else if (iocmd == DIAG_IOCTL_GET_DELAYED_RSP_ID) { struct diagpkt_delay_params *delay_params = (struct diagpkt_delay_params *) ioarg; if ((delay_params->rsp_ptr) && (delay_params->size == sizeof(delayed_rsp_id)) && (delay_params->num_bytes_ptr)) { *((uint16_t *)delay_params->rsp_ptr) = DIAGPKT_NEXT_DELAYED_RSP_ID(delayed_rsp_id); *(delay_params->num_bytes_ptr) = sizeof(delayed_rsp_id); success = 0; } } else if (iocmd == DIAG_IOCTL_LSM_DEINIT) { for (i = 0; i < driver->num_clients; i++) if (driver->client_map[i] == current->tgid) break; if (i == -1) return -EINVAL; driver->data_ready[i] |= DEINIT_TYPE; wake_up_interruptible(&driver->wait_q); success = 1; } else if (iocmd == DIAG_IOCTL_SWITCH_LOGGING) { mutex_lock(&driver->diagchar_mutex); temp = driver->logging_mode; driver->logging_mode = (int)ioarg; driver->logging_process_id = current->tgid; mutex_unlock(&driver->diagchar_mutex); if (temp == USB_MODE && driver->logging_mode == NO_LOGGING_MODE) diagfwd_disconnect(); else if (temp == NO_LOGGING_MODE && driver->logging_mode == USB_MODE) diagfwd_connect(); else if (temp == MEMORY_DEVICE_MODE && driver->logging_mode == NO_LOGGING_MODE) { driver->in_busy = 1; driver->in_busy_qdsp = 1; } else if (temp == NO_LOGGING_MODE && driver->logging_mode == MEMORY_DEVICE_MODE) { driver->in_busy = 0; driver->in_busy_qdsp = 0; /* Poll SMD channels to check for data*/ if (driver->ch) queue_work(driver->diag_wq, &(driver->diag_read_smd_work)); if (driver->chqdsp) queue_work(driver->diag_wq, &(driver->diag_read_smd_qdsp_work)); } else if (temp == USB_MODE && driver->logging_mode == MEMORY_DEVICE_MODE) { diagfwd_disconnect(); driver->in_busy = 0; driver->in_busy_qdsp = 0; /* Poll SMD channels to check for data*/ if (driver->ch) queue_work(driver->diag_wq, &(driver->diag_read_smd_work)); if (driver->chqdsp) queue_work(driver->diag_wq, &(driver->diag_read_smd_qdsp_work)); } else if (temp == MEMORY_DEVICE_MODE && driver->logging_mode == USB_MODE) diagfwd_connect(); success = 1; } #ifdef CONFIG_FIH_FXX #if SD_CARD_DOWNLOAD else if (iocmd == DIAG_IOCTL_WRITE_BUFFER) { struct diagpkt_ioctl_param pkt; uint8_t *pBuf = NULL; if (copy_from_user(&pkt, (void __user *)ioarg, sizeof(pkt))) { return -EFAULT; } if ((pBuf = kzalloc(4096, GFP_KERNEL)) == NULL) return -EFAULT; memcpy(pBuf, pkt.pPacket, pkt.Len); //print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 1, pBuf, pkt.Len, 0); diag_write_to_smd(pBuf, pkt.Len); kfree(pBuf); return 0; } else if (iocmd == DIAG_IOCTL_READ_BUFFER) { struct diagpkt_ioctl_param pkt; struct diagpkt_ioctl_param *ppkt; uint8_t *pBuf = NULL; if (copy_from_user(&pkt, (void __user *)ioarg, sizeof(pkt))) { return -EFAULT; } if ((pBuf = kzalloc(4096, GFP_KERNEL)) == NULL) return -EFAULT; ppkt = (struct diagpkt_ioctl_param *)ioarg; //printk("%s: ppkt->pPacket %p ioarg 0x%lx pkt.pPacket %p \n", __func__, ppkt->pPacket, ioarg, pkt.pPacket); if (diag_read_from_smd(pBuf, &(pkt.Len)) < 0) { kfree(pBuf); return -EFAULT; } //printk("pkt.Len =%d\n", pkt.Len); if (copy_to_user((void __user *) &ppkt->Len, &pkt.Len, sizeof(pkt.Len))) { kfree(pBuf); return -EFAULT; } if (copy_to_user((void __user *) pkt.pPacket, pBuf, pkt.Len)) { kfree(pBuf); return -EFAULT; } kfree(pBuf); return 0; } else if (iocmd == DIAG_IOCTL_PASS_FIRMWARE_LIST) { FirmwareList FL; FirmwareList * pFL = NULL; int size; if (copy_from_user(&FL, (void __user *)ioarg, sizeof(FL))) { return -EFAULT; } printk("update flag 0x%X\n",FL.iFLAG); printk("image %s\n",FL.pCOMBINED_IMAGE); printk("0x%08X 0x%08X\n", FL.aARMPRG_BIN[0], FL.aARMPRG_BIN[1]); printk("0x%08X 0x%08X\n", FL.aPARTITION[0], FL.aPARTITION[1]); printk("0x%08X 0x%08X\n", FL.aANDROID_BOOT[0], FL.aANDROID_BOOT[1]); // Fill smem_mem_type proc_comm_alloc_sd_dl_smem(0); size = sizeof(FirmwareList); //pFL = smem_get_entry(SMEM_SD_IMG_UPGRADE_STATUS, &size); pFL = smem_alloc(SMEM_SD_IMG_UPGRADE_STATUS, size); //printk("pFL 0x%08X 0x%08X\n", (uint32_t)pFL, size); if (pFL == NULL) return -EFAULT; memcpy(pFL, &FL, sizeof(FirmwareList)); print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET,16, 1, pFL, size, 0); printk("\nARMPRGBIN 0x%08X 0x%08X\n", pFL->aARMPRG_BIN[0], pFL->aARMPRG_BIN[1]); printk("0x%08X 0x%08X\n", pFL->aPARTITION[0], pFL->aPARTITION[1]); printk("0x%08X 0x%08X\n", pFL->aANDROID_BOOT[0], pFL->aANDROID_BOOT[1]); // Notify modem to write firmware list to NAND flash if (proc_comm_alloc_sd_dl_smem(1)) return -EFAULT; return 0; } else if (iocmd == DIAG_IOCTL_GET_PART_TABLE_FROM_SMEM) { struct flash_partition_table *partition_table; //struct flash_partition_entry *part_entry; //struct mtd_partition *ptn = msm_nand_partitions; //char *name = msm_nand_names; //int part; partition_table = (struct flash_partition_table *) smem_alloc(SMEM_AARM_PARTITION_TABLE, sizeof(struct flash_partition_table)); if (!partition_table) { printk(KERN_WARNING "%s: no flash partition table in shared " "memory\n", __func__); return -ENOENT; } if ((partition_table->magic1 != (u32) FLASH_PART_MAGIC1) || (partition_table->magic2 != (u32) FLASH_PART_MAGIC2) || (partition_table->version != (u32) FLASH_PARTITION_VERSION)) { printk(KERN_WARNING "%s: version mismatch -- magic1=%#x, " "magic2=%#x, version=%#x\n", __func__, partition_table->magic1, partition_table->magic2, partition_table->version); return -EFAULT; } if (copy_to_user((void __user *) ioarg, partition_table, sizeof(struct flash_partition_table))) { return -EFAULT; } return 0; } #endif //SD_CARD_DOWNLOAD #endif //CONFIG_FIH_FXX return success; }
static int lge_dm_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { short modem_number, result; struct dm_tty *lge_dm_tty_drv = NULL; int is_all_closed, i; int index=MODEM_DATA; #ifdef CONFIG_DIAGFWD_BRIDGE_CODE unsigned long spin_lock_flags; #endif result = 0; // kyle00.choi, 20130625, WBT 485977 lge_dm_tty_drv = lge_dm_tty; tty->driver_data = lge_dm_tty_drv; lge_dm_tty_drv->tty_str = tty; if (_IOC_TYPE(cmd) != DM_TTY_IOCTL_MAGIC) return -EINVAL; switch (cmd) { case DM_TTY_MODEM_OPEN: if (copy_from_user((void *)&modem_number, (const void *)arg, sizeof(modem_number)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_MODEM_OPEN modem_number = %d\n", __func__, modem_number); if (lge_dm_tty_drv->is_modem_open[modem_number] == FALSE) lge_dm_tty_drv->is_modem_open[modem_number] = TRUE; else pr_err(DM_TTY_MODULE_NAME ": %s: already open " "modem_number = %d", __func__, modem_number); #ifdef CONFIG_DIAGFWD_BRIDGE_CODE if ((diag_bridge[index].usb_connected == 1) && (diag_hsic[index].count_hsic_pool == N_MDM_WRITE)) { spin_lock_irqsave(&diag_hsic[HSIC].hsic_spinlock,spin_lock_flags); diag_hsic[index].count_hsic_pool = 0; spin_unlock_irqrestore(&diag_hsic[HSIC].hsic_spinlock,spin_lock_flags); } diag_hsic[index].num_hsic_buf_tbl_entries = 0; for (i = 0; i < diag_hsic[index].poolsize_hsic_write; i++) { if (diag_hsic[index].hsic_buf_tbl[index].buf) { /* Return the buffer to the pool */ diagmem_free(driver, (unsigned char *) (diag_hsic[index].hsic_buf_tbl[index].buf), POOL_TYPE_HSIC); diag_hsic[index].hsic_buf_tbl[index].buf = 0; } diag_hsic[index].hsic_buf_tbl[index].length = 0; } diagfwd_disconnect_bridge(1); diagfwd_cancel_hsic(REOPEN_HSIC); // QCT 161032 migration - NEED TO CHECK diagfwd_connect_bridge(0); #endif /* CONFIG_DIAGFWD_BRIDGE_CODE */ /* change path to DM APP */ mutex_lock(&driver->diagchar_mutex); driver->logging_mode = DM_APP_MODE; mutex_unlock(&driver->diagchar_mutex); if (modem_number == Primary_modem_chip) { for (i = 0; i < NUM_SMD_DATA_CHANNELS; i++) { driver->smd_data[i].in_busy_1 = 0; driver->smd_data[i].in_busy_2 = 0; /* Poll SMD channels to check for data*/ if (driver->smd_data[i].ch) queue_work(driver->diag_wq, &(driver->smd_data[i]. diag_read_smd_work)); }// end of for loop } else if (modem_number == Secondary_modem_chip) { #ifdef CONFIG_DIAGFWD_BRIDGE_CODE /* Read data from the hsic */ if (diag_hsic[index].hsic_ch) queue_work(diag_bridge[index].wq, &(diag_hsic[index]. diag_read_hsic_work)); #endif /* CONFIG_DIAGFWD_BRIDGE_CODE */ } else { pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_MODEM_OPEN" "error modem_number = %d\n", __func__, modem_number); } result = lge_dm_tty_drv->is_modem_open[modem_number]; if (copy_to_user((void *)arg, (const void *)&result, sizeof(result)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_MODEM_OPEN" "result = %d\n", __func__, result); break; case DM_TTY_MODEM_CLOSE: if (copy_from_user((void *)&modem_number, (const void *)arg, sizeof(modem_number)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_MODEM_CLOSE modem_number = %d\n", __func__, modem_number); if (modem_number == 0) { /* close all modem chip */ for (i = 0; i < NUM_MODEM_CHIP + 1; i++) lge_dm_tty_drv->is_modem_open[i] = FALSE; result = TRUE; pr_err(DM_TTY_MODULE_NAME ": %s: close all modem chip" , __func__); } else { if (lge_dm_tty_drv->is_modem_open[modem_number] == TRUE) lge_dm_tty_drv->is_modem_open[modem_number] = FALSE; else pr_err(DM_TTY_MODULE_NAME ": %s: " "already closed " "modem_number = %d", __func__, modem_number); /* check all modem chip closed */ is_all_closed = TRUE; for (i = 0; i < NUM_MODEM_CHIP + 1; i++) { if (lge_dm_tty_drv->is_modem_open[i] == TRUE) is_all_closed = FALSE; } result = is_all_closed; } if (result == TRUE) { lge_dm_tty->set_logging = 0; /* change path to USB driver */ mutex_lock(&driver->diagchar_mutex); driver->logging_mode = USB_MODE; mutex_unlock(&driver->diagchar_mutex); if (driver->usb_connected == 0) diagfwd_disconnect(); else diagfwd_connect(); #ifdef CONFIG_DIAGFWD_BRIDGE_CODE diag_hsic[index].num_hsic_buf_tbl_entries = 0; for (i = 0; i < diag_hsic[index].poolsize_hsic_write; i++) { if (diag_hsic[index].hsic_buf_tbl[index].buf) { /* Return the buffer to the pool */ diagmem_free(driver, (unsigned char *) (diag_hsic[index].hsic_buf_tbl[index].buf), POOL_TYPE_HSIC); diag_hsic[index].hsic_buf_tbl[index].buf = 0; } diag_hsic[index].hsic_buf_tbl[index].length = 0; } diagfwd_cancel_hsic(REOPEN_HSIC); // QCT 161032 migration - NEED TO CHECK diagfwd_connect_bridge(0); #endif } if (copy_to_user((void *)arg, (const void *)&result, sizeof(result)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_MODEM_CLOSE" "result = %d\n", __func__, result); break; case DM_TTY_MODEM_STATUS: if (copy_from_user((void *)&modem_number, (const void *)arg, sizeof(modem_number)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_MODEM_STATUS modem_number = %d\n", __func__, modem_number); result = lge_dm_tty_drv->is_modem_open[modem_number]; if (copy_to_user((void *)arg, (const void *)&result, sizeof(result)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_MODEM_STATUS" "result = %d\n", __func__, result); break; case DM_TTY_DATA_TO_APP: if (copy_from_user((void *)&modem_number, (const void *)arg, sizeof(modem_number)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_DATA_TO_APP modem_number = %d\n", __func__, modem_number); if (copy_to_user((void *)arg, (const void*)&result, sizeof(result)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_DATA_TO_APP" "result = %d\n", __func__, result); break; case DM_TTY_DATA_TO_USB: if (copy_from_user((void *)&modem_number, (const void *)arg, sizeof(modem_number)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_DATA_TO_USB" "modem_number = %d\n", __func__, modem_number); if (copy_to_user((void *)arg, (const void *)&result, sizeof(result)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_DATA_TO_USB" "result = %d\n", __func__, result); break; default: pr_info(DM_TTY_MODULE_NAME ": %s:" "lge_dm_tty_ioctl error\n", __func__); break; } return 0; }
static int lge_dm_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { short result; short modem_number = Primary_modem_chip; struct dm_tty *lge_dm_tty_drv = NULL; int status, i = 0; char rw_buf[300]; unsigned long flags; result = 0; lge_dm_tty_drv = lge_dm_tty; tty->driver_data = lge_dm_tty_drv; lge_dm_tty_drv->tty_str = tty; if (_IOC_TYPE(cmd) != DM_TTY_IOCTL_MAGIC) return -EINVAL; switch (cmd) { case DM_TTY_MODEM_OPEN_SDM: if(lge_dm_tty_drv->logging_mode == DM_APP_SDM) { pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "already DM_TTY_MODEM_OPEN_SDM\n", __func__); result = TRUE; if (copy_to_user((void *)arg, (const void *)&result, sizeof(result)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "already DM_TTY_MODEM_OPEN_SDM" "result = %d\n", __func__, result); break; } lge_dm_tty_drv->logging_mode = DM_APP_SDM; pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_MODEM_OPEN_SDM\n", __func__); /* change path to DM APP */ mutex_lock(&driver->diagchar_mutex); driver->logging_mode = DM_APP_MODE; mutex_unlock(&driver->diagchar_mutex); if (modem_number == Primary_modem_chip) { for (i = 0; i < NUM_SMD_DATA_CHANNELS; i++) { spin_lock_irqsave(&driver->smd_data[i].in_busy_lock, flags); driver->smd_data[i].in_busy_1 = 0; driver->smd_data[i].in_busy_2 = 0; spin_unlock_irqrestore(&driver->smd_data[i].in_busy_lock, flags); /* Poll SMD channels to check for data*/ if (driver->smd_data[i].ch) queue_work(driver->diag_wq, &(driver->smd_data[i]. diag_read_smd_work)); } for (i = 0; i < NUM_SMD_CMD_CHANNELS; i++) { spin_lock_irqsave(&driver->smd_cmd[i].in_busy_lock, flags); driver->smd_cmd[i].in_busy_1 = 0; driver->smd_cmd[i].in_busy_2 = 0; spin_unlock_irqrestore(&driver->smd_cmd[i].in_busy_lock, flags); if (driver->smd_cmd[i].ch) queue_work(driver->diag_wq, &(driver->smd_cmd[i]. diag_read_smd_work)); } } else if (modem_number == Secondary_modem_chip) { //TBD... } else { pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_MODEM_OPEN_SDM" "error modem_number = %d\n", __func__, modem_number); } result = TRUE; if (copy_to_user((void *)arg, (const void *)&result, sizeof(result)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_MODEM_OPEN_SDM" "result = %d\n", __func__, result); break; case DM_TTY_MODEM_CLOSE_SDM: lge_dm_tty_drv->logging_mode = DM_APP_ODM; pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_MODEM_CLOSE_SDM\n", __func__); lge_dm_tty_drv->set_logging = 0; /* change path to USB driver */ mutex_lock(&driver->diagchar_mutex); driver->logging_mode = USB_MODE; mutex_unlock(&driver->diagchar_mutex); if (driver->usb_connected == 0) diagfwd_disconnect(); else diagfwd_connect(); diag_ws_reset(); result = TRUE; if (copy_to_user((void *)arg, (const void *)&result, sizeof(result)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_MODEM_CLOSE_SDM" "result = %d\n", __func__, result); break; case DM_TTY_MODEM_OPEN_ODM: lge_dm_tty_drv->logging_mode = DM_APP_ODM; pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_MODEM_OPEN_ODM\n", __func__); /* change path to DM DEV */ mutex_lock(&driver->diagchar_mutex); driver->logging_mode = DM_APP_MODE; mutex_unlock(&driver->diagchar_mutex); for (i = 0; i < NUM_SMD_DATA_CHANNELS; i++) { spin_lock_irqsave(&driver->smd_data[i].in_busy_lock, flags); driver->smd_data[i].in_busy_1 = 0; driver->smd_data[i].in_busy_2 = 0; spin_unlock_irqrestore(&driver->smd_data[i].in_busy_lock, flags); /* Poll SMD channels to check for data*/ if (driver->smd_data[i].ch) queue_work(driver->diag_wq, &(driver->smd_data[i]. diag_read_smd_work)); } break; case DM_TTY_MODEM_CLOSE_ODM: lge_dm_tty_drv->logging_mode = DM_APP_ODM; pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_MODEM_CLOSE_ODM\n", __func__); lge_dm_tty_drv->set_logging = 0; /* change path to USB driver */ mutex_lock(&driver->diagchar_mutex); driver->logging_mode = USB_MODE; mutex_unlock(&driver->diagchar_mutex); if (driver->usb_connected == 0) diagfwd_disconnect(); else diagfwd_connect(); diag_ws_reset(); break; case DM_TTY_MODEM_RESET: status = subsys_modem_restart(); result = TRUE; if (copy_to_user((void *)arg, (const void *)&status, sizeof(result)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_MODEM_RESET" "result = %d\n", __func__, result); break; case DM_TTY_MODEM_CRASH: #ifdef CONFIG_DIAG_BRIDGE_CODE subsystem_restart("external_modem"); result = TRUE; #else subsystem_restart("modem"); result = TRUE; #endif if (copy_to_user((void *)arg, (const void *)&result, sizeof(result)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_MODEM_CRASH" "result = %d\n", __func__, result); break; case DM_TTY_MODEM_DEBUGGER: // memset(rw_buf, 0, sizeof(rw_buf)); strcpy(rw_buf,ssr_noti); if (copy_to_user((void *)arg, &rw_buf, sizeof(rw_buf))){ pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_MODEM_DEBUGGER error! " "rw_buf = %s\n", __func__, rw_buf); return -EFAULT; } printk("rw_buf = %s\n", rw_buf); break; default: pr_info(DM_TTY_MODULE_NAME ": %s:" "lge_dm_tty_ioctl error\n", __func__); break; } return 0; }
static int lge_dm_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { short modem_number, result; struct dm_tty *lge_dm_tty_drv = NULL; int is_all_closed, i; lge_dm_tty_drv = lge_dm_tty; tty->driver_data = lge_dm_tty_drv; lge_dm_tty_drv->tty_str = tty; if (_IOC_TYPE(cmd) != DM_TTY_IOCTL_MAGIC) return -EINVAL; switch (cmd) { case DM_TTY_MODEM_OPEN: if (copy_from_user((void *)&modem_number, (const void *)arg, sizeof(modem_number)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_MODEM_OPEN modem_number = %d\n", __func__, modem_number); if (lge_dm_tty_drv->is_modem_open[modem_number] == FALSE) lge_dm_tty_drv->is_modem_open[modem_number] = TRUE; else pr_err(DM_TTY_MODULE_NAME ": %s: already open " "modem_number = %d", __func__, modem_number); diagfwd_disconnect(); #ifdef CONFIG_DIAG_HSIC_PIPE diagfwd_disconnect_hsic(1); diagfwd_cancel_hsic(); diagfwd_connect_hsic(0); #endif /* change path to DM APP */ mutex_lock(&driver->diagchar_mutex); driver->logging_mode = DM_APP_MODE; mutex_unlock(&driver->diagchar_mutex); if (modem_number == Primary_modem_chip) { driver->in_busy_1 = 0; driver->in_busy_2 = 0; driver->in_busy_qdsp_1 = 0; driver->in_busy_qdsp_2 = 0; driver->in_busy_wcnss_1 = 0; driver->in_busy_wcnss_2 = 0; /* Poll SMD channels to check for data*/ if (driver->ch) queue_work(driver->diag_wq, &(driver->diag_read_smd_work)); if (driver->chqdsp) queue_work(driver->diag_wq, &(driver->diag_read_smd_qdsp_work)); if (driver->ch_wcnss) queue_work(driver->diag_wq, &(driver->diag_read_smd_wcnss_work)); } else if (modem_number == Secondary_modem_chip) { #ifdef CONFIG_DIAG_SDIO_PIPE driver->in_busy_sdio = 0; /* Poll SDIO channel to check for data */ if (driver->sdio_ch) queue_work(driver->diag_sdio_wq, &(driver->diag_read_sdio_work)); #endif #ifdef CONFIG_DIAG_HSIC_PIPE driver->num_hsic_buf_tbl_entries = 0; for (i = 0; i < driver->poolsize_hsic_write; i++) { driver->hsic_buf_tbl[i].buf = 0; driver->hsic_buf_tbl[i].length = 0; } #endif } else { pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_MODEM_OPEN" "error modem_number = %d\n", __func__, modem_number); } result = lge_dm_tty_drv->is_modem_open[modem_number]; if (copy_to_user((void *)arg, (const void *)&result, sizeof(result)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_MODEM_OPEN" "result = %d\n", __func__, result); break; case DM_TTY_MODEM_CLOSE: if (copy_from_user((void *)&modem_number, (const void *)arg, sizeof(modem_number)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_MODEM_CLOSE modem_number = %d\n", __func__, modem_number); if (modem_number == 0) { /* close all modem chip */ for (i = 0; i < NUM_MODEM_CHIP + 1; i++) lge_dm_tty_drv->is_modem_open[i] = FALSE; result = TRUE; pr_err(DM_TTY_MODULE_NAME ": %s: close all modem chip" , __func__); } else { if (lge_dm_tty_drv->is_modem_open[modem_number] == TRUE) lge_dm_tty_drv->is_modem_open[modem_number] = FALSE; else pr_err(DM_TTY_MODULE_NAME ": %s: " "already closed " "modem_number = %d", __func__, modem_number); /* check all modem chip closed */ is_all_closed = TRUE; for (i = 0; i < NUM_MODEM_CHIP + 1; i++) { if (lge_dm_tty_drv->is_modem_open[i] == TRUE) is_all_closed = FALSE; } result = is_all_closed; } if (result == TRUE) { lge_dm_tty->set_logging = 0; /* change path to USB driver */ mutex_lock(&driver->diagchar_mutex); driver->logging_mode = USB_MODE; mutex_unlock(&driver->diagchar_mutex); if (driver->usb_connected == 0) diagfwd_disconnect(); else diagfwd_connect(); #ifdef CONFIG_DIAG_HSIC_PIPE driver->num_hsic_buf_tbl_entries = 0; for (i = 0; i < driver->poolsize_hsic_write; i++) { if (driver->hsic_buf_tbl[i].buf) { /* Return the buffer to the pool */ diagmem_free(driver, (unsigned char *) (driver->hsic_buf_tbl[i].buf), POOL_TYPE_HSIC); driver->hsic_buf_tbl[i].buf = 0; driver->hsic_buf_tbl[i].length = 0; } } if (driver->usb_mdm_connected == 0) diagfwd_disconnect_hsic(0); else diagfwd_connect_hsic(0); #endif } if (copy_to_user((void *)arg, (const void *)&result, sizeof(result)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_MODEM_CLOSE" "result = %d\n", __func__, result); break; case DM_TTY_MODEM_STATUS: if (copy_from_user((void *)&modem_number, (const void *)arg, sizeof(modem_number)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_MODEM_STATUS modem_number = %d\n", __func__, modem_number); result = lge_dm_tty_drv->is_modem_open[modem_number]; if (copy_to_user((void *)arg, (const void *)&result, sizeof(result)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_MODEM_STATUS" "result = %d\n", __func__, result); break; case DM_TTY_DATA_TO_APP: if (copy_from_user((void *)&modem_number, (const void *)arg, sizeof(modem_number)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_DATA_TO_APP modem_number = %d\n", __func__, modem_number); if (copy_to_user((void *)arg, (const void*)&result, sizeof(result)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_DATA_TO_APP" "result = %d\n", __func__, result); break; case DM_TTY_DATA_TO_USB: if (copy_from_user((void *)&modem_number, (const void *)arg, sizeof(modem_number)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_DATA_TO_USB" "modem_number = %d\n", __func__, modem_number); if (copy_to_user((void *)arg, (const void *)&result, sizeof(result)) == 0) pr_info(DM_TTY_MODULE_NAME ": %s: lge_dm_tty_ioctl " "DM_TTY_IOCTL_DATA_TO_USB" "result = %d\n", __func__, result); break; default: pr_info(DM_TTY_MODULE_NAME ": %s:" "lge_dm_tty_ioctl error\n", __func__); break; } return 0; }
long diagchar_ioctl(struct file *filp, unsigned int iocmd, unsigned long ioarg) { int i, j, temp, success = -1, status; unsigned int count_entries = 0, interim_count = 0; void *temp_buf; uint16_t support_list = 0; struct dci_notification_tbl *dci_params; if (iocmd == DIAG_IOCTL_COMMAND_REG) { struct bindpkt_params_per_process pkt_params; struct bindpkt_params *params; struct bindpkt_params *head_params; if (copy_from_user(&pkt_params, (void *)ioarg, sizeof(struct bindpkt_params_per_process))) { return -EFAULT; } if ((UINT32_MAX/sizeof(struct bindpkt_params)) < pkt_params.count) { pr_warning("diag: integer overflow while multiply\n"); return -EFAULT; } params = kzalloc(pkt_params.count*sizeof( struct bindpkt_params), GFP_KERNEL); if (!params) { pr_err("diag: unable to alloc memory\n"); return -ENOMEM; } else head_params = params; if (copy_from_user(params, pkt_params.params, pkt_params.count*sizeof(struct bindpkt_params))) { kfree(head_params); return -EFAULT; } mutex_lock(&driver->diagchar_mutex); for (i = 0; i < diag_max_reg; i++) { if (driver->table[i].process_id == 0) { diag_add_reg(i, params, &success, &count_entries); if (pkt_params.count > count_entries) { params++; } else { mutex_unlock(&driver->diagchar_mutex); kfree(head_params); return success; } } } if (i < diag_threshold_reg) { /* Increase table size by amount required */ if (pkt_params.count >= count_entries) { interim_count = pkt_params.count - count_entries; } else { pr_warning("diag: error in params count\n"); kfree(head_params); mutex_unlock(&driver->diagchar_mutex); return -EFAULT; } if (UINT32_MAX - diag_max_reg >= interim_count) { diag_max_reg += interim_count; } else { pr_warning("diag: Integer overflow\n"); kfree(head_params); mutex_unlock(&driver->diagchar_mutex); return -EFAULT; } /* Make sure size doesnt go beyond threshold */ if (diag_max_reg > diag_threshold_reg) { diag_max_reg = diag_threshold_reg; pr_info("diag: best case memory allocation\n"); } if (UINT32_MAX/sizeof(struct diag_master_table) < diag_max_reg) { pr_warning("diag: integer overflow\n"); kfree(head_params); mutex_unlock(&driver->diagchar_mutex); return -EFAULT; } temp_buf = krealloc(driver->table, diag_max_reg*sizeof(struct diag_master_table), GFP_KERNEL); if (!temp_buf) { pr_alert("diag: Insufficient memory for reg.\n"); mutex_unlock(&driver->diagchar_mutex); if (pkt_params.count >= count_entries) { interim_count = pkt_params.count - count_entries; } else { pr_warning("diag: params count error\n"); mutex_unlock(&driver->diagchar_mutex); kfree(head_params); return -EFAULT; } if (diag_max_reg >= interim_count) { diag_max_reg -= interim_count; } else { pr_warning("diag: Integer underflow\n"); mutex_unlock(&driver->diagchar_mutex); kfree(head_params); return -EFAULT; } kfree(head_params); return 0; } else { driver->table = temp_buf; } for (j = i; j < diag_max_reg; j++) { diag_add_reg(j, params, &success, &count_entries); if (pkt_params.count > count_entries) { params++; } else { mutex_unlock(&driver->diagchar_mutex); kfree(head_params); return success; } } kfree(head_params); mutex_unlock(&driver->diagchar_mutex); } else { mutex_unlock(&driver->diagchar_mutex); kfree(head_params); pr_err("Max size reached, Pkt Registration failed for" " Process %d", current->tgid); } success = 0; } else if (iocmd == DIAG_IOCTL_GET_DELAYED_RSP_ID) { struct diagpkt_delay_params delay_params; uint16_t interim_rsp_id; int interim_size; if (copy_from_user(&delay_params, (void *)ioarg, sizeof(struct diagpkt_delay_params))) return -EFAULT; if ((delay_params.rsp_ptr) && (delay_params.size == sizeof(delayed_rsp_id)) && (delay_params.num_bytes_ptr)) { interim_rsp_id = DIAGPKT_NEXT_DELAYED_RSP_ID( delayed_rsp_id); if (copy_to_user((void *)delay_params.rsp_ptr, &interim_rsp_id, sizeof(uint16_t))) return -EFAULT; interim_size = sizeof(delayed_rsp_id); if (copy_to_user((void *)delay_params.num_bytes_ptr, &interim_size, sizeof(int))) return -EFAULT; success = 0; } } else if (iocmd == DIAG_IOCTL_DCI_REG) { if (driver->dci_state == DIAG_DCI_NO_REG) return DIAG_DCI_NO_REG; if (driver->num_dci_client >= MAX_DCI_CLIENT) return DIAG_DCI_NO_REG; dci_params = kzalloc(sizeof(struct dci_notification_tbl), GFP_KERNEL); if (dci_params == NULL) { pr_err("diag: unable to alloc memory\n"); return -ENOMEM; } if (copy_from_user(dci_params, (void *)ioarg, sizeof(struct dci_notification_tbl))) return -EFAULT; mutex_lock(&driver->dci_mutex); driver->num_dci_client++; diag_printk(1,"diag:%s id = %d\n",__func__, driver->dci_client_id); driver->dci_client_id++; for (i = 0; i < MAX_DCI_CLIENT; i++) { if (driver->dci_notify_tbl[i].client == NULL) { driver->dci_notify_tbl[i].client = current; driver->dci_notify_tbl[i].list = dci_params->list; driver->dci_notify_tbl[i].signal_type = dci_params->signal_type; break; } } mutex_unlock(&driver->dci_mutex); kfree(dci_params); return driver->dci_client_id; } else if (iocmd == DIAG_IOCTL_DCI_DEINIT) { success = -1; /* Delete this process from DCI table */ mutex_lock(&driver->dci_mutex); for (i = 0; i < dci_max_reg; i++) { if (driver->dci_tbl[i].pid == current->tgid) { diag_printk(1,"diag:%s delete %d\n",__func__, current->tgid); driver->dci_tbl[i].pid = 0; success = i; } } for (i = 0; i < MAX_DCI_CLIENT; i++) { if (driver->dci_notify_tbl[i].client == current) { driver->dci_notify_tbl[i].client = NULL; break; } } /* if any registrations were deleted successfully OR a valid client_id was sent in DEINIT call , then its DCI client */ if (success >= 0 || ioarg) driver->num_dci_client--; driver->num_dci_client--; mutex_unlock(&driver->dci_mutex); for (i = 0; i < dci_max_reg; i++) if (driver->dci_tbl[i].pid != 0) diag_printk(1,"diag:%s PID = %d, UID = %d, tag = %d\n",__func__, driver->dci_tbl[i].pid, driver->dci_tbl[i].uid, driver->dci_tbl[i].tag); diag_printk(1,"diag:%s complete deleting registrations\n",__func__); return success; } else if (iocmd == DIAG_IOCTL_DCI_SUPPORT) { if (driver->ch_dci) support_list = support_list | DIAG_CON_MPSS; *(uint16_t *)ioarg = support_list; return DIAG_DCI_NO_ERROR; } else if (iocmd == DIAG_IOCTL_LSM_DEINIT) { for (i = 0; i < driver->num_clients; i++) if (driver->client_map[i].pid == current->tgid) break; if (i == -1) return -EINVAL; driver->data_ready[i] |= DEINIT_TYPE; wake_up_interruptible(&driver->wait_q); success = 1; } else if (iocmd == DIAG_IOCTL_SWITCH_LOGGING) { mutex_lock(&driver->diagchar_mutex); temp = driver->logging_mode; driver->logging_mode = (int)ioarg; if (driver->logging_mode == MEMORY_DEVICE_MODE) { diag_clear_hsic_tbl(); driver->mask_check = 1; if (driver->socket_process) { /* * Notify the socket logging process that we * are switching to MEMORY_DEVICE_MODE */ status = send_sig(SIGCONT, driver->socket_process, 0); if (status) { pr_err("diag: %s, Error notifying ", __func__); pr_err("socket process, status: %d\n", status); } } } if (driver->logging_mode == UART_MODE) { diag_clear_hsic_tbl(); driver->mask_check = 0; driver->logging_mode = MEMORY_DEVICE_MODE; } if (driver->logging_mode == SOCKET_MODE) { diag_clear_hsic_tbl(); driver->socket_process = current; driver->mask_check = 0; driver->logging_mode = MEMORY_DEVICE_MODE; } driver->logging_process_id = current->tgid; mutex_unlock(&driver->diagchar_mutex); if (temp == MEMORY_DEVICE_MODE && driver->logging_mode == NO_LOGGING_MODE) { driver->in_busy_1 = 1; driver->in_busy_2 = 1; driver->in_busy_qdsp_1 = 1; driver->in_busy_qdsp_2 = 1; driver->in_busy_wcnss_1 = 1; driver->in_busy_wcnss_2 = 1; #ifdef CONFIG_DIAG_SDIO_PIPE driver->in_busy_sdio = 1; #endif #ifdef CONFIG_DIAG_BRIDGE_CODE diagfwd_disconnect_bridge(0); diag_clear_hsic_tbl(); #endif } else if (temp == NO_LOGGING_MODE && driver->logging_mode == MEMORY_DEVICE_MODE) { driver->in_busy_1 = 0; driver->in_busy_2 = 0; driver->in_busy_qdsp_1 = 0; driver->in_busy_qdsp_2 = 0; driver->in_busy_wcnss_1 = 0; driver->in_busy_wcnss_2 = 0; /* Poll SMD channels to check for data*/ if (driver->ch) queue_work(driver->diag_wq, &(driver->diag_read_smd_work)); if (driver->chqdsp) queue_work(driver->diag_wq, &(driver->diag_read_smd_qdsp_work)); if (driver->ch_wcnss) queue_work(driver->diag_wq, &(driver->diag_read_smd_wcnss_work)); #ifdef CONFIG_DIAG_SDIO_PIPE driver->in_busy_sdio = 0; /* Poll SDIO channel to check for data */ if (driver->sdio_ch) queue_work(driver->diag_sdio_wq, &(driver->diag_read_sdio_work)); #endif #ifdef CONFIG_DIAG_BRIDGE_CODE diagfwd_connect_bridge(0); #endif } #ifdef CONFIG_DIAG_OVER_USB else if (temp == USB_MODE && driver->logging_mode == NO_LOGGING_MODE) { diagfwd_disconnect(); #ifdef CONFIG_DIAG_BRIDGE_CODE diagfwd_disconnect_bridge(0); #endif } else if (temp == NO_LOGGING_MODE && driver->logging_mode == USB_MODE) { diagfwd_connect(); #ifdef CONFIG_DIAG_BRIDGE_CODE diagfwd_connect_bridge(0); #endif } else if (temp == USB_MODE && driver->logging_mode == MEMORY_DEVICE_MODE) { diagfwd_disconnect(); driver->in_busy_1 = 0; driver->in_busy_2 = 0; driver->in_busy_qdsp_1 = 0; driver->in_busy_qdsp_2 = 0; driver->in_busy_wcnss_1 = 0; driver->in_busy_wcnss_2 = 0; /* Poll SMD channels to check for data*/ if (driver->ch) queue_work(driver->diag_wq, &(driver->diag_read_smd_work)); if (driver->chqdsp) queue_work(driver->diag_wq, &(driver->diag_read_smd_qdsp_work)); if (driver->ch_wcnss) queue_work(driver->diag_wq, &(driver->diag_read_smd_wcnss_work)); #ifdef CONFIG_DIAG_SDIO_PIPE driver->in_busy_sdio = 0; /* Poll SDIO channel to check for data */ if (driver->sdio_ch) queue_work(driver->diag_sdio_wq, &(driver->diag_read_sdio_work)); #endif #ifdef CONFIG_DIAG_BRIDGE_CODE diagfwd_cancel_hsic(); diagfwd_connect_bridge(0); #endif } else if (temp == MEMORY_DEVICE_MODE && driver->logging_mode == USB_MODE) { diagfwd_connect(); #ifdef CONFIG_DIAG_BRIDGE_CODE diag_clear_hsic_tbl(); diagfwd_cancel_hsic(); diagfwd_connect_bridge(0); #endif } #endif /* DIAG over USB */ success = 1; } return success; }
long diagchar_ioctl(struct file *filp, unsigned int iocmd, unsigned long ioarg) { int i, j, count_entries = 0, temp; int success = -1; void *temp_buf; uint16_t support_list = 0; struct diag_dci_client_tbl *params = kzalloc(sizeof(struct diag_dci_client_tbl), GFP_KERNEL); struct diag_dci_health_stats stats; int status; if (iocmd == DIAG_IOCTL_COMMAND_REG) { struct bindpkt_params_per_process *pkt_params = (struct bindpkt_params_per_process *) ioarg; mutex_lock(&driver->diagchar_mutex); for (i = 0; i < diag_max_reg; i++) { if (driver->table[i].process_id == 0) { diag_add_reg(i, pkt_params->params, &success, &count_entries); if (pkt_params->count > count_entries) { pkt_params->params++; } else { mutex_unlock(&driver->diagchar_mutex); return success; } } } if (i < diag_threshold_reg) { /* Increase table size by amount required */ diag_max_reg += pkt_params->count - count_entries; /* Make sure size doesnt go beyond threshold */ if (diag_max_reg > diag_threshold_reg) { diag_max_reg = diag_threshold_reg; pr_info("diag: best case memory allocation\n"); } temp_buf = krealloc(driver->table, diag_max_reg*sizeof(struct diag_master_table), GFP_KERNEL); if (!temp_buf) { diag_max_reg -= pkt_params->count - count_entries; pr_alert("diag: Insufficient memory for reg."); mutex_unlock(&driver->diagchar_mutex); return 0; } else { driver->table = temp_buf; } for (j = i; j < diag_max_reg; j++) { diag_add_reg(j, pkt_params->params, &success, &count_entries); if (pkt_params->count > count_entries) { pkt_params->params++; } else { mutex_unlock(&driver->diagchar_mutex); return success; } } mutex_unlock(&driver->diagchar_mutex); } else { mutex_unlock(&driver->diagchar_mutex); pr_err("Max size reached, Pkt Registration failed for" " Process %d", current->tgid); } success = 0; } else if (iocmd == DIAG_IOCTL_GET_DELAYED_RSP_ID) { struct diagpkt_delay_params *delay_params = (struct diagpkt_delay_params *) ioarg; if ((delay_params->rsp_ptr) && (delay_params->size == sizeof(delayed_rsp_id)) && (delay_params->num_bytes_ptr)) { *((uint16_t *)delay_params->rsp_ptr) = DIAGPKT_NEXT_DELAYED_RSP_ID(delayed_rsp_id); *(delay_params->num_bytes_ptr) = sizeof(delayed_rsp_id); success = 0; } } else if (iocmd == DIAG_IOCTL_DCI_REG) { if (driver->dci_state == DIAG_DCI_NO_REG) return DIAG_DCI_NO_REG; if (driver->num_dci_client >= MAX_DCI_CLIENTS) return DIAG_DCI_NO_REG; if (copy_from_user(params, (void *)ioarg, sizeof(struct diag_dci_client_tbl))) return -EFAULT; mutex_lock(&driver->dci_mutex); if (!(driver->num_dci_client)) driver->in_busy_dci = 0; driver->num_dci_client++; pr_debug("diag: id = %d\n", driver->dci_client_id); driver->dci_client_id++; for (i = 0; i < MAX_DCI_CLIENTS; i++) { if (driver->dci_client_tbl[i].client == NULL) { driver->dci_client_tbl[i].client = current; driver->dci_client_tbl[i].list = params->list; driver->dci_client_tbl[i].signal_type = params->signal_type; create_dci_log_mask_tbl(driver-> dci_client_tbl[i].dci_log_mask); create_dci_event_mask_tbl(driver-> dci_client_tbl[i].dci_event_mask); driver->dci_client_tbl[i].data_len = 0; driver->dci_client_tbl[i].dci_data = kzalloc(IN_BUF_SIZE, GFP_KERNEL); driver->dci_client_tbl[i].total_capacity = IN_BUF_SIZE; driver->dci_client_tbl[i].dropped_logs = 0; driver->dci_client_tbl[i].dropped_events = 0; driver->dci_client_tbl[i].received_logs = 0; driver->dci_client_tbl[i].received_events = 0; break; } } mutex_unlock(&driver->dci_mutex); return driver->dci_client_id; } else if (iocmd == DIAG_IOCTL_DCI_DEINIT) { success = -1; /* Delete this process from DCI table */ mutex_lock(&driver->dci_mutex); for (i = 0; i < dci_max_reg; i++) if (driver->req_tracking_tbl[i].pid == current->tgid) driver->req_tracking_tbl[i].pid = 0; for (i = 0; i < MAX_DCI_CLIENTS; i++) { if (driver->dci_client_tbl[i].client && driver->dci_client_tbl[i].client->tgid == current->tgid) { driver->dci_client_tbl[i].client = NULL; success = i; break; } } if (success >= 0) driver->num_dci_client--; mutex_unlock(&driver->dci_mutex); return success; } else if (iocmd == DIAG_IOCTL_DCI_SUPPORT) { if (driver->ch_dci) support_list = support_list | DIAG_CON_MPSS; *(uint16_t *)ioarg = support_list; return DIAG_DCI_NO_ERROR; } else if (iocmd == DIAG_IOCTL_DCI_HEALTH_STATS) { if (copy_from_user(&stats, (void *)ioarg, sizeof(struct diag_dci_health_stats))) return -EFAULT; for (i = 0; i < MAX_DCI_CLIENTS; i++) { params = &(driver->dci_client_tbl[i]); if (params->client && params->client->tgid == current->tgid) { stats.dropped_logs = params->dropped_logs; stats.dropped_events = params->dropped_events; stats.received_logs = params->received_logs; stats.received_events = params->received_events; if (stats.reset_status) { params->dropped_logs = 0; params->dropped_events = 0; params->received_logs = 0; params->received_events = 0; } break; } } if (copy_to_user((void *)ioarg, &stats, sizeof(struct diag_dci_health_stats))) return -EFAULT; return DIAG_DCI_NO_ERROR; } else if (iocmd == DIAG_IOCTL_LSM_DEINIT) { for (i = 0; i < driver->num_clients; i++) if (driver->client_map[i].pid == current->tgid) break; if (i == -1) return -EINVAL; driver->data_ready[i] |= DEINIT_TYPE; wake_up_interruptible(&driver->wait_q); success = 1; } else if (iocmd == DIAG_IOCTL_SWITCH_LOGGING) { mutex_lock(&driver->diagchar_mutex); temp = driver->logging_mode; driver->logging_mode = (int)ioarg; if (temp == driver->logging_mode) { mutex_unlock(&driver->diagchar_mutex); pr_alert("diag: forbidden logging change requested\n"); return 0; } if (driver->logging_mode == MEMORY_DEVICE_MODE) { diag_clear_hsic_tbl(); driver->mask_check = 1; if (driver->socket_process) { /* * Notify the socket logging process that we * are switching to MEMORY_DEVICE_MODE */ status = send_sig(SIGCONT, driver->socket_process, 0); if (status) { pr_err("diag: %s, Error notifying ", __func__); pr_err("socket process, status: %d\n", status); } } } if (driver->logging_mode == SOCKET_MODE) driver->socket_process = current; if (driver->logging_mode == CALLBACK_MODE) driver->callback_process = current; if (driver->logging_mode == UART_MODE || driver->logging_mode == SOCKET_MODE || driver->logging_mode == CALLBACK_MODE) { diag_clear_hsic_tbl(); driver->mask_check = 0; driver->logging_mode = MEMORY_DEVICE_MODE; } driver->logging_process_id = current->tgid; mutex_unlock(&driver->diagchar_mutex); if (temp == MEMORY_DEVICE_MODE && driver->logging_mode == NO_LOGGING_MODE) { driver->in_busy_1 = 1; driver->in_busy_2 = 1; driver->in_busy_lpass_1 = 1; driver->in_busy_lpass_2 = 1; driver->in_busy_wcnss_1 = 1; driver->in_busy_wcnss_2 = 1; #ifdef CONFIG_DIAG_SDIO_PIPE driver->in_busy_sdio = 1; #endif #ifdef CONFIG_DIAG_BRIDGE_CODE diagfwd_disconnect_bridge(0); diag_clear_hsic_tbl(); #endif } else if (temp == NO_LOGGING_MODE && driver->logging_mode == MEMORY_DEVICE_MODE) { driver->in_busy_1 = 0; driver->in_busy_2 = 0; driver->in_busy_lpass_1 = 0; driver->in_busy_lpass_2 = 0; driver->in_busy_wcnss_1 = 0; driver->in_busy_wcnss_2 = 0; /* Poll SMD channels to check for data*/ if (driver->ch) queue_work(driver->diag_wq, &(driver->diag_read_smd_work)); if (driver->chlpass) queue_work(driver->diag_wq, &(driver->diag_read_smd_lpass_work)); if (driver->ch_wcnss) queue_work(driver->diag_wq, &(driver->diag_read_smd_wcnss_work)); #ifdef CONFIG_DIAG_SDIO_PIPE driver->in_busy_sdio = 0; /* Poll SDIO channel to check for data */ if (driver->sdio_ch) queue_work(driver->diag_sdio_wq, &(driver->diag_read_sdio_work)); #endif #ifdef CONFIG_DIAG_BRIDGE_CODE diagfwd_connect_bridge(0); #endif } #ifdef CONFIG_DIAG_OVER_USB else if (temp == USB_MODE && driver->logging_mode == NO_LOGGING_MODE) { diagfwd_disconnect(); #ifdef CONFIG_DIAG_BRIDGE_CODE diagfwd_disconnect_bridge(0); #endif } else if (temp == NO_LOGGING_MODE && driver->logging_mode == USB_MODE) { diagfwd_connect(); #ifdef CONFIG_DIAG_BRIDGE_CODE diagfwd_connect_bridge(0); #endif } else if (temp == USB_MODE && driver->logging_mode == MEMORY_DEVICE_MODE) { diagfwd_disconnect(); driver->in_busy_1 = 0; driver->in_busy_2 = 0; driver->in_busy_lpass_1 = 0; driver->in_busy_lpass_2 = 0; driver->in_busy_wcnss_1 = 0; driver->in_busy_wcnss_2 = 0; /* Poll SMD channels to check for data*/ if (driver->ch) queue_work(driver->diag_wq, &(driver->diag_read_smd_work)); if (driver->chlpass) queue_work(driver->diag_wq, &(driver->diag_read_smd_lpass_work)); if (driver->ch_wcnss) queue_work(driver->diag_wq, &(driver->diag_read_smd_wcnss_work)); #ifdef CONFIG_DIAG_SDIO_PIPE driver->in_busy_sdio = 0; /* Poll SDIO channel to check for data */ if (driver->sdio_ch) queue_work(driver->diag_sdio_wq, &(driver->diag_read_sdio_work)); #endif #ifdef CONFIG_DIAG_BRIDGE_CODE diagfwd_cancel_hsic(); diagfwd_connect_bridge(0); #endif } else if (temp == MEMORY_DEVICE_MODE && driver->logging_mode == USB_MODE) { diagfwd_connect(); #ifdef CONFIG_DIAG_BRIDGE_CODE diag_clear_hsic_tbl(); diagfwd_cancel_hsic(); diagfwd_connect_bridge(0); #endif } #endif /* DIAG over USB */ success = 1; } else if (iocmd == DIAG_IOCTL_REMOTE_DEV) { uint16_t remote_dev = diag_get_remote_device_mask(); if (copy_to_user((void *)ioarg, &remote_dev, sizeof(uint16_t))) success = -EFAULT; else success = 1; } return success; }
static int lge_dm_dev_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { // int index=0; int index=MODEM_DATA; int i; #ifdef CONFIG_DIAGFWD_BRIDGE_CODE unsigned long spin_lock_flags; #endif struct dm_dev_tty *lge_dm_dev_tty_drv = NULL; lge_dm_dev_tty_drv = lge_dm_dev_tty; tty->driver_data = lge_dm_dev_tty_drv; lge_dm_dev_tty_drv->tty_str = tty; if (_IOC_TYPE(cmd) != DM_DEV_TTY_IOCTL_MAGIC) return -EINVAL; switch (cmd){ case DM_DEV_TTY_MODEM_OPEN: #ifdef CONFIG_DIAGFWD_BRIDGE_CODE if ((diag_bridge[index].usb_connected == 1) && (diag_hsic[index].count_hsic_pool == N_MDM_WRITE)) { spin_lock_irqsave(&diag_hsic[HSIC].hsic_spinlock,spin_lock_flags); diag_hsic[index].count_hsic_pool = 0; spin_unlock_irqrestore(&diag_hsic[HSIC].hsic_spinlock,spin_lock_flags); } diag_hsic[index].num_hsic_buf_tbl_entries = 0; for (i = 0; i < diag_hsic[index].poolsize_hsic_write; i++) { if (diag_hsic[index].hsic_buf_tbl[index].buf) { /* Return the buffer to the pool */ diagmem_free(driver, (unsigned char *) (diag_hsic[index].hsic_buf_tbl[index].buf), POOL_TYPE_HSIC); diag_hsic[index].hsic_buf_tbl[index].buf = 0; } diag_hsic[index].hsic_buf_tbl[index].length = 0; } diagfwd_disconnect_bridge(1); diagfwd_cancel_hsic(REOPEN_HSIC); // QCT 161032 migration - NEED TO CHECK diagfwd_connect_bridge(0); #endif /* CONFIG_DIAGFWD_BRIDGE_CODE */ /* change path to DM DEV */ mutex_lock(&driver->diagchar_mutex); driver->logging_mode = DM_DEV_MODE; mutex_unlock(&driver->diagchar_mutex); #ifdef CONFIG_DIAG_SDIO_PIPE driver->in_busy_sdio = 0; /* Poll SDIO channel to check for data */ if (driver->sdio_ch) queue_work(driver->diag_sdio_wq, &(driver->diag_read_sdio_work)); #endif #ifdef CONFIG_DIAGFWD_BRIDGE_CODE /* Read data from the hsic */ if (diag_hsic[index].hsic_ch) queue_work(diag_bridge[index].wq, &(diag_hsic[index]. diag_read_hsic_work)); #endif /* CONFIG_DIAGFWD_BRIDGE_CODE */ break; case DM_DEV_TTY_MODEM_CLOSE: lge_dm_dev_tty->set_logging = 0; /* change path to USB driver */ mutex_lock(&driver->diagchar_mutex); driver->logging_mode = USB_MODE; mutex_unlock(&driver->diagchar_mutex); if (driver->usb_connected == 0) diagfwd_disconnect(); else diagfwd_connect(); #ifdef CONFIG_DIAGFWD_BRIDGE_CODE diag_hsic[index].num_hsic_buf_tbl_entries = 0; for (i = 0; i < diag_hsic[index].poolsize_hsic_write; i++) { if (diag_hsic[index].hsic_buf_tbl[index].buf) { /* Return the buffer to the pool */ diagmem_free(driver, (unsigned char *) (diag_hsic[index].hsic_buf_tbl[index].buf), POOL_TYPE_HSIC); diag_hsic[index].hsic_buf_tbl[index].buf = 0; } diag_hsic[index].hsic_buf_tbl[index].length = 0; } diagfwd_cancel_hsic(REOPEN_HSIC); // QCT 161032 migration - NEED TO CHECK diagfwd_connect_bridge(0); #endif pr_info(DM_DEV_TTY_MODULE_NAME ": %s : lge_dm_dev_tty_ioctl " "DM_DEV_TTY_IOCTL_MODEM_CLOSE\n", __func__); break; case DM_DEV_TTY_ENABLE: /* change path to DM DEV */ mutex_lock(&driver->diagchar_mutex); pr_info(DM_DEV_TTY_MODULE_NAME ": %s:, Logging mode Change to DM_DEV_MODE\n",__func__); driver->logging_mode = DM_DEV_MODE; mutex_unlock(&driver->diagchar_mutex); break; #ifdef CONFIG_MACH_APQ8064_ALTEV case DM_DEV_TTY_MODEM_RESET: pr_info( "DM_TTY_MODEM_RESET\n"); subsys_modem_restart(); break; // kyle00.choi, 20140411, RF Device Check [START] case DM_TTY_MODEM_DEBUGGER: { char rw_buf[300]; memset(rw_buf, 0, sizeof(rw_buf)); strcpy(rw_buf,ssr_noti); if (copy_to_user((void *)arg, &rw_buf, sizeof(rw_buf))) { pr_info(DM_DEV_TTY_MODULE_NAME ": %s: DM_TTY_MODEM_DEBUGGER error! rw_buf = %s\n", __func__, rw_buf); return -EFAULT; } printk("rw_buf = %s\n",rw_buf); break; } // kyle00.choi, 20140411, RF Device Check [END] #endif default: pr_info(DM_DEV_TTY_MODULE_NAME ": %s:" "lge_dm_tty_ioctl error\n", __func__); break; } return 0; }
long diagchar_ioctl(struct file *filp, unsigned int iocmd, unsigned long ioarg) { int i, j, temp, success = -1; unsigned int count_entries = 0, interim_count = 0; void *temp_buf; if (iocmd == DIAG_IOCTL_COMMAND_REG) { struct bindpkt_params_per_process pkt_params; struct bindpkt_params *params; struct bindpkt_params *head_params; if (copy_from_user(&pkt_params, (void *)ioarg, sizeof(struct bindpkt_params_per_process))) { return -EFAULT; } if ((UINT32_MAX/sizeof(struct bindpkt_params)) < pkt_params.count) { pr_alert("diag: integer overflow while multiply\n"); return -EFAULT; } params = kzalloc(pkt_params.count*sizeof( struct bindpkt_params), GFP_KERNEL); if (!params) { pr_alert("diag: unable to alloc memory\n"); return -ENOMEM; } else head_params = params; if (copy_from_user(params, pkt_params.params, pkt_params.count*sizeof(struct bindpkt_params))) { kfree(head_params); return -EFAULT; } mutex_lock(&driver->diagchar_mutex); for (i = 0; i < diag_max_reg; i++) { if (driver->table[i].process_id == 0) { diag_add_reg(i, params, &success, &count_entries); if (pkt_params.count > count_entries) { params++; } else { mutex_unlock(&driver->diagchar_mutex); kfree(head_params); return success; } } } if (i < diag_threshold_reg) { /* Increase table size by amount required */ if (pkt_params.count >= count_entries) { interim_count = pkt_params.count - count_entries; } else { pr_alert("diag: error in params count\n"); kfree(head_params); mutex_unlock(&driver->diagchar_mutex); return -EFAULT; } if (UINT32_MAX - diag_max_reg >= interim_count) { diag_max_reg += interim_count; } else { pr_alert("diag: Integer overflow\n"); kfree(head_params); mutex_unlock(&driver->diagchar_mutex); return -EFAULT; } /* Make sure size doesnt go beyond threshold */ if (diag_max_reg > diag_threshold_reg) { diag_max_reg = diag_threshold_reg; pr_info("diag: best case memory allocation\n"); } if (UINT32_MAX/sizeof(struct diag_master_table) < diag_max_reg) { pr_alert("diag: integer overflow\n"); kfree(head_params); mutex_unlock(&driver->diagchar_mutex); return -EFAULT; } temp_buf = krealloc(driver->table, diag_max_reg*sizeof(struct diag_master_table), GFP_KERNEL); if (!temp_buf) { pr_alert("diag: Insufficient memory for reg.\n"); mutex_unlock(&driver->diagchar_mutex); if (pkt_params.count >= count_entries) { interim_count = pkt_params.count - count_entries; } else { pr_alert("diag: params count error\n"); mutex_unlock(&driver->diagchar_mutex); kfree(head_params); return -EFAULT; } if (diag_max_reg >= interim_count) { diag_max_reg -= interim_count; } else { pr_alert("diag: Integer underflow\n"); mutex_unlock(&driver->diagchar_mutex); kfree(head_params); return -EFAULT; } kfree(head_params); return 0; } else { driver->table = temp_buf; } for (j = i; j < diag_max_reg; j++) { diag_add_reg(j, params, &success, &count_entries); if (pkt_params.count > count_entries) { params++; } else { mutex_unlock(&driver->diagchar_mutex); kfree(head_params); return success; } } kfree(head_params); mutex_unlock(&driver->diagchar_mutex); } else { mutex_unlock(&driver->diagchar_mutex); kfree(head_params); pr_err("Max size reached, Pkt Registration failed for" " Process %d", current->tgid); } success = 0; } else if (iocmd == DIAG_IOCTL_GET_DELAYED_RSP_ID) { struct diagpkt_delay_params delay_params; uint16_t interim_rsp_id; int interim_size; if (copy_from_user(&delay_params, (void *)ioarg, sizeof(struct diagpkt_delay_params))) return -EFAULT; if ((delay_params.rsp_ptr) && (delay_params.size == sizeof(delayed_rsp_id)) && (delay_params.num_bytes_ptr)) { interim_rsp_id = DIAGPKT_NEXT_DELAYED_RSP_ID( delayed_rsp_id); if (copy_to_user((void *)delay_params.rsp_ptr, &interim_rsp_id, sizeof(uint16_t))) return -EFAULT; interim_size = sizeof(delayed_rsp_id); if (copy_to_user((void *)delay_params.num_bytes_ptr, &interim_size, sizeof(int))) return -EFAULT; success = 0; } } else if (iocmd == DIAG_IOCTL_LSM_DEINIT) { for (i = 0; i < driver->num_clients; i++) if (driver->client_map[i].pid == current->tgid) break; if (i == -1) return -EINVAL; driver->data_ready[i] |= DEINIT_TYPE; wake_up_interruptible(&driver->wait_q); success = 1; } else if (iocmd == DIAG_IOCTL_SWITCH_LOGGING) { mutex_lock(&driver->diagchar_mutex); temp = driver->logging_mode; driver->logging_mode = (int)ioarg; if (driver->logging_mode == MEMORY_DEVICE_MODE) driver->mask_check = 1; if (driver->logging_mode == UART_MODE) { driver->mask_check = 0; driver->logging_mode = MEMORY_DEVICE_MODE; } driver->logging_process_id = current->tgid; mutex_unlock(&driver->diagchar_mutex); if (temp == MEMORY_DEVICE_MODE && driver->logging_mode == NO_LOGGING_MODE) { driver->in_busy_1 = 1; driver->in_busy_2 = 1; driver->in_busy_qdsp_1 = 1; driver->in_busy_qdsp_2 = 1; driver->in_busy_wcnss = 1; #ifdef CONFIG_DIAG_SDIO_PIPE driver->in_busy_sdio = 1; #endif } else if (temp == NO_LOGGING_MODE && driver->logging_mode == MEMORY_DEVICE_MODE) { driver->in_busy_1 = 0; driver->in_busy_2 = 0; driver->in_busy_qdsp_1 = 0; driver->in_busy_qdsp_2 = 0; driver->in_busy_wcnss = 0; /* Poll SMD channels to check for data*/ if (driver->ch) queue_work(driver->diag_wq, &(driver->diag_read_smd_work)); if (driver->chqdsp) queue_work(driver->diag_wq, &(driver->diag_read_smd_qdsp_work)); if (driver->ch_wcnss) queue_work(driver->diag_wq, &(driver->diag_read_smd_wcnss_work)); #ifdef CONFIG_DIAG_SDIO_PIPE driver->in_busy_sdio = 0; /* Poll SDIO channel to check for data */ if (driver->sdio_ch) queue_work(driver->diag_sdio_wq, &(driver->diag_read_sdio_work)); #endif } #ifdef CONFIG_DIAG_OVER_USB else if (temp == USB_MODE && driver->logging_mode == NO_LOGGING_MODE) diagfwd_disconnect(); else if (temp == NO_LOGGING_MODE && driver->logging_mode == USB_MODE) diagfwd_connect(); else if (temp == USB_MODE && driver->logging_mode == MEMORY_DEVICE_MODE) { diagfwd_disconnect(); driver->in_busy_1 = 0; driver->in_busy_2 = 0; driver->in_busy_qdsp_2 = 0; driver->in_busy_qdsp_2 = 0; driver->in_busy_wcnss = 0; /* Poll SMD channels to check for data*/ if (driver->ch) queue_work(driver->diag_wq, &(driver->diag_read_smd_work)); if (driver->chqdsp) queue_work(driver->diag_wq, &(driver->diag_read_smd_qdsp_work)); if (driver->ch_wcnss) queue_work(driver->diag_wq, &(driver->diag_read_smd_wcnss_work)); #ifdef CONFIG_DIAG_SDIO_PIPE driver->in_busy_sdio = 0; /* Poll SDIO channel to check for data */ if (driver->sdio_ch) queue_work(driver->diag_sdio_wq, &(driver->diag_read_sdio_work)); #endif } else if (temp == MEMORY_DEVICE_MODE && driver->logging_mode == USB_MODE) diagfwd_connect(); #endif /* DIAG over USB */ success = 1; } return success; }
static int diagchar_ioctl(struct inode *inode, struct file *filp, unsigned int iocmd, unsigned long ioarg) { int i, j, count_entries = 0, temp; int success = -1; void *temp_buf; DIAG_INFO("%s:%s(parent:%s): tgid=%d\n", __func__, current->comm, current->parent->comm, current->tgid); if (iocmd == DIAG_IOCTL_COMMAND_REG) { struct bindpkt_params_per_process *pkt_params = (struct bindpkt_params_per_process *) ioarg; for (i = 0; i < diag_max_registration; i++) { if (driver->table[i].process_id == 0) { success = 1; driver->table[i].cmd_code = pkt_params->params->cmd_code; driver->table[i].subsys_id = pkt_params->params->subsys_id; driver->table[i].cmd_code_lo = pkt_params->params->cmd_code_lo; driver->table[i].cmd_code_hi = pkt_params->params->cmd_code_hi; driver->table[i].process_id = current->tgid; count_entries++; if (pkt_params->count > count_entries) pkt_params->params++; else return success; } } if (i < diag_threshold_registration) { /* Increase table size by amount required */ diag_max_registration += pkt_params->count - count_entries; /* Make sure size doesnt go beyond threshold */ if (diag_max_registration > diag_threshold_registration) diag_max_registration = diag_threshold_registration; temp_buf = krealloc(driver->table, diag_max_registration*sizeof(struct diag_master_table), GFP_KERNEL); BUG_ON(!temp_buf); driver->table = temp_buf; for (j = i; j < diag_max_registration; j++) { success = 1; driver->table[j].cmd_code = pkt_params-> params->cmd_code; driver->table[j].subsys_id = pkt_params-> params->subsys_id; driver->table[j].cmd_code_lo = pkt_params-> params->cmd_code_lo; driver->table[j].cmd_code_hi = pkt_params-> params->cmd_code_hi; driver->table[j].process_id = current->tgid; count_entries++; if (pkt_params->count > count_entries) pkt_params->params++; else return success; } } else pr_err("Max size reached, Pkt Registration failed for" " Process %d", current->tgid); success = 0; } else if (iocmd == DIAG_IOCTL_GET_DELAYED_RSP_ID) { struct diagpkt_delay_params *delay_params = (struct diagpkt_delay_params *) ioarg; if ((delay_params->rsp_ptr) && (delay_params->size == sizeof(delayed_rsp_id)) && (delay_params->num_bytes_ptr)) { *((uint16_t *)delay_params->rsp_ptr) = DIAGPKT_NEXT_DELAYED_RSP_ID(delayed_rsp_id); *(delay_params->num_bytes_ptr) = sizeof(delayed_rsp_id); success = 0; } } else if (iocmd == DIAG_IOCTL_LSM_DEINIT) { for (i = 0; i < driver->num_clients; i++) if (driver->client_map[i].pid == current->tgid) break; if (i == -1) return -EINVAL; driver->data_ready[i] |= DEINIT_TYPE; wake_up_interruptible(&driver->wait_q); success = 1; } else if (iocmd == DIAG_IOCTL_SWITCH_LOGGING) { mutex_lock(&driver->diagchar_mutex); temp = driver->logging_mode; driver->logging_mode = (int)ioarg; driver->logging_process_id = current->tgid; mutex_unlock(&driver->diagchar_mutex); if (temp == MEMORY_DEVICE_MODE && driver->logging_mode == NO_LOGGING_MODE) { driver->in_busy_1 = 1; driver->in_busy_2 = 1; driver->in_busy_qdsp_1 = 1; driver->in_busy_qdsp_2 = 1; } else if (temp == NO_LOGGING_MODE && driver->logging_mode == MEMORY_DEVICE_MODE) { driver->in_busy_1 = 0; driver->in_busy_2 = 0; driver->in_busy_qdsp_1 = 0; driver->in_busy_qdsp_2 = 0; /* Poll SMD channels to check for data*/ if (driver->ch) queue_work(driver->diag_wq, &(driver->diag_read_smd_work)); if (driver->chqdsp) queue_work(driver->diag_wq, &(driver->diag_read_smd_qdsp_work)); } #ifdef CONFIG_DIAG_OVER_USB else if (temp == USB_MODE && driver->logging_mode == NO_LOGGING_MODE) diagfwd_disconnect(); else if (temp == NO_LOGGING_MODE && driver->logging_mode == USB_MODE) diagfwd_connect(); else if (temp == USB_MODE && driver->logging_mode == MEMORY_DEVICE_MODE) { if (driver->enable_sd_log) driver->enable_sd_log(1); DIAG_INFO("diag: USB disconnected\n"); diagfwd_disconnect(); DIAG_INFO("sdlogging enable\n"); #if 0 /* defined(CONFIG_ARCH_MSM8X60_LTE) */ if (mdm_diag) { driver->in_busy_sdio = 0; buf_9k = kzalloc(USB_MAX_OUT_BUF, GFP_KERNEL); if (driver->sdio_ch) queue_work(driver->diag_sdio_wq, &(driver->diag_read_sdio_work)); } else #endif { driver->in_busy_1 = 0; driver->in_busy_2 = 0; driver->in_busy_qdsp_2 = 0; driver->in_busy_qdsp_2 = 0; /* Poll SMD channels to check for data*/ if (driver->ch) queue_work(driver->diag_wq, &(driver->diag_read_smd_work)); if (driver->chqdsp) queue_work(driver->diag_wq, &(driver->diag_read_smd_qdsp_work)); } } else if (temp == MEMORY_DEVICE_MODE && driver->logging_mode == USB_MODE) { DIAG_INFO("sdlogging disable\n"); if (driver->enable_sd_log) driver->enable_sd_log(0); diagfwd_connect(); } #endif /* DIAG over USB */ success = 1; } return success; }
long diagchar_ioctl(struct file *filp, unsigned int iocmd, unsigned long ioarg) { int i, j, count_entries = 0, temp; int success = -1; void *temp_buf; if (iocmd == DIAG_IOCTL_COMMAND_REG) { struct bindpkt_params_per_process *pkt_params = (struct bindpkt_params_per_process *) ioarg; mutex_lock(&driver->diagchar_mutex); for (i = 0; i < diag_max_registration; i++) { if (driver->table[i].process_id == 0) { diag_add_reg(i, pkt_params->params, &success, &count_entries); if (pkt_params->count > count_entries) { pkt_params->params++; } else { mutex_unlock(&driver->diagchar_mutex); return success; } } } if (i < diag_threshold_registration) { /* Increase table size by amount required */ diag_max_registration += pkt_params->count - count_entries; /* Make sure size doesnt go beyond threshold */ if (diag_max_registration > diag_threshold_registration) diag_max_registration = diag_threshold_registration; temp_buf = krealloc(driver->table, diag_max_registration*sizeof(struct diag_master_table), GFP_KERNEL); if (!temp_buf) { diag_max_registration -= pkt_params->count - count_entries; pr_alert("diag: Insufficient memory for reg."); mutex_unlock(&driver->diagchar_mutex); return 0; } else { driver->table = temp_buf; } for (j = i; j < diag_max_registration; j++) { diag_add_reg(j, pkt_params->params, &success, &count_entries); if (pkt_params->count > count_entries) { pkt_params->params++; } else { mutex_unlock(&driver->diagchar_mutex); return success; } } } else { mutex_unlock(&driver->diagchar_mutex); pr_err("Max size reached, Pkt Registration failed for" " Process %d", current->tgid); } success = 0; } else if (iocmd == DIAG_IOCTL_GET_DELAYED_RSP_ID) { struct diagpkt_delay_params *delay_params = (struct diagpkt_delay_params *) ioarg; if ((delay_params->rsp_ptr) && (delay_params->size == sizeof(delayed_rsp_id)) && (delay_params->num_bytes_ptr)) { *((uint16_t *)delay_params->rsp_ptr) = DIAGPKT_NEXT_DELAYED_RSP_ID(delayed_rsp_id); *(delay_params->num_bytes_ptr) = sizeof(delayed_rsp_id); success = 0; } } else if (iocmd == DIAG_IOCTL_LSM_DEINIT) { for (i = 0; i < driver->num_clients; i++) if (driver->client_map[i].pid == current->tgid) break; if (i == -1) return -EINVAL; driver->data_ready[i] |= DEINIT_TYPE; wake_up_interruptible(&driver->wait_q); success = 1; } else if (iocmd == DIAG_IOCTL_SWITCH_LOGGING) { mutex_lock(&driver->diagchar_mutex); temp = driver->logging_mode; driver->logging_mode = (int)ioarg; if (driver->logging_mode == MEMORY_DEVICE_MODE) driver->mask_check = 1; if (driver->logging_mode == UART_MODE) { driver->mask_check = 0; driver->logging_mode = MEMORY_DEVICE_MODE; } driver->logging_process_id = current->tgid; mutex_unlock(&driver->diagchar_mutex); if (temp == MEMORY_DEVICE_MODE && driver->logging_mode == NO_LOGGING_MODE) { driver->in_busy_1 = 1; driver->in_busy_2 = 1; driver->in_busy_qdsp_1 = 1; driver->in_busy_qdsp_2 = 1; driver->in_busy_wcnss = 1; #ifdef CONFIG_DIAG_SDIO_PIPE driver->in_busy_sdio = 1; #endif } else if (temp == NO_LOGGING_MODE && driver->logging_mode == MEMORY_DEVICE_MODE) { driver->in_busy_1 = 0; driver->in_busy_2 = 0; driver->in_busy_qdsp_1 = 0; driver->in_busy_qdsp_2 = 0; driver->in_busy_wcnss = 0; /* Poll SMD channels to check for data*/ if (driver->ch) queue_work(driver->diag_wq, &(driver->diag_read_smd_work)); if (driver->chqdsp) queue_work(driver->diag_wq, &(driver->diag_read_smd_qdsp_work)); if (driver->ch_wcnss) queue_work(driver->diag_wq, &(driver->diag_read_smd_wcnss_work)); #ifdef CONFIG_DIAG_SDIO_PIPE driver->in_busy_sdio = 0; /* Poll SDIO channel to check for data */ if (driver->sdio_ch) queue_work(driver->diag_sdio_wq, &(driver->diag_read_sdio_work)); #endif } #ifdef CONFIG_DIAG_OVER_USB else if (temp == USB_MODE && driver->logging_mode == NO_LOGGING_MODE) diagfwd_disconnect(); else if (temp == NO_LOGGING_MODE && driver->logging_mode == USB_MODE) diagfwd_connect(); else if (temp == USB_MODE && driver->logging_mode == MEMORY_DEVICE_MODE) { diagfwd_disconnect(); driver->in_busy_1 = 0; driver->in_busy_2 = 0; driver->in_busy_qdsp_2 = 0; driver->in_busy_qdsp_2 = 0; driver->in_busy_wcnss = 0; /* Poll SMD channels to check for data*/ if (driver->ch) queue_work(driver->diag_wq, &(driver->diag_read_smd_work)); if (driver->chqdsp) queue_work(driver->diag_wq, &(driver->diag_read_smd_qdsp_work)); if (driver->ch_wcnss) queue_work(driver->diag_wq, &(driver->diag_read_smd_wcnss_work)); #ifdef CONFIG_DIAG_SDIO_PIPE driver->in_busy_sdio = 0; /* Poll SDIO channel to check for data */ if (driver->sdio_ch) queue_work(driver->diag_sdio_wq, &(driver->diag_read_sdio_work)); #endif } else if (temp == MEMORY_DEVICE_MODE && driver->logging_mode == USB_MODE) diagfwd_connect(); #endif /* DIAG over USB */ success = 1; } return success; }
static void lge_dm_tty_close(struct tty_struct *tty, struct file *file) { int index=MODEM_DATA; int i; struct dm_tty *lge_dm_tty_drv = NULL; lge_dm_tty_drv = lge_dm_tty; tty->driver_data = lge_dm_tty_drv; lge_dm_tty_drv->tty_str = tty; clear_bit(TTY_NO_WRITE_SPLIT, &lge_dm_tty_drv->tty_str->flags); if (!tty) { pr_err(DM_TTY_MODULE_NAME ": %s: NULL tty", __func__); return; } lge_dm_tty_drv = tty->driver_data; if (!lge_dm_tty_drv) { pr_err(DM_TTY_MODULE_NAME ": %s: NULL sdio_tty_drv", __func__); return; } if (lge_dm_tty_drv->tty_state != DM_TTY_OPEN) { pr_err(DM_TTY_MODULE_NAME ": %s: TTY device was not opened\n", __func__); return; } lge_dm_tty_drv->set_logging = 1; wake_up_interruptible(&lge_dm_tty_drv->waitq); kthread_stop(lge_dm_tty_drv->tty_ts); lge_dm_tty_drv->tty_state = DM_TTY_CLOSED; pr_info(DM_TTY_MODULE_NAME ": %s: TTY device closed\n", __func__); cancel_work_sync(&(lge_dm_tty_drv->dm_usb_work)); destroy_workqueue(lge_dm_tty_drv->dm_wq); lge_dm_tty->set_logging = 0; /* change path to USB driver */ mutex_lock(&driver->diagchar_mutex); driver->logging_mode = USB_MODE; mutex_unlock(&driver->diagchar_mutex); if (driver->usb_connected == 0) diagfwd_disconnect(); else diagfwd_connect(); #ifdef CONFIG_DIAGFWD_BRIDGE_CODE diag_hsic[index].num_hsic_buf_tbl_entries = 0; for (i = 0; i < diag_hsic[index].poolsize_hsic_write; i++) { if (diag_hsic[index].hsic_buf_tbl[index].buf) { /* Return the buffer to the pool */ diagmem_free(driver, (unsigned char *) (diag_hsic[index].hsic_buf_tbl[index].buf), POOL_TYPE_HSIC); diag_hsic[index].hsic_buf_tbl[index].buf = 0; } diag_hsic[index].hsic_buf_tbl[index].length = 0; } diagfwd_cancel_hsic(REOPEN_HSIC); // QCT 161032 migration - NEED TO CHECK diagfwd_connect_bridge(0); #endif return; }