Esempio n. 1
0
static long vpapi_ioctl(struct file *pFile, unsigned int cmd, unsigned long arg)
{
	int ret = 0;

	/* Argument checking */
	if (_IOC_TYPE(cmd) != VPAPI_MOD_IOCTL_MAGIC) {
		printk("%s: invalid VPAPI MOD Magic Num %i %i\n", __func__, _IOC_TYPE(cmd), VPAPI_MOD_IOCTL_MAGIC);
		return -ENOTTY;
	}

	if ((_IOC_NR(cmd) > VPAPI_MOD_IOCTL_MAX) || (_IOC_NR(cmd) < VPAPI_MOD_IOCTL_MIN)) {
		printk("%s: invalid VPAPI MOD IOCTL request\n", __func__);
		return -ENOTTY;
	}

	if (_IOC_DIR(cmd) & _IOC_READ) {
		ret = !access_ok(VERIFY_WRITE, (void __user*)arg, _IOC_SIZE(cmd));
	}
	else if (_IOC_DIR(cmd) & _IOC_WRITE) {
		ret = !access_ok(VERIFY_READ, (void __user*)arg, _IOC_SIZE(cmd));
	}

	if (ret) {
		printk("%s: invalid VPAPI MOD access type %i from cmd %i\n", __func__, _IOC_DIR(cmd), cmd);
		return -EFAULT;
	}

#if defined(SLIC_TIMER_EVENT_SUPPORT)
	/* Disable timer routine processing */
	atomic_set(&vpapi_in_ioctl, 1);
#endif

	switch (cmd) {
		case VPAPI_MOD_IOX_MK_DEV_OBJ:
			//printk("ioctl: VPAPI_MOD_IOX_MK_DEV_OBJ\n");
			ret = vpapi_make_dev_object(arg);
			break;

		case VPAPI_MOD_IOX_MK_LN_OBJ:
			//printk("ioctl: VPAPI_MOD_IOX_MK_LN_OBJ\n");
			ret = vpapi_make_line_object(arg);
			break;

		case VPAPI_MOD_IOX_MAP_LN_ID:
			//printk("ioctl: VPAPI_MOD_IOX_MAP_LN_ID\n");
			ret = vpapi_map_line_id(arg);
			break;

		case VPAPI_MOD_IOX_MAP_SLAC_ID:
			//printk("ioctl: VPAPI_MOD_IOX_MAP_SLAC_ID\n");
			ret  = vpapi_map_slac_id(arg);
			break;

		case VPAPI_MOD_IOX_FREE_LN_CTX:
			//printk("ioctl: VPAPI_MOD_IOX_FREE_LN_CTX\n");
			ret = vpapi_free_line_context(arg);
			break;

		case VPAPI_MOD_IOX_INIT_DEV:
			//printk("ioctl: VPAPI_MOD_IOX_INIT_DEV\n");
			ret = vpapi_init_device(arg);
			break;

		case VPAPI_MOD_IOX_CAL_LN:
			//printk("ioctl: VPAPI_MOD_IOX_CAL_LN\n");
			ret = vpapi_cal_line(arg);
			break;

		case VPAPI_MOD_IOX_SET_LN_ST:
			//printk("ioctl: VPAPI_MOD_IOX_SET_LN_ST\n");
			ret = vpapi_set_line_state(arg);
			break;

		case VPAPI_MOD_IOX_SET_OPTION:
			//printk("ioctl: VPAPI_MOD_IOX_SET_OPTION\n");
			ret = vpapi_set_option(arg);
			break;

		case VPAPI_MOD_IOX_GET_EVENT:
			//printk("ioctl: VPAPI_MOD_IOX_GET_EVENT\n");
			ret = vpapi_get_event(arg);
			break;

#if defined(CONFIG_ZARLINK_SLIC_VE792)
		case VPAPI_MOD_IOX_BATT_ON:
			//printk("ioctl: VPAPI_MOD_IOX_BATT_ON\n");
			ret = vpapi_batt_on(arg);
			break;

		case VPAPI_MOD_IOX_BATT_OFF:
			//printk("ioctl: VPAPI_MOD_IOX_BATT_OFF\n");
			ret = vpapi_batt_off(arg);
			break;
#endif
#if defined(CONFIG_ZARLINK_SLIC_VE880)
		case VPAPI_MOD_IOX_REG_READ:
			ret = vpapi_reg_read(arg);
			break;

		case VPAPI_MOD_IOX_REG_WRITE:
			ret = vpapi_reg_write(arg);
			break;
#endif
		default:
			printk("%s: error, ioctl command(0x%x) not supported !!!\n", __func__, cmd);
			ret = -EFAULT;
			break;
	}

#if defined(SLIC_TIMER_EVENT_SUPPORT)
	/* Enable timer routine processing */
	atomic_set(&vpapi_in_ioctl, 0);
#endif

	return ret;
}
Esempio n. 2
0
int scull_ioctl (struct inode *inode, struct file *filp,
                 unsigned int cmd, unsigned long arg)
{

    int tmp, size = _IOC_SIZE(cmd); /* the size bitfield in cmd */

    /*
     * extract the type and number bitfields, and don't decode
     * wrong cmds: return EINVAL before verify_area()
     */
    if (_IOC_TYPE(cmd) != SCULL_IOC_MAGIC) return -EINVAL;
    if (_IOC_NR(cmd) > SCULL_IOC_MAXNR) return -EINVAL;

    /*
     * the direction is a bitmask, and VERIFY_WRITE catches R/W
     * transfers. `Type' is user-oriented, while
     * verify_area is kernel-oriented, so the concept of "read" and
     * "write" is reversed
     */
    if ((_IOC_DIR(cmd) & _IOC_READ) &&
        verify_area_20(VERIFY_WRITE, (void *)arg, size))
        return -EINVAL;
    else if ((_IOC_DIR(cmd) & _IOC_WRITE) &&
             verify_area_20(VERIFY_READ, (void *)arg, size))
        return -EINVAL;
    
    switch(cmd) {


      case SCULL_IOCRESET:
        scull_quantum = SCULL_QUANTUM;
        scull_qset = SCULL_QSET;
        break;
        
      case SCULL_IOCSQUANTUM: /* Set: arg points to the value */
        GET_USER_RET(scull_quantum,(int *)arg, -EFAULT);
        break;

      case SCULL_IOCTQUANTUM: /* Tell: arg is the value */
        scull_quantum = arg;
        break;

      case SCULL_IOCGQUANTUM: /* Get: arg is pointer to result */
        PUT_USER_RET(scull_quantum, (int *)arg, -EFAULT);
        break;

      case SCULL_IOCQQUANTUM: /* Query: return it (it's positive) */
        return scull_quantum;

      case SCULL_IOCXQUANTUM: /* eXchange: use arg as pointer */
        tmp = scull_quantum;
        GET_USER_RET(scull_quantum,(int *)arg, -EFAULT);
        PUT_USER_RET(tmp, (int *)arg, -EFAULT);
        break;

      case SCULL_IOCHQUANTUM: /* sHift: like Tell + Query */
        tmp = scull_quantum;
        scull_quantum = arg;
        return tmp;
        
      case SCULL_IOCSQSET:
        GET_USER_RET(scull_qset, (int *)arg, -EFAULT);
        break;

      case SCULL_IOCTQSET:
        scull_qset = arg;
        break;

      case SCULL_IOCGQSET:
        PUT_USER_RET(scull_qset, (int *)arg, -EFAULT);
        break;

      case SCULL_IOCQQSET:
        return scull_qset;

      case SCULL_IOCXQSET:
        tmp = scull_qset;
        GET_USER_RET(scull_qset, (int *)arg, -EFAULT);
        PUT_USER_RET(tmp, (int *)arg, -EFAULT);
        break;

      case SCULL_IOCHQSET:
        tmp = scull_qset;
        scull_quantum = arg;
        return tmp;

        /*
         * The following two change the buffer size for scullpipe.
         * The scullpipe device uses this same ioctl method, just to
         * write less code. Actually, it's the same driver, isn't it?
         */

      case SCULL_P_IOCTSIZE:
        scull_p_buffer = arg;
        break;

      case SCULL_P_IOCQSIZE:
        return scull_p_buffer;


      default:  /* redundant, as cmd was checked against MAXNR */
        return -EINVAL;
    }
    return 0;
}
//static int lgx_ioctl(struct inode* inode, struct file* filp, unsigned int cmd, unsigned long arg)
static long lgx_ioctl(struct file* filp, unsigned int cmd, unsigned long arg)
{
	long retval = 0;
	long val;
//	inno_device_t* inno_dev = &g_inno_dev;

	/* FIHTDC, ALXiao, add cmmb ftm test function, 20101008 { */
	if(_IOC_TYPE(cmd) != INNO_IOC_MAGIC)
		return -ENOTTY;
	/* FIHTDC, ALXiao, add cmmb ftm test function, 20101008 } */

	inno_msg("[CMMB]%s+",__FUNCTION__);

	// ASUS_BSP+++ JimmyLin "[CMMB] avoid UI hang"
	// msleep(100);
	// ASUS_BSP--- 
	switch(cmd){
		case INNO_STOP_POLL:                // stop polling,avoid poll block,then driver can't deinit
			{
				cancle_wait  =(u8)arg;
				inno_msg("[lgx_ioctl] INNO_STOP_POLL cancle_wait =%d",cancle_wait);
				if(cancle_wait){
					struct inno_lgx* lgx0 = g_inno_dev.lgxs[0];
					struct inno_lgx* lgx1 = g_inno_dev.lgxs[1];
					struct inno_lgx* lgx2 = g_inno_dev.lgxs[2];
					struct inno_lgx* lgx3 = g_inno_dev.lgxs[3];
					wake_up_interruptible(&lgx0->read_wait);
					wake_up_interruptible(&lgx1->read_wait);
					wake_up_interruptible(&lgx2->read_wait);
					wake_up_interruptible(&lgx3->read_wait);
				}
				break;
			}
		case INNO_MEMSET_MFS:                      // memset mfs buffer before fetch mfs data
			{
				flag_memset= (u8)arg; 
				inno_msg("[lgx_ioctl] INNO_MEMSET_MFS flag_memset =%d",flag_memset);
				break;
			}
#if 0
		case INNO_GET_INTR_TYPE:                              //no use
			inno_msg("[lgx_ioctl] INNO_GET_INTR_TYPE");
			val = inno_dev->cfg.intr_type;
			put_user(val, (long*)arg);
			break;
		case INNO_READ_REG:                                  //no use
			{
				struct inno_reg_data* reg_data;
				inno_msg("[lgx_ioctl] INNO_READ_REG");
				reg_data = kmalloc(sizeof(struct inno_reg_data), GFP_KERNEL);
				retval = copy_from_user(reg_data, (void*)arg, sizeof(struct inno_reg_data));
				if(retval == 0){
					/*
					   down(&inno_iic_mutex);
					   g_inno_dev.i2c_driver->read(reg_data->reg, (unsigned char*)&reg_data->data);	
					   up(&inno_iic_mutex);
					   retval = copy_to_user((void*)arg, reg_data, sizeof(struct inno_reg_data));
					 */
				}
				kfree(reg_data);
				break;
			}
		case INNO_WRITE_REG:                                 //no use
			{
				struct inno_reg_data* reg_data;
				inno_msg("[lgx_ioctl] INNO_WRITE_REG");
				reg_data = kmalloc(sizeof(struct inno_reg_data), GFP_KERNEL);
				retval = copy_from_user(reg_data, (void*)arg, sizeof(struct inno_reg_data));
				if(retval == 0){
					/*
					   down(&inno_iic_mutex);
					   g_inno_dev.i2c_driver->write(reg_data->reg, reg_data->data);
					   up(&inno_iic_mutex);
					   retval = copy_to_user((void*)arg, reg_data, sizeof(struct inno_reg_data));
					 */
				}
				kfree(reg_data);
				break;
			}
		case INNO_MMIS_READ:                     	//no use
			{
				u8 reg  = (u8)arg;
				u8 value;
				inno_msg("[lgx_ioctl] INNO_MMIS_READ");
				mutex_lock(&inno_spi_mutex);
				inno_spi_drive_cs(0);
				g_inno_dev.spi_driver->write(&reg, 1);
				inno_spi_drive_cs(1);

				inno_spi_drive_cs(0);
				g_inno_dev.spi_driver->read(&value, 1);
				inno_spi_drive_cs(1);

				retval = value;
				mutex_unlock(&inno_spi_mutex);
				break;
			}
		case INNO_MMIS_CMD:	                       //no use
			{
				u8 value = (u8)arg;
				inno_msg("[lgx_ioctl] INNO_MMIS_CMD");
				mutex_lock(&inno_spi_mutex);
				inno_spi_drive_cs(0);		
				g_inno_dev.spi_driver->write(&value,1);
				inno_spi_drive_cs(1);		
				mutex_unlock(&inno_spi_mutex);
				break;
			}
		case INNO_MMIS_WRITE:	          //pass value	mmis_cmd|value no use
			{
				u8 cmd, value;
				inno_msg("[lgx_ioctl] INNO_MMIS_WRITE");
				val = arg;
				cmd = (val & 0xFF00)>>8;
				value = (val & 0x00FF);
				mutex_lock(&inno_spi_mutex);
				inno_spi_drive_cs(0);		
				g_inno_dev.spi_driver->write(&cmd, 1);
				inno_spi_drive_cs(1);

				inno_spi_drive_cs(0);		
				g_inno_dev.spi_driver->write(&value, 1);
				inno_spi_drive_cs(1);
				mutex_unlock(&inno_spi_mutex);
				break;
			}
		case INNO_SCAN_FREQUENCY:                   // if228 not support scan function  no use
			{
				struct inno_freq_scan_area* 	scan_area;
				inno_msg("[lgx_ioctl] INNO_SCAN_FREQUENCY");
				scan_area = kmalloc(sizeof(struct inno_freq_scan_area), GFP_KERNEL);
				retval = copy_from_user(scan_area, (void*)arg, sizeof(struct inno_freq_scan_area));

				if(retval == 0)
					;//retval = inno_scan_frequency(scan_area->start, scan_area->end);
				kfree(scan_area);
				break;
			}
		case INNO_SCAN_FREQUENCY_DOT:              // if228 not support scan function no use
			{
				struct inno_freq_scan_area*		scan_area;
				inno_msg("[lgx_ioctl] INNO_SCAN_FREQUENCY_DOT");
				scan_area = kmalloc(sizeof(struct inno_freq_scan_area), GFP_KERNEL);
				retval = copy_from_user(scan_area, (void*)arg, sizeof(struct inno_freq_scan_area));
				if(retval == 0)
					;//retval = inno_scan_frequency_dot((u8)scan_area->start, (u8)scan_area->end);
				kfree(scan_area);
				break;
			}
#endif
#if 0
		case INNO_SET_FREQUENCY:	// unit:MHZ
			{
				inno_msg("[lgx_ioctl] INNO_SET_FREQUENCY");
				retval = copy_from_user(&val, (void*)arg, sizeof(unsigned long));
				inno_msg("[inno-ioctl]: INNO_SET_FREQUENCY, val=%ld", val);

				if(retval == 0)
					retval = inno_set_frequency((u16)val);

				break;
			}
#endif		
		case INNO_SET_FREQUENCY_DOT:
			{
				inno_msg("[lgx_ioctl] INNO_SET_FREQUENCY_DOT");
				retval = copy_from_user(&val, (void*)arg, sizeof(unsigned long));
				inno_msg("[inno-ioctl]: INNO_SET_FREQUENCY_DOT, val=%ld", val);
				if(retval == 0)
					retval = inno_set_frequency_dot((u8)val);
				if(retval)
					retval = -1;
				break;
			}
#if 0
		case INNO_SET_CP_TYPE:                    // no use   
			{
				inno_msg("[lgx_ioctl] INNO_SET_CP_TYPE");
				retval = copy_from_user(&val, (void*)arg, sizeof(unsigned long));
				if(retval == 0)
					retval = inno_set_cp_type((u8)val);
				break;
			}
#endif
		case INNO_GET_CHANNEL_CONFIG:                         
			{
				struct inno_channel_config* 	cfg;
				inno_msg("[lgx_ioctl] INNO_GET_CHANNEL_CONFIG");
				cfg = kmalloc(sizeof(struct inno_channel_config), GFP_KERNEL);
				if(!cfg ){
					inno_err("kmalloc cfg ==NULL");
					retval =-1;
					break;
				}

				retval = copy_from_user(cfg, (void*)arg, sizeof(struct inno_channel_config));

				if(retval == 0)
					retval =INNO_GetChannelConfig(cfg);            
				if(!retval){
					retval = copy_to_user((void*)arg, cfg, sizeof(struct inno_channel_config));
					inno_msg("[lgx_ioctl] INNO_Get_CHANNEL_CONFIG:cid(%d),close(%d),start(%d),count(%d),ldpc(%d),itlv(%d),rs(%d),mod(%d) "
							,cfg->ch_id,cfg->ch_close,cfg->ts_start,cfg->ts_count,cfg->ldpc,cfg->itlv,cfg->rs,cfg->modulate);			
				}
				else
					retval =-1;
				kfree(cfg);
				break;	
			}
		case INNO_SET_CHANNEL_CONFIG:                 
			{
				struct inno_channel_config* 	cfg;
				cfg = kmalloc(sizeof(struct inno_channel_config), GFP_KERNEL);
				if(!cfg ){
					inno_err("kmalloc cfg ==NULL");
					retval =-1;
					break;
				}
				inno_msg("[inno-ioctl]: INNO_SET_CHANNEL_CONFIG");
				retval = copy_from_user(cfg, (void*)arg, sizeof(struct inno_channel_config));
				inno_msg("[lgx_ioctl] INNO_SET_CHANNEL_CONFIG:cid(%d),close(%d),start(%d),count(%d),ldpc(%d),itlv(%d),rs(%d),mod(%d),subframeID(%d) "
						,cfg->ch_id,cfg->ch_close,cfg->ts_start,cfg->ts_count,cfg->ldpc,cfg->itlv,cfg->rs,cfg->modulate,cfg->subframe_ID);
				if(retval == 0)
					retval = inno_set_channel_config(cfg);
				kfree(cfg);
				break;	
			}
		case INNO_GET_SYS_STATE:
			{
				struct inno_sys_state*	sys_state;
				inno_msg("[lgx_ioctl] INNO_GET_SYS_STATE");
				sys_state = kmalloc(sizeof(struct inno_sys_state), GFP_KERNEL);
				if(!sys_state){
					inno_err("kmalloc fail sys_state = null");
					retval =1;
					break;
				}
				retval = copy_from_user(sys_state, (void*)arg, sizeof(struct inno_sys_state));

				if(retval == 0)
					retval = inno_get_system_state(sys_state);
				if(!retval)
					retval = copy_to_user((void*)arg, sys_state, sizeof(struct inno_sys_state));
				else
					retval = -1;
				kfree(sys_state);
				break;
			}
#if 0                             // no use
		case INNO_SET_PM:                                    // no use
			{
				struct inno_pm_control* pmctl;
				inno_msg("[lgx_ioctl] INNO_SET_PM");
				pmctl = kmalloc(sizeof(struct inno_pm_control), GFP_KERNEL);
				retval = copy_from_user(pmctl, (void*)arg, sizeof(struct inno_pm_control));

				if(retval == 0)
					retval = inno_set_pm(pmctl);
				kfree(pmctl);
				break;
			}
		case INNO_GET_FW_VER:                                 //no use
			{	
				struct inno_fw_ver ver = {0, 0};
				inno_msg("[lgx_ioctl] INNO_GET_FW_VER");
				inno_get_fireware_version(&ver);
				retval = copy_to_user((void*)arg, &ver, sizeof(struct inno_fw_ver));
				break;
			}
#endif
		case INNO_FW_DOWNLOAD:
			{
				int retry=0;
			//	struct INNOCHAR_FW_DATA *up = (struct INNOCHAR_FW_DATA *)arg;
				unsigned char* fwbuf =NULL;
				//inno_msg("check up->fw_size =%d",up->fw_size);                    
				//unsigned char* fwbuf = kmalloc(up->fw_size, GFP_KERNEL| GFP_DMA);
                                inno_msg("download using h file in kernel");
				if(FIRMWARE_BUF_DATA_SIZE < 40960)
					fwbuf =3*INNO_BUFFER_SIZE+g_inno_buffer;
				else{
					inno_err("fw_size >40k fail");
					retval = -1;
					break;
				}			 

				//int pass=0;
				//INNO_RET ret_tmp = INNO_NO_ERROR;

				inno_msg("[lgx_ioctl] INNO_FW_DOWNLOAD");
                                memset(fwbuf,0,FIRMWARE_BUF_DATA_SIZE);
			//	memset(fwbuf, 0, up->fw_size);
	         	//	retval = copy_from_user(fwbuf, (void*)up->fwbuf, up->fw_size);
                                memcpy(fwbuf,fw_buf,FIRMWARE_BUF_DATA_SIZE);
#if 0            				//check copy fw
				int i;
				inno_msg("check copy_from_user fw_bu");
				for(i=0;i<4;i++)
					inno_msg(" %02x",fwbuf[i]);
				inno_msg("end");
				for(i=0;i<4;i++)
					inno_msg(" %02x",fwbuf[up->fw_size-i-1]);
				inno_msg("end");	
				//mtk_spi_test();
				//break;
				//inno_msg("******** sleep 1s for download fw");
				//msleep(5000);
#endif
				if(retval == 0){
					for(retry=0;retry<1;retry++){                                
						retval = inno_download_fireware(fwbuf,FIRMWARE_BUF_DATA_SIZE);
						if(retval){
							inno_err("firmware download failed retval =%d!",(int)retval);
							retval =  -EIO;
							continue;
						}
#if 0
						//	mdelay(100);                                                       //no need delay,refer to innofidei code
						inno_msg("inno_download_fireware OK,then check FW");
						ret_tmp = INNO_CheckFWDownload(fw_buf,up->fw_size,&pass);
						if(ret_tmp){
							inno_err("INNO_CheckFWDownload fail ret =%d",ret_tmp);
							retval = -1;
							continue;
						}
						if(!pass){
							inno_err("FW Download Fail, checksum no pass =%d!",pass);
						}
						else{
							inno_msg("INNO_CheckFWDownload success");	
							break;
						}
#else
						else{
							inno_msg("inno_download_fireware ok");
							break;
						}
#endif
					}
					if(retry ==5){
						inno_err("inno_download_fireware timeout");
						retval = -1;
					}
				}
				//kfree(fwbuf);
				break;
			}
#if 0                               // no use
		case INNO_UPDATE_FW:                         // no use
			{
				inno_msg("[lgx_ioctl] INNO_UPDATE_FW");
				inno_update_fireware();
				break;
			}
#endif
		case INNO_GET_FW_BYTES:
			{
				int ret =INNO_Chip_errHandle();
				if(ret != INNO_NO_ERROR)       {
					inno_err("INNO_Chip_errHandle fail");
					retval =-1;   
				}	
				break;
			}
		case INNO_ENABLE_IRQ:
			inno_msg("[lgx_ioctl] INNO_ENABLE_IRQ");
			break;
		case INNO_DISABLE_IRQ:
			inno_msg("[lgx_ioctl] INNO_DISABLE_IRQ");
			break;
#if 0
		case INNO_SHUTDOWN_IRQ:                                    // no use
			{	//NOTE: cleanup all (i2c, spi, power down) mannually while, NOT the device itself
				inno_msg("[lgx_ioctl] INNO_SHUTDOWN_IRQ");
				if(!g_inno_dev.use_count)
				{
					inno_msg("shutdown innodev. %d", g_inno_dev.use_count);
					innodev_shutdown(&g_inno_dev);
					g_inno_dev.use_count = 0; //unrefer all reference counter
				}
				break;
			}
		case INNO_GET_BUFFERLEN:                                        //xingyu getbufferlen
			val = INNO_BUFFER_SIZE;
			put_user(val, (long*)arg);
			inno_msg("[lgx_ioctl] INNO_GET_BUFFERLEN:%ld",val);
			break;
#endif
			//////////////////////////// uam ///////////////////////////
		case INNO_UAM_TRANSFER:
			{
				struct inno_uam_parameter *uam_para_tmp;
				inno_msg("[lgx_ioctl] INNO_UAM_TRANSFER");
				uam_para_tmp = kmalloc(sizeof(struct inno_uam_parameter), GFP_KERNEL);
				if(!uam_para_tmp){
					inno_msg("uam_para_tmp kmalloc fail");
					retval = -1;
					break;
				}			 
				retval = copy_from_user(uam_para_tmp, (void*)arg, sizeof(struct inno_uam_parameter));

				if(retval == 0)
					retval = inno_uam_transfer(uam_para_tmp);
				if(!retval)
					retval = copy_to_user((void*)arg, uam_para_tmp, sizeof(struct inno_uam_parameter));     
				else
					retval = -1;
				kfree(uam_para_tmp);
				uam_para_tmp=NULL;
			}
			break;
		case INNO_UAM_INIT:
			inno_msg("[lgx_ioctl] INNO_UAM_INIT");
			retval = inno_init_uam();
			if(retval !=0){
				retval =-1;                   //tell user space fail
				inno_err("init uam fail");
			}
			break;		

		case INNO_SEND_UAM_CMD:
			{
				unsigned char* cmd_tmp0;
				struct uam_cmd_par* up0 = (struct uam_cmd_par*)arg;
				inno_msg("[lgx_ioctl] INNO_SEND_UAM_CMD");
				cmd_tmp0= kmalloc(up0->len, GFP_KERNEL);
				if(cmd_tmp0 == NULL){
					inno_msg("cmd_tmp0 kmalloc fail");
					retval = -1;
					break;
				}			 
				memset(cmd_tmp0, 0, up0->len);
				retval = copy_from_user(cmd_tmp0, (void*)up0->cmd, up0->len);

				if(retval ==0)
					retval = INNO_Send_UAM_Cmd(cmd_tmp0,up0->len);
				if(retval)
					retval = -1;
				kfree(cmd_tmp0);
				cmd_tmp0 =NULL;
			}
			break;		
		case INNO_SEND_CMD:
			{
				unsigned char *cmd_tmp;
				inno_msg("[lgx_ioctl] INNO_SEND_CMD");
				cmd_tmp = kmalloc(8,GFP_KERNEL);
				if(!cmd_tmp){
					inno_err("kmalloc fail,cmd_tmp==null");
					retval=-1;
					break;
				}
				retval = copy_from_user(cmd_tmp, (void*)arg, 8);
				if(retval ==0){
					mutex_lock(&inno_spi_mutex);                         //xingyu 2011-06-24
					retval = INNO_Send_Cmd(cmd_tmp);
					mutex_unlock(&inno_spi_mutex);
				}
				if(retval)
					retval =-1;
				kfree(cmd_tmp);
				cmd_tmp =NULL;
				break;		
			}	
#if 0                                        // no use
		case INNO_UAM_SET_CMD:                               //no use
			//inno_msg("we are in kernel ioctl^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
			inno_msg("[lgx_ioctl] INNO_UAM_SET_CMD");
			retval = copy_from_user(&uam_para.pBufIn, (void*)arg, uam_cmd_len);
			if(retval == 0){
				inno_dbg("IOCTL: INNO_UAM_TRANSFER");
			}
			uam_para.bufInLen = uam_cmd_len;
			inno_uam_transfer(&uam_para);
			break;

		case INNO_UAM_SET_CMDL:                               // no use
			inno_msg("[lgx_ioctl] INNO_UAM_SET_CMDL");
			retval = copy_from_user((void *)&uam_cmd_len, (void*)arg, sizeof(unsigned int));
			inno_dbg("INNO_UAM_SET_CMDL - uam_cmd_len: %d", uam_cmd_len);
			break;

		case INNO_UAM_READ_RES:                              // no use
			inno_msg("[lgx_ioctl] INNO_UAM_READ_RES");
			inno_dbg("INNO_UAM_READ_RES - return response len: %d", uam_para.pBufOutLen);
			return copy_to_user((void *)arg, uam_para.pBufOut, uam_para.pBufOutLen);

		case INNO_UAM_READ_STATUS:                                 // no sue
			inno_msg("[lgx_ioctl] INNO_UAM_READ_STATUS");
			inno_dbg("INNO_UAM_READ_STATUS - return status: 0x%x", uam_para.sw);
			return put_user(uam_para.sw, (unsigned long *)arg);

		case INNO_UAM_READ_STATUS_LEN:                              // no use
			inno_msg("[lgx_ioctl] INNO_UAM_READ_STATUS_LEN");
			inno_dbg("INNO_UAM_READ_STATUS_LEN - return response len: 0x%x", uam_para.pBufOutLen);
			return put_user(uam_para.pBufOutLen, (unsigned long *)arg);
#endif

		default:
			return -ENOTTY;
	}
Esempio n. 4
0
 /**
 * hp3a_unlocked_ioctl - I/O control function for hp3a module
 * @inode: Inode structure associated with the Resizer Wrapper.
 * @file: File structure associated with the hp3a driver.
 * @cmd: Type of command to execute.
 * @arg: Argument to send to requested command.
 *
 * Returns 0 if successful, -1 if bad command passed or access is denied,
 * -EFAULT if copy_from_user() or copy_to_user()  fails,
 * -EINVAL if parameter validation fails or parameter structure is not present.
 **/
long hp3a_unlocked_ioctl(struct file *file, unsigned int cmd,
	unsigned long arg)
{
	int ret = -1;
	struct hp3a_fh *fh = file->private_data;
	struct hp3a_dev *device = fh->device;

	if (unlikely(_IOC_TYPE(cmd) != OMAP3_HP3A_MAGIC)) {
		dev_err(device->dev, "Bad command value (%d)\n", cmd);
		return  -ENOTTY;
	}

	switch (cmd) {
	/*
	 * Gets all statistics.
	 */
	case HP3A_G_STATISTICS: {
		struct hp3a_statistics statistics;

		ret = hp3a_collect_statistics(&statistics);
		if (SUCCEEDED(ret)) {
			if (copy_to_user((struct hp3a_statistics *)arg,
				&statistics,
				sizeof(struct hp3a_statistics)) != 0)
				ret = -EFAULT;
		}
		break;
	}
	/*
	 * Set sensor parameters.
	 */
	case HP3A_S_SENSOR_PARAM: {
		struct hp3a_sensor_param sensor_param;

		if (copy_from_user(&sensor_param,
				(struct hp3a_sensor_param *)arg,
				sizeof(struct hp3a_sensor_param)) == 0) {
			ret = hp3a_set_sensor_param(&sensor_param, fh);
		} else {
			ret = -EFAULT;
		}

		break;
	}
	/*
	 * Set ISP/Hardpipe parameters
	 */
	case HP3A_S_HARDPIPE_PARAM: {
		struct hp3a_hardpipe_param hpipe_param;

		if (copy_from_user(&hpipe_param,
				(struct hp3a_hardpipe_param *)arg,
				sizeof(struct hp3a_hardpipe_param)) == 0) {
			ret = hp3a_set_hardpipe_param(&hpipe_param, fh);
		} else {
			ret = -EFAULT;
		}

		break;
	}
	/*
	 * Queue histogram stat buffer.
	 */
	case HP3A_QBUF_HISTQ: {
		struct hp3a_internal_buffer *ibuffer;
		int index = (int)arg;

		if (index < fh->buffer_count && index > -1) {
			ibuffer = &(fh->buffers[index]);
			ret = hp3a_enqueue_irqsave(&g_tc.hist_stat_queue,
				&ibuffer);
		}

		break;
	}
	/*
	 * Queue AF stat buffer.
	 */
	case HP3A_QBUF_AFQ: {
		struct hp3a_internal_buffer *ibuffer;
		int index = (int)arg;

		if (index < fh->buffer_count && index > -1) {
			ibuffer = &(fh->buffers[index]);
			if (ibuffer->isp_addr == 0) {
				ibuffer->isp_addr =
					ispmmu_map_pages(ibuffer->pages,
					NR_PAGES((unsigned long)ibuffer->user_addr,
					ibuffer->buffer_size));
				if (ibuffer->isp_addr == 0) {
					dev_err(device->dev , \
						"isp mmu fail to map memory\n");
					return -EFAULT;
				}
			}
			flush_dcache_ibuffer(ibuffer);
			ret = hp3a_enqueue_irqsave(&g_tc.af_stat_queue,
				&ibuffer);
		}

		break;
	}
	/*
	 * Queue RAW frame buffer.
	 */
	case HP3A_QBUF_RAWQ: {
		struct hp3a_internal_buffer *ibuffer ;
		int index = (int)arg;

		if (index < fh->buffer_count && index > -1) {
			ibuffer = &(fh->buffers[index]);
			if (ibuffer->isp_addr == 0) {
				ibuffer->isp_addr =
					ispmmu_map_pages(ibuffer->pages,
					NR_PAGES((unsigned long)ibuffer->user_addr,
					ibuffer->buffer_size));
				if (ibuffer->isp_addr == 0) {
					dev_err(device->dev , \
						"isp mmu fail to map memory\n");
					return -EFAULT;
				}
			}
			ret = hp3a_enqueue_irqsave(&g_tc.raw_frame_queue,
				&ibuffer);
		}

		break;
	}
	/*
	 * Request for array of buffer placeholders.
	 */
	case HP3A_REQBUF: {
		struct hp3a_request_bufffers req_buf;
		int i;

		if (copy_from_user(&req_buf,
				(struct hp3a_request_bufffers *)arg,
				sizeof(struct hp3a_request_bufffers)) == 0) {
			ret = -1;
			if (req_buf.count > 0) {
				fh->buffers = kzalloc(req_buf.count * \
					sizeof(struct hp3a_internal_buffer),
					GFP_KERNEL);
				if (fh->buffers) {
					fh->buffer_count = req_buf.count;
					for (i = 0; i < fh->buffer_count; ++i)
						fh->buffers[i].index = i;
					ret = 0;
				}
			}
		} else {
			ret = -EFAULT;
		}

		break;
	}
	/*
	 * Install buffers into internal list and map to kernel space.
	 */
	case HP3A_INSTALL_BUF: {
		struct hp3a_buffer buffer;

		if (copy_from_user(&buffer,
				(struct hp3a_buffer *)arg,
				sizeof(struct hp3a_buffer)) == 0) {
			ret = -1;
			if (buffer.index >= 0 && buffer.index <
				fh->buffer_count) {
				if (fh->buffers[buffer.index].buffer_size
					==	0) {
					ret = map_user_to_kernel(&buffer,
						&(fh->buffers[buffer.index]));
				}
			}
		} else {
			ret = -EFAULT;
		}

		break;
	}
	/*
	 * Remove buffers from internal list and unmap from kernel space.
	 */
	case HP3A_UNINSTALL_BUF: {
		struct hp3a_buffer buffer;

		if (copy_from_user(&buffer,
				(struct hp3a_buffer *)arg,
				sizeof(struct hp3a_buffer)) == 0) {
			ret = -1;
			if (buffer.index >= 0 && buffer.index <
				fh->buffer_count) {
				if (fh->buffers[buffer.index].buffer_size &&
					fh->buffers[buffer.index].pages) {
					unmap_buffer_from_kernel(
						&(fh->buffers[buffer.index]));
					ret = 0;
				}
			}
		} else {
			ret = -EFAULT;
		}

		break;
	}
	/*
	 * Configure Histogram hardware.
	 */
	case HP3A_CONFIG_HIST: {
		struct hp3a_histogram_config config;

		if (copy_from_user(&config,
				(struct hp3a_histogram_config *)arg,
				sizeof(struct hp3a_histogram_config)) == 0) {
			ret = hp3a_config_histogram(&config, fh);
		} else {
			ret = -EFAULT;
		}

		break;
	}
	/*
	 * Configure Histogram hardware.
	 */
   case HP3A_CONFIG_AF: {
		struct hp3a_af_config config;

		if (copy_from_user(&config,
				(struct hp3a_af_config *)arg,
				sizeof(struct hp3a_af_config)) == 0) {
			ret = hp3a_config_af(&config, fh);
		} else {
			ret = -EFAULT;
		}

      break;
   }
	/*
	 * Configure raw hardware.
	 */
	case HP3A_CONFIG_RAW: {
		struct hp3a_raw_config config;

		if (copy_from_user(&config,
				(struct hp3a_raw_config *)arg,
				sizeof(struct hp3a_raw_config)) == 0) {

			ret = hp3a_configure_raw(&config);
			if (SUCCEEDED(ret)) {
				if (copy_to_user((struct hp3a_raw_config *)arg,
					&config,
					sizeof(struct hp3a_raw_config)) != 0)
					ret = -EFAULT;
			}
		} else {
			ret = -EFAULT;
		}

		break;
	}
	/*
	 * Flush histogram queue.
	 */
	case HP3A_FLUSH_HISTQ: {
		hp3a_flush_queue_irqsave(&g_tc.hist_stat_queue);
		ret = 0;
		break;
	}
	/*
	 * Flush AF queue.
	 */
	case HP3A_FLUSH_AFQ:	{
		hp3a_flush_queue_irqsave(&g_tc.af_stat_queue);
		ret = 0;
		break;
	}
	/*
	 * Flush RAW queue.
	 */
	case HP3A_FLUSH_RAWQ: {
		hp3a_flush_queue_irqsave(&g_tc.raw_frame_queue);
		ret = 0;
		break;
	}
	/*
	 * Set V4L2 device specific index.
	 */
	case HP3A_S_V4L2_DEV_INDEX: {
		fh->v4l2_dev = (int)arg;
		g_tc.default_v4l2_dev = fh->v4l2_dev;
		ret = 0;
		break;
	}
	/*
	 * Read ISP registers.
	 */
	case HP3A_READ_ISP_REGS: {
		ret = hp3a_read_ispregs_to_user((struct hp3a_reg_page *)arg);
		break;
	}
	case HP3A_READ_ISP_REG: {
		ret = hp3a_read_ispreg_to_user((struct hp3a_reg *)arg);
		break;
	}
	default:
		break;
	}

	return (long)ret;
}
Esempio n. 5
0
/*
 * The ioctl() implementation
 */
int scull_ioctl(struct inode *inode, struct file *filp,
                 unsigned int cmd, unsigned long arg)
{
	int err = 0, tmp;
	int retval = 0;
    
	/*
	 * extract the type and number bitfields, and don't decode
	 * wrong cmds: return ENOTTY (inappropriate ioctl) before access_ok()
	 */
	if (_IOC_TYPE(cmd) != SCULL_IOC_MAGIC) return -ENOTTY;
	if (_IOC_NR(cmd) > SCULL_IOC_MAXNR) return -ENOTTY;

	/*
	 * the direction is a bitmask, and VERIFY_WRITE catches R/W
	 * transfers. `Type' is user-oriented, while
	 * access_ok is kernel-oriented, so the concept of "read" and
	 * "write" is reversed
	 */
	if (_IOC_DIR(cmd) & _IOC_READ)
		err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
	else if (_IOC_DIR(cmd) & _IOC_WRITE)
		err =  !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
	if (err) return -EFAULT;

	switch(cmd) {
	  case SCULL_IOCRESET:
		scull_quantum = SCULL_QUANTUM;
		scull_qset = SCULL_QSET;
		break;
        
	  case SCULL_IOCSQUANTUM: /* Set: arg points to the value */
		if (! capable (CAP_SYS_ADMIN))
			return -EPERM;
		retval = __get_user(scull_quantum, (int __user *)arg);
		break;

	  case SCULL_IOCTQUANTUM: /* Tell: arg is the value */
		if (! capable (CAP_SYS_ADMIN))
			return -EPERM;
		scull_quantum = arg;
		break;

	  case SCULL_IOCGQUANTUM: /* Get: arg is pointer to result */
		retval = __put_user(scull_quantum, (int __user *)arg);
		break;

	  case SCULL_IOCQQUANTUM: /* Query: return it (it's positive) */
		return scull_quantum;

	  case SCULL_IOCXQUANTUM: /* eXchange: use arg as pointer */
		if (! capable (CAP_SYS_ADMIN))
			return -EPERM;
		tmp = scull_quantum;
		retval = __get_user(scull_quantum, (int __user *)arg);
		if (retval == 0)
			retval = __put_user(tmp, (int __user *)arg);
		break;

	  case SCULL_IOCHQUANTUM: /* sHift: like Tell + Query */
		if (! capable (CAP_SYS_ADMIN))
			return -EPERM;
		tmp = scull_quantum;
		scull_quantum = arg;
		return tmp;
        
	  case SCULL_IOCSQSET:
		if (! capable (CAP_SYS_ADMIN))
			return -EPERM;
		retval = __get_user(scull_qset, (int __user *)arg);
		break;

	  case SCULL_IOCTQSET:
		if (! capable (CAP_SYS_ADMIN))
			return -EPERM;
		scull_qset = arg;
		break;

	  case SCULL_IOCGQSET:
		retval = __put_user(scull_qset, (int __user *)arg);
		break;

	  case SCULL_IOCQQSET:
		return scull_qset;

	  case SCULL_IOCXQSET:
		if (! capable (CAP_SYS_ADMIN))
			return -EPERM;
		tmp = scull_qset;
		retval = __get_user(scull_qset, (int __user *)arg);
		if (retval == 0)
			retval = put_user(tmp, (int __user *)arg);
		break;

	  case SCULL_IOCHQSET:
		if (! capable (CAP_SYS_ADMIN))
			return -EPERM;
		tmp = scull_qset;
		scull_qset = arg;
		return tmp;

        /*
         * The following two change the buffer size for scullpipe.
         * The scullpipe device uses this same ioctl method, just to
         * write less code. Actually, it's the same driver, isn't it?
         */
	  case SCULL_P_IOCTSIZE:
		scull_p_buffer = arg;
		break;

	  case SCULL_P_IOCQSIZE:
		return scull_p_buffer;

	  default:  /* redundant, as cmd was checked against MAXNR */
		return -ENOTTY;
	}

	return retval;
}
Esempio n. 6
0
/*!
 * This function implements IOCTL controls on a PMIC device.
 *
 * @param        inode       pointer on the node
 * @param        file        pointer on the file
 * @param        cmd         the command
 * @param        arg         the parameter
 * @return       This function returns 0 if successful.
 */
static int pmic_dev_ioctl(struct inode *inode, struct file *file,
			  unsigned int cmd, unsigned long arg)
{
	register_info reg_info;
	pmic_event_callback_t event_sub;
	type_event event = EVENT_NB;
	int ret = 0;

	if (_IOC_TYPE(cmd) != 'P')
		return -ENOTTY;

	switch (cmd) {
	case PMIC_READ_REG:
		if (copy_from_user(&reg_info, (register_info *) arg,
				   sizeof(register_info))) {
			return -EFAULT;
		}
		ret =
		    pmic_read_reg(reg_info.reg, &(reg_info.reg_value),
				  0x00ffffff);
		pr_debug("read reg %d %x\n", reg_info.reg, reg_info.reg_value);
		if (copy_to_user((register_info *) arg, &reg_info,
				 sizeof(register_info))) {
			return -EFAULT;
		}
		break;

	case PMIC_WRITE_REG:
		if (copy_from_user(&reg_info, (register_info *) arg,
				   sizeof(register_info))) {
			return -EFAULT;
		}
		ret =
		    pmic_write_reg(reg_info.reg, reg_info.reg_value,
				   0x00ffffff);
		pr_debug("write reg %d %x\n", reg_info.reg, reg_info.reg_value);
		if (copy_to_user((register_info *) arg, &reg_info,
				 sizeof(register_info))) {
			return -EFAULT;
		}
		break;

	case PMIC_SUBSCRIBE:
		if (get_user(event, (int __user *)arg)) {
			return -EFAULT;
		}
		event_sub.func = callbackfn;
		event_sub.param = (void *)event;
		ret = pmic_event_subscribe(event, event_sub);
		pr_debug("subscribe done\n");
		break;

	case PMIC_UNSUBSCRIBE:
		if (get_user(event, (int __user *)arg)) {
			return -EFAULT;
		}
		event_sub.func = callbackfn;
		event_sub.param = (void *)event;
		ret = pmic_event_unsubscribe(event, event_sub);
		pr_debug("unsubscribe done\n");
		break;

	case PMIC_NOTIFY_USER:
		if (get_user(event, (int __user *)arg)) {
			return -EFAULT;
		}
		event_sub.func = user_notify_callback;
		event_sub.param = (void *)event;
		ret = pmic_event_subscribe(event, event_sub);
		break;

	case PMIC_GET_NOTIFY:
		down(&event_mutex);
		if (CIRC_CNT(pmic_events.head, pmic_events.tail, CIRC_BUF_MAX)) {
			event = (int)pmic_events.buf[pmic_events.tail];
			pmic_events.tail = (pmic_events.tail + 1) & (CIRC_BUF_MAX - 1);
		} else {
			pr_info("No valid notified event\n");
		}
		up(&event_mutex);

		if (put_user(event, (int __user *)arg)) {
			return -EFAULT;
		}
		break;

	default:
		printk(KERN_ERR "%d unsupported ioctl command\n", (int)cmd);
		return -EINVAL;
	}

	return ret;
}
Esempio n. 7
0
long mdm_modem_ioctl(struct file *filp, unsigned int cmd,
				unsigned long arg)
{
	int status, ret = 0;

	if (_IOC_TYPE(cmd) != CHARM_CODE) {
		pr_err("%s: invalid ioctl code\n", __func__);
		return -EINVAL;
	}

	pr_debug("%s: Entering ioctl cmd = %d\n", __func__, _IOC_NR(cmd));
	switch (cmd) {
	case WAKE_CHARM:
		pr_info("%s: Powering on mdm\n", __func__);
		mdm_drv->ops->power_on_mdm_cb(mdm_drv);
		break;
	case CHECK_FOR_BOOT:
		if (gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 0)
			put_user(1, (unsigned long __user *) arg);
		else
			put_user(0, (unsigned long __user *) arg);
		break;
	case NORMAL_BOOT_DONE:
		pr_debug("%s: check if mdm is booted up\n", __func__);
		get_user(status, (unsigned long __user *) arg);
		if (status) {
			pr_debug("%s: normal boot failed\n", __func__);
			mdm_drv->mdm_boot_status = -EIO;
		} else {
			pr_info("%s: normal boot done\n", __func__);
			mdm_drv->mdm_boot_status = 0;
		}
		mdm_drv->mdm_ready = 1;

		if (mdm_drv->ops->normal_boot_done_cb != NULL)
			mdm_drv->ops->normal_boot_done_cb(mdm_drv);

		if (!first_boot)
			complete(&mdm_boot);
		else
			first_boot = 0;

		/* If successful, start a timer to check that the mdm2ap_status
		 * gpio goes high.
		 */
		if (!status && gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 0)
			schedule_delayed_work(&mdm2ap_status_check_work,
				msecs_to_jiffies(MDM2AP_STATUS_TIMEOUT_MS));
		break;
	case RAM_DUMP_DONE:
		pr_debug("%s: mdm done collecting RAM dumps\n", __func__);
		get_user(status, (unsigned long __user *) arg);
		if (status)
			mdm_drv->mdm_ram_dump_status = -EIO;
		else {
			pr_info("%s: ramdump collection completed\n", __func__);
			mdm_drv->mdm_ram_dump_status = 0;
		}
		complete(&mdm_ram_dumps);
		break;
	case WAIT_FOR_RESTART:
		pr_debug("%s: wait for mdm to need images reloaded\n",
				__func__);
		ret = wait_for_completion_interruptible(&mdm_needs_reload);
		if (!ret)
			put_user(mdm_drv->boot_type,
					 (unsigned long __user *) arg);
		INIT_COMPLETION(mdm_needs_reload);
		break;
	case GET_DLOAD_STATUS:
		pr_debug("getting status of mdm2ap_errfatal_gpio\n");
		if (gpio_get_value(mdm_drv->mdm2ap_errfatal_gpio) == 1 &&
			!mdm_drv->mdm_ready)
			put_user(1, (unsigned long __user *) arg);
		else
			put_user(0, (unsigned long __user *) arg);
		break;
	case IMAGE_UPGRADE:
		pr_debug("%s Image upgrade ioctl recieved\n", __func__);
		if (mdm_drv->pdata->image_upgrade_supported &&
				mdm_drv->ops->image_upgrade_cb) {
			get_user(status, (unsigned long __user *) arg);
			mdm_drv->ops->image_upgrade_cb(mdm_drv, status);
		} else
			pr_debug("%s Image upgrade not supported\n", __func__);
		break;
	case SHUTDOWN_CHARM:
		if (!mdm_drv->pdata->send_shdn)
			break;
		mdm_drv->mdm_ready = 0;
		if (mdm_debug_mask & MDM_DEBUG_MASK_SHDN_LOG)
			pr_info("Sending shutdown request to mdm\n");
		ret = sysmon_send_shutdown(SYSMON_SS_EXT_MODEM);
		if (ret)
			pr_err("%s: Graceful shutdown of the external modem failed, ret = %d\n",
				   __func__, ret);
		break;
	default:
		pr_err("%s: invalid ioctl cmd = %d\n", __func__, _IOC_NR(cmd));
		ret = -EINVAL;
		break;
	}

	return ret;
}
Esempio n. 8
0
/*
 * ioctl calls for this driver. Why return -ENOTTY upon error? Because
 * POSIX says so!
 */
static int pcf8563_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	/* Some sanity checks. */
	if (_IOC_TYPE(cmd) != RTC_MAGIC)
		return -ENOTTY;

	if (_IOC_NR(cmd) > RTC_MAX_IOCTL)
		return -ENOTTY;

	switch (cmd) {
	case RTC_RD_TIME:
	{
		struct rtc_time tm;

		mutex_lock(&rtc_lock);
		memset(&tm, 0, sizeof tm);
		get_rtc_time(&tm);

		if (copy_to_user((struct rtc_time *) arg, &tm,
				 sizeof tm)) {
			mutex_unlock(&rtc_lock);
			return -EFAULT;
		}

		mutex_unlock(&rtc_lock);

		return 0;
	}
	case RTC_SET_TIME:
	{
		int leap;
		int year;
		int century;
		struct rtc_time tm;

		memset(&tm, 0, sizeof tm);
		if (!capable(CAP_SYS_TIME))
			return -EPERM;

		if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof tm))
			return -EFAULT;

		/* Convert from struct tm to struct rtc_time. */
		tm.tm_year += 1900;
		tm.tm_mon += 1;

		/*
		 * Check if tm.tm_year is a leap year. A year is a leap
		 * year if it is divisible by 4 but not 100, except
		 * that years divisible by 400 _are_ leap years.
		 */
		year = tm.tm_year;
		leap = (tm.tm_mon == 2) &&
			((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);

		/* Perform some sanity checks. */
		if ((tm.tm_year < 1970) ||
		    (tm.tm_mon > 12) ||
		    (tm.tm_mday == 0) ||
		    (tm.tm_mday > days_in_month[tm.tm_mon] + leap) ||
		    (tm.tm_wday >= 7) ||
		    (tm.tm_hour >= 24) ||
		    (tm.tm_min >= 60) ||
		    (tm.tm_sec >= 60))
			return -EINVAL;

		century = (tm.tm_year >= 2000) ? 0x80 : 0;
		tm.tm_year = tm.tm_year % 100;

		tm.tm_year = bin2bcd(tm.tm_year);
		tm.tm_mon = bin2bcd(tm.tm_mon);
		tm.tm_mday = bin2bcd(tm.tm_mday);
		tm.tm_hour = bin2bcd(tm.tm_hour);
		tm.tm_min = bin2bcd(tm.tm_min);
		tm.tm_sec = bin2bcd(tm.tm_sec);
		tm.tm_mon |= century;

		mutex_lock(&rtc_lock);

		rtc_write(RTC_YEAR, tm.tm_year);
		rtc_write(RTC_MONTH, tm.tm_mon);
		rtc_write(RTC_WEEKDAY, tm.tm_wday); /* Not coded in BCD. */
		rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday);
		rtc_write(RTC_HOURS, tm.tm_hour);
		rtc_write(RTC_MINUTES, tm.tm_min);
		rtc_write(RTC_SECONDS, tm.tm_sec);

		mutex_unlock(&rtc_lock);

		return 0;
	}
	case RTC_VL_READ:
		if (voltage_low) {
			printk(KERN_ERR "%s: RTC Voltage Low - "
			       "reliable date/time information is no "
			       "longer guaranteed!\n", PCF8563_NAME);
		}

		if (copy_to_user((int *) arg, &voltage_low, sizeof(int)))
			return -EFAULT;
		return 0;

	case RTC_VL_CLR:
	{
		/* Clear the VL bit in the seconds register in case
		 * the time has not been set already (which would
		 * have cleared it). This does not really matter
		 * because of the cached voltage_low value but do it
		 * anyway for consistency. */

		int ret = rtc_read(RTC_SECONDS);

		rtc_write(RTC_SECONDS, (ret & 0x7F));

		/* Clear the cached value. */
		voltage_low = 0;

		return 0;
	}
	default:
		return -ENOTTY;
	}

	return 0;
}
Esempio n. 9
0
/*!
 * This function implements IOCTL controls on a PMIC Battery device.
 *
 * @param        inode       pointer on the node
 * @param        file        pointer on the file
 * @param        cmd         the command
 * @param        arg         the parameter
 * @return       This function returns 0 if successful.
 */
