static int snd_compress_simple_ioctls(struct file *file,
                                      struct snd_compr_stream *stream,
                                      unsigned int cmd, unsigned long arg)
{
    int retval = -ENOTTY;

    switch (_IOC_NR(cmd)) {
    case _IOC_NR(SNDRV_COMPRESS_IOCTL_VERSION):
        retval = put_user(SNDRV_COMPRESS_VERSION,
                          (int __user *)arg) ? -EFAULT : 0;
        break;

    case _IOC_NR(SNDRV_COMPRESS_GET_CAPS):
        retval = snd_compr_get_caps(stream, arg);
        break;

    case _IOC_NR(SNDRV_COMPRESS_GET_CODEC_CAPS):
        retval = snd_compr_get_codec_caps(stream, arg);
        break;


    case _IOC_NR(SNDRV_COMPRESS_TSTAMP):
        retval = snd_compr_tstamp(stream, arg);
        break;

    case _IOC_NR(SNDRV_COMPRESS_AVAIL):
        retval = snd_compr_ioctl_avail(stream, arg);
        break;

    case _IOC_NR(SNDRV_COMPRESS_DRAIN):
        retval = snd_compr_drain(stream);
        break;

    case _IOC_NR(SNDRV_COMPRESS_PARTIAL_DRAIN):
        retval = snd_compr_partial_drain(stream);
        break;
    }

    return retval;
}
int al3010_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	int err = 1;

	if (_IOC_TYPE(cmd) != AL3010_IOC_MAGIC)
	return -ENOTTY;
	if (_IOC_NR(cmd) > AL3010_IOC_MAXNR)
	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)
		return -EFAULT;

	switch (cmd) {
		case AL3010_POLL_DATA:
			if (arg == AL3010_IOCTL_START_HEAVY){
				printk("light sensor info : ioctl heavy\n");
				poll_mode = START_HEAVY;
				queue_delayed_work(sensor_work_queue, &al3010_poll_data_work, poll_mode);
			}
			else if (arg == AL3010_IOCTL_START_NORMAL){
				printk("light sensor info : ioctl normal\n");
				poll_mode = START_NORMAL;
				queue_delayed_work(sensor_work_queue, &al3010_poll_data_work, poll_mode);
			}
			else if  (arg == AL3010_IOCTL_END){
				printk("light sensor info : ioctl end\n");
				cancel_delayed_work_sync(&al3010_poll_data_work);
			}
			else
				return -ENOTTY;
			break;
		default: /* redundant, as cmd was checked against MAXNR */
			return -ENOTTY;
	}

	return 0;
}
/**************************************************************************
*  DEV DRIVER IOCTL
**************************************************************************/
static long devinfo_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	u32 index = 0;
	int err   = 0;
	int ret   = 0;
	u32 data_size = ARRAY_SIZE(g_devinfo_data);
	u32 data_read = 0;

	/* ---------------------------------- */
	/* IOCTL							  */
	/* ---------------------------------- */
	if (_IOC_TYPE(cmd) != DEV_IOC_MAGIC)
		return -ENOTTY;
	if (_IOC_NR(cmd) > DEV_IOC_MAXNR)
		return -ENOTTY;
	if (_IOC_DIR(cmd) & _IOC_READ)
		err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
	if (_IOC_DIR(cmd) & _IOC_WRITE)
		err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
	if (err)
		return -EFAULT;

	switch (cmd) {
	/* ---------------------------------- */
	/* get dev info data				  */
	/* ---------------------------------- */
	case READ_DEV_DATA:
		if (copy_from_user((void *)&index, (void __user *)arg, sizeof(u32)))
			return -1;
		if (index < data_size) {
			data_read = get_devinfo_with_index(index);
			ret = copy_to_user((void __user *)arg, (void *)&(data_read), sizeof(u32));
		} else {
			pr_warn("%s Error! Data index larger than data size. index:%d, size:%d\n", MODULE_NAME,
			index, data_size);
			return -2;
		}
		break;
	}

	return 0;
}
static int snd_compress_simple_ioctls(struct file *file,
				struct snd_compr_stream *stream,
				unsigned int cmd, unsigned long arg)
{
	int retval = -ENOTTY;

	switch (_IOC_NR(cmd)) {
	case _IOC_NR(SNDRV_COMPRESS_IOCTL_VERSION):
		retval = put_user(SNDRV_COMPRESS_VERSION,
				(int __user *)arg) ? -EFAULT : 0;
		break;
	case _IOC_NR(SNDRV_COMPRESS_GET_CAPS):
		retval = snd_compr_get_caps(stream, arg);
		break;
	case _IOC_NR(SNDRV_COMPRESS_GET_CODEC_CAPS):
		retval = snd_compr_get_codec_caps(stream, arg);
		break;

	case _IOC_NR(SNDRV_COMPRESS_TSTAMP):
		retval = snd_compr_tstamp(stream, arg);
		break;
	case _IOC_NR(SNDRV_COMPRESS_AVAIL):
		retval = snd_compr_ioctl_avail(stream, arg);
		break;

	/* drain and partial drain need special handling
	 * we need to drop the locks here as the streams would get blocked on the
	 * fw to get drained. The locking would be handled in respective
	 * function here
	 */
	case _IOC_NR(SNDRV_COMPRESS_DRAIN):
		retval = snd_compr_drain(stream);
		break;
	case _IOC_NR(SNDRV_COMPRESS_PARTIAL_DRAIN):
		retval = snd_compr_partial_drain(stream);
		break;
	}
	return retval;
}
Beispiel #5
0
/*
 * Check sanity of parameter control fields and if a path is present
 * check that it is terminated and contains at least one "/".
 */
static int validate_dev_ioctl(int cmd, struct autofs_dev_ioctl *param)
{
	int err;

	err = check_dev_ioctl_version(cmd, param);
	if (err) {
		pr_warn("invalid device control module version "
			"supplied for cmd(0x%08x)\n", cmd);
		goto out;
	}

	if (param->size > AUTOFS_DEV_IOCTL_SIZE) {
		err = invalid_str(param->path, param->size - AUTOFS_DEV_IOCTL_SIZE);
		if (err) {
			pr_warn(
			  "path string terminator missing for cmd(0x%08x)\n",
			  cmd);
			goto out;
		}

		err = check_name(param->path);
		if (err) {
			pr_warn("invalid path supplied for cmd(0x%08x)\n",
				cmd);
			goto out;
		}
	} else {
		unsigned int inr = _IOC_NR(cmd);

		if (inr == AUTOFS_DEV_IOCTL_OPENMOUNT_CMD ||
		    inr == AUTOFS_DEV_IOCTL_REQUESTER_CMD ||
		    inr == AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD) {
			err = -EINVAL;
			goto out;
		}
	}

	err = 0;
out:
	return err;
}
Beispiel #6
0
// -------------------------------------------------------------------------
long bks_ioctl(struct file *file, unsigned int request, unsigned long arg)
{
    long rc = 0;
    struct BksDeviceContext* ctx = file->private_data;
    int nr = 0;
    unsigned char* ptr = 0;

    const int dir = _IOC_DIR(request);
    const int type = _IOC_TYPE(request);
    const int number = _IOC_NR(request);
    const int size = _IOC_SIZE(request);
    printk(KERN_INFO "[bks] ioctl(), request: %u, arg: %lu)\n", request, arg);
    printk(KERN_INFO "[bks] ioctl(), data direction: %d, type: %d, number: %d, size: %d\n", dir, type, number, size);

    if (!ctx) {
        rc = -EINVAL;
        goto exit; // not much we can do.
    } else {
        nr = ctx->nr;
        ptr = ctx->ptr;
    }
    printk(KERN_INFO "[bks] ioctl(), context: %p, minor: %d, ptr: %p\n", ctx, nr, ptr);

    if (!arg) {
        rc = -1;
    } else if (BKS_IOCTL_OPEN_COUNT == request) {
        int count = bks_getOpenCount();
        rc = copy_to_user((int*)arg, &count, sizeof(int));
    } else if (BKS_IOCTL_BUFSIZE == request) {
        int size = bks_getBufferSize(nr);
        rc = copy_to_user((int*)arg, &size, sizeof(int));
    } else if (BKS_IOCTL_CONTENT_LENGTH == request) {
        int len = bks_getBufferContentLength(nr);
        rc = copy_to_user((int*)arg, &len, sizeof(int));
    } else {
        rc = -1;
    }

exit:
    return rc;
}
Beispiel #7
0
static long capella_cm3602_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	int val;
	/*DPS("%s cmd %d\n", __func__, _IOC_NR(cmd));*/
	switch (cmd) {
	case CAPELLA_CM3602_IOCTL_ENABLE:
		if (get_user(val, (unsigned long __user *)arg))
			return -EFAULT;
		if (val)
			return capella_cm3602_enable(&the_data);
		else
			return capella_cm3602_disable(&the_data);
		break;
	case CAPELLA_CM3602_IOCTL_GET_ENABLED:
		return put_user(the_data.enabled, (unsigned long __user *)arg);
		break;
	default:
		DPS("%s: invalid cmd %d\n", __func__, _IOC_NR(cmd));
		return -EINVAL;
	}
}
Beispiel #8
0
/*
 * Ioctl main entry point
 */
