Пример #1
0
static int diagchar_close(struct inode *inode, struct file *file)
{
    int i = 0;
    struct diagchar_priv *diagpriv_data = file->private_data;

    if (!(file->private_data)) {
        pr_alert("diag: Invalid file pointer");
        return -ENOMEM;
    }

    /* clean up any DCI registrations for this client
    * This will specially help in case of ungraceful exit of any DCI client
    * This call will remove any pending registrations of such client
    */
    diagchar_ioctl(NULL, DIAG_IOCTL_DCI_DEINIT, 0);

    /* If the exiting process is the socket process */
    if (driver->socket_process &&
            (driver->socket_process->tgid == current->tgid)) {
        driver->socket_process = NULL;
    }

#ifdef CONFIG_DIAG_OVER_USB
    /* If the SD logging process exits, change logging to USB mode */
    if (driver->logging_process_id == current->tgid) {
        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 */
    /* Delete the pkt response table entry for the exiting process */
    for (i = 0; i < diag_max_reg; i++)
        if (driver->table[i].process_id == current->tgid)
            driver->table[i].process_id = 0;

    if (driver) {
        mutex_lock(&driver->diagchar_mutex);
        driver->ref_count--;
        /* On Client exit, try to destroy all 3 pools */
        diagmem_exit(driver, POOL_TYPE_COPY);
        diagmem_exit(driver, POOL_TYPE_HDLC);
        diagmem_exit(driver, POOL_TYPE_WRITE_STRUCT);
        for (i = 0; i < driver->num_clients; i++) {
            if (NULL != diagpriv_data && diagpriv_data->pid ==
                    driver->client_map[i].pid) {
                driver->client_map[i].pid = 0;
                kfree(diagpriv_data);
                diagpriv_data = NULL;
                break;
            }
        }
        mutex_unlock(&driver->diagchar_mutex);
        return 0;
    }
    return -ENOMEM;
}
Пример #2
0
static int diagchar_close(struct inode *inode, struct file *file)
{
	int i = 0;
#ifdef CONFIG_DIAG_OVER_USB
	/* If the SD logging process exits, change logging to USB mode */
	if (driver->logging_process_id == current->tgid) {
		driver->logging_mode = USB_MODE;
		diagfwd_connect();
	}
#endif /* DIAG over USB */
	/* Delete the pkt response table entry for the exiting process */
	for (i = 0; i < diag_max_registration; i++)
			if (driver->table[i].process_id == current->tgid)
					driver->table[i].process_id = 0;

			if (driver) {
				mutex_lock(&driver->diagchar_mutex);
				driver->ref_count--;
				/* On Client exit, try to destroy all 3 pools */
				diagmem_exit(driver, POOL_TYPE_COPY);
				diagmem_exit(driver, POOL_TYPE_HDLC);
				diagmem_exit(driver, POOL_TYPE_WRITE_STRUCT);
				for (i = 0; i < driver->num_clients; i++)
					if (driver->client_map[i].pid ==
					     current->tgid) {
						driver->client_map[i].pid = 0;
						break;
					}
		mutex_unlock(&driver->diagchar_mutex);
		return 0;
	}
	return -ENOMEM;
}
Пример #3
0
static int diagchar_close(struct inode *inode, struct file *file)
{
	int i = 0;

	/* If the SD logging process exits, change logging to USB mode */
	if (driver->logging_process_id == current->tgid) {
		driver->logging_mode = USB_MODE;
		diagfwd_connect();
	}
	/* Delete the pkt response table entry for the exiting process */
	for (i = 0; i < diag_max_registration; i++)
			if (driver->table[i].process_id == current->tgid)
					driver->table[i].process_id = 0;

			if (driver) {
				mutex_lock(&driver->diagchar_mutex);
				driver->ref_count--;
				diagmem_exit(driver);
				for (i = 0; i < driver->num_clients; i++)
					if (driver->client_map[i].pid ==
					     current->tgid) {
						driver->client_map[i].pid = 0;
						break;
					}
		mutex_unlock(&driver->diagchar_mutex);
		return 0;
	}
	return -ENOMEM;
}
Пример #4
0
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;
}
Пример #5
0
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;

}
static int diag_sdio_probe(struct platform_device *pdev)
{
	int err;
	if (diag9k_debug_mask)
		DIAG_INFO("%s\n", __func__);

	err = sdio_open("SDIO_DIAG", &driver->sdio_ch, driver,
							 diag_sdio_notify);
	if (err)
		DIAG_ERR("DIAG could not open SDIO channel");
	else {
		DIAG_INFO("DIAG opened SDIO channel");

		if (!strcmp(DIAG_LEGACY, usb_ch_name)) {
			driver->legacy_ch = usb_diag_open(DIAG_LEGACY, driver,
				diag_usb_legacy_notifier);
			if (IS_ERR(driver->legacy_ch)) {
				DIAG_ERR("Unable to open USB diag legacy channel\n");
				goto err;
			}
			DIAG_INFO("open USB diag legacy channel\n");
		} else if (!strcmp(DIAG_MDM, usb_ch_name)) {
			driver->legacy_ch = usb_diag_open(DIAG_LEGACY, driver,
				diag_usb_legacy_notifier);
			if (IS_ERR(driver->legacy_ch)) {
				DIAG_ERR("Unable to open USB diag legacy channel\n");
				goto err;
			}
			DIAG_INFO("open USB diag legacy channel\n");

			driver->mdm_ch = usb_diag_open(DIAG_MDM, driver,
				diag_usb_legacy_notifier);
			if (IS_ERR(driver->mdm_ch)) {
				DIAG_ERR("Unable to open USB diag MDM channel\n");
				goto err;
			}
			DIAG_INFO("open USB diag MDM channel\n");
		}
/*		queue_work(driver->diag_sdio_wq, &(driver->diag_read_mdm_work));*/
	}
	if (diag_configured)
		diagfwd_connect();
	driver->in_busy_sdio_1 = 0;
	driver->in_busy_sdio_2 = 0;
	driver->qxdm2sd_drop = 0;
	sdio_diag_initialized = 1;
err:
	return err;
}
Пример #7
0
static int diagchar_close(struct inode *inode, struct file *file)
{
	int i = 0;
	struct diagchar_priv *diagpriv_data = file->private_data;

	if (!(file->private_data)) {
		pr_alert("diag: Invalid file pointer");
		return -ENOMEM;
	}

	if (!driver)
		return -ENOMEM;

#ifdef CONFIG_DIAG_OVER_USB
	/* If the SD logging process exits, change logging to USB mode */
	if (driver->logging_process_id == current->tgid) {
		driver->logging_mode = USB_MODE;
		diagfwd_connect();
	}
#endif /* DIAG over USB */
	/* Delete the pkt response table entry for the exiting process */
	for (i = 0; i < diag_max_registration; i++) {
		if (driver->table[i].process_id == current->tgid)
			driver->table[i].process_id = 0;
	}

	mutex_lock(&driver->diagchar_mutex);
	driver->ref_count--;
			/* On Client exit, try to destroy all 3 pools */
			diagmem_exit(driver, POOL_TYPE_COPY);
			diagmem_exit(driver, POOL_TYPE_HDLC);
			diagmem_exit(driver, POOL_TYPE_WRITE_STRUCT);
	for (i = 0; i < driver->num_clients; i++) {
		if (NULL != diagpriv_data && diagpriv_data->pid ==
			 driver->client_map[i].pid) {
			driver->client_map[i].pid = 0;
			kfree(diagpriv_data);
			diagpriv_data = NULL;
			break;
		}
	}
	mutex_unlock(&driver->diagchar_mutex);
	return 0;
}
Пример #8
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;
	}
}
Пример #9
0
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_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;
}
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;

}
Пример #12
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;

}
Пример #13
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 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;
}
Пример #14
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;
}
Пример #15
0
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;
}
Пример #16
0
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;
}
Пример #17
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;
	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;

}
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;
}
Пример #19
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;

}
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;
}
Пример #21
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, 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;
}
Пример #23
0
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;

}