static int pmic_battery_ioctl(struct inode *inode, struct file *file,
			      unsigned int cmd, unsigned long arg)
{
	t_charger_setting *chgr_setting = NULL;
	unsigned short c_current;
	unsigned int bc_info;
	t_eol_setting *eol_setting;

	if (_IOC_TYPE(cmd) != 'p')
		return -ENOTTY;

	switch (cmd) {
	case PMIC_BATT_CHARGER_CONTROL:
		if ((chgr_setting = kmalloc(sizeof(t_charger_setting),
					    GFP_KERNEL)) == NULL) {
			return -ENOMEM;
		}
		if (copy_from_user(chgr_setting, (t_charger_setting *) arg,
				   sizeof(t_charger_setting))) {
			kfree(chgr_setting);
			return -EFAULT;
		}

		if (chgr_setting->on != false) {
			CHECK_ERROR_KFREE(pmic_batt_enable_charger
					  (chgr_setting->chgr,
					   chgr_setting->c_voltage,
					   chgr_setting->c_current),
					  (kfree(chgr_setting)));
		} else {
			CHECK_ERROR(pmic_batt_disable_charger
				    (chgr_setting->chgr));
		}

		kfree(chgr_setting);
		break;

	case PMIC_BATT_SET_CHARGER:
		if ((chgr_setting = kmalloc(sizeof(t_charger_setting),
					    GFP_KERNEL)) == NULL) {
			return -ENOMEM;
		}
		if (copy_from_user(chgr_setting, (t_charger_setting *) arg,
				   sizeof(t_charger_setting))) {
			kfree(chgr_setting);
			return -EFAULT;
		}

		CHECK_ERROR_KFREE(pmic_batt_set_charger(chgr_setting->chgr,
							chgr_setting->c_voltage,
							chgr_setting->
							c_current),
				  (kfree(chgr_setting)));

		kfree(chgr_setting);
		break;

	case PMIC_BATT_GET_CHARGER:
		if ((chgr_setting = kmalloc(sizeof(t_charger_setting),
					    GFP_KERNEL)) == NULL) {
			return -ENOMEM;
		}
		if (copy_from_user(chgr_setting, (t_charger_setting *) arg,
				   sizeof(t_charger_setting))) {
			kfree(chgr_setting);
			return -EFAULT;
		}

		CHECK_ERROR_KFREE(pmic_batt_get_charger_setting
				  (chgr_setting->chgr, &chgr_setting->c_voltage,
				   &chgr_setting->c_current),
				  (kfree(chgr_setting)));
		if (copy_to_user
		    ((t_charger_setting *) arg, chgr_setting,
		     sizeof(t_charger_setting))) {
			return -EFAULT;
		}

		kfree(chgr_setting);
		break;

	case PMIC_BATT_GET_CHARGER_SENSOR:
		{
			t_sensor_bits sensor;
			pmic_get_sensors(&sensor);
			if (copy_to_user
			    ((unsigned int *)arg, &sensor.sense_chgdets,
			     sizeof(unsigned int)))
				return -EFAULT;

			break;
		}
	case PMIC_BATT_GET_BATTERY_VOLTAGE:
		CHECK_ERROR(pmic_batt_get_batt_voltage(&c_current));
		bc_info = (unsigned int)c_current * 2300 / 1023 + 2400;
		if (copy_to_user((unsigned int *)arg, &bc_info,
				 sizeof(unsigned int)))
			return -EFAULT;

		break;

	case PMIC_BATT_GET_BATTERY_CURRENT:
		CHECK_ERROR(pmic_batt_get_batt_current(&c_current));
		bc_info = (unsigned int)c_current * 5750 / 1023;
		if (copy_to_user((unsigned int *)arg, &bc_info,
				 sizeof(unsigned int)))
			return -EFAULT;
		break;

	case PMIC_BATT_GET_BATTERY_TEMPERATURE:
		CHECK_ERROR(pmic_batt_get_batt_temperature(&c_current));
		bc_info = (unsigned int)c_current;
		if (copy_to_user((unsigned int *)arg, &bc_info,
				 sizeof(unsigned int)))
			return -EFAULT;

		break;

	case PMIC_BATT_GET_CHARGER_VOLTAGE:
		CHECK_ERROR(pmic_batt_get_charge_voltage(&c_current));
		bc_info = (unsigned int)c_current * 23000 / 1023;
		if (copy_to_user((unsigned int *)arg, &bc_info,
				 sizeof(unsigned int)))
			return -EFAULT;

		break;

	case PMIC_BATT_GET_CHARGER_CURRENT:
		CHECK_ERROR(pmic_batt_get_charge_current(&c_current));
		bc_info = (unsigned int)c_current * 5750 / 1023;
		if (copy_to_user((unsigned int *)arg, &bc_info,
				 sizeof(unsigned int)))
			return -EFAULT;

		break;

	case PMIC_BATT_EOL_CONTROL:
		if ((eol_setting = kmalloc(sizeof(t_eol_setting), GFP_KERNEL))
		    == NULL) {
			return -ENOMEM;
		}
		if (copy_from_user(eol_setting, (t_eol_setting *) arg,
				   sizeof(t_eol_setting))) {
			kfree(eol_setting);
			return -EFAULT;
		}

		if (eol_setting->enable != false) {
			CHECK_ERROR_KFREE(pmic_batt_bp_enable_eol
					  (eol_setting->typical),
					  (kfree(chgr_setting)));
		} else {
			CHECK_ERROR_KFREE(pmic_batt_disable_eol(),
					  (kfree(chgr_setting)));
		}

		kfree(eol_setting);
		break;

	case PMIC_BATT_SET_OUT_CONTROL:
		CHECK_ERROR(pmic_batt_set_out_control((t_control) arg));
		break;

	case PMIC_BATT_SET_THRESHOLD:
		CHECK_ERROR(pmic_batt_set_threshold((int)arg));
		break;

	case PMIC_BATT_LED_CONTROL:
		CHECK_ERROR(pmic_batt_led_control((bool) arg));
		break;

	case PMIC_BATT_REV_SUPP_CONTROL:
		CHECK_ERROR(pmic_batt_set_reverse_supply((bool) arg));
		break;

	case PMIC_BATT_UNREG_CONTROL:
		CHECK_ERROR(pmic_batt_set_unregulated((bool) arg));
		break;

	default:
		return -EINVAL;
	}
	return 0;
}
Esempio n. 10
0
STATIC      status_t
c4_ioctl (struct net_device * ndev, struct ifreq * ifr, int cmd)
{
    ci_t       *ci;
    void       *data;
    int         iocmd, iolen;
    status_t    ret;
    static struct data
    {
        union
        {
            u_int8_t c;
            u_int32_t i;
            struct sbe_brd_info bip;
            struct sbe_drv_info dip;
            struct sbe_iid_info iip;
            struct sbe_brd_addr bap;
            struct sbecom_chan_stats stats;
            struct sbecom_chan_param param;
            struct temux_card_stats cards;
            struct sbecom_card_param cardp;
            struct sbecom_framer_param frp;
        }           u;
    }           arg;

    if (!capable (CAP_SYS_ADMIN))
        return -EPERM;
    if (cmd != SIOCDEVPRIVATE + 15)
        return -EINVAL;
    if (!(ci = get_ci_by_dev (ndev)))
        return -EINVAL;
    if (ci->state != C_RUNNING)
        return -ENODEV;
    if (copy_from_user (&iocmd, ifr->ifr_data, sizeof (iocmd)))
        return -EFAULT;
#if 0
    if (copy_from_user (&len, ifr->ifr_data + sizeof (iocmd), sizeof (len)))
        return -EFAULT;
#endif

#if 0
    pr_info("c4_ioctl: iocmd %x, dir %x type %x nr %x iolen %d.\n", iocmd,
            _IOC_DIR (iocmd), _IOC_TYPE (iocmd), _IOC_NR (iocmd),
            _IOC_SIZE (iocmd));
#endif
    iolen = _IOC_SIZE (iocmd);
    data = ifr->ifr_data + sizeof (iocmd);
    if (copy_from_user (&arg, data, iolen))
        return -EFAULT;

    ret = 0;
    switch (iocmd)
    {
    case SBE_IOC_PORT_GET:
        //pr_info(">> SBE_IOC_PORT_GET Ioctl...\n");
        ret = do_get_port (ndev, data);
        break;
    case SBE_IOC_PORT_SET:
        //pr_info(">> SBE_IOC_PORT_SET Ioctl...\n");
        ret = do_set_port (ndev, data);
        break;
    case SBE_IOC_CHAN_GET:
        //pr_info(">> SBE_IOC_CHAN_GET Ioctl...\n");
        ret = do_get_chan (ndev, data);
        break;
    case SBE_IOC_CHAN_SET:
        //pr_info(">> SBE_IOC_CHAN_SET Ioctl...\n");
        ret = do_set_chan (ndev, data);
        break;
    case C4_DEL_CHAN:
        //pr_info(">> C4_DEL_CHAN Ioctl...\n");
        ret = do_del_chan (ndev, data);
        break;
    case SBE_IOC_CHAN_NEW:
        ret = do_create_chan (ndev, data);
        break;
    case SBE_IOC_CHAN_GET_STAT:
        ret = do_get_chan_stats (ndev, data);
        break;
    case SBE_IOC_LOGLEVEL:
        ret = do_set_loglevel (ndev, data);
        break;
    case SBE_IOC_RESET_DEV:
        ret = do_reset (ndev, data);
        break;
    case SBE_IOC_CHAN_DEL_STAT:
        ret = do_reset_chan_stats (ndev, data);
        break;
    case C4_LOOP_PORT:
        ret = do_port_loop (ndev, data);
        break;
    case C4_RW_FRMR:
        ret = do_framer_rw (ndev, data);
        break;
    case C4_RW_MSYC:
        ret = do_musycc_rw (ndev, data);
        break;
    case C4_RW_PLD:
        ret = do_pld_rw (ndev, data);
        break;
    case SBE_IOC_IID_GET:
        ret = (iolen == sizeof (struct sbe_iid_info)) ? c4_get_iidinfo (ci, &arg.u.iip) : -EFAULT;
        if (ret == 0)               /* no error, copy data */
            if (copy_to_user (data, &arg, iolen))
                return -EFAULT;
        break;
    default:
        //pr_info(">> c4_ioctl: EINVAL - unknown iocmd <%x>\n", iocmd);
        ret = -EINVAL;
        break;
    }
    return mkret (ret);
}
long mdm_modem_ioctl(struct file *filp, unsigned int cmd,
				unsigned long arg)
{
	int status, ret = 0;

	if (_IOC_TYPE(cmd) != CHARM_CODE) {
		pr_err("%s: invalid ioctl code\n", __func__);
		return -EINVAL;
	}

	pr_debug("%s: Entering ioctl cmd = %d\n", __func__, _IOC_NR(cmd));
	switch (cmd) {
	case WAKE_CHARM:
		pr_info("%s: Powering on mdm\n", __func__);
		mdm_drv->ops->power_on_mdm_cb(mdm_drv);
		break;
	case CHECK_FOR_BOOT:
		if (gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 0)
			put_user(1, (unsigned long __user *) arg);
		else
			put_user(0, (unsigned long __user *) arg);
		break;
	case NORMAL_BOOT_DONE:
		pr_debug("%s: check if mdm is booted up\n", __func__);
		get_user(status, (unsigned long __user *) arg);
		if (status) {
			pr_debug("%s: normal boot failed\n", __func__);
			mdm_drv->mdm_boot_status = -EIO;
		} else {
			pr_info("%s: normal boot done\n", __func__);
			mdm_drv->mdm_boot_status = 0;
		}
		mdm_drv->mdm_ready = 1;

		if (mdm_drv->ops->normal_boot_done_cb != NULL)
			mdm_drv->ops->normal_boot_done_cb(mdm_drv);

		if (!first_boot)
			complete(&mdm_boot);
		else
			first_boot = 0;
		break;
	case RAM_DUMP_DONE:
		pr_debug("%s: mdm done collecting RAM dumps\n", __func__);
		get_user(status, (unsigned long __user *) arg);
		if (status)
			mdm_drv->mdm_ram_dump_status = -EIO;
		else {
			pr_info("%s: ramdump collection completed\n", __func__);
			mdm_drv->mdm_ram_dump_status = 0;
		}
		complete(&mdm_ram_dumps);
		break;
	case WAIT_FOR_RESTART:
		pr_debug("%s: wait for mdm to need images reloaded\n",
				__func__);
		ret = wait_for_completion_interruptible(&mdm_needs_reload);
		if (!ret)
			put_user(mdm_drv->boot_type,
					 (unsigned long __user *) arg);
		INIT_COMPLETION(mdm_needs_reload);
		break;
	default:
		pr_err("%s: invalid ioctl cmd = %d\n", __func__, _IOC_NR(cmd));
		ret = -EINVAL;
		break;
	}

	return ret;
}
Esempio n. 12
0
/*
 * "ioctl" file op
 */