static long fsl_hv_ioctl(struct file *file, unsigned int cmd,
			 unsigned long argaddr)
{
	void __user *arg = (void __user *)argaddr;
	long ret;

	switch (cmd) {
	case FSL_HV_IOCTL_PARTITION_RESTART:
		ret = ioctl_restart(arg);
		break;
	case FSL_HV_IOCTL_PARTITION_GET_STATUS:
		ret = ioctl_status(arg);
		break;
	case FSL_HV_IOCTL_PARTITION_START:
		ret = ioctl_start(arg);
		break;
	case FSL_HV_IOCTL_PARTITION_STOP:
		ret = ioctl_stop(arg);
		break;
	case FSL_HV_IOCTL_MEMCPY:
		ret = ioctl_memcpy(arg);
		break;
	case FSL_HV_IOCTL_DOORBELL:
		ret = ioctl_doorbell(arg);
		break;
	case FSL_HV_IOCTL_GETPROP:
		ret = ioctl_dtprop(arg, 0);
		break;
	case FSL_HV_IOCTL_SETPROP:
		ret = ioctl_dtprop(arg, 1);
		break;
	default:
		pr_debug("fsl-hv: bad ioctl dir=%u type=%u cmd=%u size=%u\n",
			 _IOC_DIR(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd),
			 _IOC_SIZE(cmd));
		return -ENOTTY;
	}

	return ret;
}
/* Common ioctl debug function. This function can be used by
   external ioctl messages as well as internal V4L ioctl */
void v4l_printk_ioctl(unsigned int cmd)
{
	char *dir, *type;

	switch (_IOC_TYPE(cmd)) {
	case 'd':
		if (_IOC_NR(cmd) >= V4L2_INT_IOCTLS) {
			type = "v4l2_int";
			break;
		}
		printk("%s", v4l2_int_ioctls[_IOC_NR(cmd)]);
		return;
#ifdef CONFIG_VIDEO_V4L1_COMPAT
	case 'v':
		if (_IOC_NR(cmd) >= V4L1_IOCTLS) {
			type = "v4l1";
			break;
		}
		printk("%s", v4l1_ioctls[_IOC_NR(cmd)]);
		return;
#endif
	case 'V':
		if (_IOC_NR(cmd) >= V4L2_IOCTLS) {
			type = "v4l2";
			break;
		}
		printk("%s", v4l2_ioctls[_IOC_NR(cmd)]);
		return;
	default:
		type = "unknown";
	}

	switch (_IOC_DIR(cmd)) {
	case _IOC_NONE:              dir = "--"; break;
	case _IOC_READ:              dir = "r-"; break;
	case _IOC_WRITE:             dir = "-w"; break;
	case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
	default:                     dir = "*ERR*"; break;
	}
	printk("%s ioctl '%c', dir=%s, #%d (0x%08x)",
		type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
}
static long boardid_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	void __user *argp = (void __user *)arg;
	unsigned int boardid = 0;
	int ret = 0;

	switch (cmd) {
    case BOARDID_READ_DATA:
    	boardid = get_boardid();
    	pr_info("%s: get boardid : %d\n", __func__, boardid);
    	if (copy_to_user(argp, &boardid, sizeof(int))){
        	pr_err("%s: copy_to_user error\n", __func__);
            ret = -EFAULT;
        }
    	break;
    default:
		pr_err("%s: invalid command %d\n", __func__, _IOC_NR(cmd));
    	break;
    }

    return ret;
}
Beispiel #11
0
static int
ioctl_simplestruct_init_from_text(ioctl_tree * node, const char *data)
{
    /* node->id is initialized at this point, but does not necessarily have the
     * correct length for data; this happens for variable length ioctls such as
     * EVIOCGBIT */
    size_t data_len = strlen(data) / 2;
    node->data = malloc(data_len);

    if (NSIZE(node) != data_len) {
	DBG(DBG_IOCTL_TREE, "ioctl_simplestruct_init_from_text: adjusting ioctl ID %lX (size %lu) to actual data length %zu\n",
	    node->id, NSIZE(node), data_len);
	node->id = _IOC(_IOC_DIR(node->id), _IOC_TYPE(node->id), _IOC_NR(node->id), data_len);
    }

    if (!read_hex(data, node->data, NSIZE(node))) {
	DBG(DBG_IOCTL_TREE, "ioctl_simplestruct_init_from_text: failed to parse '%s'\n", data);
	free(node->data);
	return FALSE;
    }
    return TRUE;
}
Beispiel #12
0
void saa7134_print_ioctl(char *name, unsigned int cmd)
{
	char *dir;

	switch (_IOC_DIR(cmd)) {
	case _IOC_NONE:              dir = "--"; break;
	case _IOC_READ:              dir = "r-"; break;
	case _IOC_WRITE:             dir = "-w"; break;
	case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
	default:                     dir = "??"; break;
	}
	switch (_IOC_TYPE(cmd)) {
	case 'v':
		printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l1, %s, VIDIOC%s)\n",
		       name, cmd, dir, (_IOC_NR(cmd) < V4L1_IOCTLS) ?
		       v4l1_ioctls[_IOC_NR(cmd)] : "???");
		break;
	case 'V':
		printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l2, %s, VIDIOC_%s)\n",
		       name, cmd, dir, (_IOC_NR(cmd) < V4L2_IOCTLS) ?
		       v4l2_ioctls[_IOC_NR(cmd)] : "???");
		break;
	case 'P':
		printk(KERN_DEBUG "%s: ioctl 0x%08x (oss dsp, %s, SNDCTL_DSP_%s)\n",
		       name, cmd, dir, (_IOC_NR(cmd) < OSSPCM_IOCTLS) ?
		       osspcm_ioctls[_IOC_NR(cmd)] : "???");
		break;
	case 'M':
		printk(KERN_DEBUG "%s: ioctl 0x%08x (oss mixer, %s, #%d)\n",
		       name, cmd, dir, _IOC_NR(cmd));
		break;
	default:
		printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n",
		       name, cmd, dir, _IOC_NR(cmd));
	}
}
Beispiel #13
0
static int netdev_wifr_ioctl(FAR struct socket *psock, int cmd,
                             FAR struct iwreq *req)
{
  FAR struct net_driver_s *dev;
  int ret = -ENOTTY;

  /* Verify that this is a valid wireless network IOCTL command */

  if (_WLIOCVALID(cmd) && (unsigned)_IOC_NR(cmd) <= WL_NNETCMDS)
    {
      /* Get the wireless device associated with the IOCTL command */

      dev = netdev_findbyname(req->ifr_name);
      if (dev != NULL)
        {
          /* Just forward the IOCTL to the wireless driver */

          ret = dev->d_ioctl(dev, cmd, ((unsigned long)(uintptr_t)req));
        }
    }

  return ret;
}
static int
i2c_ioctl(struct inode *inode, struct file *file,
	  unsigned int cmd, unsigned long arg)
{
	if(_IOC_TYPE(cmd) != ETRAXI2C_IOCTYPE) {
		return -EINVAL;
	}

	switch (_IOC_NR(cmd)) {
		case I2C_WRITEREG:
			/* write to an i2c slave */
			D(printk("i2cw %d %d %d\n", 
				 I2C_ARGSLAVE(arg),
				 I2C_ARGREG(arg),
				 I2C_ARGVALUE(arg)));

			return i2c_writereg(I2C_ARGSLAVE(arg),
					    I2C_ARGREG(arg),
					    I2C_ARGVALUE(arg));
		case I2C_READREG:
		{
			unsigned char val;
			/* read from an i2c slave */
			D(printk("i2cr %d %d ", 
				I2C_ARGSLAVE(arg),
				I2C_ARGREG(arg)));
			val = i2c_readreg(I2C_ARGSLAVE(arg), I2C_ARGREG(arg));
			D(printk("= %d\n", val));
			return val;
		}					    
		default:
			return -EINVAL;

	}
	
	return 0;
}
Beispiel #15
0
int match_fops_ioctl(struct inode *fops_inode, struct file *fops_file, unsigned int cmd, unsigned long arg)
{
	static int inret = 1, otret = 1;
	printk("match_fops_ioctl called.\n");
//	printk("command[%d]\n", cmd);
	if (_IOC_TYPE(cmd) != NF_IOC_MAGIC)
		return -EINVAL;
	if (_IOC_NR(cmd) > NF_IOC_MAXNR)
		return -EINVAL;

    switch (cmd)
    {
	case SET_MATCH_SEGMENT_IN :
        inret = segment_load((struct segment_info*)arg, 0);
        break;
    case SET_MATCH_SEGMENT_OUT:
        otret = segment_load((struct segment_info*)arg, 1);
        break;
	case SET_MATCH_PATTERN_IN :
		if (inret == 0)
		{
			match_load((struct match_info*)arg, 0);
			inret = 1;
		}
		break;
	case SET_MATCH_PATTERN_OUT:
		if (otret == 0)
		{
			match_load((struct match_info*)arg, 1);
			otret = 1;
		}
		break;
    }

    return 0;
}
static long snd_compr_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
{
	struct snd_compr_file *data = f->private_data;
	struct snd_compr_stream *stream;
	int retval = -ENOTTY;

	if (snd_BUG_ON(!data))
		return -EFAULT;
	stream = &data->stream;
	if (snd_BUG_ON(!stream))
		return -EFAULT;

	mutex_lock(&stream->device->lock);
	switch (_IOC_NR(cmd)) {
	case _IOC_NR(SNDRV_COMPRESS_SET_PARAMS):
		retval = snd_compr_set_params(stream, arg);
		break;

	case _IOC_NR(SNDRV_COMPRESS_GET_PARAMS):
		retval = snd_compr_get_params(stream, arg);
		break;

	case _IOC_NR(SNDRV_COMPRESS_SET_METADATA):
		retval = snd_compr_set_metadata(stream, arg);
		break;

	case _IOC_NR(SNDRV_COMPRESS_GET_METADATA):
		retval = snd_compr_get_metadata(stream, arg);
		break;

	case _IOC_NR(SNDRV_COMPRESS_PAUSE):
		retval = snd_compr_pause(stream);
		break;

	case _IOC_NR(SNDRV_COMPRESS_RESUME):
		retval = snd_compr_resume(stream);
		break;

	case _IOC_NR(SNDRV_COMPRESS_START):
		retval = snd_compr_start(stream);
		break;

	case _IOC_NR(SNDRV_COMPRESS_STOP):
		retval = snd_compr_stop(stream);
		break;

	case _IOC_NR(SNDRV_COMPRESS_NEXT_TRACK):
		retval = snd_compr_next_track(stream);
		break;

	case _IOC_NR(SNDRV_COMPRESS_ENABLE_EFFECT):
		retval = snd_compr_effect(stream, arg);
		break;

	default:
		mutex_unlock(&stream->device->lock);
		return snd_compress_simple_ioctls(f, stream, cmd, arg);

	}

	mutex_unlock(&stream->device->lock);
	return retval;
}
static long aic3254_ioctl(struct file *file, unsigned int cmd,
	   unsigned long argc)
{
	struct AIC3254_PARAM para;
	void *table;
	int ret = 0, i = 0, mem_size, volume = 0;
	CODEC_SPI_CMD reg[2];
	unsigned char data;

	if (aic3254_uplink == NULL ||
		aic3254_downlink == NULL ||
		aic3254_minidsp == NULL) {
		pr_aud_err("%s: cmd 0x%x, invalid pointers\n", __func__, cmd);
		return -EFAULT;
	}

	switch (cmd) {
	case AIC3254_SET_TX_PARAM:
	case AIC3254_SET_RX_PARAM:
		if (copy_from_user(&para, (void *)argc, sizeof(para))) {
			pr_aud_err("%s: failed on copy_from_user\n", __func__);
			return -EFAULT;
		}

		pr_aud_info("%s: parameters(%d, %d, %p)\n", __func__,
				para.row_num, para.col_num, para.cmd_data);
		if (cmd == AIC3254_SET_TX_PARAM)
			table = aic3254_uplink[0];
		else
			table = aic3254_downlink[0];

		/* confirm indicated size doesn't exceed the allocated one */
		if (para.row_num > IO_CTL_ROW_MAX
				|| para.col_num != IO_CTL_COL_MAX) {
			pr_aud_err("%s: data size mismatch with allocated"
					" memory (%d,%d)\n", __func__,
					IO_CTL_ROW_MAX, IO_CTL_COL_MAX);
			return -EFAULT;
		}

		mem_size = para.row_num * para.col_num * sizeof(CODEC_SPI_CMD);
		if (copy_from_user(table, para.cmd_data, mem_size)) {
			pr_aud_err("%s: failed on copy_from_user\n", __func__);
			return -EFAULT;
		}

		/* invoking initialization procedure of AIC3254 */
		if (cmd == AIC3254_SET_TX_PARAM)
			aic3254_tx_config(INITIAL);

		pr_aud_info("%s: update table(%d,%d) successfully\n",
				__func__, para.row_num, para.col_num);
			break;
	case AIC3254_SET_DSP_PARAM:
		if (copy_from_user(&para, (void *)argc, sizeof(para))) {
			pr_aud_err("%s: failed on copy_from_user\n", __func__);
			return -EFAULT;
		}

		pr_aud_info("%s: parameters(%d, %d, %p)\n", __func__,
				para.row_num, para.col_num, para.cmd_data);

		table = aic3254_minidsp[0];

		/* confirm indicated size doesn't exceed the allocated one */
		if (para.row_num > MINIDSP_ROW_MAX
				|| para.col_num != MINIDSP_COL_MAX) {
			pr_aud_err("%s: data size mismatch with allocated"
					" memory (%d,%d)\n", __func__,
					MINIDSP_ROW_MAX, MINIDSP_COL_MAX);
			return -EFAULT;
			}

		mem_size = para.row_num * para.col_num * sizeof(CODEC_SPI_CMD);
		if (copy_from_user(table, para.cmd_data, mem_size)) {
			pr_aud_err("%s: failed on copy_from_user\n", __func__);
			return -EFAULT;
		}

		pr_aud_info("%s: update table(%d,%d) successfully\n",
				__func__, para.row_num, para.col_num);
		break;
	case AIC3254_CONFIG_TX:
	case AIC3254_CONFIG_RX:
	case AIC3254_CONFIG_MEDIA:
		if (copy_from_user(&i, (void *)argc, sizeof(int))) {
			pr_aud_err("%s: failed on copy_from_user\n", __func__);
			return -EFAULT;
		}
		ret = aic3254_set_config(cmd, i, 1);
		if (ret < 0)
			pr_aud_err("%s: configure(%d) error %d\n",
				__func__, i, ret);
		break;
	case AIC3254_CONFIG_VOLUME_L:
		if (copy_from_user(&volume, (void *)argc, sizeof(int))) {
			pr_aud_err("%s: failed on copy_from_user\n", __func__);
			return -EFAULT;
		}

		if (volume < -127 || volume > 48) {
			pr_aud_err("%s: volume out of range\n", __func__);
			return -EFAULT;
		}

		pr_aud_info("%s: AIC3254 config left volume %d\n",
				__func__, volume);

		CODEC_SET_VOLUME_L[1].data = volume;
		aic3254_config_ex(CODEC_SET_VOLUME_L, ARRAY_SIZE(CODEC_SET_VOLUME_L));
		break;
	case AIC3254_CONFIG_VOLUME_R:
		if (copy_from_user(&volume, (void *)argc, sizeof(int))) {
			pr_aud_err("%s: failed on copy_from_user\n", __func__);
			return -EFAULT;
		}

		if (volume < -127 || volume > 48) {
			pr_aud_err("%s: volume out of range\n", __func__);
			return -EFAULT;
		}

		pr_aud_info("%s: AIC3254 config right volume %d\n",
				__func__, volume);

		CODEC_SET_VOLUME_R[1].data = volume;
		aic3254_config_ex(CODEC_SET_VOLUME_R, ARRAY_SIZE(CODEC_SET_VOLUME_R));
		break;
	case AIC3254_DUMP_PAGES:
		if (copy_from_user(&i, (void *)argc, sizeof(int))) {
			pr_aud_err("%s: failed on copy_from_user\n", __func__);
			return -EFAULT;
		}
		if (i > AIC3254_MAX_PAGES) {
			pr_aud_err("%s: invalid page number %d\n", __func__, i);
			return -EINVAL;
		}

		pr_aud_info("========== %s: dump page %d ==========\n",
				__func__, i);
		/* indicated page number to AIC3254 */
		if (ctl_ops->rx_amp_enable)
			ctl_ops->rx_amp_enable(1);
		codec_spi_write(0x00, i);
		for (i = 0; i < AIC3254_MAX_REGS; i++) {
			ret = codec_spi_read(i, &data);
			if (ret < 0)
				pr_aud_err("read fail on register 0x%X\n", i);
			else
				pr_aud_info("(0x%02X, 0x%02X)\n", i, data);
		}
		if (ctl_ops->rx_amp_enable)
			ctl_ops->rx_amp_enable(0);
		pr_aud_info("=============================================\n");
		break;
	case AIC3254_WRITE_REG:
		if (copy_from_user(&reg, (void *)argc,
					sizeof(CODEC_SPI_CMD)*2)) {
			pr_aud_err("%s: failed on copy_from_user\n", __func__);
			return -EFAULT;
		}
		pr_aud_info("%s: command list (%c,%02X,%02X) (%c,%02X,%02X)\n",
				__func__, reg[0].act, reg[0].reg, reg[0].data,
				reg[1].act, reg[1].reg, reg[1].data);
		aic3254_config_ex(reg, 2);
		break;
	case AIC3254_READ_REG:
		if (copy_from_user(&reg, (void *)argc,
					sizeof(CODEC_SPI_CMD)*2)) {
			pr_aud_err("%s: failed on copy_from_user\n", __func__);
			return -EFAULT;
		}
		if (ctl_ops->spibus_enable)
			ctl_ops->spibus_enable(1);
		for (i = 0; i < 2; i++) {
			if (reg[i].act == 'r' || reg[i].act == 'R')
				codec_spi_read(reg[i].reg, &reg[i].data);
			else if (reg[i].act == 'w' || reg[i].act == 'W')
				codec_spi_write(reg[i].reg, reg[i].data);
			else
				return -EINVAL;
		}
		if (ctl_ops->spibus_enable)
			ctl_ops->spibus_enable(0);
		if (copy_to_user((void *)argc, &reg, sizeof(CODEC_SPI_CMD)*2)) {
			pr_aud_err("%s: failed on copy_to_user\n", __func__);
			return -EFAULT;
		}
		break;
	case AIC3254_POWERDOWN:
		mutex_lock(&lock);
		aic3254_powerdown();
		mutex_unlock(&lock);
		break;
	case AIC3254_LOOPBACK:
		if (copy_from_user(&i, (void *)argc, sizeof(int))) {
			pr_aud_err("%s: failed on copy_from_user\n", __func__);
			return -EFAULT;
		}
		pr_aud_info("%s: index %d for LOOPBACK\n", __func__, i);
		aic3254_loopback(i);
		break;
	default:
		pr_aud_err("%s: invalid command %d\n", __func__, _IOC_NR(cmd));
		ret = -EINVAL;
	}

	return ret;
}
Beispiel #18
0
int ali_openVG_ioctl( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
#endif                                      
{
	/*driver relative data*/
	struct ali_openVG_dev *dev=ali_ovg_devices;
	struct ali_openVG_handle* handle = ((struct ali_openVG_handle*)filp->private_data);
	struct list_head *head = handle->mem_list;
	//struct list_head *allocated = handle->allocated_list;	
	/*parameter relative data*/
	int result = 0;

	ovg_srecord(_IOC_NR(cmd) -1);

	switch(cmd) {
		case ALI_OPENVG_EnableCMDQ:
//			dev = container_of(inode->i_cdev, struct ali_openVG_dev, cdev);
			result = ali_ovg_enableQ(dev, arg, (unsigned int)(handle->pdt));
		break;
		case ALI_OPENVG_TessWaitTessFinish:
		case ALI_OPENVG_RastWaitRastFinish:
		case ALI_OPENVG_ImageWaitImageFinish:
		case ALI_OPENVG_HWWaitHWFinish:
			result = ali_ovg_waitHWFinish(cmd, arg);
		break;

		case ALI_OPENVG_MemoryAlloc:
//			dev = container_of(inode->i_cdev, struct ali_openVG_dev, cdev);
			result = ali_ovg_alloc(dev, filp, arg);
		break;
		
		case ALI_OPENVG_MemoryFree:
			result = ali_ovg_free(arg, filp);
		break;
		
		case ALI_OPENVG_SetData:
			result = ali_ovg_setData(arg, head);
		break;
		
		case ALI_OPENVG_GetData:
			result = ali_ovg_getData(arg, head);
		break;
		
		case ALI_OPENVG_Reset:
			result = ali_ovg_reset();
		break;
		
		case ALI_OPENVG_GetHWRegister:
			result = ali_ovg_getHWRegister(arg);
		break;
		
		case ALI_OPENVG_SetHWRegister:
			result = ali_ovg_setHWRegister(arg);
		break;		

		case ALI_OPENVG_Virt2Phy:
			result = ali_ovg_virt2phy(arg, head);
		break;

		case ALI_OPENVG_PFNMapTable:
//			dev = container_of(inode->i_cdev, struct ali_openVG_dev, cdev);
			result = ali_ovg_pfnMapTable(dev, filp, arg);
		break;

		case ALI_OPENVG_GetPDTBaseAddr:
			if(ALI_OPENVG_GET_UINT32(VG_ID) >= 0x00000002)
				result = copy_to_user((unsigned int __user*)arg, &(handle->pdt), sizeof(unsigned int));
			else{
				OVG_PRINTK("hey, MMU is not supported on this HW version \n");
				result = -EFAULT;
			}	
		break;

		case ALI_OPENVG_GEN_PageTable:
				result = ali_ovg_genPageTable(filp, arg);
		break;
		
		case ALI_OPENVG_Realloc:
			if(ALI_OPENVG_GET_UINT32(VG_ID) >= 0x00000002){
//				dev = container_of(inode->i_cdev, struct ali_openVG_dev, cdev);
				result = ali_ovg_realloc(dev, filp, arg);
			}else{
				OVG_PRINTK("hey, MMU is not supported on this HW version \n");
				result = -EFAULT;
			}	
		break;	
		
		case ALI_OPENVG_DestroyAllMemory:
			OVG_PRINTK("Destroy all openVG memory buffers, be careful!\n");
			if(memfp.ovg_session_end)
				memfp.ovg_session_end(filp);
			result = 0;	
		break;	
		
		case ALI_OPENVG_DumpMemory:
			#if MEMORY_DEBUG
				OVG_PRINTK("memory allocate %d , memory release %d, leak %d \n"
				,memory_usage, memory_release, (memory_usage - memory_release) );
			#endif	
			result = 0;
		break;		

		case ALI_OPENVG_MemoryAlloc_Shared:
			result = ali_ovg_alloc_shared(arg);
		break;

		case ALI_OPENVG_MemoryFree_Shared:
			result = ali_ovg_free_shared(arg);
		break;

		default:
			OVG_PRINTK("Driver Error: Unknow Command ID %d \n", cmd);
			result = -EFAULT;
	}
	if(!result)
		ovg_erecord(_IOC_NR(cmd)-1);
	return result;
}
static long snd_compr_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
{
	struct snd_compr_file *data = f->private_data;
	struct snd_compr_stream *stream;
	int retval = -ENOTTY;

	if (snd_BUG_ON(!data))
		return -EFAULT;
	stream = &data->stream;
	if (snd_BUG_ON(!stream))
		return -EFAULT;
	mutex_lock(&stream->device->lock);
	switch (_IOC_NR(cmd)) {
	case _IOC_NR(SNDRV_COMPRESS_IOCTL_VERSION):
		retval = put_user(SNDRV_COMPRESS_VERSION,
				(int __user *)arg) ? -EFAULT : 0;
		break;
	case _IOC_NR(SNDRV_COMPRESS_GET_CAPS):
		retval = snd_compr_get_caps(stream, arg);
		break;
	case _IOC_NR(SNDRV_COMPRESS_GET_CODEC_CAPS):
		retval = snd_compr_get_codec_caps(stream, arg);
		break;
	case _IOC_NR(SNDRV_COMPRESS_SET_PARAMS):
		retval = snd_compr_set_params(stream, arg);
		break;
	case _IOC_NR(SNDRV_COMPRESS_GET_PARAMS):
		retval = snd_compr_get_params(stream, arg);
		break;
	case _IOC_NR(SNDRV_COMPRESS_TSTAMP):
		retval = snd_compr_tstamp(stream, arg);
		break;
	case _IOC_NR(SNDRV_COMPRESS_AVAIL):
		retval = snd_compr_ioctl_avail(stream, arg);
		break;
	case _IOC_NR(SNDRV_COMPRESS_PAUSE):
		retval = snd_compr_pause(stream);
		break;
	case _IOC_NR(SNDRV_COMPRESS_RESUME):
		retval = snd_compr_resume(stream);
		break;
	case _IOC_NR(SNDRV_COMPRESS_START):
		retval = snd_compr_start(stream);
		break;
	case _IOC_NR(SNDRV_COMPRESS_STOP):
		retval = snd_compr_stop(stream);
		break;
	case _IOC_NR(SNDRV_COMPRESS_DRAIN):
		retval = snd_compr_drain(stream);
		break;
	}
	mutex_unlock(&stream->device->lock);
	return retval;
}
Beispiel #20
0
/*
 * ioctl calls for this driver. Why return -ENOTTY upon error? Because
 * POSIX says so!
 */
int
pcf8563_ioctl(struct inode *inode, 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;

				get_rtc_time(&tm);

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

				return 0;
			}
			break;
		case RTC_SET_TIME:
			{
#ifdef CONFIG_ETRAX_RTC_READONLY
				return -EPERM;
#else
				int leap;
				int century;
				struct rtc_time tm;

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

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

				/* Convert from struct tm to struct rtc_time. */
				tm.tm_year += 1900;
				tm.tm_mon += 1;
				
				leap = ((tm.tm_mon == 2) && ((tm.tm_year % 4) == 0)) ? 1 : 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_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;

				BIN_TO_BCD(tm.tm_year);
				BIN_TO_BCD(tm.tm_mday);
				BIN_TO_BCD(tm.tm_hour);
				BIN_TO_BCD(tm.tm_min);
				BIN_TO_BCD(tm.tm_sec);
				tm.tm_mon |= century;
				
				rtc_write(RTC_YEAR, tm.tm_year);
				rtc_write(RTC_MONTH, tm.tm_mon);
				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);

				return 0;
#endif /* !CONFIG_ETRAX_RTC_READONLY */
			}

		case RTC_VLOW_RD:
		{
			int vl_bit = 0;

			if (rtc_read(RTC_SECONDS) & 0x80) {
				vl_bit = 1;
				printk(KERN_WARNING "%s: RTC Voltage Low - reliable "
				       "date/time information is no longer guaranteed!\n",
				       PCF8563_NAME);
			}
			if (copy_to_user((int *) arg, &vl_bit, sizeof(int)))
				return -EFAULT;

			return 0;
		}

		case RTC_VLOW_SET:
		{
			/* Clear the VL bit in the seconds register */
			int ret = rtc_read(RTC_SECONDS);

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

			return 0;
		}

		default:
				return -ENOTTY;
	}

	return 0;
}
Beispiel #21
0
/*
 * The ioctl() implementation
 * We are NOT locking the session because the specific implementations will
 * take care of that!
 */