static int hiddev_ioctl(struct inode *inode, struct file *file,
			unsigned int cmd, unsigned long arg)
{
	struct hiddev_list *list = file->private_data;
	struct hiddev *hiddev = list->hiddev;
	struct hid_device *hid = hiddev->hid;
	struct usb_device *dev = hid->dev;
	struct hiddev_report_info rinfo;
	struct hiddev_usage_ref uref;
	struct hid_report *report;
	struct hid_field *field;

	if (!hiddev->exist) return -EIO;

	switch (cmd) {

	case HIDIOCGVERSION:
		return put_user(HID_VERSION, (int *) arg);

	case HIDIOCAPPLICATION:
		if (arg < 0 || arg >= hid->maxapplication)
			return -EINVAL;
		return hid->application[arg];

	case HIDIOCGDEVINFO:
	{
		struct hiddev_devinfo dinfo;
		dinfo.bustype = BUS_USB;
		dinfo.busnum = dev->bus->busnum;
		dinfo.devnum = dev->devnum;
		dinfo.ifnum = hid->ifnum;
		dinfo.vendor = dev->descriptor.idVendor;
		dinfo.product = dev->descriptor.idProduct;
		dinfo.version = dev->descriptor.bcdDevice;
		dinfo.num_applications = hid->maxapplication;
		return copy_to_user((void *) arg, &dinfo, sizeof(dinfo));
	}

	case HIDIOCGSTRING:
		{
			int idx, len;
			char *buf;

			if (get_user(idx, (int *) arg))
				return -EFAULT;

			if ((buf = kmalloc(HID_STRING_SIZE, GFP_KERNEL)) == NULL)
				return -ENOMEM;

			if ((len = usb_string(dev, idx, buf, HID_STRING_SIZE-1)) < 0) {
				kfree(buf);
				return -EINVAL;
			}

			if (copy_to_user((void *) (arg+sizeof(int)), buf, len+1)) {
				kfree(buf);
				return -EFAULT;
			}

			kfree(buf);

			return len;
		}

	case HIDIOCINITREPORT:

		hid_init_reports(hid);

		return 0;

	case HIDIOCGREPORT:
		if (copy_from_user(&rinfo, (void *) arg, sizeof(rinfo)))
			return -EFAULT;

		if (rinfo.report_type == HID_REPORT_TYPE_OUTPUT)
			return -EINVAL;

		if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
			return -EINVAL;

		hid_read_report(hid, report);

		return 0;

	case HIDIOCSREPORT:
		if (copy_from_user(&rinfo, (void *) arg, sizeof(rinfo)))
			return -EFAULT;

		if (rinfo.report_type == HID_REPORT_TYPE_INPUT)
			return -EINVAL;

		if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
			return -EINVAL;

		hid_write_report(hid, report);

		return 0;

	case HIDIOCGREPORTINFO:
		if (copy_from_user(&rinfo, (void *) arg, sizeof(rinfo)))
			return -EFAULT;

		if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
			return -EINVAL;

		rinfo.num_fields = report->maxfield;

		return copy_to_user((void *) arg, &rinfo, sizeof(rinfo));

	case HIDIOCGFIELDINFO:
	{
		struct hiddev_field_info finfo;
		if (copy_from_user(&finfo, (void *) arg, sizeof(finfo)))
			return -EFAULT;
		rinfo.report_type = finfo.report_type;
		rinfo.report_id = finfo.report_id;
		if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
			return -EINVAL;

		if (finfo.field_index >= report->maxfield)
			return -EINVAL;

		field = report->field[finfo.field_index];
		memset(&finfo, 0, sizeof(finfo));
		finfo.report_type = rinfo.report_type;
		finfo.report_id = rinfo.report_id;
		finfo.field_index = field->report_count - 1;
		finfo.maxusage = field->maxusage;
		finfo.flags = field->flags;
		finfo.physical = field->physical;
		finfo.logical = field->logical;
		finfo.application = field->application;
		finfo.logical_minimum = field->logical_minimum;
		finfo.logical_maximum = field->logical_maximum;
		finfo.physical_minimum = field->physical_minimum;
		finfo.physical_maximum = field->physical_maximum;
		finfo.unit_exponent = field->unit_exponent;
		finfo.unit = field->unit;

		return copy_to_user((void *) arg, &finfo, sizeof(finfo));
	}

	case HIDIOCGUCODE:
		if (copy_from_user(&uref, (void *) arg, sizeof(uref)))
			return -EFAULT;

		rinfo.report_type = uref.report_type;
		rinfo.report_id = uref.report_id;
		if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
			return -EINVAL;

		if (uref.field_index >= report->maxfield)
			return -EINVAL;

		field = report->field[uref.field_index];
		if (uref.usage_index >= field->maxusage)
			return -EINVAL;

		uref.usage_code = field->usage[uref.usage_index].hid;

		return copy_to_user((void *) arg, &uref, sizeof(uref));

	case HIDIOCGUSAGE:
		if (copy_from_user(&uref, (void *) arg, sizeof(uref)))
			return -EFAULT;

		if (uref.report_id == HID_REPORT_ID_UNKNOWN) {
			field = hiddev_lookup_usage(hid, &uref);
			if (field == NULL)
				return -EINVAL;
		} else {
			rinfo.report_type = uref.report_type;
			rinfo.report_id = uref.report_id;
			if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
				return -EINVAL;

			if (uref.field_index >= report->maxfield)
				return -EINVAL;

			field = report->field[uref.field_index];
			if (uref.usage_index >= field->maxusage)
				return -EINVAL;
		}

		uref.value = field->value[uref.usage_index];

		return copy_to_user((void *) arg, &uref, sizeof(uref));

	case HIDIOCSUSAGE:
		if (copy_from_user(&uref, (void *) arg, sizeof(uref)))
			return -EFAULT;

		if (uref.report_type == HID_REPORT_TYPE_INPUT)
			return -EINVAL;

		if (uref.report_id == HID_REPORT_ID_UNKNOWN) {
			field = hiddev_lookup_usage(hid, &uref);
			if (field == NULL)
				return -EINVAL;
		} else {
			rinfo.report_type = uref.report_type;
			rinfo.report_id = uref.report_id;
			if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
				return -EINVAL;

			if (uref.field_index >= report->maxfield)
				return -EINVAL;

			field = report->field[uref.field_index];
			if (uref.usage_index >= field->maxusage)
				return -EINVAL;
		}

		field->value[uref.usage_index] = uref.value;

		return 0;

	default:

		if (_IOC_TYPE(cmd) != 'H' || _IOC_DIR(cmd) != _IOC_READ)
			return -EINVAL;

		if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGNAME(0))) {
			int len;
			if (!hid->name) return 0;
			len = strlen(hid->name) + 1;
			if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
			return copy_to_user((char *) arg, hid->name, len) ?
				-EFAULT : len;
		}
	}
	return -EINVAL;
}
long msm_isp_ioctl(struct v4l2_subdev *sd,
	unsigned int cmd, void *arg)
{
	long rc = 0;
	struct vfe_device *vfe_dev = v4l2_get_subdevdata(sd);

	if (!vfe_dev) {
		pr_err("%s: vfe_dev NULL\n", __func__);
		return -EINVAL;
	}
	/* Use real time mutex for hard real-time ioctls such as
	 * buffer operations and register updates.
	 * Use core mutex for other ioctls that could take
	 * longer time to complete such as start/stop ISP streams
	 * which blocks until the hardware start/stop streaming
	 */
	ISP_DBG("%s cmd: %d\n", __func__, _IOC_TYPE(cmd));
	switch (cmd) {
	case VIDIOC_MSM_VFE_REG_CFG: {
		mutex_lock(&vfe_dev->realtime_mutex);
		rc = msm_isp_proc_cmd(vfe_dev, arg);
		mutex_unlock(&vfe_dev->realtime_mutex);
		break;
	}
	case VIDIOC_MSM_ISP_REQUEST_BUF:
	case VIDIOC_MSM_ISP_ENQUEUE_BUF:
	case VIDIOC_MSM_ISP_RELEASE_BUF: {
		mutex_lock(&vfe_dev->realtime_mutex);
		rc = msm_isp_proc_buf_cmd(vfe_dev->buf_mgr, cmd, arg);
		mutex_unlock(&vfe_dev->realtime_mutex);
		break;
	}
	case VIDIOC_MSM_ISP_REQUEST_STREAM:
		mutex_lock(&vfe_dev->core_mutex);
		rc = msm_isp_request_axi_stream(vfe_dev, arg);
		mutex_unlock(&vfe_dev->core_mutex);
		break;
	case VIDIOC_MSM_ISP_RELEASE_STREAM:
		mutex_lock(&vfe_dev->core_mutex);
		rc = msm_isp_release_axi_stream(vfe_dev, arg);
		mutex_unlock(&vfe_dev->core_mutex);
		break;
	case VIDIOC_MSM_ISP_CFG_STREAM:
		mutex_lock(&vfe_dev->core_mutex);
		rc = msm_isp_cfg_axi_stream(vfe_dev, arg);
		mutex_unlock(&vfe_dev->core_mutex);
		break;
	case VIDIOC_MSM_ISP_INPUT_CFG:
		mutex_lock(&vfe_dev->core_mutex);
		rc = msm_isp_cfg_input(vfe_dev, arg);
		mutex_unlock(&vfe_dev->core_mutex);
		break;
	case VIDIOC_MSM_ISP_SET_SRC_STATE:
		mutex_lock(&vfe_dev->core_mutex);
		msm_isp_set_src_state(vfe_dev, arg);
		mutex_unlock(&vfe_dev->core_mutex);
		break;
	case VIDIOC_MSM_ISP_REQUEST_STATS_STREAM:
		mutex_lock(&vfe_dev->core_mutex);
		rc = msm_isp_request_stats_stream(vfe_dev, arg);
		mutex_unlock(&vfe_dev->core_mutex);
		break;
	case VIDIOC_MSM_ISP_RELEASE_STATS_STREAM:
		mutex_lock(&vfe_dev->core_mutex);
		rc = msm_isp_release_stats_stream(vfe_dev, arg);
		mutex_unlock(&vfe_dev->core_mutex);
		break;
	case VIDIOC_MSM_ISP_CFG_STATS_STREAM:
		mutex_lock(&vfe_dev->core_mutex);
		rc = msm_isp_cfg_stats_stream(vfe_dev, arg);
		mutex_unlock(&vfe_dev->core_mutex);
		break;
	case VIDIOC_MSM_ISP_UPDATE_STREAM:
		mutex_lock(&vfe_dev->core_mutex);
		rc = msm_isp_update_axi_stream(vfe_dev, arg);
		mutex_unlock(&vfe_dev->core_mutex);
		break;
	case MSM_SD_SHUTDOWN:
		while (vfe_dev->vfe_open_cnt != 0)
			msm_isp_close_node(sd, NULL);
		rc = 0;
		break;

	default:
		pr_err("%s: Invalid ISP command\n", __func__);
		rc = -EINVAL;
	}
	return rc;
}
Esempio n. 14
0
/*
 * IOCTL
 */
int lighty_ioctl(struct inode * i_node, struct file * file, unsigned int cmd,
                                                            unsigned long arg)
{
	int err = 0;
	int retval = 0;
	struct urb *usb_led;
	char command; // a, b, c ,d, e, f
	char *buf;
	struct usb_lighty *dev = file->private_data;
       /*
        * extract the type and number bitfields, and don't decode
        * wrong cmds: return ENOTTY (inappropriate ioctl) before access_ok()
        */
        if (_IOC_TYPE(cmd) != LIGHTY_IOCTL_MAGIC)
        {
                printk(KERN_NOTICE
                        "lighty_ioctl: !lighty_IOC_MAGIC\n");
                return -ENOTTY;
        }
        if (_IOC_NR(cmd) > LIGHTY_IOCTL_MAX)
        {
                printk(KERN_NOTICE
                        "lighty_ioctl:  > lighty_IOC_MAXNR\n");
                return -ENOTTY;
        }

       /*
        * If not root/sysadmin, go away 
        */
        if (! capable (CAP_SYS_ADMIN))
                return -EPERM;

        /*
         * the direction is a bitmask, and VERIFY_WRITE catches R/W
         * transfers. `Type' is user-oriented, while
         * access_ok is kernel-oriented, so the concept of "read" and
         * "write" is reversed
         */
        if (_IOC_DIR(cmd) & _IOC_READ)
                err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
        else if (_IOC_DIR(cmd) & _IOC_WRITE)
                err =  !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
        if (err)
        {
                printk(KERN_NOTICE
                        "lighty_ioctl: access !ok\n");
                return -EFAULT;
        }


        switch(cmd) {
                case LIGHTY_IOCTL_1RED:
                        printk(KERN_NOTICE
                                "LIGHTY_IOCTL_1RED\n");
			command = 'a';
			break;
                case LIGHTY_IOCTL_1GREEN:
                        printk(KERN_NOTICE
                                "LIGHTY_IOCTL_1GREEN\n");
			command = 'b';
			break;
                case LIGHTY_IOCTL_1BLUE:
                        printk(KERN_NOTICE
                                "LIGHTY_IOCTL_1BLUE\n");
			command = 'c';
			break;
                case LIGHTY_IOCTL_2RED:
                        printk(KERN_NOTICE
                                "LIGHTY_IOCTL_2RED\n");
			command = 'd';
			break;
                case LIGHTY_IOCTL_2GREEN:
                        printk(KERN_NOTICE
                                "LIGHTY_IOCTL_2GREEN\n");
			command = 'e';
			break;
                case LIGHTY_IOCTL_2BLUE:
                        printk(KERN_NOTICE
                                "LIGHTY_IOCTL_2BLUE\n");
			command = 'f';
			break;
		default:
			printk(KERN_NOTICE
				"Not a known command %x\n", cmd);
			return -ENOMEM;
	}
	usb_led = usb_alloc_urb(0, GFP_KERNEL);
	if (!usb_led) {
		return -ENOMEM;
	}
	buf = usb_buffer_alloc(dev->udev, 64, GFP_KERNEL, &usb_led->transfer_dma);
	if (!buf) {
		printk (KERN_NOTICE "usb_buffer_alloc failed\n");
    		usb_buffer_free(dev->udev, usb_led->transfer_buffer_length,
            		usb_led->transfer_buffer, usb_led->transfer_dma);
		return -ENOMEM;
	}
	buf[0] = command; // a, b, c, d, e or f
	usb_fill_int_urb(usb_led, dev->udev, usb_sndintpipe(dev->udev, dev->intr_out_endpointAddr), buf,
				64, (usb_complete_t)lighty_write_intr_callback, dev, 250);
	usb_led->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
	if( (retval = usb_submit_urb(usb_led, GFP_KERNEL)) ) {
		err("%s - failed submitting write urb, error %d", __FUNCTION__, retval);
	}
	return 0;
}
Esempio n. 15
0
static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	struct usblp *usblp = file->private_data;
	int length, err, i;
	unsigned char newChannel;
	int status;
	int twoints[2];
	int retval = 0;

	mutex_lock(&usblp->mut);
	if (!usblp->present) {
		retval = -ENODEV;
		goto done;
	}

	dev_dbg(&usblp->intf->dev,
		"usblp_ioctl: cmd=0x%x (%c nr=%d len=%d dir=%d)\n", cmd,
		_IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd), _IOC_DIR(cmd));

	if (_IOC_TYPE(cmd) == 'P')	/* new-style ioctl number */

		switch (_IOC_NR(cmd)) {

		case IOCNR_GET_DEVICE_ID: /* get the DEVICE_ID string */
			if (_IOC_DIR(cmd) != _IOC_READ) {
				retval = -EINVAL;
				goto done;
			}

			length = usblp_cache_device_id_string(usblp);
			if (length < 0) {
				retval = length;
				goto done;
			}
			if (length > _IOC_SIZE(cmd))
				length = _IOC_SIZE(cmd); /* truncate */

			if (copy_to_user((void __user *) arg,
					usblp->device_id_string,
					(unsigned long) length)) {
				retval = -EFAULT;
				goto done;
			}

			break;

		case IOCNR_GET_PROTOCOLS:
			if (_IOC_DIR(cmd) != _IOC_READ ||
			    _IOC_SIZE(cmd) < sizeof(twoints)) {
				retval = -EINVAL;
				goto done;
			}

			twoints[0] = usblp->current_protocol;
			twoints[1] = 0;
			for (i = USBLP_FIRST_PROTOCOL;
			     i <= USBLP_LAST_PROTOCOL; i++) {
				if (usblp->protocol[i].alt_setting >= 0)
					twoints[1] |= (1<<i);
			}

			if (copy_to_user((void __user *)arg,
					(unsigned char *)twoints,
					sizeof(twoints))) {
				retval = -EFAULT;
				goto done;
			}

			break;

		case IOCNR_SET_PROTOCOL:
			if (_IOC_DIR(cmd) != _IOC_WRITE) {
				retval = -EINVAL;
				goto done;
			}

#ifdef DEBUG
			if (arg == -10) {
				usblp_dump(usblp);
				break;
			}
#endif

			usblp_unlink_urbs(usblp);
			retval = usblp_set_protocol(usblp, arg);
			if (retval < 0) {
				usblp_set_protocol(usblp,
					usblp->current_protocol);
			}
			break;

		case IOCNR_HP_SET_CHANNEL:
			if (_IOC_DIR(cmd) != _IOC_WRITE ||
			    le16_to_cpu(usblp->dev->descriptor.idVendor) != 0x03F0 ||
			    usblp->quirks & USBLP_QUIRK_BIDIR) {
				retval = -EINVAL;
				goto done;
			}

			err = usblp_hp_channel_change_request(usblp,
				arg, &newChannel);
			if (err < 0) {
				dev_err(&usblp->dev->dev,
					"usblp%d: error = %d setting "
					"HP channel\n",
					usblp->minor, err);
				retval = -EIO;
				goto done;
			}

			dev_dbg(&usblp->intf->dev,
				"usblp%d requested/got HP channel %ld/%d\n",
				usblp->minor, arg, newChannel);
			break;

		case IOCNR_GET_BUS_ADDRESS:
			if (_IOC_DIR(cmd) != _IOC_READ ||
			    _IOC_SIZE(cmd) < sizeof(twoints)) {
				retval = -EINVAL;
				goto done;
			}

			twoints[0] = usblp->dev->bus->busnum;
			twoints[1] = usblp->dev->devnum;
			if (copy_to_user((void __user *)arg,
					(unsigned char *)twoints,
					sizeof(twoints))) {
				retval = -EFAULT;
				goto done;
			}

			dev_dbg(&usblp->intf->dev,
				"usblp%d is bus=%d, device=%d\n",
				usblp->minor, twoints[0], twoints[1]);
			break;

		case IOCNR_GET_VID_PID:
			if (_IOC_DIR(cmd) != _IOC_READ ||
			    _IOC_SIZE(cmd) < sizeof(twoints)) {
				retval = -EINVAL;
				goto done;
			}

			twoints[0] = le16_to_cpu(usblp->dev->descriptor.idVendor);
			twoints[1] = le16_to_cpu(usblp->dev->descriptor.idProduct);
			if (copy_to_user((void __user *)arg,
					(unsigned char *)twoints,
					sizeof(twoints))) {
				retval = -EFAULT;
				goto done;
			}

			dev_dbg(&usblp->intf->dev,
				"usblp%d is VID=0x%4.4X, PID=0x%4.4X\n",
				usblp->minor, twoints[0], twoints[1]);
			break;

		case IOCNR_SOFT_RESET:
			if (_IOC_DIR(cmd) != _IOC_NONE) {
				retval = -EINVAL;
				goto done;
			}
			retval = usblp_reset(usblp);
			break;
		default:
			retval = -ENOTTY;
		}
	else	/* old-style ioctl value */
		switch (cmd) {

		case LPGETSTATUS:
			if ((retval = usblp_read_status(usblp, usblp->statusbuf))) {
				printk_ratelimited(KERN_ERR "usblp%d:"
					    "failed reading printer status (%d)\n",
					    usblp->minor, retval);
				retval = -EIO;
				goto done;
			}
			status = *usblp->statusbuf;
			if (copy_to_user((void __user *)arg, &status, sizeof(int)))
				retval = -EFAULT;
			break;

		case LPABORT:
			if (arg)
				usblp->flags |= LP_ABORT;
			else
				usblp->flags &= ~LP_ABORT;
			break;

		default:
			retval = -ENOTTY;
		}