long file_ioctl_open(struct file *filp, unsigned int cmd, unsigned long arg)
{
	int err = 0, ret = 0;
	struct phys_mem_session *session =
				(struct phys_mem_session *) filp->private_data;

#if 0
	pr_debug("Session %llu: file_ioctl_open: %x Type: %c (expect %c), Number %i Arg: %p\n",
		 session->session_id, cmd, _IOC_TYPE(cmd),
		 PHYS_MEM_IOC_MAGIC, _IOC_NR(cmd), (void *) arg);
#endif

	/* don't even decode wrong cmds: better returning  ENOTTY than EFAULT */
	if (_IOC_TYPE(cmd) != PHYS_MEM_IOC_MAGIC)
		return -ENOTTY;
	if (_IOC_NR(cmd) > PHYS_MEM_IOC_MAXNR)
		return -ENOTTY;

	/*
	 * the type is a bitmask, and VERIFY_WRITE catches R/W
	 * transfers. Note that the 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) {
		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 PHYS_MEM_IOC_REQUEST_PAGES:
		{
			/*  arg points to the struct phys_mem_request */
			struct phys_mem_request request;

			if (copy_from_user(&request,
					(struct phys_mem_request __user *)arg,
					   sizeof (struct phys_mem_request))) {
				pr_debug("Session %llu: file_ioctl_open: copy_from_user failed. \n",
					  session->session_id);
				ret = -EFAULT;
			} else {
#if 0
				pr_debug("Session %llu: request: Ver %lu, %lu items @%p\n",
						session->session_id,
						request.protocol_version,
						request.num_requests, request.req);
#endif
				if (request.protocol_version
				    != IOCTL_REQUEST_VERSION)
					ret = -EINVAL;
				else
					ret = handle_request_pages(session,
								   &request);
			}
			break;
		}
	case PHYS_MEM_IOC_MARK_FRAME_BAD:
		{
			/*  arg points to the struct mark_page_poison */
			struct mark_page_poison request;

			if (copy_from_user(&request,
					(struct mark_page_poison __user *)arg,
					sizeof(struct mark_page_poison))) {
				pr_debug("Session %llu: file_ioctl_open: copy_from_user failed. \n",
					  session->session_id);
				ret = -EFAULT;
			} else {
#if 0
				pr_debug("Session %llu: request: Ver %lu,  pfn: %lu  \n",
					  session->session_id,
					  request.protocol_version,
					  request.bad_pfn);
#endif
				if (request.protocol_version
				    != IOCTL_REQUEST_VERSION)
					ret = -EINVAL;
				else
					ret = handle_mark_page_poison(session,
								      &request);
			}
			break;
		}
	default:
		/* redundant, as cmd was checked against MAXNR */
		pr_debug("Session %llu: file_ioctl_open: default %d\n",
			  session->session_id, cmd);
		return -ENOTTY;
	}

	return ret;
}
Beispiel #22
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->mdm_ready = 0;	
		mdm_drv->mdm_hsic_reconnectd = 0;
		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:
		{
			int ret_mdm_hsic_reconnectd = 0;
			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_status_change_notified = false;
	                queue_work_on(0, mdm_gpio_monitor_queue, &mdm_status_check_work);
	                
			mdm_drv->mdm_ready = 1;

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

			ret_mdm_hsic_reconnectd = mdm_hsic_reconnectd_check_fn();

			if ( ret_mdm_hsic_reconnectd == 1 ) {
				pr_info("%s: ret_mdm_hsic_reconnectd == 1\n", __func__);
			} else {
				pr_info("%s: ret_mdm_hsic_reconnectd == 0\n", __func__);
			}

			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__);

		if (mdm_drv) {
	        dump_gpio("MDM2AP_STATUS", mdm_drv->mdm2ap_status_gpio);
	        dump_gpio("MDM2AP_ERRFATAL", mdm_drv->mdm2ap_errfatal_gpio);
		}

		ret = wait_for_completion_interruptible(&mdm_needs_reload);
		if (!ret) {
			put_user(mdm_drv->boot_type,
					 (unsigned long __user *) arg);

			pr_err("%s: mdm_drv->boot_type:%d\n", __func__, mdm_drv->boot_type);
		}
		INIT_COMPLETION(mdm_needs_reload);
		break;
	case GET_MFG_MODE:
		pr_info("%s: board_mfg_mode()=%d\n", __func__, board_mfg_mode());
		put_user(board_mfg_mode(),
				 (unsigned long __user *) arg);
		break;
	case SET_MODEM_ERRMSG:
		pr_info("%s: Set modem fatal errmsg\n", __func__);
		ret = set_mdm_errmsg((void __user *) arg);
		break;
	case GET_RADIO_FLAG:
		pr_info("%s:get_radio_flag()=%x\n", __func__, get_radio_flag());
		put_user(get_radio_flag(),
				 (unsigned long __user *) arg);
		break;
	case EFS_SYNC_DONE:
		pr_info("%s: efs sync is done\n", __func__);
		break;
	case NV_WRITE_DONE:
		pr_info("%s: NV write done!\n", __func__);
		notify_mdm_nv_write_done();
		break;
	default:
		pr_err("%s: invalid ioctl cmd = %d\n", __func__, _IOC_NR(cmd));
		ret = -EINVAL;
		break;
	}

	return ret;
}
Beispiel #23
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;

	/* The validate routine above always sets the version */
	if (cmd == AUTOFS_DEV_IOCTL_VERSION_CMD)
		goto done;

	fn = lookup_dev_ioctl(cmd);
	if (!fn) {
		AUTOFS_WARN("unknown command 0x%08x", command);
		return -ENOTTY;
	}

	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.
	 */
	if (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;
		}

		if (!fp->f_op) {
			err = -ENOTTY;
			fput(fp);
			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);