done:
	mutex_unlock(&usblp->mut);
	return retval;
}
Esempio n. 16
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;

#ifdef CONFIG_DIAG_BRIDGE_CODE
	unsigned long spin_lock_flags;
#endif

	lge_dm_tty_drv = lge_dm_tty;
	tty->driver_data = lge_dm_tty_drv;
	lge_dm_tty_drv->tty_str = tty;

	result = 0;

	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_DIAG_BRIDGE_CODE
		if ((driver->usb_connected == 1) && (driver->count_hsic_pool == N_MDM_WRITE)) {
			spin_lock_irqsave(&driver->hsic_spinlock, spin_lock_flags);
			driver->count_hsic_pool = 0;
			spin_unlock_irqrestore(&driver->hsic_spinlock, spin_lock_flags);
		}
#endif

#ifdef CONFIG_DIAG_BRIDGE_CODE
		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;
		}

		diagfwd_disconnect_bridge(1);

		diagfwd_cancel_hsic();
		diagfwd_connect_bridge(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_BRIDGE_CODE
			/* Read data from the hsic */
			if (driver->hsic_ch)
				queue_work(driver->diag_bridge_wq,
				&driver->diag_read_hsic_work);
#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_BRIDGE_CODE
			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;
			}

			diagfwd_cancel_hsic();
			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;

}
Esempio n. 17
0
long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
{
	long ret = -ENOIOCTLCMD;

	if (!file->f_op->ioctl && !file->f_op->unlocked_ioctl)
		return ret;

	switch (cmd) {
#ifdef CONFIG_VIDEO_V4L1_COMPAT
	case VIDIOCGCAP:
	case VIDIOCGCHAN:
	case VIDIOCSCHAN:
	case VIDIOCGTUNER32:
	case VIDIOCSTUNER32:
	case VIDIOCGPICT:
	case VIDIOCSPICT:
	case VIDIOCCAPTURE32:
	case VIDIOCGWIN32:
	case VIDIOCSWIN32:
	case VIDIOCGFBUF32:
	case VIDIOCSFBUF32:
	case VIDIOCKEY:
	case VIDIOCGFREQ32:
	case VIDIOCSFREQ32:
	case VIDIOCGAUDIO:
	case VIDIOCSAUDIO:
	case VIDIOCSYNC32:
	case VIDIOCMCAPTURE:
	case VIDIOCGMBUF:
	case VIDIOCGUNIT:
	case VIDIOCGCAPTURE:
	case VIDIOCSCAPTURE:
	case VIDIOCSPLAYMODE:
	case VIDIOCSWRITEMODE32:
	case VIDIOCGPLAYINFO:
	case VIDIOCSMICROCODE32:
	case VIDIOCGVBIFMT:
	case VIDIOCSVBIFMT:
#endif
#ifdef __OLD_VIDIOC_
	case VIDIOC_OVERLAY32_OLD:
	case VIDIOC_S_PARM_OLD:
	case VIDIOC_S_CTRL_OLD:
	case VIDIOC_G_AUDIO_OLD:
	case VIDIOC_G_AUDOUT_OLD:
	case VIDIOC_CROPCAP_OLD:
#endif
	case VIDIOC_QUERYCAP:
	case VIDIOC_RESERVED:
	case VIDIOC_ENUM_FMT:
	case VIDIOC_G_FMT32:
	case VIDIOC_S_FMT32:
	case VIDIOC_REQBUFS:
	case VIDIOC_QUERYBUF32:
	case VIDIOC_G_FBUF32:
	case VIDIOC_S_FBUF32:
	case VIDIOC_OVERLAY32:
	case VIDIOC_QBUF32:
	case VIDIOC_DQBUF32:
	case VIDIOC_STREAMON32:
	case VIDIOC_STREAMOFF32:
	case VIDIOC_G_PARM:
	case VIDIOC_S_PARM:
	case VIDIOC_G_STD:
	case VIDIOC_S_STD:
	case VIDIOC_ENUMSTD32:
	case VIDIOC_ENUMINPUT32:
	case VIDIOC_G_CTRL:
	case VIDIOC_S_CTRL:
	case VIDIOC_G_TUNER:
	case VIDIOC_S_TUNER:
	case VIDIOC_G_AUDIO:
	case VIDIOC_S_AUDIO:
	case VIDIOC_QUERYCTRL:
	case VIDIOC_QUERYMENU:
	case VIDIOC_G_INPUT32:
	case VIDIOC_S_INPUT32:
	case VIDIOC_G_OUTPUT32:
	case VIDIOC_S_OUTPUT32:
	case VIDIOC_ENUMOUTPUT:
	case VIDIOC_G_AUDOUT:
	case VIDIOC_S_AUDOUT:
	case VIDIOC_G_MODULATOR:
	case VIDIOC_S_MODULATOR:
	case VIDIOC_S_FREQUENCY:
	case VIDIOC_G_FREQUENCY:
	case VIDIOC_CROPCAP:
	case VIDIOC_G_CROP:
	case VIDIOC_S_CROP:
	case VIDIOC_G_JPEGCOMP:
	case VIDIOC_S_JPEGCOMP:
	case VIDIOC_QUERYSTD:
	case VIDIOC_TRY_FMT32:
	case VIDIOC_ENUMAUDIO:
	case VIDIOC_ENUMAUDOUT:
	case VIDIOC_G_PRIORITY:
	case VIDIOC_S_PRIORITY:
	case VIDIOC_G_SLICED_VBI_CAP:
	case VIDIOC_LOG_STATUS:
	case VIDIOC_G_EXT_CTRLS32:
	case VIDIOC_S_EXT_CTRLS32:
	case VIDIOC_TRY_EXT_CTRLS32:
	case VIDIOC_ENUM_FRAMESIZES:
	case VIDIOC_ENUM_FRAMEINTERVALS:
	case VIDIOC_G_ENC_INDEX:
	case VIDIOC_ENCODER_CMD:
	case VIDIOC_TRY_ENCODER_CMD:
	case VIDIOC_DBG_S_REGISTER:
	case VIDIOC_DBG_G_REGISTER:
	case VIDIOC_DBG_G_CHIP_IDENT:
	case VIDIOC_S_HW_FREQ_SEEK:
	case VIDIOC_ENUM_DV_PRESETS:
	case VIDIOC_S_DV_PRESET:
	case VIDIOC_G_DV_PRESET:
	case VIDIOC_QUERY_DV_PRESET:
	case VIDIOC_S_DV_TIMINGS:
	case VIDIOC_G_DV_TIMINGS:
	case VIDIOC_DQEVENT:
	case VIDIOC_SUBSCRIBE_EVENT:
	case VIDIOC_UNSUBSCRIBE_EVENT:
		ret = do_video_ioctl(file, cmd, arg);
		break;

#ifdef CONFIG_VIDEO_V4L1_COMPAT
	/* BTTV specific... */
	case _IOW('v',  BASE_VIDIOCPRIVATE+0, char [256]):
	case _IOR('v',  BASE_VIDIOCPRIVATE+1, char [256]):
	case _IOR('v' , BASE_VIDIOCPRIVATE+2, unsigned int):
	case _IOW('v' , BASE_VIDIOCPRIVATE+3, char [16]): /* struct bttv_pll_info */
	case _IOR('v' , BASE_VIDIOCPRIVATE+4, int):
	case _IOR('v' , BASE_VIDIOCPRIVATE+5, int):
	case _IOR('v' , BASE_VIDIOCPRIVATE+6, int):
	case _IOR('v' , BASE_VIDIOCPRIVATE+7, int):
		ret = native_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
		break;
#endif
	default:
		printk(KERN_WARNING "compat_ioctl32: "
			"unknown ioctl '%c', dir=%d, #%d (0x%08x)\n",
			_IOC_TYPE(cmd), _IOC_DIR(cmd), _IOC_NR(cmd), cmd);
		break;
	}
	return ret;
}
Esempio n. 18
0
static long ak_client_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
  int size = _IOC_SIZE(cmd);	// Bloco de dados a ler/gravar
  int minor;			// Numero minor do device
  void *buffer;
  int error;

  if (_IOC_TYPE(cmd) != 'A')
    return -ENOTTY;
  minor = MINOR(filp->f_path.dentry->d_inode->i_rdev);
  if (minor != AK_CLIENT_API_MINOR)
    return -ENODEV;

  switch(cmd)
  {
    case AK_CLIENT_LOGIN:
      if (size != sizeof(ak_client_logon))
        return -EINVAL;

      buffer = kmalloc(size, GFP_KERNEL);
      if (!buffer)
        return -ENOMEM;

      if (copy_from_user(buffer, (void *) arg, size))
      {
        kfree(buffer);
        return -EFAULT;
      }
      error = 0 - ak_client_add_user((ak_client_logon *) buffer);
      kfree(buffer);
      return error;
      break;

    case AK_CLIENT_LOGOUT:
      if (size != sizeof(ak_client_logoff))
        return -EINVAL;

      buffer = kmalloc(size, GFP_KERNEL);
      if (!buffer)
        return -ENOMEM;

      if (copy_from_user(buffer, (void *) arg, size))
      {
        kfree(buffer);
        return -EFAULT;
      }
      error = 0 - ak_client_remove_user((ak_client_logoff *) buffer);
      kfree(buffer);
      return error;
      break;

    case AK_CLIENT_FLUSH:
      ak_client_flush_users();
      return 0;
      break;

    case AK_CLIENT_UDP_ENABLE:
      if (size != sizeof(int))
        return -EINVAL;
      ak_client_udp_enable((int) arg);
      return 0;
      break;

    default:
      return -ENOTTY;		// Comando invalido
      break;
  }
}
Esempio n. 19
0
static long device_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	int err = 0, ret = 0, i;
	int intBuf[SENSOR_DATA_SIZE];
	s16 xyz[SENSOR_DATA_SIZE];
	//check type and number
	if (_IOC_TYPE(cmd) != IOCTL_MAGIC) return -ENOTTY;
	if (_IOC_NR(cmd) > SENSOR_MAXNR) return -ENOTTY;

	//check user space pointer is valid
	if (_IOC_DIR(cmd) & _IOC_READ)
		err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
	else if (_IOC_DIR(cmd) & _IOC_WRITE)
		err =  !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
	if (err) return -EFAULT;
	
	switch(cmd) 
	{
		case SENSOR_RESET:
			//gsensor_reset();
			printk("RUN RESET");
			return ret;

		case SENSOR_CALIBRATION:
			// get orientation info
			if(copy_from_user(&intBuf, (int*)arg, sizeof(int))) return -EFAULT;
			gsensor_calibrate(intBuf[0]);
			// write in to file	
			gsensor_write_offset_to_file();
			
			// return the offset
			for(i = 0; i < SENSOR_DATA_SIZE; ++i)
				intBuf[i] = offset.v[i];
			
			ret = copy_to_user((int *)arg, &intBuf, sizeof(intBuf));
			return ret;
		
		case SENSOR_GET_OFFSET:
			// get offset from file
			gsensor_read_offset_from_file();
			
			for(i = 0; i < SENSOR_DATA_SIZE; ++i)
				intBuf[i] = offset.v[i];

			ret = copy_to_user((int *)arg, &intBuf, sizeof(intBuf));
			return ret;

		case SENSOR_SET_OFFSET:
			ret = copy_from_user(&intBuf, (int *)arg, sizeof(intBuf));
			gsensor_set_offset(intBuf);
			// write in to file
			gsensor_write_offset_to_file();
			return ret;
		
		case SENSOR_READ_ACCEL_XYZ:
			device_i2c_read_xyz(dev.client, (s16 *)&xyz);
			for(i = 0; i < SENSOR_DATA_SIZE; ++i)
				intBuf[i] = xyz[i] - offset.v[i];
			
		  	ret = copy_to_user((int*)arg, &intBuf, sizeof(intBuf));
			return ret;
		case SENSOR_SETYPR:
			if(copy_from_user(&intBuf, (int*)arg, sizeof(intBuf))) 
			{
				printk("%s:copy_from_user(&intBuf, (int*)arg, sizeof(intBuf)) ERROR, -EFAULT\n",__func__);			
				return -EFAULT;
			}
			input_report_abs(input, ABS_X, intBuf[0]);
			input_report_abs(input, ABS_Y, intBuf[1]);
			input_report_abs(input, ABS_Z, intBuf[2]);
			input_sync(input);
			//printk("%s:SENSOR_SETYPR OK! x=%d,y=%d,z=%d\n",__func__,intBuf[0],intBuf[1],intBuf[2]);

			return 1;
		case SENSOR_GET_OPEN_STATUS:
			//printk("%s:Going into DMT_GetOpenStatus()\n",__func__);
			DMT_GetOpenStatus();
			//printk("%s:DMT_GetOpenStatus() finished\n",__func__);
			return 1;
			break;
		case SENSOR_GET_CLOSE_STATUS:
			//printk("%s:Going into DMT_GetCloseStatus()\n",__func__);
			DMT_GetCloseStatus();	
			//printk("%s:DMT_GetCloseStatus() finished\n",__func__);
			return 1;
			break;		
		case SENSOR_GET_DELAY:
			
		  	ret = copy_to_user((int*)arg, &interval, sizeof(interval));
			return 1;
			break;
		default:  /* redundant, as cmd was checked against MAXNR */
			return -ENOTTY;
	}
	
	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 = 0;
    unsigned long flags;

#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
    int index=0;
    unsigned long spin_lock_flags;
#endif

    int j = 0;
    struct diag_buf_tbl_t *entry = NULL;

    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
        for (index = 0; index < MAX_HSIC_DATA_CH; index++) {
            if ((diag_bridge[index].usb_connected == 1) && (diag_hsic[index].count_hsic_pool == N_MDM_WRITE)) {
                spin_lock_irqsave(&diag_hsic[index].hsic_spinlock,spin_lock_flags);
                diag_hsic[index].count_hsic_pool = 0;
                spin_unlock_irqrestore(&diag_hsic[index].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),
                        index+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 /* 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 (j = 0; j < lge_dm_tty->num_tbl_entries; j++) {
                entry = &lge_dm_tty->tbl[j];
                if (entry->len <= 0)
                    continue;

                spin_lock_irqsave(&entry->lock, flags);
                entry->buf = NULL;
                entry->len = 0;
                entry->ctx = 0;
                spin_unlock_irqrestore(&entry->lock, flags);
            }

            diag_ws_reset(DIAG_WS_MD);

            if (driver->rsp_buf_busy) {
                spin_lock_irqsave(&driver->rsp_buf_busy_lock, flags);
                driver->rsp_buf_busy = 0;
                spin_unlock_irqrestore(&driver->rsp_buf_busy_lock, flags);
            }

            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 data channels to check for data */
                queue_work(driver->smd_data[i].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);

                /* Poll SMD data channels to check for data */
                queue_work(driver->diag_wq,
                    &(driver->smd_cmd[i].diag_read_smd_work));
            }
        } else if (modem_number == Secondary_modem_chip) {
#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
                    for (index = 0; index < MAX_HSIC_DATA_CH; index++) {
                        /* 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);

        result = TRUE;

#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
        for (index = 0; index < MAX_HSIC_DATA_CH; index++) {

            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),
                        index+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, modem_number = %d\n", __func__, modem_number);

#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
        for (index = 0; index < MAX_HSIC_DATA_CH; index++) {
            if ((diag_bridge[index].usb_connected == 1) && (diag_hsic[index].count_hsic_pool == N_MDM_WRITE)) {
                spin_lock_irqsave(&diag_hsic[index].hsic_spinlock,spin_lock_flags);
                diag_hsic[index].count_hsic_pool = 0;
                spin_unlock_irqrestore(&diag_hsic[index].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),
                        index+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 /* 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 (j = 0; j < lge_dm_tty->num_tbl_entries; j++) {
                entry = &lge_dm_tty->tbl[j];
                if (entry->len <= 0)
                    continue;

                spin_lock_irqsave(&entry->lock, flags);
                entry->buf = NULL;
                entry->len = 0;
                entry->ctx = 0;
                spin_unlock_irqrestore(&entry->lock, flags);
            }

            diag_ws_reset(DIAG_WS_MD);

            if (driver->rsp_buf_busy) {
                spin_lock_irqsave(&driver->rsp_buf_busy_lock, flags);
                driver->rsp_buf_busy = 0;
                spin_unlock_irqrestore(&driver->rsp_buf_busy_lock, flags);
            }

            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 data channels to check for data */
                queue_work(driver->smd_data[i].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);

                /* Poll SMD data channels to check for data */
                queue_work(driver->diag_wq,
                    &(driver->smd_cmd[i].diag_read_smd_work));
            }
        } else if (modem_number == Secondary_modem_chip) {

#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
                    for (index = 0; index < MAX_HSIC_DATA_CH; index++) {
                        /* 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);
        }

        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);
        result = TRUE;

        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 (modem_number == Primary_modem_chip) {

        } else if (modem_number == Secondary_modem_chip) {
#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
        for (index = 0; index < MAX_HSIC_DATA_CH; index++) {
            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),
                        index+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
            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:
/*
                                      
                            
                                                            
                                                                
                                           
                                               
                           
       

                                      
*/
  break;

    default:
        pr_info(DM_TTY_MODULE_NAME ": %s:"
        "lge_dm_tty_ioctl error\n", __func__);
        break;

    }

    return 0;

}
Esempio n. 21
0
/* ioctl dispatcher */
static int _autofs_dev_ioctl(unsigned int command,
			     struct autofs_dev_ioctl __user *user)
{
	struct autofs_dev_ioctl *param;
	struct file *fp;
	struct autofs_sb_info *sbi;
	unsigned int cmd_first, cmd;
	ioctl_fn fn = NULL;
	int err = 0;

	/* only root can play with this */
	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

	cmd_first = _IOC_NR(AUTOFS_DEV_IOCTL_IOC_FIRST);
	cmd = _IOC_NR(command);

	if (_IOC_TYPE(command) != _IOC_TYPE(AUTOFS_DEV_IOCTL_IOC_FIRST) ||
	    cmd - cmd_first > AUTOFS_DEV_IOCTL_IOC_COUNT) {
		return -ENOTTY;
	}

	/* Copy the parameters into kernel space. */
	param = copy_dev_ioctl(user);
	if (IS_ERR(param))
		return PTR_ERR(param);

	err = validate_dev_ioctl(command, param);
	if (err)
		goto out;

	fn = lookup_dev_ioctl(cmd);
	if (!fn) {
		pr_warn("unknown command 0x%08x\n", command);
		err = -ENOTTY;
		goto out;
	}

	fp = NULL;
	sbi = NULL;

	/*
	 * For obvious reasons the openmount can't have a file
	 * descriptor yet. We don't take a reference to the
	 * file during close to allow for immediate release,
	 * and the same for retrieving ioctl version.
	 */
	if (cmd != AUTOFS_DEV_IOCTL_VERSION_CMD &&
	    cmd != AUTOFS_DEV_IOCTL_OPENMOUNT_CMD &&
	    cmd != AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD) {
		fp = fget(param->ioctlfd);
		if (!fp) {
			if (cmd == AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD)
				goto cont;
			err = -EBADF;
			goto out;
		}

		sbi = autofs_dev_ioctl_sbi(fp);
		if (!sbi || sbi->magic != AUTOFS_SBI_MAGIC) {
			err = -EINVAL;
			fput(fp);
			goto out;
		}

		/*
		 * Admin needs to be able to set the mount catatonic in
		 * order to be able to perform the re-open.
		 */
		if (!autofs4_oz_mode(sbi) &&
		    cmd != AUTOFS_DEV_IOCTL_CATATONIC_CMD) {
			err = -EACCES;
			fput(fp);
			goto out;
		}
	}
cont:
	err = fn(fp, sbi, param);