done:
	if (err >= 0 && copy_to_user(user, param, AUTOFS_DEV_IOCTL_SIZE))
		err = -EFAULT;
out:
	free_dev_ioctl(param);
	return err;
}
Beispiel #24
0
static long snapshot_ioctl(struct file *filp, unsigned int cmd,
							unsigned long arg)
{
	int error = 0;
	struct snapshot_data *data;
	loff_t size;
	sector_t offset;

	if (_IOC_TYPE(cmd) != SNAPSHOT_IOC_MAGIC)
		return -ENOTTY;
	if (_IOC_NR(cmd) > SNAPSHOT_IOC_MAXNR)
		return -ENOTTY;
	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

	if (!mutex_trylock(&pm_mutex))
		return -EBUSY;

	data = filp->private_data;

	switch (cmd) {

	case SNAPSHOT_FREEZE:
		if (data->frozen)
			break;

		printk("Syncing filesystems ... ");
		sys_sync();
		printk("done.\n");

		error = usermodehelper_disable();
		if (error)
			break;

		error = freeze_processes();
		if (error) {
			thaw_processes();
			usermodehelper_enable();
		}
		if (!error)
			data->frozen = 1;
		break;

	case SNAPSHOT_UNFREEZE:
		if (!data->frozen || data->ready)
			break;
		thaw_processes();
		usermodehelper_enable();
		data->frozen = 0;
		break;

	case SNAPSHOT_CREATE_IMAGE:
	case SNAPSHOT_ATOMIC_SNAPSHOT:
		if (data->mode != O_RDONLY || !data->frozen  || data->ready) {
			error = -EPERM;
			break;
		}
		error = hibernation_snapshot(data->platform_support);
		if (!error)
			error = put_user(in_suspend, (int __user *)arg);
		if (!error)
			data->ready = 1;
		break;

	case SNAPSHOT_ATOMIC_RESTORE:
		snapshot_write_finalize(&data->handle);
		if (data->mode != O_WRONLY || !data->frozen ||
		    !snapshot_image_loaded(&data->handle)) {
			error = -EPERM;
			break;
		}
		error = hibernation_restore(data->platform_support);
		break;

	case SNAPSHOT_FREE:
		swsusp_free();
		memset(&data->handle, 0, sizeof(struct snapshot_handle));
		data->ready = 0;
		break;

	case SNAPSHOT_PREF_IMAGE_SIZE:
	case SNAPSHOT_SET_IMAGE_SIZE:
		image_size = arg;
		break;

	case SNAPSHOT_GET_IMAGE_SIZE:
		if (!data->ready) {
			error = -ENODATA;
			break;
		}
		size = snapshot_get_image_size();
		size <<= PAGE_SHIFT;
		error = put_user(size, (loff_t __user *)arg);
		break;

	case SNAPSHOT_AVAIL_SWAP_SIZE:
	case SNAPSHOT_AVAIL_SWAP:
		size = count_swap_pages(data->swap, 1);
		size <<= PAGE_SHIFT;
		error = put_user(size, (loff_t __user *)arg);
		break;

	case SNAPSHOT_ALLOC_SWAP_PAGE:
	case SNAPSHOT_GET_SWAP_PAGE:
		if (data->swap < 0 || data->swap >= MAX_SWAPFILES) {
			error = -ENODEV;
			break;
		}
		offset = alloc_swapdev_block(data->swap);
		if (offset) {
			offset <<= PAGE_SHIFT;
			error = put_user(offset, (loff_t __user *)arg);
		} else {
			error = -ENOSPC;
		}
		break;

	case SNAPSHOT_FREE_SWAP_PAGES:
		if (data->swap < 0 || data->swap >= MAX_SWAPFILES) {
			error = -ENODEV;
			break;
		}
		free_all_swap_pages(data->swap);
		break;

	case SNAPSHOT_SET_SWAP_FILE: /* This ioctl is deprecated */
		if (!swsusp_swap_in_use()) {
			/*
			 * User space encodes device types as two-byte values,
			 * so we need to recode them
			 */
			if (old_decode_dev(arg)) {
				data->swap = swap_type_of(old_decode_dev(arg),
							0, NULL);
				if (data->swap < 0)
					error = -ENODEV;
			} else {
				data->swap = -1;
				error = -EINVAL;
			}
		} else {
			error = -EPERM;
		}
		break;

	case SNAPSHOT_S2RAM:
		if (!data->frozen) {
			error = -EPERM;
			break;
		}
		/*
		 * Tasks are frozen and the notifiers have been called with
		 * PM_HIBERNATION_PREPARE
		 */
		error = suspend_devices_and_enter(PM_SUSPEND_MEM);
		break;

	case SNAPSHOT_PLATFORM_SUPPORT:
		data->platform_support = !!arg;
		break;

	case SNAPSHOT_POWER_OFF:
		if (data->platform_support)
			error = hibernation_platform_enter();
		break;

	case SNAPSHOT_PMOPS: /* This ioctl is deprecated */
		error = -EINVAL;

		switch (arg) {

		case PMOPS_PREPARE:
			data->platform_support = 1;
			error = 0;
			break;

		case PMOPS_ENTER:
			if (data->platform_support)
				error = hibernation_platform_enter();
			break;

		case PMOPS_FINISH:
			if (data->platform_support)
				error = 0;
			break;

		default:
			printk(KERN_ERR "SNAPSHOT_PMOPS: invalid argument %ld\n", arg);

		}
		break;

	case SNAPSHOT_SET_SWAP_AREA:
		if (swsusp_swap_in_use()) {
			error = -EPERM;
		} else {
			struct resume_swap_area swap_area;
			dev_t swdev;

			error = copy_from_user(&swap_area, (void __user *)arg,
					sizeof(struct resume_swap_area));
			if (error) {
				error = -EFAULT;
				break;
			}

			/*
			 * User space encodes device types as two-byte values,
			 * so we need to recode them
			 */
			swdev = old_decode_dev(swap_area.dev);
			if (swdev) {
				offset = swap_area.offset;
				data->swap = swap_type_of(swdev, offset, NULL);
				if (data->swap < 0)
					error = -ENODEV;
			} else {
				data->swap = -1;
				error = -EINVAL;
			}
		}
		break;

	default:
		error = -ENOTTY;

	}

	mutex_unlock(&pm_mutex);

	return error;
}
long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
{
	long ret = -ENOIOCTLCMD;

	if (!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;
}
Beispiel #26
0
static int
evdev_decode_number(const unsigned int code)
{
	const unsigned int nr = _IOC_NR(code);

	if (_IOC_DIR(code) == _IOC_WRITE) {
		if (nr >= 0xc0 && nr <= 0xc0 + 0x3f) {
			tprints("EVIOCSABS(");
			printxval(evdev_abs, nr - 0xc0, "EV_???");
			tprints(")");
			return 1;
		}
	}

	if (_IOC_DIR(code) != _IOC_READ)
		return 0;

	if (nr >= 0x20 && nr <= 0x20 + 0x1f) {
		tprints("EVIOCGBIT(");
		printxval(evdev_ev, nr - 0x20, "EV_???");
		tprintf(", %u)", _IOC_SIZE(code));
		return 1;
	} else if (nr >= 0x40 && nr <= 0x40 + 0x3f) {
		tprints("EVIOCGABS(");
		printxval(evdev_abs, nr - 0x40, "ABS_???");
		tprints(")");
		return 1;
	}

	switch (_IOC_NR(nr)) {
		case 0x06:
			tprintf("EVIOCGNAME(%u)", _IOC_SIZE(code));
			return 1;
		case 0x07:
			tprintf("EVIOCGPHYS(%u)", _IOC_SIZE(code));
			return 1;
		case 0x08:
			tprintf("EVIOCGUNIQ(%u)", _IOC_SIZE(code));
			return 1;
		case 0x09:
			tprintf("EVIOCGPROP(%u)", _IOC_SIZE(code));
			return 1;
		case 0x0a:
			tprintf("EVIOCGMTSLOTS(%u)", _IOC_SIZE(code));
			return 1;
		case 0x18:
			tprintf("EVIOCGKEY(%u)", _IOC_SIZE(code));
			return 1;
		case 0x19:
			tprintf("EVIOCGLED(%u)", _IOC_SIZE(code));
			return 1;
		case 0x1a:
			tprintf("EVIOCGSND(%u)", _IOC_SIZE(code));
			return 1;
		case 0x1b:
			tprintf("EVIOCGSW(%u)", _IOC_SIZE(code));
			return 1;
		default:
			return 0;
	}
}
Beispiel #27
0
static long piris_ioctl(struct file* file, unsigned int cmd, unsigned long arg)
{
    int __user* pPirisPos;
    PIRIS_DATA_S __user* argp;
    PIRIS_STATUS_E __user* pPirisStatus;
    PIRIS_DEV* pstPirisDev = (PIRIS_DEV*) file->private_data;

    int err = 0;

    if (_IOC_TYPE(cmd) != PIRIS_IOC_MAGIC)
    {
        return -ENOTTY;
    }
    if (_IOC_NR(cmd) > PIRIS_IOC_MAXNR)
    {
        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)
    {
        return -EFAULT;
    }

    // lock pstPirisDev
    if (down_interruptible(&pstPirisDev->sem))
    {
        return -ERESTARTSYS;
    }

    switch (cmd)
    {
        case PIRIS_SET_ACT_ARGS:
            pPirisPos = (int __user*)arg;
            piris_gpio_update(pPirisPos);
            break;

        case PIRIS_SET_ORGIN:
            argp = (PIRIS_DATA_S __user*)arg;
            piris_origin_set(argp);
            break;

        case PIRIS_SET_CLOSE:
            argp = (PIRIS_DATA_S __user*)arg;
            piris_close_set(argp);
            break;

        case PIRIS_GET_STATUS:
            pPirisStatus = (PIRIS_STATUS_E __user*)arg;

            if (pstPirisDev->dest_pos != pstPirisDev->src_pos)
            {
                *pPirisStatus = PIRIS_BUSY;
            }
            else
            {
                *pPirisStatus = PIRIS_IDLE;
                //PIRIS_DRV_Disable();
            }
            break;

        default:  /* redundant, as cmd was checked against MAXNR */
            break;
    }

    // unlock pstPirisDev
    up(&pstPirisDev->sem);

    return 0 ;
}
static long epl6803_ioctl(struct file* file, unsigned int cmd, unsigned long arg)
{
	int rc = 0;

	#if debug
	pr_info("%s cmd:%d, arg:%ld\n", __func__, _IOC_NR(cmd), arg);
	#endif

	mutex_lock(&Epl6803_global_lock);
	switch(cmd){
		case PROXIMITY_IOCTL_SET_STATE:
			rc = arg ? epl6803_enable() : epl6803_disable();
			break;
		case PROXIMITY_IOCTL_GET_DEVICE_INFOR:
		{
			struct device_infor infor = {
				.name		= "Proximity Sensor",
				.vendor		= "ELAN Microelectronics Corp.",
				.maxRange	= PROXIMITY_UNDETECTED,
				.resolution	= 2500,//
				.power		= 350,// uA
			};
			rc = copy_to_user((unsigned long __user *)arg, (char *)&(infor), sizeof(struct device_infor));
			break;
		}
		default:
			pr_err("%s: invalid cmd %d\n", __func__, _IOC_NR(cmd));
			rc = -EINVAL;
	}
	mutex_unlock(&Epl6803_global_lock);

	return rc;
}

static struct file_operations epl6803_fops = {
	.owner			= THIS_MODULE,
	.read			= epl6803_read,
	.write			= epl6803_write,
	.open			= epl6803_open,
	.release		= epl6803_release,
	.unlocked_ioctl = epl6803_ioctl
};

struct miscdevice epl6803_misc = {
	.minor	= MISC_DYNAMIC_MINOR,
	.name	= "proximity",
	.fops	= &epl6803_fops
};

static int epl6803_reportData(Proximity* data){
	u8 State = PROXIMITY_STATE_UNKNOWN;
	int Value = (i2cData[1] << 8) | i2cData[0];

	int Threshold = (data->sdata.State != PROXIMITY_STATE_TRUE) ? data->sdata.Threshold_H : data->sdata.Threshold_L;
	State = (Value > Threshold) ? PROXIMITY_STATE_TRUE : PROXIMITY_STATE_FALSE;

	mutex_lock(&data->mutex);
	data->sdata.Value = Value;
	if(State != data->sdata.State){
		if(need2ChangeState == true){
			data->sdata.State = State;
			input_report_abs(data->input, ABS_DISTANCE, (State) ? PROXIMITY_DETECTED : PROXIMITY_UNDETECTED);
			input_sync(data->input);
		}
		need2ChangeState = !need2ChangeState;
	}else{
		need2ChangeState = false;
	}
	mutex_unlock(&data->mutex);

	#if debug
	pr_info("EPL6803: Proximity : %d\n", Value);
	#endif
	return Value;
}

static void epl6803_autoCalibrate(Proximity* data, int Value){
	// Auto-calibrate
	if(!i2cIsFine || !stateIsFine || Value < 0 || ((Value + THRESHOLD_RANGE) > data->sdata.Threshold_H)){
		need2Reset = false;
	}else{
		(need2Reset) ? proximity_resetThreshold(Value + THRESHOLD_LEVEL, THRESHOLD_LEVEL) : 0;
		need2Reset = !need2Reset;
	}
}

static void epl6803_work_func(struct work_struct* work)
{
	int Value = 0;
	Proximity* data = i2c_get_clientdata(this_client);

	#if debug
	pr_info("EPL6803: %s ++\n", __func__);
	#endif
	
	memset(i2cData, 0, sizeof(i2cData));
	if(data->enabled && !data->suspend && 
		(i2cIsFine = (i2c_smbus_read_i2c_block_data(this_client, PROXIMITY_REG_CH1DATA_LSB | 0x01, 2, &i2cData[0]) == 2)) && 
		(stateIsFine = !(i2c_smbus_read_byte_data(this_client, PROXIMITY_REG_CHIP_STATE) & 0x02))){
		#if debug
		printk("Reg: %x, %x\n", PROXIMITY_REG_CHIP_STATE >> 3, i2c_smbus_read_byte_data(this_client, PROXIMITY_REG_CHIP_STATE));
		#endif

		Value = epl6803_reportData(data);

	}else if(!i2cIsFine || !stateIsFine){
Beispiel #29
0
static int _mod_ir_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
#endif
{
    int err= 0;
  	int retval = 0;
    MS_IR_DelayTime delaytime;
    MS_IR_LastKeyTime keytime;
    MS_IR_KeyValue keyvalue;
    U8 bEnableIR;
    MS_IR_KeyInfo keyinfo;
    pid_t masterPid;

    IR_PRINT("%s is invoked\n", __FUNCTION__);

    /*
     * extract the type and number bitfields, and don't decode
     * wrong cmds: return ENOTTY (inappropriate ioctl) before access_ok()
     */
    if ((IR_IOC_MAGIC!= _IOC_TYPE(cmd)) || (_IOC_NR(cmd)> IR_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)
    {
        #if 0
        case IR_IOC:
            IR_PRINT("ioctl: receive IR_IOC\n");
            break;
        case IR_IOCREAD:
            IR_PRINT("ioctl: receive IR_IOCREAD with user pointer 0x%08x 0x%08x\n", (u32)arg, *((u32*)(arg)));
            ptrData = (PMS_IR_KDATA)arg;
            IR_PRINT("IR_IOCREAD (1) -> data1=%d, data2=%d, data3=%d\n", ptrData->data1, ptrData->data2, ptrData->data3);
            ptrData->data1 = 11;
            ptrData->data2 = 22;
            ptrData->data3 = 33;
            IR_PRINT("IR_IOCREAD (2) -> data1=%d, data2=%d, data3=%d\n", ptrData->data1, ptrData->data2, ptrData->data3);
            break;
        case IR_IOCWRITE:
            IR_PRINT("ioctl: receive IR_IOCWRITE with user pointer 0x%08x 0x%08x\n", (u32)arg, *((u32*)(arg)));
            break;
        case IR_IOCRW:
            IR_PRINT("ioctl: receive IR_IOCRW with user pointer 0x%08x 0x%08x\n", (u32)arg, *((u32*)(arg)));
            ptrData = (PMS_IR_KDATA)arg;
            IR_PRINT("IR_IOCREAD (1) -> data1=%d, data2=%d, data3=%d\n", ptrData->data1, ptrData->data2, ptrData->data3);
            ptrData->data1 = 55;
            ptrData->data2 = 66;
            ptrData->data3 = 77;
            IR_PRINT("IR_IOCREAD (2) -> data1=%d, data2=%d, data3=%d\n", ptrData->data1, ptrData->data2, ptrData->data3);
            break;

            break;
        #endif
        case MDRV_IR_INIT:
            MDrv_IR_Init(0);
            IRDev.u32IRFlag |= (IRFLAG_IRENABLE|IRFLAG_HWINITED);
            break;
        case MDRV_IR_SEND_KEY:
	     	printk("Send Key!!!\n");
            IR_PRINT("ioctl: MDRV_IR_SEND_KEY\n");
    	    retval = __get_user(keyinfo.u8Key, &(((MS_IR_KeyInfo __user *)arg)->u8Key));
            retval = __get_user(keyinfo.u8Flag, &(((MS_IR_KeyInfo __user *)arg)->u8Flag));
	     MDrv_IR_SendKey(keyinfo.u8Key, keyinfo.u8Flag);
            break;
        case MDRV_IR_SET_DELAYTIME:
            IR_PRINT("ioctl: MDRV_IR_SET_DELAYTIME\n");
    		retval = __get_user(delaytime.u32_1stDelayTimeMs, &(((MS_IR_DelayTime __user *)arg)->u32_1stDelayTimeMs));
    		retval = __get_user(delaytime.u32_2ndDelayTimeMs, &(((MS_IR_DelayTime __user *)arg)->u32_2ndDelayTimeMs));
            MDrv_IR_SetDelayTime(delaytime.u32_1stDelayTimeMs, delaytime.u32_2ndDelayTimeMs);
            break;
        case MDRV_IR_GET_KEY:
            IR_PRINT("ioctl: MDRV_IR_GET_KEY\n");
            //TBD: need mutex here to protect data
            keyinfo.u8Valid = MDrv_IR_GetKey(&keyinfo.u8Key, &keyinfo.u8System, &keyinfo.u8Flag);
            retval = __put_user(keyinfo.u8Key, &(((MS_IR_KeyInfo __user *)arg)->u8Key));
            retval = __put_user(keyinfo.u8System, &(((MS_IR_KeyInfo __user *)arg)->u8System));
            retval = __put_user(keyinfo.u8Flag, &(((MS_IR_KeyInfo __user *)arg)->u8Flag));
            retval = __put_user(keyinfo.u8Valid, &(((MS_IR_KeyInfo __user *)arg)->u8Valid));
            break;
        case MDRV_IR_GET_LASTKEYTIME:
            IR_PRINT("ioctl: MDRV_IR_GET_LASTKEYTIME\n");
            //retval = __get_user(keytime.time, &(((MS_IR_LastKeyTime __user *)arg)->time));
            keytime.time = MDrv_IR_GetLastKeyTime();
            retval = __put_user(keytime.time, &(((MS_IR_LastKeyTime __user *)arg)->time));
            break;
        case MDRV_IR_PARSE_KEY:
            IR_PRINT("ioctl: MDRV_IR_PARSE_KEY\n");
            retval = __get_user(keyvalue.u8KeyIn, &(((MS_IR_KeyValue __user *)arg)->u8KeyIn));
            keyvalue.u8KeyOut = MDrv_IR_ParseKey(keyvalue.u8KeyIn);
            retval = __put_user(keyvalue.u8KeyOut, &(((MS_IR_KeyValue __user *)arg)->u8KeyOut));
            break;
        case MDRV_IR_TEST:
            IR_PRINT("ioctl: MDRV_IR_TEST\n");
            break;
        case MDRV_IR_ENABLE_IR:
            IR_PRINT("ioctl: MDRV_IR_ENABLE_IR\n");
            retval = __get_user(bEnableIR, (int __user *)arg);
            MDrv_IR_EnableIR(bEnableIR);
            if(bEnableIR){
                IRDev.u32IRFlag |= IRFLAG_IRENABLE;
            }else{
                IRDev.u32IRFlag &= ~IRFLAG_IRENABLE;
            }
            break;
        case MDRV_IR_IS_FANTASY_PROTOCOL_SUPPORTED:
            IR_PRINT("ioctl: MDRV_IR_IS_FANTASY_PROTOCOL_SUPPORTED\n");
            retval = __put_user( MDrv_IR_IsFantasyProtocolSupported(),(BOOL __user *)arg);
            break;

        case MDRV_IR_SET_MASTER_PID:
            retval = __get_user(masterPid, (pid_t __user *)arg);
            MDrv_IR_SetMasterPid(masterPid);
            break;

        case MDRV_IR_GET_MASTER_PID:
            masterPid = MDrv_IR_GetMasterPid();
            retval = __put_user(masterPid, (pid_t __user *)arg);
            break;

        case MDRV_IR_INITCFG:
            {
                MS_IR_InitCfg stInitCfg;

                if(copy_from_user(&stInitCfg, (MS_IR_InitCfg __user *)arg, sizeof(MS_IR_InitCfg)))
                {
                    return EFAULT;
                }
                MDrv_IR_InitCfg((MS_IR_InitCfg*)&stInitCfg);
            }
            break;

        case MDRV_IR_TIMECFG:
            {
                MS_IR_TimeCfg stTimeCfg;

                if(copy_from_user(&stTimeCfg, (MS_IR_TimeCfg __user *)arg, sizeof(MS_IR_TimeCfg)))
                {
                    return EFAULT;
                }
                MDrv_IR_TimeCfg((MS_IR_TimeCfg*)&stTimeCfg);
            }
            break;

        case MDRV_IR_GET_SWSHOT_BUF:

            MDrv_IR_ReadShotBuffer(&stIrShotInfo);
            if (copy_to_user((MS_IR_ShotInfo  __user *) arg, &stIrShotInfo, sizeof(MS_IR_ShotInfo)))
            {
                return -EFAULT;
            }
		break;
		case MDRV_IR_SET_HEADER:
		{
			MS_MultiIR_HeaderInfo stItMulti_HeaderInfo;
			printk("\nioctl:MDRV_IR_SET_HEADER\n");
			if(copy_from_user(&stItMulti_HeaderInfo, (MS_MultiIR_HeaderInfo __user *)arg, sizeof(MS_MultiIR_HeaderInfo)))
			{
				return EFAULT;
			}
			MDrv_IR_SetHeaderCode((MS_MultiIR_HeaderInfo*)&stItMulti_HeaderInfo);
		}
		break;
        default:
            IR_PRINT("ioctl: unknown command\n");
            return -ENOTTY;
    }

    return 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;
}