	if (fp)
		fput(fp);
	if (err >= 0 && copy_to_user(user, param, AUTOFS_DEV_IOCTL_SIZE))
		err = -EFAULT;
out:
	free_dev_ioctl(param);
	return err;
}
Esempio n. 22
0
int audio_ioctl(int dev, struct file *file, unsigned int cmd, void __user *arg)
{
	int val, count;
	unsigned long flags;
	struct dma_buffparms *dmap;
	int __user *p = arg;

	dev = dev >> 4;

	if (_IOC_TYPE(cmd) == 'C')	{
		if (audio_devs[dev]->coproc)	/* Coprocessor ioctl */
			return audio_devs[dev]->coproc->ioctl(audio_devs[dev]->coproc->devc, cmd, arg, 0);
		/* else
		        printk(KERN_DEBUG"/dev/dsp%d: No coprocessor for this device\n", dev); */
		return -ENXIO;
	}
	else switch (cmd) 
	{
		case SNDCTL_DSP_SYNC:
			if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
				return 0;
			if (audio_devs[dev]->dmap_out->fragment_size == 0)
				return 0;
			sync_output(dev);
			DMAbuf_sync(dev);
			DMAbuf_reset(dev);
			return 0;

		case SNDCTL_DSP_POST:
			if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
				return 0;
			if (audio_devs[dev]->dmap_out->fragment_size == 0)
				return 0;
			audio_devs[dev]->dmap_out->flags |= DMA_POST | DMA_DIRTY;
			sync_output(dev);
			dma_ioctl(dev, SNDCTL_DSP_POST, NULL);
			return 0;

		case SNDCTL_DSP_RESET:
			audio_devs[dev]->audio_mode = AM_NONE;
			DMAbuf_reset(dev);
			return 0;

		case SNDCTL_DSP_GETFMTS:
			val = audio_devs[dev]->format_mask | AFMT_MU_LAW;
			break;
	
		case SNDCTL_DSP_SETFMT:
			if (get_user(val, p))
				return -EFAULT;
			val = set_format(dev, val);
			break;

		case SNDCTL_DSP_GETISPACE:
			if (!(audio_devs[dev]->open_mode & OPEN_READ))
				return 0;
  			if ((audio_devs[dev]->audio_mode & AM_WRITE) && !(audio_devs[dev]->flags & DMA_DUPLEX))
  				return -EBUSY;
			return dma_ioctl(dev, cmd, arg);

		case SNDCTL_DSP_GETOSPACE:
			if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
				return -EPERM;
  			if ((audio_devs[dev]->audio_mode & AM_READ) && !(audio_devs[dev]->flags & DMA_DUPLEX))
  				return -EBUSY;
			return dma_ioctl(dev, cmd, arg);
		
		case SNDCTL_DSP_NONBLOCK:
			spin_lock(&file->f_lock);
			file->f_flags |= O_NONBLOCK;
			spin_unlock(&file->f_lock);
			return 0;

		case SNDCTL_DSP_GETCAPS:
				val = 1 | DSP_CAP_MMAP;	/* Revision level of this ioctl() */
				if (audio_devs[dev]->flags & DMA_DUPLEX &&
					audio_devs[dev]->open_mode == OPEN_READWRITE)
					val |= DSP_CAP_DUPLEX;
				if (audio_devs[dev]->coproc)
					val |= DSP_CAP_COPROC;
				if (audio_devs[dev]->d->local_qlen)	/* Device has hidden buffers */
					val |= DSP_CAP_BATCH;
				if (audio_devs[dev]->d->trigger)	/* Supports SETTRIGGER */
					val |= DSP_CAP_TRIGGER;
				break;
			
		case SOUND_PCM_WRITE_RATE:
			if (get_user(val, p))
				return -EFAULT;
			val = audio_devs[dev]->d->set_speed(dev, val);
			break;

		case SOUND_PCM_READ_RATE:
			val = audio_devs[dev]->d->set_speed(dev, 0);
			break;
			
		case SNDCTL_DSP_STEREO:
			if (get_user(val, p))
				return -EFAULT;
			if (val > 1 || val < 0)
				return -EINVAL;
			val = audio_devs[dev]->d->set_channels(dev, val + 1) - 1;
			break;

		case SOUND_PCM_WRITE_CHANNELS:
			if (get_user(val, p))
				return -EFAULT;
			val = audio_devs[dev]->d->set_channels(dev, val);
			break;

		case SOUND_PCM_READ_CHANNELS:
			val = audio_devs[dev]->d->set_channels(dev, 0);
			break;
		
		case SOUND_PCM_READ_BITS:
			val = audio_devs[dev]->d->set_bits(dev, 0);
			break;

		case SNDCTL_DSP_SETDUPLEX:
			if (audio_devs[dev]->open_mode != OPEN_READWRITE)
				return -EPERM;
			return (audio_devs[dev]->flags & DMA_DUPLEX) ? 0 : -EIO;

		case SNDCTL_DSP_PROFILE:
			if (get_user(val, p))
				return -EFAULT;
			if (audio_devs[dev]->open_mode & OPEN_WRITE)
				audio_devs[dev]->dmap_out->applic_profile = val;
			if (audio_devs[dev]->open_mode & OPEN_READ)
				audio_devs[dev]->dmap_in->applic_profile = val;
			return 0;
		
		case SNDCTL_DSP_GETODELAY:
			dmap = audio_devs[dev]->dmap_out;
			if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
				return -EINVAL;
			if (!(dmap->flags & DMA_ALLOC_DONE))
			{
				val=0;
				break;
			}
		
			spin_lock_irqsave(&dmap->lock,flags);
			/* Compute number of bytes that have been played */
			count = DMAbuf_get_buffer_pointer (dev, dmap, DMODE_OUTPUT);
			if (count < dmap->fragment_size && dmap->qhead != 0)
				count += dmap->bytes_in_use;	/* Pointer wrap not handled yet */
			count += dmap->byte_counter;
		
			/* Subtract current count from the number of bytes written by app */
			count = dmap->user_counter - count;
			if (count < 0)
				count = 0;
			spin_unlock_irqrestore(&dmap->lock,flags);
			val = count;
			break;
		
		default:
			return dma_ioctl(dev, cmd, arg);
	}
	return put_user(val, p);
}
Esempio n. 23
0
/*	ioctl command for BMA accel device file	*/
static int bma_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
	int err = 0;
	unsigned char data[6];

	/* check cmd */
	if(_IOC_TYPE(cmd) != BMA220_IOC_MAGIC)	
	{
#ifdef BMA_DEBUG
		printk("cmd magic type error\n");
#endif
		return -ENOTTY;
	}
	if(_IOC_NR(cmd) > BMA220_IOC_MAXNR)
	{
#ifdef BMA_DEBUG
		printk("cmd number error\n");
#endif
		return -ENOTTY;
	}

	if(_IOC_DIR(cmd) & _IOC_READ)
		err = !access_ok(VERIFY_WRITE,(void __user*)arg, _IOC_SIZE(cmd));
	else if(_IOC_DIR(cmd) & _IOC_WRITE)
		err = !access_ok(VERIFY_READ, (void __user*)arg, _IOC_SIZE(cmd));
	
	if(err)
	{
#ifdef BMA_DEBUG
		printk("cmd access_ok error\n");
#endif
		return -EFAULT;
	}
	/* check bam120_client */
	if( bma_client == NULL)
	{
#ifdef BMA_DEBUG
		printk("I2C driver not install\n"); 
#endif
		return -EFAULT;
	}
	
	/* cmd mapping */

	switch(cmd)
	{
	case BMA220_SOFT_RESET:
		err = bma220_soft_reset();
		return err;

	case BMA220_SET_SUSPEND:
		err = bma220_set_suspend();
		return err;

	case BMA220_SET_OFFSET_TARGET_X:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_offset_target_x(*data);
		return err;

	case BMA220_SET_OFFSET_TARGET_Y:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_offset_target_y(*data);
		return err;

	case BMA220_SET_OFFSET_TARGET_Z:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_offset_target_z(*data);
		return err;

	case BMA220_SET_RANGE:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_range(*data);
		return err;

	case BMA220_GET_RANGE:
		err = bma220_get_range(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

	case BMA220_SET_MODE:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_mode(*data);
		return err;

	case BMA220_GET_MODE:
		err = bma220_get_mode(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

	case BMA220_SET_BANDWIDTH:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_bandwidth(*data);
		return err;

	case BMA220_GET_BANDWIDTH:
		err = bma220_get_bandwidth(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

	case BMA220_SET_LOW_TH:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_low_th(*data);
		return err;

	case BMA220_SET_LOW_DUR:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_low_dur(*data);
		return err;

	case BMA220_SET_HIGH_TH:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_high_th(*data);
		return err;

	case BMA220_SET_HIGH_DUR:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_high_dur(*data);
		return err;

	case BMA220_RESET_INTERRUPT:
		err = bma220_reset_int();
		return err;

	case BMA220_READ_ACCEL_X:
		err = bma220_read_accel_x((signed char*)data);
		if(copy_to_user((signed char*)arg,(signed char*)data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

	case BMA220_READ_ACCEL_Y:
		err = bma220_read_accel_y((signed char*)data);
		if(copy_to_user((signed char*)arg,(signed char*)data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

	case BMA220_READ_ACCEL_Z:
		err = bma220_read_accel_z((signed char*)data);
		if(copy_to_user((signed char*)arg,(signed char*)data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

	case BMA220_SET_EN_LOW:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_en_low(*data);
		return err;

	case BMA220_SET_EN_HIGH_XYZ:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_en_high_xyz(*data);
		return err;

	case BMA220_SET_LATCH_INT:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_latch_int(*data);
		return err;

	case BMA220_SET_LOW_HY:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_low_hy(*data);
		return err;

	case BMA220_SET_HIGH_HY:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_high_hy(*data);
		return err;

	case BMA220_READ_ACCEL_XYZ:
		if(sensor_type == BMA220)
		{
			err = bma220_read_accel_xyz((bma220acc_t*)data);
			if(copy_to_user((bma220acc_t*)arg,(bma220acc_t*)data,3)!=0)
			{
#ifdef BMA_DEBUG
				printk("copy_to error\n");
#endif
				return -EFAULT;
			}
		}else if(sensor_type == BMA023)
		{
			err = bma023_read_accel_xyz((bma023acc_t*)data);
			//printk("[%s] read accel x = %d, y = %d, z = %d\n", __func__, ((bma023acc_t*)data)->x, ((bma023acc_t*)data)->y, ((bma023acc_t*)data)->z);
			if(copy_to_user((bma023acc_t*)arg,(bma023acc_t*)data,3*sizeof(short))!=0)
			{
#ifdef BMA_DEBUG
				printk("copy_to error\n");
#endif
				return -EFAULT;
			}
		}
		
		return err;

    case BMA220_GET_OFFSET_XYZ:
		err = bma220_get_offset_xyz((bma220acc_t*)data);
		if(copy_to_user((bma220acc_t*)arg,(bma220acc_t*)data,3)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_SET_OFFSET_XYZ:
		if(copy_from_user((bma220acc_t*)data,(bma220acc_t*)arg,3)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
        err = bma220_set_offset_xyz(*(bma220acc_t *)data);
		return err;

	
	case BMA220_SET_SLEEP_EN:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_sleep_en(*data);
		return err;

	case BMA220_SET_SC_FILT_CONFIG:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_sc_filt_config(*data);
		return err;

	case BMA220_SET_SERIAL_HIGH_BW:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_serial_high_bw(*data);
		return err;

	case BMA220_SET_EN_ORIENT:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_en_orient(*data);
		return err;

	case BMA220_SET_ORIENT_EX:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_orient_ex(*data);
		return err;

	case BMA220_SET_ORIENT_BLOCKING:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_orient_blocking(*data);
		return err;

	case BMA220_SET_EN_TT_XYZ:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_en_tt_xyz(*data);
		return err;

	case BMA220_SET_TT_TH:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_tt_th(*data);
		return err;

	case BMA220_SET_TT_DUR:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_tt_dur(*data);
		return err;

	case BMA220_SET_TT_FILT:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_tt_filt(*data);
		return err;

	case BMA220_SET_EN_SLOPE_XYZ:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_en_slope_xyz(*data);
		return err;

	case BMA220_SET_EN_DATA:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_en_data(*data);
		return err;

	case BMA220_SET_SLOPE_TH:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_slope_th(*data);
		return err;

	case BMA220_SET_SLOPE_DUR:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_slope_dur(*data);
		return err;

	case BMA220_SET_SLOPE_FILT:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_slope_filt(*data);
		return err;

	case BMA220_SET_CAL_TRIGGER:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_cal_trigger(*data);
		return err;

	case BMA220_SET_HP_XYZ_EN:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_hp_xyz_en(*data);
		return err;

	case BMA220_SET_SLEEP_DUR:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_sleep_dur(*data);
		return err;

	case BMA220_SET_OFFSET_RESET:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_offset_reset(*data);
		return err;

	case BMA220_SET_CUT_OFF_SPEED:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_cut_off_speed(*data);
		return err;

	case BMA220_SET_CAL_MANUAL:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
    	err = bma220_set_cal_manual(*data);
		return err;

	case BMA220_SET_SBIST:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_sbist(*data);
		return err;

	case BMA220_SET_INTERRUPT_REGISTER:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_interrupt_register(*data);
		return err;

	case BMA220_SET_DIRECTION_INTERRUPT_REGISTER:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_direction_interrupt_register(*data);
		return err;
	
	case BMA220_GET_DIRECTION_STATUS_REGISTER:
		err = bma220_get_direction_status_register(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

	case BMA220_GET_INTERRUPT_STATUS_REGISTER:
		err = bma220_get_interrupt_status_register(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

	case BMA220_GET_ORIENTATION:
		err = bma220_get_orientation(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

	case BMA220_GET_ORIENT_INT:
		err = bma220_get_orient_int(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_CHIP_ID:
		err = bma220_get_chip_id(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_SC_FILT_CONFIG:
		err = bma220_get_sc_filt_config(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_SLEEP_EN:
		err = bma220_get_sleep_en(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_SERIAL_HIGH_BW:
		err = bma220_get_serial_high_bw(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_LATCH_INT:
		err = bma220_get_latch_int(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_EN_DATA:
		err = bma220_get_en_data(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_EN_HIGH_XYZ:
		err = bma220_get_en_high_xyz(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_HIGH_TH:
		err = bma220_get_high_th(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_HIGH_HY:
		err = bma220_get_high_hy(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_HIGH_DUR:
		err = bma220_get_high_g_dur(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_EN_LOW:
		err = bma220_get_en_low(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_LOW_TH:
		err = bma220_get_low_th(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_LOW_HY:
		err = bma220_get_low_hy(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_LOW_DUR:
		err = bma220_get_low_g_dur(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_EN_ORIENT:
		err = bma220_get_en_orient(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_ORIENT_EX:
		err = bma220_get_orient_ex(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_ORIENT_BLOCKING:
		err = bma220_get_orient_blocking(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_EN_TT_XYZ:
		err = bma220_get_en_tt_xyz(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_TT_TH:
		err = bma220_get_tt_th(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_TT_DUR:
		err = bma220_get_tt_dur(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_TT_FILT:
		err = bma220_get_tt_filt(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_SET_TT_SAMP:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_tt_samp(*data);
		return err;

    case BMA220_SET_TIP_EN:
		if(copy_from_user(data,(unsigned char*)arg,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_from_user error\n");
#endif
			return -EFAULT;
		}
		err = bma220_set_tip_en(*data);
		return err;

    case BMA220_GET_TT_SAMP:
		err = bma220_get_tt_samp(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_TIP_EN:
		err = bma220_get_tip_en(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_EN_SLOPE_XYZ:
		err = bma220_get_en_slope_xyz(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_SLOPE_TH:
		err = bma220_get_slope_th(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_SLOPE_DUR:
		err = bma220_get_slope_dur(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_SLOPE_FILT:
		err = bma220_get_slope_filt(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_HP_XYZ_EN:
		err = bma220_get_hp_xyz_en(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_OFFSET_TARGET_X:
		err = bma220_get_offset_target_x(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_OFFSET_TARGET_Y:
		err = bma220_get_offset_target_y(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_OFFSET_TARGET_Z:
		err = bma220_get_offset_target_z(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_CUT_OFF_SPEED:
		err = bma220_get_cut_off_speed(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

    case BMA220_GET_CAL_MANUAL:
		err = bma220_get_cal_manual(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

	case BMA220_GET_CAL_RDY:
		err = bma220_get_cal_rdy(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

	case BMA220_GET_SLEEP_DUR:
		err = bma220_get_sleep_dur(data);
		if(copy_to_user((unsigned char*)arg,data,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

	case BMA220_GET_SENSOR_TYPE:		
		printk("[%s] Get Sensor Type = %d\n", __func__, sensor_type);
		if(copy_to_user((char*)arg,&sensor_type,1)!=0)
		{
#ifdef BMA_DEBUG
			printk("copy_to_user error\n");
#endif
			return -EFAULT;
		}
		return err;

	default:
		return 0;
	}
}
static long low_mem_inject_unlocked_ioctl(struct file * file, unsigned int cmd, unsigned long arg)
{
    char *buffer;
    unsigned int i;
    unsigned long int j;
    pr_info("[HW]: %s: init the GlodenEye driver ioctrl... \n", __func__);
    pr_info("[HW]: %s: cmd = %d, arg = %ld \n", __func__, cmd, arg);

    if(_IOC_TYPE(cmd) != TEST_MAGIC){
        pr_info("[HW]: %s: cmd error \n", __func__);
        return - EINVAL;
    }

    if(_IOC_NR(cmd) > TEST_MAX_NR){
        pr_info("[HW]: %s: cmd error \n", __func__);
        return - EINVAL;
    }

    switch(cmd) {
        case LOW_MEM_SETTING_ENABLE:
            if(arg == 1)
                host_low_mem_inject.flags.enabled = 1;
            else if(arg == 0){
                host_low_mem_inject.flags.enabled = 0;
                pr_info("[HW] %s %d free memory \n", __func__, __LINE__);
                for(i=0; i < index_buffer; i++){
                    kfree(buffers[i]);
                }
                index_buffer = 0;
            }
            else
                pr_err("[HW]: %s: arg error \n", __func__);
            break;

        case LOW_MEM_SETTING_INJECT_SIZE:
            pr_info("[HW]: %s: arg = %d\n", __func__, (int)arg);

            if(host_low_mem_inject.flags.enabled){
                if (index_buffer >= 1024) {
                    pr_info("[HW]: %s: inject full\n", __func__);
                    return -ENOMEM;
                }
                buffer = kmalloc(sizeof(char)*arg, GFP_KERNEL);
                if (buffer == NULL) {
                    pr_info("[HW]: %s: kmalloc error\n", __func__);
                    return -ENOMEM;
                }else{
                    buffers[index_buffer++] = buffer;
                    pr_info("[HW]: %s: kmalloc addr = 0x%08ld\n", __func__, (long)buffer);
                }

                for(i=0; i< 0xFE; i++){
                    memset(buffer, i, sizeof(char)*arg);
                    for(j=0;j<arg; j++){
                        if(*(buffer + j) != i){
                            pr_err("[HW]: %s: shift = %ld error \n", __func__, j);
                        }
                    }
                }
            }
            break;
        default:
            return -EINVAL;
    }
    return 0;
}
static int hdhomerun_control_ioctl(struct inode *inode,struct file *f,
				    unsigned int cmd, unsigned long arg)
#endif
{
	int retval = 0;
	int err = 1;
	
	DEBUG_FUNC(1);

	if (_IOC_DIR(cmd) & _IOC_READ) {
		err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
	}
	else if (_IOC_DIR(cmd) & _IOC_WRITE) {
		err =  !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
	}
	
	if (err) {
		printk(KERN_ERR "access_ok() fails\n");
		return -EFAULT;
	}

	switch(cmd) {
	case HDHOMERUN_REGISTER_TUNER: {
		struct hdhomerun_register_tuner_data tuner_data;

		retval = copy_from_user(&tuner_data, (struct hdhomerun_register_tuner_data*)arg, sizeof(struct hdhomerun_register_tuner_data));
		if(retval != 0) {
			printk(KERN_ERR "hdhomerun: get_user() failed, no dvb device created!\n");
		}
		else {
			printk(KERN_INFO "hdhomerun: creating dvb device for %s\n", tuner_data.name);

			retval = dvb_hdhomerun_data_init(tuner_data.num_of_devices);
			if(retval != 0) {
				printk(KERN_ERR "hdhomerun: hdhomerun_data_init() failed, no dvb device created\n");
				return -EFAULT;
			}

			retval = dvb_hdhomerun_register_hdhomerun(&tuner_data);
			if(retval != 0) {
				printk(KERN_ERR "hdhomerun: register_hdhomerun() failed, no dvb device created\n");
				return -EFAULT;
			}

			retval = copy_to_user((void *)arg, &tuner_data, sizeof(struct hdhomerun_register_tuner_data));
			break;
		}
	}
		
	default:
		retval = -ENOTTY;
		DEBUG_OUT(1,"Unknown/unhandled ioctl cmd: %x, nr:%d, type:%d\n", cmd, _IOC_NR(cmd), _IOC_TYPE(cmd));
	}
	
	return retval;
}
/*
   IO controls for user space accessing

   \param   ino      Pointer to the stucture of inode.
   \param   fil      Pointer to the stucture of file.
   \param   command     The ioctl command.
   \param   lon      The address of data.
   \return  Success or failure.
   \ingroup Internal
*/
DSL_int_t DSL_DRV_Ioctls(DSL_DRV_DevHeader_t *pDrvHdr, DSL_uint_t nCommand, DSL_uint32_t nArg)
{
   DSL_int_t nErr=0;
   DSL_boolean_t bIsInKernel;
   DSL_Error_t nRetCode = DSL_SUCCESS;
   DSL_Context_t *pContext;
   DSL_devCtx_t *pDevCtx;
   DSL_OpenContext_t *pOpenCtx = pDrvHdr->pOpenCtx;

   DSL_DEBUG(DSL_DBG_MSG, (DSL_NULL, SYS_DBG_MSG"Device will be controled..."DSL_DRV_CRLF));

   DSL_DEBUG(DSL_DBG_MSG, (DSL_NULL, SYS_DBG_MSG"IN - DSL_DRV_Ioctls: The ioctl "
      "command(0x%X) is called" DSL_DRV_CRLF, nCommand));

   if (pOpenCtx == DSL_NULL)
   {
      /* This should never happen */
      DSL_DEBUG(DSL_DBG_ERR, (DSL_NULL, SYS_DBG_ERR"!!! Ioctl call for file which "
         "was not opened" DSL_DRV_CRLF));

      return -1;
   }
   else
   {
      if ((pDevCtx = pOpenCtx->pDevCtx) == DSL_NULL)
      {
         /* This should never happen */
         DSL_DEBUG(DSL_DBG_ERR, (DSL_NULL, SYS_DBG_ERR"DSL_DRV_Poll: !!! Ioctl call "
            "for file which was not opened correctly" DSL_DRV_CRLF));

         return -1;
      }
      else
      {
         if ((pContext = pDevCtx->pContext) == DSL_NULL)
         {
            /* This should never happen */
            DSL_DEBUG(DSL_DBG_ERR, (DSL_NULL, SYS_DBG_ERR"!!! Ioctl call to device "
               "which was not ready" DSL_DRV_CRLF));

            return -1;
         }
      }
   }

   bIsInKernel = DSL_TRUE;

   switch(nCommand)
   {
      case FIOSELECT:
      /* add to wakeup list */
      DSL_DRV_ADD_TASK_WAKELIST(
         (DSL_DRV_SelectOsArg_t*) nArg,
         (DSL_DRV_WaitQueue_t*) &(pOpenCtx->eventWaitQueue),
         (DSL_DRV_SelectTable_t*)DSL_NULL);

      if ( DSL_Fifo_isEmpty( pOpenCtx->eventFifo ) == DSL_FALSE )
      {
         selWakeup((SEL_WAKEUP_NODE*) nArg);
      }
      return 0;

      case FIOUNSELECT:
      selNodeDelete(&pOpenCtx->eventWaitQueue, (SEL_WAKEUP_NODE*) nArg);
      return 0;
   }

   if ( (_IOC_TYPE(nCommand) == DSL_IOC_MAGIC_CPE_API) ||
        (_IOC_TYPE(nCommand) == DSL_IOC_MAGIC_CPE_API_G997) ||
        (_IOC_TYPE(nCommand) == DSL_IOC_MAGIC_CPE_API_PM) ||
        (_IOC_TYPE(nCommand) == DSL_IOC_MAGIC_CPE_API_DEP) )
   {
      nRetCode = DSL_DRV_IoctlHandle(pOpenCtx, pContext, bIsInKernel, nCommand, nArg);

      if (nRetCode < DSL_SUCCESS)
      {
         nErr = DSL_DRV_ErrorToOS(nRetCode);
      }
   }
#if defined(INCLUDE_DSL_ADSL_MIB)
   else if (_IOC_TYPE(nCommand) == DSL_IOC_MAGIC_MIB)
   {
      nRetCode = DSL_DRV_MIB_IoctlHandle(pContext, bIsInKernel, nCommand, nArg);
      nErr = (DSL_int_t)nRetCode;
   }
#endif
   else
   {
      DSL_DEBUG(DSL_DBG_ERR, (DSL_NULL, SYS_DBG_ERR"The ioctl command(0x%X) is not "
         "supported!" DSL_DRV_CRLF, nCommand));
      nErr = -1;
      return nErr;
   }

   DSL_DEBUG(DSL_DBG_MSG, (DSL_NULL, SYS_DBG_MSG"OUT - DSL_DRV_Ioctls(), retCode=%d"
      DSL_DRV_CRLF, nErr));

   return nErr;
}
Esempio n. 27
0
/*!
 * This function implements IOCTL controls on a mc13783 rtc device.
 *
 * @param        inode       pointer on the node
 * @param        file        pointer on the file
 * @param        cmd         the command
 * @param        arg         the parameter
 * @return       This function returns 0 if successful.
 */
static int mc13783_rtc_ioctl(struct inode *inode, struct file *file,
			     unsigned int cmd, unsigned long arg)
{
	struct timeval *mc13783_time = NULL;

	if (_IOC_TYPE(cmd) != 'R')
		return -ENOTTY;

	if (arg) {
		if ((mc13783_time = kmalloc(sizeof(struct timeval), GFP_KERNEL))
		    == NULL) {
			return -ENOMEM;
		}
		if (copy_from_user(mc13783_time, (struct timeval *)arg,
				   sizeof(struct timeval))) {
			return -EFAULT;
		}
	}

	switch (cmd) {
	case MC13783_RTC_SET_TIME:
		TRACEMSG_RTC(_K_D("SET RTC"));
		CHECK_ERROR(mc13783_rtc_set_time(mc13783_time));
		break;
	case MC13783_RTC_GET_TIME:
		TRACEMSG_RTC(_K_D("GET RTC"));
		CHECK_ERROR(mc13783_rtc_get_time(mc13783_time));
		break;
	case MC13783_RTC_SET_ALARM:
		TRACEMSG_RTC(_K_D("SET RTC ALARM"));
		CHECK_ERROR(mc13783_rtc_set_time_alarm(mc13783_time));
		break;
	case MC13783_RTC_GET_ALARM:
		TRACEMSG_RTC(_K_D("GET RTC ALARM"));
		CHECK_ERROR(mc13783_rtc_get_time_alarm(mc13783_time));
		break;
	case MC13783_RTC_WAIT_ALARM:
		TRACEMSG_RTC(_K_I("WAIT ALARM..."));
		CHECK_ERROR(mc13783_rtc_event_sub(RTC_IT_ALARM,
						  callback_test_sub));
		CHECK_ERROR(mc13783_rtc_wait_alarm());
		TRACEMSG_RTC(_K_I("ALARM DONE"));
		CHECK_ERROR(mc13783_rtc_event_unsub(RTC_IT_ALARM,
						    callback_test_sub));
		break;
	case MC13783_RTC_ALARM_REGISTER:
		TRACEMSG_RTC(_K_I("MC13783 RTC ALARM REGISTER"));
		mc13783_event_init(&alarm_event);
		alarm_event.event = EVENT_TODAI;
		alarm_event.callback = callback_alarm_asynchronous;
		CHECK_ERROR(mc13783_event_subscribe(alarm_event));
		break;
	case MC13783_RTC_ALARM_UNREGISTER:
		TRACEMSG_RTC(_K_I("MC13783 RTC ALARM UNREGISTER"));
		mc13783_event_init(&alarm_event);
		alarm_event.event = EVENT_TODAI;
		alarm_event.callback = callback_alarm_asynchronous;
		CHECK_ERROR(mc13783_event_unsubscribe(alarm_event));
		mc13783_rtc_done = false;
		break;
	default:
		TRACEMSG_RTC(_K_D("%d unsupported ioctl command"), (int)cmd);
		return -EINVAL;
	}

	if (arg) {
		if (copy_to_user((struct timeval *)arg, mc13783_time,
				 sizeof(struct timeval))) {
			return -EFAULT;
		}
		kfree(mc13783_time);
	}

	return ERROR_NONE;
}
long mdm_modem_ioctl(struct file *filp, unsigned int cmd,
				unsigned long arg)
{
	int status, ret = 0;

	if (_IOC_TYPE(cmd) != CHARM_CODE) {
		pr_err("%s: invalid ioctl code\n", __func__);
		return -EINVAL;
	}

	pr_debug("%s: Entering ioctl cmd = %d\n", __func__, _IOC_NR(cmd));
	switch (cmd) {
	case WAKE_CHARM:
		pr_info("%s: Powering on mdm\n", __func__);
#ifdef CONFIG_MDM_HSIC_PM
		request_boot_lock_set(rmnet_pm_dev);
#endif
		mdm_drv->ops->power_on_mdm_cb(mdm_drv);
		break;
	case CHECK_FOR_BOOT:
		if (gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 0)
			put_user(1, (unsigned long __user *) arg);
		else
			put_user(0, (unsigned long __user *) arg);
		break;
	case NORMAL_BOOT_DONE:
		pr_info("%s: check if mdm is booted up\n", __func__);
		get_user(status, (unsigned long __user *) arg);
		if (status) {
			pr_debug("%s: normal boot failed\n", __func__);
			mdm_drv->mdm_boot_status = -EIO;
		} else {
			pr_info("%s: normal boot done\n", __func__);
			mdm_drv->mdm_boot_status = 0;
		}
		mdm_drv->mdm_ready = 1;

		if (mdm_drv->ops->normal_boot_done_cb != NULL)
			mdm_drv->ops->normal_boot_done_cb(mdm_drv);

		if (!first_boot)
			complete(&mdm_boot);
		else
			first_boot = 0;

		/* If bootup succeeded, start a timer to check that the
		 * mdm2ap_status gpio goes high.
		 */
		if (!status && gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 0)
			schedule_delayed_work(&mdm2ap_status_check_work,
				msecs_to_jiffies(MDM2AP_STATUS_TIMEOUT_MS));
		break;
	case RAM_DUMP_DONE:
		pr_info("%s: mdm done collecting RAM dumps\n", __func__);
		get_user(status, (unsigned long __user *) arg);
		if (status)
			mdm_drv->mdm_ram_dump_status = -EIO;
		else {
			pr_info("%s: ramdump collection completed\n", __func__);
			mdm_drv->mdm_ram_dump_status = 0;
			panic("CP Crash %s", mdm_read_err_report());
		}
		complete(&mdm_ram_dumps);
		break;

	case WAIT_FOR_ERROR:
		pr_debug("%s: wait for mdm error\n", __func__);
		#if 0
		ret = wait_for_completion_interruptible(&mdm_error);
		INIT_COMPLETION(mdm_error);
		#endif
		break;

	case WAIT_FOR_RESTART:
		pr_info("%s: wait for mdm to need images reloaded\n",
				__func__);
		ret = wait_for_completion_interruptible(&mdm_needs_reload);
		if (!ret)
			put_user(mdm_drv->boot_type,
					 (unsigned long __user *) arg);
		INIT_COMPLETION(mdm_needs_reload);
		break;

	case SILENT_RESET_CONTROL:
		pr_info("%s: mdm doing silent reset\n", __func__);
		mdm_drv->mdm_ram_dump_status = 0;
		complete(&mdm_ram_dumps);
		break;

	case AUTOPM_LOCK:
		get_user(status, (unsigned long __user *) arg);
		pr_info("%s: mdm autopm request[%s]\n", __func__,
						status ? "lock" : "release");
		request_autopm_lock(status);
		break;

	case GET_BOOT_PROTOCOL:
		pr_info("%s: mdm get boot protocol %d\n", __func__,
						mdm_drv->proto_is_dload);
		return mdm_drv->proto_is_dload;

	case GET_FORCE_RAMDUMP:
		get_user(status, (unsigned long __user *) arg);
		pr_info("%s: mdm get dump mode = %d\n", __func__, force_dump);
		if (status)
			mdm_force_fatal();
		else
			mdm_silent_reset();
		break;

#ifdef CONFIG_SIM_DETECT
	case GET_SIM_DETECT:
		pr_info("%s: mdm get sim detect = %d\n", __func__,
						mdm_drv->sim_state);
		return mdm_drv->sim_state;
#endif
	default:
		pr_err("%s: invalid ioctl cmd = %d\n", __func__, _IOC_NR(cmd));
		ret = -EINVAL;
		break;
	}

	return ret;
}
Esempio n. 29
0
/* ======================================================================== */
static int Godshand_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
	int err = 0;
	int ret = 0;
	void * Godshand_location = NULL;
	DWORD tmp;
	GODSHAND_Dev *dev = (GODSHAND_Dev *)filp->private_data;
	DWORD GODSHAND_LOCATION;
	DWORD GODSHAND_AREA_SIZE;
	Godshand_info = (GODSHAND_Info *)arg;

	GODSHAND_LOCATION = Godshand_info->dwAddress;
	GODSHAND_AREA_SIZE = GODSHAND_SIZE; 
	PDEBUG("the address is %x\n",Godshand_info->dwAddress);
	if (Godshand_info->dwFlag & GODSHAND_FLAG_AREA)
	{
		GODSHAND_AREA_SIZE = Godshand_info->dwSize;
	}

	if (check_mem_region(GODSHAND_START, GODSHAND_SIZE) < 0) {
		PDEBUG("ERROR: allocated fail!\n\r");
		ret = -EBUSY;
		goto fail;
	}
	request_mem_region(GODSHAND_START, GODSHAND_SIZE, "GODSHAND module .");

	Godshand_base = (unsigned long *)ioremap((int)GODSHAND_START, (int)GODSHAND_SIZE);
	Godshand_location = (unsigned long *)ioremap((int)GODSHAND_LOCATION, (int)GODSHAND_AREA_SIZE);
	PDEBUG("%x: Allocated\n\r", (int)Godshand_base);

	if (!dev) {
		return -ENODEV;
	}
	/*
	 * extract the type and number bitfields, and don't decode
	 * wrong cmds: return ENOTTY (inappropriate ioctl) before access_ok()
	 */
	if (_IOC_TYPE(cmd) != GODSHAND_IOC_MAGIC) {
		return -ENOTTY;
	}

	if (_IOC_NR(cmd) > GODSHAND_IOC_MAXNUM) {
		return -ENOTTY;
	}
	/*
	 * the direction is a bitmask, and VERIFY_WRITE catches R/W
	 * transfers. `Type' is user-oriented, while
	 * access_ok is kernel-oriented, so the concept of "read" and
	  * "write" is reversed
	*/
	if (_IOC_DIR(cmd) & _IOC_READ) {
		err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));
	} else if (_IOC_DIR(cmd) & _IOC_WRITE){
		err = !access_ok(VERIFY_READ,  (void *)arg, _IOC_SIZE(cmd));
	}
	
	if (err) {
		return -EFAULT;
	}

	switch (cmd)
	{
		case GODSHAND_IOC_RESET :
			break;
		case GODSHAND_IOC_CLEAR :
			break;
		case GODSHAND_IOC_READ :
			if (down_interruptible(&dev->sem)) {
				return -ERESTARTSYS;
			}
			ret = __put_user(readl((u32*)(Godshand_location)), (u32*)(&Godshand_info->dwData));
			up(&dev->sem);
			break;
		case GODSHAND_IOC_READ_AREA :
			if (down_interruptible(&dev->sem)) {
				return -ERESTARTSYS;
			}
			ret = copy_to_user(Godshand_info->pDataBuffer, ((u32*)Godshand_location), GODSHAND_AREA_SIZE);
			up(&dev->sem);
			break;
		case GODSHAND_IOC_WRITE :
			ret = __get_user(tmp, (u32*)(&Godshand_info->dwData));
			if (down_interruptible(&dev->sem)) {
				return -ERESTARTSYS;
			}
			writel(tmp,(u32*)(Godshand_location));
			up(&dev->sem);
			break;
		case GODSHAND_IOC_WRITE_AREA :
			ret = __get_user(tmp, (u32*)(&Godshand_info->dwData));
			if (down_interruptible(&dev->sem)) {
				return -ERESTARTSYS;
			}
			writel(tmp,(u32*)(Godshand_location));
			up(&dev->sem);
			break;
		default:  /* redundant, as cmd was checked against MAXNR */
			return -ENOTTY;
	}
fail :
	PDEBUG("%s iounmap\n",__func__);
	iounmap(Godshand_location);
	iounmap(Godshand_base);
	Godshand_base = NULL;
	PDEBUG("%s release_mem_region\n",__func__);
	release_mem_region(GODSHAND_START,GODSHAND_SIZE);
	return ret;

}
Esempio n. 30
0
int scull_p_ioctl(struct file *filp, unsigned int cmd, unsigned long arg){

       int retval = 0, tmp, err = 0;

        /* extract the type and number bitfields, and don't
         * decode wrong cmds: return ENOTTY before access_ok()
         */
        if(_IOC_TYPE(cmd) != SCULL_IOC_MAGIC)
                return -ENOTTY;

        if(_IOC_NR(cmd) > SCULL_IOC_MAXNR)
                return -ENOTTY;

       /* the direction field is a bitmask (2 bits), and
        * VERIFY_WRITE catches R/W transfers. 'direction'
        * bitfield is user-oriented, while acces_ok() is
         * kernel-oriented, so the concept of "read" and
         * "write" is reversed
         */

        /* access_ok() returns non-zero as success and 0
	 * as error
         */

        if(_IOC_DIR(cmd) & _IOC_READ)
                err = !access_ok(VERIFY_WRITE, (void __user*)arg, _IOC_SIZE(cmd));

        else if(_IOC_DIR(cmd) & _IOC_WRITE)
                err = !access_ok(VERIFY_READ, (void __user*)arg, _IOC_SIZE(cmd));

        if(err)
                return -EFAULT;

        switch(cmd){

               case SCULL_IOCRESET:
                        scull_quantum = SCULL_QUANTUM;
                        scull_qset = SCULL_QSET;
                       break;

                case SCULL_IOCSQUANTUM: /* Set: arg points to the value */
                        if(!capable(CAP_SYS_ADMIN))
                                return -EPERM;

                        retval = __get_user(scull_quantum, (int __user*)arg);
                        break;

                case SCULL_IOCTQUANTUM: /* Tell: arg is the value */
                       if(!capable(CAP_SYS_ADMIN))
                                return -EPERM;

                        scull_quantum = arg;
                        break;

                case SCULL_IOCGQUANTUM: /* Get: arg is pointer to result */
                        retval = __put_user(scull_quantum, (int __user*)arg);
                       break;

                case SCULL_IOCQQUANTUM: /* Query: return it (it's positive) */
                        return scull_quantum;

                case SCULL_IOCXQUANTUM: /* eXchange: use arg as pointer */
                        if(!capable(CAP_SYS_ADMIN))
                                return -EPERM;
                        tmp = scull_quantum;
                        retval = __get_user(scull_quantum, (int __user*)arg);
                        if(retval == 0)
                                retval = __put_user(tmp, (int __user *)arg);
                        break;

                case SCULL_IOCHQUANTUM: /* sHift: like Tell + Query */
                        if(!capable(CAP_SYS_ADMIN))
                                return -EPERM;
                        tmp = scull_quantum;
                        scull_quantum = arg;
                       return tmp;

                default: /* Redundant, as cmd was checked against MAXNR */
			return -ENOTTY;
	
        }
        return retval;

}