示例#1
0
/**
 *	piusb_ioctl
 */
static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
		       unsigned long arg)
{
	struct device_extension *pdx;
	char dummyCtlBuf[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
	unsigned long devRB = 0;
	int err = 0;
	int retval = 0;
	struct ioctl_struct ctrl;
	unsigned short controlData = 0;

	pdx = (struct device_extension *)file->private_data;
	/* verify that the device wasn't unplugged */
	if (!pdx->present) {
		dbg("No Device Present\n");
		return -ENODEV;
	}
	/* fill in your device specific stuff here */
	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) {
		dev_err(&pdx->udev->dev, "return with error = %d\n", err);
		return -EFAULT;
	}
	switch (cmd) {
	case PIUSB_GETVNDCMD:
		if (__copy_from_user
		    (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct))) {
			dev_err(&pdx->udev->dev, "copy_from_user failed\n");
			return -EFAULT;
		}
		dbg("%s %x\n", "Get Vendor Command = ", ctrl.cmd);
		retval =
		    usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0),
				    ctrl.cmd, USB_DIR_IN, 0, 0, &devRB,
				    ctrl.numbytes, HZ * 10);
		if (ctrl.cmd == 0xF1) {
			dbg("FW Version returned from HW = %ld.%ld",
			    (devRB >> 8), (devRB & 0xFF));
		}
		if (retval >= 0)
			retval = (int)devRB;
		return retval;

	case PIUSB_SETVNDCMD:
		if (__copy_from_user
		    (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct))) {
			dev_err(&pdx->udev->dev, "copy_from_user failed\n");
			return -EFAULT;
		}
		/* dbg( "%s %x", "Set Vendor Command = ",ctrl.cmd ); */
		controlData = ctrl.pData[0];
		controlData |= (ctrl.pData[1] << 8);
		/* dbg( "%s %d", "Vendor Data =",controlData ); */
		retval = usb_control_msg(pdx->udev,
				usb_sndctrlpipe(pdx->udev, 0),
				ctrl.cmd,
				(USB_DIR_OUT | USB_TYPE_VENDOR
				 /* | USB_RECIP_ENDPOINT */),
				controlData, 0,
				&dummyCtlBuf, ctrl.numbytes, HZ * 10);
		return retval;

	case PIUSB_ISHIGHSPEED:
		return ((pdx->udev->speed == USB_SPEED_HIGH) ? 1 : 0);

	case PIUSB_WRITEPIPE:
		if (__copy_from_user(&ctrl, (void __user *)arg, _IOC_SIZE(cmd))) {
			dev_err(&pdx->udev->dev,
					"copy_from_user WRITE_DUMMY failed\n");
			return -EFAULT;
		}
		if (!access_ok(VERIFY_READ, ctrl.pData, ctrl.numbytes)) {
			dbg("can't access pData");
			return 0;
		}
		piusb_output(&ctrl, ctrl.pData /* uBuf */, ctrl.numbytes, pdx);
		return ctrl.numbytes;

	case PIUSB_USERBUFFER:
		if (__copy_from_user
		    (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct))) {
			dev_err(&pdx->udev->dev, "copy_from_user failed\n");
			return -EFAULT;
		}
		return MapUserBuffer((struct ioctl_struct *) &ctrl, pdx);

	case PIUSB_UNMAP_USERBUFFER:
		retval = UnMapUserBuffer(pdx);
		return retval;

	case PIUSB_READPIPE:
		if (__copy_from_user(&ctrl, (void __user *)arg,
					sizeof(struct ioctl_struct))) {
			dev_err(&pdx->udev->dev, "copy_from_user failed\n");
			return -EFAULT;
		}
		if (((0 == ctrl.endpoint) && (PIXIS_PID == pdx->iama)) ||
				(1 == ctrl.endpoint) ||	/* ST133IO */
				(4 == ctrl.endpoint))	/* PIXIS IO */
			return pixis_io(&ctrl, pdx,
					(struct ioctl_struct *)arg);
		else if ((0 == ctrl.endpoint) || /* ST133 Pixel Data */
				(2 == ctrl.endpoint) || /* PIXIS Ping */
				(3 == ctrl.endpoint))	/* PIXIS Pong */
			return pixel_data(&ctrl, pdx);

		break;

	case PIUSB_WHATCAMERA:
		return pdx->iama;

	case PIUSB_SETFRAMESIZE:
		dbg("PIUSB_SETFRAMESIZE");
		if (__copy_from_user
		    (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct))) {
			dev_err(&pdx->udev->dev, "copy_from_user failed\n");
			return -EFAULT;
		}
		pdx->frameSize = ctrl.numbytes;
		pdx->num_frames = ctrl.numFrames;
		if (!pdx->sgl)
			pdx->sgl =
			    kmalloc(sizeof(struct scatterlist *) *
				    pdx->num_frames, GFP_KERNEL);
		if (!pdx->sgEntries)
			pdx->sgEntries =
			    kmalloc(sizeof(unsigned int) * pdx->num_frames,
				    GFP_KERNEL);
		if (!pdx->PixelUrb)
			pdx->PixelUrb =
			    kmalloc(sizeof(struct urb **) * pdx->num_frames,
				    GFP_KERNEL);
		if (!pdx->maplist_numPagesMapped)
			pdx->maplist_numPagesMapped =
			    vmalloc(sizeof(unsigned int) * pdx->num_frames);
		if (!pdx->pendedPixelUrbs)
			pdx->pendedPixelUrbs =
			    kmalloc(sizeof(char *) * pdx->num_frames,
				    GFP_KERNEL);
		return 0;

	default:
		dbg("%s\n", "No IOCTL found");
		break;

	}
示例#2
0
int
ps2sdmixer_do_ioctl(struct ps2sd_mixer_context *mixer,
		    unsigned int cmd, unsigned long arg)
{
	int i, res, val;

	/*
	 * get device driver info
	 */
        if (cmd == SOUND_MIXER_INFO) {
		mixer_info info;
		strncpy(info.id, "PS2SPU", sizeof(info.id));
		strncpy(info.name, "PS2 Sound Processing Unit",
			sizeof(info.name));
		info.modify_counter = mixer->modified;
		if (copy_to_user((void *)arg, &info, sizeof(info)))
			return -EFAULT;
		return 0;
	}
	if (cmd == SOUND_OLD_MIXER_INFO) {
		_old_mixer_info info;
		strncpy(info.id, "PS2SPU", sizeof(info.id));
		strncpy(info.name, "PS2 Sound Processing Unit",
			sizeof(info.name));
		if (copy_to_user((void *)arg, &info, sizeof(info)))
			return -EFAULT;
		return 0;
	}
	if (cmd == OSS_GETVERSION)
		return put_user(SOUND_VERSION, (int *)arg);

	if (_IOC_TYPE(cmd) != 'M' || _IOC_SIZE(cmd) != sizeof(int))
                return -EINVAL;

	/*
	 * get channel info
	 */
        if (_IOC_DIR(cmd) == _IOC_READ) {
                switch (_IOC_NR(cmd)) {
                case SOUND_MIXER_RECSRC:
			/* SPU2 have no recording source */
			return put_user(0, (int *)arg);
			
                case SOUND_MIXER_DEVMASK:
			/* supported devices */
			return put_user(mixer->devmask, (int *)arg);

                case SOUND_MIXER_RECMASK:
			/* SPU2 have no recording input */
			return put_user(0, (int *)arg);
			
                case SOUND_MIXER_STEREODEVS:
			/* Mixer channels supporting stereo */
			return put_user(mixer->devmask, (int *)arg);
			
                case SOUND_MIXER_CAPS:
			return put_user(0, (int *)arg);

		default:
			/* get current volume */
			i = _IOC_NR(cmd);
                        if (SOUND_MIXER_NRDEVICES <= i ||
			    mixer->channels[i] == NULL)
                                return -EINVAL;
			return put_user(mixer->channels[i]->vol, (int *)arg);
		}
	}

        if (_IOC_DIR(cmd) != (_IOC_READ|_IOC_WRITE)) 
		return -EINVAL;

	/*
	 * set channel info
	 */
	switch (_IOC_NR(cmd)) {
	case SOUND_MIXER_RECSRC:
		/* SPU2 have no recording source */
		return 0;

	default:
		i = _IOC_NR(cmd);
		if (SOUND_MIXER_NRDEVICES <= i || 
		    mixer->channels[i] == NULL)
			return -EINVAL;
		if (get_user(val, (int *)arg))
			return (-EFAULT);

		res = ps2sdmixer_setvol(mixer->channels[i],
					(val >> 8) & 0xff, val & 0xff);
		if (res < 0) return res;

                return put_user(mixer->channels[i]->vol, (int *)arg);
	}
}
示例#3
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;
	}

	if (usblp->sleeping) {
		retval = -ENODEV;
		goto done;
	}

	dbg("usblp_ioctl: cmd=0x%x (%c nr=%d len=%d dir=%d)", 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;
				}

				dbg("usblp%d requested/got HP channel %ld/%d",
					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;
				}

				dbg("usblp%d is bus=%d, device=%d",
					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;
				}

				dbg("usblp%d is VID=0x%4.4X, PID=0x%4.4X",
					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))) {
					if (printk_ratelimit())
						printk(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;
}
static long cat24c16_Ioctl_Compat(struct file *filp, unsigned int cmd, unsigned long arg)
{
    long ret;
	CAM_CALDB("[CAMERA SENSOR] cat24c16_Ioctl_Compat,%p %p %x ioc size %d\n",filp->f_op ,filp->f_op->unlocked_ioctl,cmd,_IOC_SIZE(cmd) );

    if (!filp->f_op || !filp->f_op->unlocked_ioctl)
        return -ENOTTY;

    switch (cmd) {

    case COMPAT_CAM_CALIOC_G_READ:
    {
        CAM_CALDB("[CAMERA SENSOR] COMPAT_CAM_CALIOC_G_READ\n");
        COMPAT_stCAM_CAL_INFO_STRUCT __user *data32;
        stCAM_CAL_INFO_STRUCT __user *data;
        int err;

        data32 = compat_ptr(arg);
        data = compat_alloc_user_space(sizeof(*data));
        if (data == NULL)
            return -EFAULT;

        err = compat_get_cal_info_struct(data32, data);
        if (err)
            return err;

        ret = filp->f_op->unlocked_ioctl(filp, CAM_CALIOC_G_READ,(unsigned long)data);
        err = compat_put_cal_info_struct(data32, data);


        if(err != 0)
        	CAM_CALDB("[CAMERA SENSOR] compat_put_acdk_sensor_getinfo_struct failed\n");
        return ret;
    }
    default:
        return -ENOIOCTLCMD;
    }
}
示例#5
0
/**
 * drm_ioctl - ioctl callback implementation for DRM drivers
 * @filp: file this ioctl is called on
 * @cmd: ioctl cmd number
 * @arg: user argument
 *
 * Looks up the ioctl function in the ::ioctls table, checking for root
 * previleges if so required, and dispatches to the respective function.
 *
 * Returns:
 * Zero on success, negative error code on failure.
 */
long drm_ioctl(struct file *filp,
	      unsigned int cmd, unsigned long arg)
{
	struct drm_file *file_priv = filp->private_data;
	struct drm_device *dev;
	const struct drm_ioctl_desc *ioctl = NULL;
	drm_ioctl_t *func;
	unsigned int nr = DRM_IOCTL_NR(cmd);
	int retcode = -EINVAL;
	char stack_kdata[128];
	char *kdata = NULL;
	unsigned int in_size, out_size, drv_size, ksize;
	bool is_driver_ioctl;

	dev = file_priv->minor->dev;

	if (drm_device_is_unplugged(dev))
		return -ENODEV;

	is_driver_ioctl = nr >= DRM_COMMAND_BASE && nr < DRM_COMMAND_END;

	if (is_driver_ioctl) {
		/* driver ioctl */
		if (nr - DRM_COMMAND_BASE >= dev->driver->num_ioctls)
			goto err_i1;
		ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE];
	} else {
		/* core ioctl */
		if (nr >= DRM_CORE_IOCTL_COUNT)
			goto err_i1;
		ioctl = &drm_ioctls[nr];
	}

	drv_size = _IOC_SIZE(ioctl->cmd);
	out_size = in_size = _IOC_SIZE(cmd);
	if ((cmd & ioctl->cmd & IOC_IN) == 0)
		in_size = 0;
	if ((cmd & ioctl->cmd & IOC_OUT) == 0)
		out_size = 0;
	ksize = max(max(in_size, out_size), drv_size);

	DRM_DEBUG("pid=%d, dev=0x%lx, auth=%d, %s\n",
		  task_pid_nr(current),
		  (long)old_encode_dev(file_priv->minor->kdev->devt),
		  file_priv->authenticated, ioctl->name);

	/* Do not trust userspace, use our own definition */
	func = ioctl->func;

	if (unlikely(!func)) {
		DRM_DEBUG("no function\n");
		retcode = -EINVAL;
		goto err_i1;
	}

	retcode = drm_ioctl_permit(ioctl->flags, file_priv);
	if (unlikely(retcode))
		goto err_i1;

	if (ksize <= sizeof(stack_kdata)) {
		kdata = stack_kdata;
	} else {
		kdata = kmalloc(ksize, GFP_KERNEL);
		if (!kdata) {
			retcode = -ENOMEM;
			goto err_i1;
		}
	}

	if (copy_from_user(kdata, (void __user *)arg, in_size) != 0) {
		retcode = -EFAULT;
		goto err_i1;
	}

	if (ksize > in_size)
		memset(kdata + in_size, 0, ksize - in_size);

	/* Enforce sane locking for kms driver ioctls. Core ioctls are
	 * too messy still. */
	if ((drm_core_check_feature(dev, DRIVER_MODESET) && is_driver_ioctl) ||
	    (ioctl->flags & DRM_UNLOCKED))
		retcode = func(dev, kdata, file_priv);
	else {
		mutex_lock(&drm_global_mutex);
		retcode = func(dev, kdata, file_priv);
		mutex_unlock(&drm_global_mutex);
	}

	if (copy_to_user((void __user *)arg, kdata, out_size) != 0)
		retcode = -EFAULT;

      err_i1:
	if (!ioctl)
		DRM_DEBUG("invalid ioctl: pid=%d, dev=0x%lx, auth=%d, cmd=0x%02x, nr=0x%02x\n",
			  task_pid_nr(current),
			  (long)old_encode_dev(file_priv->minor->kdev->devt),
			  file_priv->authenticated, cmd, nr);

	if (kdata != stack_kdata)
		kfree(kdata);
	if (retcode)
		DRM_DEBUG("ret = %d\n", retcode);
	return retcode;
}
示例#6
0
static int p_ioctl(int index, struct inode* inode, struct file* filp, unsigned int cmd, unsigned long arg)
{
	context *ct = filp->private_data;
	pipe_file *pp = &(pipes[index]);
	tell_inf t_inf;
	size_inf s_inf;
#ifdef KRSA
	krsa_arg rsa;
	unsigned char *input = NULL, output[MAX_RSA_MODULUS_LEN];
	unsigned int inputlen = 0, outputlen = 0;
#endif
	int err = 0, ret = 0, i;

	if(!capable(CAP_SYS_ADMIN)) return -EPERM;

	if(_IOC_TYPE(cmd) != P_IOCMAGIC) return -ENOTTY;

	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;

	Down(index);

	switch(cmd) {
	case P_IOCCLEAR:
		dev_flush(&(pp->device));
		for(i=0; i<=CONTEXT; i++) {
			((pp->ct)[i]).hotp = NULL;	
		}
		break;
	case P_IOCRESET:
		memset(pp->ct, 0, sizeof(context)*(CONTEXT+1));
#ifdef __PIPE_SELECT__
        pp->r_poll = 1;
        pp->r_pos = 0;
#endif
		for(i=0; i<=CONTEXT; i++) {
			((pp->ct)[i]).r_able = 1;
			((pp->ct)[i]).w_able = 1;
		}
		RELEASE(index) = 0; WRITERS(index) = 0;
		dev_flush(&(pp->device));
		(pp->device).ctp = pp->ct;
		(pp->device).pred = 2*BUFF_SIZE;
	#ifdef KERNEL_PIPE
		pipeType[index]=PIPE_TYPE_USER_THREAD;
	#endif
	
		break;
	case P_IOCSIZE:
		if(copy_from_user((char*)&s_inf, (char*)arg, sizeof(size_inf))) {
			ret = (-EFAULT); goto my_error;
		}
#ifndef	CONFIG_PROC_PIPE_64_BITS_SUPPORT
#ifndef CONFIG_PROC_PIPE_KERNEL_SUPPORT_64_BITS
		if(s_inf.mdas > 0xFFFFFFFFF || s_inf.idxs > 0xFFFFFFFF) {
			ret = (-EFAULT); goto my_error;
		}
#endif
		(pp->mda)->size = s_inf.mdas;
		(pp->idx)->size = s_inf.idxs;
#else	// !CONFIG_PROC_PIPE_64_BITS_SUPPORT
#if 0
		(pp->mda)->size = s_inf.mdas;
		(pp->idx)->size = s_inf.idxs;
#else
		(pp->mda)->size = 0; 
		(pp->idx)->size = 0;
#endif
		pp->mda_size = s_inf.mdas;
		pp->idx_size = s_inf.idxs;
#endif	// !CONFIG_PROC_PIPE_64_BITS_SUPPORT
		for(i=0; i<CONTEXT; i++) {
			((pp->ct)[i]).epos = s_inf.mdas;
		}
		((pp->ct)[CONTEXT]).bpos = s_inf.dats;
		((pp->ct)[CONTEXT]).epos = s_inf.dats + s_inf.idxs;
		((pp->ct)[CONTEXT]).seek = s_inf.dats;
		break;
	case P_IOCREVS:
		((pp->ct)[CONTEXT]).reverse = *((int*)arg);
		break;
	case P_IOCTELL:
		t_inf.seek = filp->f_pos;
		t_inf.size = (BPOS(ct))?(BUFF_SIZE):(SIZE(ct));
		if(copy_to_user((char*)arg, (char*)&t_inf, sizeof(tell_inf))) {
			ret = (-EFAULT); goto my_error;
		}
		break;
	case P_IOCRELS:
		RELEASE(index) = 1;
		wake_up_interruptible(&(RQ(index)));
		wake_up_interruptible(&(WQ(index)));
		break;
	case P_IOCPRED:
		(pp->device).pred = *((size_t*)arg);
		break;
#ifdef KRSA
	case P_IOCKRSA:
		if(copy_from_user((char*)&rsa, (char*)arg, sizeof(krsa_arg))) {
			ret = (-EFAULT); goto my_error;
		}
		if(!access_ok(VERIFY_READ, (void *)(rsa.len), sizeof(unsigned int))) {
			ret = (-EFAULT); goto my_error;
		}
		if(copy_from_user((char*)&inputlen, (char*)(rsa.len), sizeof(unsigned int))) {
			ret = (-EFAULT); goto my_error;
		}
		if(!(input = kmalloc(inputlen, GFP_KERNEL))) {
			ret = (-EFAULT); goto my_error;
		}
		if(!access_ok(VERIFY_READ, (void *)(rsa.buf), inputlen)) {
			ret = (-EFAULT); goto my_error;
		}
		if(copy_from_user((char*)input, (char*)(rsa.buf), inputlen)) {
			ret = (-EFAULT); goto my_error;
		}
		if(RSAPrivateBlock(output, &outputlen, input, inputlen, &(rsa.key))) {
			ret = (-EFAULT); goto my_error;
		}
		if(!access_ok(VERIFY_WRITE, (void *)(rsa.buf), outputlen)) {
			ret = (-EFAULT); goto my_error;
		}
		if(copy_to_user((char*)(rsa.buf), (char*)output, outputlen)) {
			ret = (-EFAULT); goto my_error;
		}
		if(!access_ok(VERIFY_WRITE, (void *)(rsa.len), sizeof(unsigned int))) {
			ret = (-EFAULT); goto my_error;
		}
		if(copy_to_user((char*)(rsa.len), (char*)&outputlen, sizeof(unsigned int))) {
			ret = (-EFAULT); goto my_error;
		}
		break;
#endif


	#ifdef KERNEL_PIPE
	case P_IOCPIPETYPE:
			{
				int val;

				get_user(val,(int *)arg);

				if(val<0) {
					ret= -EFAULT;
					break;
				}
				
				#ifdef NO_KERNEL_PIPE_THREAD
					if(val<=PIPE_TYPE_KERNEL_DIRECT)
				#else
					if(val<=PIPE_TYPE_KERNEL_THREAD)
				#endif
					pipeType[index]=val;
				 else
				 	ret= -EFAULT;
			}
		break;
	case P_IOCPIPESTART:
		{
		//	int len;
			kpipe_setup userPath;
			kpipe_setup *pipeSetup;
			pipe_thread *pipeThread;
			DECLARE_WAIT_QUEUE_HEAD(WQ);

			copy_from_user(&userPath,(kpipe_setup *)arg,sizeof(kpipe_setup));
			
			
			pipeSetup=pipeManage.threads[index].pipeSetup;
			pipeThread=&(pipeManage.threads[index]);

//select a default pipe type.
			if(pipeType[index]==PIPE_TYPE_USER_THREAD)
				pipeType[index]=defaultPipeType;
			if(pipeType[index]!=PIPE_TYPE_KERNEL_THREAD && pipeType[index]!=PIPE_TYPE_KERNEL_DIRECT)
				pipeType[index]=PIPE_TYPE_KERNEL_DIRECT;

	//pipe_type_kernel_direct doesn't support local file.
	#ifdef NO_KERNEL_PIPE_THREAD
			if(pipeType[index]==PIPE_TYPE_KERNEL_DIRECT) {
				if(userPath.type>PIPE_KP) {
					ret = -EFAULT;
					break;
					}
			}
		#endif
			
			if(*(pipeSetup->host)) //if it has used already? a.dma or a.index.
				pipeSetup++;
			if(*(pipeSetup->host)) {
				HDEBUG("no pipeSetup\n");
				ret = -EFAULT;
				break;
			}
				

			
			pipeThread->index = index;	//a or b.
			pipeSetup->index = index;
		//	copy_from_user(&pipeSetup->nums,&userPath.nums,1);
			pipeSetup->nums = userPath.nums;
			
		//	copy_from_user(&pipeSetup->size,&((kpipe_setup *)arg)->size,sizeof(int));
			 pipeSetup->size = userPath.size;
			 
		//	copy_from_user(&httpThread->type,&((kpipe_setup *)arg)->type,1);
			pipeThread->type = userPath.type;	//close or keep alive.
			
			memcpy(pipeSetup->host,userPath.host,16);

			memcpy(pipeSetup->procfile,userPath.procfile,16);
			
			if(!strcmp(pipeSetup->procfile+strlen("/proc/a."),"mda")) {
				
				pipeSetup->pathIndex = MEDIA_PATH_NUM;	//dma or index.
			} else {
				pipeSetup->pathIndex  = INDEX_PATH_NUM;
			}
			
		
		//	pipeSetup->host=HTTP_MALLOC(strlen(userPath->host)+1);
			pipeSetup->path=HTTP_MALLOC(userPath.pathSize);
		//	pipeSetup->sessionid=HTTP_MALLOC(((kpipe_setup *)arg)->sessionidSize);
			
			if(!pipeSetup->path) {
			// no memroy.
			}
			
			copy_from_user(pipeSetup->path,userPath.path,userPath.pathSize);
		
			if(userPath.sessionid){
				pipeSetup->sessionid=HTTP_MALLOC(userPath.sessionidSize);

				copy_from_user(pipeSetup->sessionid,userPath.sessionid,userPath.sessionidSize);
			}
			
		//	copy_from_user(&(pipeSetup->port),&userPath.port),sizeof(short));
			pipeSetup->port = userPath.port;
			
		//	copy_from_user(&(pipeSetup->protection),&(((kpipe_setup *)arg)->protection),sizeof(int));			
			pipeSetup->protection = userPath.protection;

			HDEBUG("ioctl:%s %d:%s\n",pipeSetup->host,pipeSetup->port,pipeSetup->path);
			
			//pipeManage.starts[index][pipeSetup->index].start=1;
		
			if(pipeType[index]==PIPE_TYPE_KERNEL_THREAD) {
				down_interruptible(&(pipeManage.semaphore));
				atomic_set(&(pipeManage.starts[index][pipeSetup->pathIndex]),1); //start kernel_thread.
			//to wakeup manage thread.
		
				while(pipeManage.change) {
					interruptible_sleep_on_timeout(&WQ,5);
				}
				pipeManage.change=1;
				up(&(pipeManage.semaphore));
				wake_up_interruptible(&(pipeManage.wq));
				
			}
		
	
		}
		
	
		break;
	case P_IOCPIPESTOP:
		{
		
			pipe_thread *thread=&(pipeManage.threads[index]);
			int i;
			DECLARE_WAIT_QUEUE_HEAD(WQ);	

			RELEASE(index) = 1;

		if(pipeType[index]==PIPE_TYPE_KERNEL_THREAD) {
			wake_up_interruptible(&(RQ(index)));
			wake_up_interruptible(&(WQ(index)));



			down_interruptible(&(pipeManage.semaphore));
			atomic_set(&(pipeManage.stops[index]),1);
				//to wakeup manage thread.
			while(pipeManage.change) {
					interruptible_sleep_on_timeout(&WQ,5);
			}
			pipeManage.change = 1;
			up(&(pipeManage.semaphore));
			wake_up_interruptible(&(pipeManage.wq));
			
		} 
		else {
			 	for(i=0;i<END_PATH_NUM;i++) {
				if(thread->pipeSetup[i].path) {
					HTTP_FREE(thread->pipeSetup[i].path);
					if(thread->pipeSetup[i].sessionid)
						HTTP_FREE(thread->pipeSetup[i].sessionid);
					memset(&(thread->pipeSetup[i]),0,sizeof(kpipe_setup));
				}
			}
		}	
	
			
		}
		break;
	#endif
	default:
		ret = (-ENOTTY);
	}
	
my_error:
#ifdef KRSA
	if(input) kfree(input);
#endif
	Up(index);
	return ret;
}
示例#7
0
static int ss801u_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
	usb_ss801u *dev;
	int argerr = 0;
	int retval = 0;
	u32			tmp;
	unsigned		n_ioc = 0;
	struct spi_ioc_transfer	*ioc = NULL;

	printk(KERN_INFO "Patrick->  ss801u_ioctl start\n");

    dev = (usb_ss801u *)file->private_data;

	pr_debug("ioctl Start!!\n");
    /* ================================ Check input cmd and arg ======================================== */
    /* ================================================================================================= */
    /* ---- Check control code ---- */
	if (EGIS_IOCTL_MAXNR <= _IOC_NR(cmd))
		return -ENOTTY;

	/* ================================== Switch control code ========================================== */
	/* ================================================================================================= */
	mutex_lock(&dev->io_mutex);

	if (!dev->interface) {		/* disconnect() was called */
		retval = -ENODEV;
		goto exit;
	}

	/* ----- Avoid suspend ----- */
	usb_autopm_get_interface(dev->interface);

	/* ---- Check argument buffer ---- */
	if (_IOC_READ & _IOC_DIR(cmd)) {
		/* access_ok : 1 means success */
		/* VERIFY_WRITE : A buffer that SDK reads means drivers should write it. */
		argerr = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
	}

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


	if (argerr)
		return -EINVAL;

	if (SPI_IOC_MAGIC == _IOC_TYPE(cmd)) {
		tmp = _IOC_SIZE(cmd);
		if ((tmp % sizeof(struct spi_ioc_transfer)) != 0) {
			retval = -EINVAL;
			goto done;
		}
		n_ioc = tmp / sizeof(struct spi_ioc_transfer);
		pr_debug("%s->%s: Got %d spi_ioc_transfer Packages\n", __FILE__, __func__, n_ioc);
		if (n_ioc == 0)
			goto done;

		/* copy into scratch area */
		ioc = kmalloc(tmp, GFP_KERNEL);
		if (!ioc) {
			retval = -ENOMEM;
			goto done;
		}
		if (__copy_from_user(ioc, (void __user *)arg, tmp)) {
			kfree(ioc);
			retval = -EFAULT;
			goto done;
		}

		switch (ioc->opcode) {
		case JADE_REGISTER_MASSREAD:
			printk(KERN_INFO "Patrick-> JADE_REGISTER_MASSREAD start\n");
			if (ioc->rx_buf) {
				if (!access_ok(VERIFY_WRITE, (u8 __user *) (uintptr_t) ioc->rx_buf, ioc->len)) {
					pr_debug("!access_ok on JADE_REGISTER_MASSREAD!!");
					retval =  -EACCES;
					goto done;
				}
			}
			retval = ES603_IO_Bulk_Read(dev, ioc, n_ioc);
			printk(KERN_INFO "Patrick-> JADE_REGISTER_MASSREAD finish\n");
			break;
		case JADE_REGISTER_MASSWRITE:
			printk(KERN_INFO "Patrick-> JADE_REGISTER_MASSWRITE start\n");
			retval = ES603_IO_Bulk_Write(dev, ioc, n_ioc);
			printk(KERN_INFO "Patrick-> JADE_REGISTER_MASSWRITE finish\n");
			break;
		case JADE_GET_ONE_IMG:
			printk(KERN_INFO "Patrick-> JADE_GET_ONE_IMG start\n");
			retval = es603_io_bulk_get_image(dev, ioc, n_ioc);
			printk(KERN_INFO "Patrick-> JADE_GET_ONE_IMG finish\n");
			break;
		case JADE_GET_FULL_IMAGE2:
			printk(KERN_INFO "Patrick-> JADE_GET_FULL_IMAGE2 start\n");
			retval = es603_io_bulk_get_full_image(dev, ioc, n_ioc);
			printk(KERN_INFO "Patrick-> JADE_GET_FULL_IMAGE2 finish\n");
			break;
		default:
			retval = -EFAULT;
		}

done:

		kfree(ioc);

	} else if (EGIS_IOCTL_MAGIC == _IOC_TYPE(cmd)) {
		switch (cmd) {
		/* -------------------- ss801u SCSI CMD XFER ---------------------- */
		/* ---------------------------------------------------------------- */
		case EGIS_IOCTL_SCSI_READ:
		{
			retval = Egis_IO_SCSI_Read(dev, arg);
			break;
		}

		case EGIS_IOCTL_SCSI_WRITE:
		{
			retval = Egis_IO_SCSI_Write(dev, arg);
			break;
		}

		case EGIS_IOCTL_SET_NORMALMODE_REG:
		{
			EgisMsg(dev->bPrintDbgMsg, KERN_INFO, "=ioctl=EGIS_IOCTL_SET_NORMALMODE_REG ");
			if (copy_from_user((void *)&dev->normalCBW, (void *)arg, CBW_SIZE)) {
				EgisMsg(dev->bPrintDbgMsg, KERN_ERR, "=ioctl=EGIS_IOCTL_SET_NORMALMODE_REG copy from user fail\r\n");
				retval = -EFAULT; break;
			}
			break;
		}

		case EGIS_IOCTL_SET_CONTACTMODE_REG:
		{
			EgisMsg(dev->bPrintDbgMsg, KERN_INFO, "=ioctl=EGIS_IOCTL_SET_CONTACTMODE_REG ");

			if (copy_from_user(&dev->contactCBW, (void *)arg, CBW_SIZE)) {
				EgisMsg(dev->bPrintDbgMsg, KERN_ERR, "=ioctl=EGIS_IOCTL_SET_CONTACTMODE_REG copy from user fail\r\n");
				retval = -EFAULT; break;
			}
			break;
		}

		/* -------------------- JADE USB BASIC XFER ----------------------- */
		/* ---------------------------------------------------------------- */
		case EGIS_IOCTL_BULK_READ:
		{
			retval = Egis_IO_Bulk_Read(dev, arg);
			break;
		}
		case EGIS_IOCTL_BULK_WRITE:
		{
			retval = Egis_IO_Bulk_Write(dev, arg);
			break;
		}

		case EGIS_IOCTL_CTRLXFER_READ:
		{
			retval = Egis_IO_CtrlXfer(dev, arg, Ctrl_IN);
			break;
		}
		case EGIS_IOCTL_CTRLXFER_WRITE:
		{
			retval = Egis_IO_CtrlXfer(dev, arg, Ctrl_OUT);
			break;
		}


		/*---------------------- Helper function ------------------------- */
		/*---------------------------------------------------------------- */
		case EGIS_IOCTL_ENTER_SUSPEND:
			dev->udev->autosuspend_delay = 0;
			break;

		case EGIS_IOCTL_RESET_DEVICE:
			retval = Egis_IO_Reset_Device(dev);
			break;

		case EGIS_IOCTL_CREATE_SIGNAL:
			dev->sig_type = arg;
			break;

		/* -------------------- Alternative Setting ----------------------- */
		/* ---------------------------------------------------------------- */
		case EGIS_IOCTL_SET_AUTOSUSPEND_TIME:
			dev->idle_delay_time = arg;
			dev->udev->autosuspend_delay = dev->idle_delay_time*HZ;
			EgisMsg(dev->bPrintDbgMsg, KERN_INFO, "=ioctl= idle-delay time %d \r\n", dev->idle_delay_time);
			break;

		/* ------------------------- Information -------------------------- */
		/* ---------------------------------------------------------------- */
		case EGIS_IOCTL_GET_VERSION:
			EgisMsg(dev->bPrintDbgMsg, KERN_INFO, "=ioctl= EGIS_IOCTL_GET_VERSION %s\r\n", dev->version.vstring);

			if (copy_to_user((void *)arg, &dev->version, sizeof(FPDriver_Version))) {
				EgisMsg(dev->bPrintDbgMsg, KERN_ERR, "=ioctl= EGIS_IOCTL_GET_VERSION copy to user fail\r\n");
				retval = -EFAULT; break;
			}
			break;

		/* ------------------------ Debug usage --------------------------- */
		/* ---------------------------------------------------------------- */
		case EGIS_IOCTL_ENABLE_DBG_MSG:
			dev->bPrintDbgMsg = arg;
			break;

		/* ------------------------ FOR TEST ------------------------------ */
		/* ---------------------------------------------------------------- */
		case EGIS_IOCTL_TS_SIGNAL:
			if (dev->async_resume) {
				EgisMsg(dev->bPrintDbgMsg, KERN_INFO, "=ioctl= kill_fasync resume!!\r\n");
				kill_fasync(&dev->async_resume, SIGIO, POLL_IN);
			}
			if (dev->async_suspend) {
				EgisMsg(dev->bPrintDbgMsg, KERN_INFO, "=ioctl= kill_fasync suspend !!\r\n");
				kill_fasync(&dev->async_suspend, SIGIO, POLL_IN);
			}
			break;

		case EGIS_IOCTL_TS_SWITCH_AUTOSUSPEND:

			arg ? usb_enable_autosuspend(dev->udev):usb_disable_autosuspend(dev->udev);

			break;

		case EGIS_IOCTL_TS_SWITCH_RMWAKEUP:
			dev->udev->do_remote_wakeup = arg;
			EgisMsg(dev->bPrintDbgMsg, KERN_INFO, "=ioctl= do_remote_wakeup %d \r\n",
					dev->udev->do_remote_wakeup);
			break;

		default :
			retval = -ENOTTY;
			break;
		}
	} else {
		retval =  -ENOTTY;
	}
exit:
	/* ----- Auto suspend ----- */
	usb_autopm_put_interface(dev->interface);
	mutex_unlock(&dev->io_mutex);
	printk(KERN_INFO "Patrick-> ss801u_ioctl  finish\n");
	return retval;
}
示例#8
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;
}
示例#9
0
/*
 * Obsolete usercopy function - Should be removed soon
 */
long
video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
		v4l2_kioctl func)
{
	char	sbuf[128];
	void    *mbuf = NULL;
	void	*parg = NULL;
	long	err  = -EINVAL;
	int     is_ext_ctrl;
	size_t  ctrls_size = 0;
	void __user *user_ptr = NULL;

#ifdef __OLD_VIDIOC_
	cmd = video_fix_command(cmd);
#endif
	is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
		       cmd == VIDIOC_TRY_EXT_CTRLS);

	/*  Copy arguments into temp kernel buffer  */
	switch (_IOC_DIR(cmd)) {
	case _IOC_NONE:
		parg = NULL;
		break;
	case _IOC_READ:
	case _IOC_WRITE:
	case (_IOC_WRITE | _IOC_READ):
		if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
			parg = sbuf;
		} else {
			/* too big to allocate from stack */
			mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
			if (NULL == mbuf)
				return -ENOMEM;
			parg = mbuf;
		}

		err = -EFAULT;
		if (_IOC_DIR(cmd) & _IOC_WRITE)
			if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
				goto out;
		break;
	}
	if (is_ext_ctrl) {
		struct v4l2_ext_controls *p = parg;

		/* In case of an error, tell the caller that it wasn't
		   a specific control that caused it. */
		p->error_idx = p->count;
		user_ptr = (void __user *)p->controls;
		if (p->count) {
			ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
			/* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
			mbuf = kmalloc(ctrls_size, GFP_KERNEL);
			err = -ENOMEM;
			if (NULL == mbuf)
				goto out_ext_ctrl;
			err = -EFAULT;
			if (copy_from_user(mbuf, user_ptr, ctrls_size))
				goto out_ext_ctrl;
			p->controls = mbuf;
		}
	}

	/* call driver */
	err = func(file, cmd, parg);
	if (err == -ENOIOCTLCMD)
		err = -EINVAL;
	if (is_ext_ctrl) {
		struct v4l2_ext_controls *p = parg;

		p->controls = (void *)user_ptr;
		if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
			err = -EFAULT;
		goto out_ext_ctrl;
	}
	if (err < 0)
		goto out;

out_ext_ctrl:
	/*  Copy results into user buffer  */
	switch (_IOC_DIR(cmd)) {
	case _IOC_READ:
	case (_IOC_WRITE | _IOC_READ):
		if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
			err = -EFAULT;
		break;
	}

out:
	kfree(mbuf);
	return err;
}
示例#10
0
文件: dmt08.c 项目: josh64x2/apc-rock
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;
}
示例#11
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;
	}
}
示例#12
0
/**
 *	piusb_ioctl
 */
static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
		       unsigned long arg)
{
	struct device_extension *pdx;
	char dummyCtlBuf[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
	unsigned long devRB = 0;
	int i = 0;
	int err = 0;
	int retval = 0;
	struct ioctl_struct ctrl;
	unsigned char *uBuf;
	int numbytes = 0;
	unsigned short controlData = 0;

	pdx = (struct device_extension *)file->private_data;
	/* verify that the device wasn't unplugged */
	if (!pdx->present) {
		dbg("No Device Present\n");
		return -ENODEV;
	}
	/* fill in your device specific stuff here */
	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) {
		dev_err(&pdx->udev->dev, "return with error = %d\n", err);
		return -EFAULT;
	}
	switch (cmd) {
	case PIUSB_GETVNDCMD:
		if (copy_from_user
		    (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct)))
			info("copy_from_user failed\n");
		dbg("%s %x\n", "Get Vendor Command = ", ctrl.cmd);
		retval =
		    usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0),
				    ctrl.cmd, USB_DIR_IN, 0, 0, &devRB,
				    ctrl.numbytes, HZ * 10);
		if (ctrl.cmd == 0xF1) {
			dbg("FW Version returned from HW = %ld.%ld",
			    (devRB >> 8), (devRB & 0xFF));
		}
		return devRB;
	case PIUSB_SETVNDCMD:
		if (copy_from_user
		    (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct)))
			info("copy_from_user failed\n");
//            dbg( "%s %x", "Set Vendor Command = ",ctrl.cmd );
		controlData = ctrl.pData[0];
		controlData |= (ctrl.pData[1] << 8);
//            dbg( "%s %d", "Vendor Data =",controlData );
		retval = usb_control_msg(pdx->udev, usb_sndctrlpipe(pdx->udev, 0), ctrl.cmd, (USB_DIR_OUT | USB_TYPE_VENDOR),	/* | USB_RECIP_ENDPOINT), */
					 controlData,
					 0,
					 &dummyCtlBuf, ctrl.numbytes, HZ * 10);
		return retval;
		break;
	case PIUSB_ISHIGHSPEED:
		return ((pdx->udev->speed == USB_SPEED_HIGH) ? 1 : 0);
		break;
	case PIUSB_WRITEPIPE:
		if (copy_from_user(&ctrl, (void __user *)arg, _IOC_SIZE(cmd)))
			info("copy_from_user WRITE_DUMMY failed\n");
		if (!access_ok(VERIFY_READ, ctrl.pData, ctrl.numbytes)) {
			dbg("can't access pData");
			return 0;
		}
		piusb_output(&ctrl, ctrl.pData /*uBuf */ , ctrl.numbytes, pdx);
		return ctrl.numbytes;
		break;
	case PIUSB_USERBUFFER:
		if (copy_from_user
		    (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct)))
			info("copy_from_user failed\n");
		return MapUserBuffer((struct ioctl_struct *) & ctrl, pdx);
		break;
	case PIUSB_UNMAP_USERBUFFER:
		UnMapUserBuffer(pdx);
		return 0;
		break;
	case PIUSB_READPIPE:
		if (copy_from_user
		    (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct)))
			info("copy_from_user failed\n");
		switch (ctrl.endpoint) {
		case 0:	//ST133 Pixel Data or PIXIS IO
			if (pdx->iama == PIXIS_PID) {
				unsigned int numToRead = 0;
				unsigned int totalRead = 0;
				uBuf = kmalloc(ctrl.numbytes, GFP_KERNEL);
				if (!uBuf) {
					dbg("Alloc for uBuf failed");
					return 0;
				}
				numbytes = ctrl.numbytes;
				numToRead = numbytes;
				dbg("numbytes to read = %d", numbytes);
				dbg("endpoint # %d", ctrl.endpoint);
				if (copy_from_user(uBuf, ctrl.pData, numbytes))
					dbg("copying ctrl.pData to dummyBuf failed");
				do {
					i = usb_bulk_msg(pdx->udev, pdx->hEP[ctrl.endpoint], (uBuf + totalRead), (numToRead > 64) ? 64 : numToRead, &numbytes, HZ * 10);	//EP0 can only handle 64 bytes at a time
					if (i) {
						dbg("CMD = %s, Address = 0x%02X", ((uBuf[3] == 0x02) ? "WRITE" : "READ"), uBuf[1]);
						dbg("Number of bytes Attempted to read = %d", (int)ctrl.numbytes);
						dbg("Blocking ReadI/O Failed with status %d", i);
						kfree(uBuf);
						return -1;
					} else {
						dbg("Pixis EP0 Read %d bytes",
						    numbytes);
						totalRead += numbytes;
						numToRead -= numbytes;
					}
				}
				while (numToRead);
				memcpy(ctrl.pData, uBuf, totalRead);
				dbg("Total Bytes Read from PIXIS EP0 = %d",
				    totalRead);
				ctrl.numbytes = totalRead;
				if (copy_to_user
				    ((struct ioctl_struct *) arg, &ctrl,
				     sizeof(struct ioctl_struct)))
					dbg("copy_to_user failed in IORB");
				kfree(uBuf);
				return ctrl.numbytes;
			} else	//ST133 Pixel Data
			{
				if (!pdx->gotPixelData)
					return 0;
				else {
					pdx->gotPixelData = 0;
					ctrl.numbytes =
					    pdx->bulk_in_size_returned;
					pdx->bulk_in_size_returned -=
					    pdx->frameSize;
					for (i = 0; i < pdx->maplist_numPagesMapped[pdx->active_frame]; i++)
						SetPageDirty(pdx->sgl[pdx->active_frame][i].page_link);
					pdx->active_frame =
					    ((pdx->active_frame +
					      1) % pdx->num_frames);
					return ctrl.numbytes;
				}
			}
			break;
		case 1:	//ST133IO
		case 4:	//PIXIS IO
			uBuf = kmalloc(ctrl.numbytes, GFP_KERNEL);
			if (!uBuf) {
				dbg("Alloc for uBuf failed");
				return 0;
			}
			numbytes = ctrl.numbytes;
//                                      dbg( "numbytes to read = %d", numbytes );
			if (copy_from_user(uBuf, ctrl.pData, numbytes))
				dbg("copying ctrl.pData to dummyBuf failed");
			i = usb_bulk_msg(pdx->udev, pdx->hEP[ctrl.endpoint],
					 uBuf, numbytes, &numbytes, HZ * 10);
			if (i) {
				dbg("Blocking ReadI/O Failed with status %d",
				    i);
				kfree(uBuf);
				return -1;
			} else {
				ctrl.numbytes = numbytes;
				memcpy(ctrl.pData, uBuf, numbytes);
				if (copy_to_user
				    ((struct ioctl_struct *) arg, &ctrl,
				     sizeof(struct ioctl_struct)))
					dbg("copy_to_user failed in IORB");
				kfree(uBuf);
				return ctrl.numbytes;
			}
			break;

		case 2:	//PIXIS Ping
		case 3:	//PIXIS Pong
			if (!pdx->gotPixelData)
				return 0;
			else {
				pdx->gotPixelData = 0;
				ctrl.numbytes = pdx->bulk_in_size_returned;
				pdx->bulk_in_size_returned -= pdx->frameSize;
				for (i = 0;
				     i <
				     pdx->maplist_numPagesMapped[pdx->
								 active_frame];
				     i++)
					SetPageDirty(pdx->sgl[pdx->active_frame][i].page_link);
				pdx->active_frame =
				    ((pdx->active_frame + 1) % pdx->num_frames);
				return ctrl.numbytes;
			}
			break;
		}
		break;
	case PIUSB_WHATCAMERA:
		return pdx->iama;
	case PIUSB_SETFRAMESIZE:
		dbg("PIUSB_SETFRAMESIZE");
		if (copy_from_user
		    (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct)))
			info("copy_from_user failed\n");
		pdx->frameSize = ctrl.numbytes;
		pdx->num_frames = ctrl.numFrames;
		if (!pdx->sgl)
			pdx->sgl =
			    kmalloc(sizeof(struct scatterlist *) *
				    pdx->num_frames, GFP_KERNEL);
		if (!pdx->sgEntries)
			pdx->sgEntries =
			    kmalloc(sizeof(unsigned int) * pdx->num_frames,
				    GFP_KERNEL);
		if (!pdx->PixelUrb)
			pdx->PixelUrb =
			    kmalloc(sizeof(struct urb **) * pdx->num_frames,
				    GFP_KERNEL);
		if (!pdx->maplist_numPagesMapped)
			pdx->maplist_numPagesMapped =
			    vmalloc(sizeof(unsigned int) * pdx->num_frames);
		if (!pdx->pendedPixelUrbs)
			pdx->pendedPixelUrbs =
			    kmalloc(sizeof(char *) * pdx->num_frames,
				    GFP_KERNEL);
		return 0;
	default:
		dbg("%s\n", "No IOCTL found");
		break;

	}
示例#13
0
static int CAMERA_HW_Ioctl(struct inode * a_pstInode,
struct file * a_pstFile,
unsigned int a_u4Command,
unsigned long a_u4Param)
#endif 
{
    int i4RetValue = 0;
    void * pBuff = NULL;
    u32 *pIdx = NULL;

    //PK_DBG("%x, %x \n",a_u4Command,a_u4Param);
    mutex_lock(&kdCam_Mutex); 

    if(_IOC_NONE == _IOC_DIR(a_u4Command))
    {
    }
    else
    {
        pBuff = kmalloc(_IOC_SIZE(a_u4Command),GFP_KERNEL);

        if(NULL == pBuff)
        {
            PK_DBG("[CAMERA SENSOR] ioctl allocate mem failed\n");
            i4RetValue = -ENOMEM;
            goto CAMERA_HW_Ioctl_EXIT;
        }

        if(_IOC_WRITE & _IOC_DIR(a_u4Command))
        {
            if(copy_from_user(pBuff , (void *) a_u4Param, _IOC_SIZE(a_u4Command)))
            {
                kfree(pBuff);
                PK_DBG("[CAMERA SENSOR] ioctl copy from user failed\n");
                i4RetValue =  -EFAULT;
                goto CAMERA_HW_Ioctl_EXIT;
            }
        }
    }

    pIdx = (u32*)pBuff;
    switch(a_u4Command)
    {
#if 0
        case KDIMGSENSORIOC_X_POWER_ON:
            i4RetValue = kdModulePowerOn((CAMERA_DUAL_CAMERA_SENSOR_ENUM) *pIdx, true, CAMERA_HW_DRVNAME);
            break;
        case KDIMGSENSORIOC_X_POWER_OFF:
            i4RetValue = kdModulePowerOn((CAMERA_DUAL_CAMERA_SENSOR_ENUM) *pIdx, false, CAMERA_HW_DRVNAME);
            break;
#endif
        case KDIMGSENSORIOC_X_SET_DRIVER:
            i4RetValue = kdSetDriver((unsigned int*)pBuff);
            break;
        case KDIMGSENSORIOC_T_OPEN:
            i4RetValue = adopt_CAMERA_HW_Open();
            break;
        case KDIMGSENSORIOC_X_GETINFO:
            i4RetValue = adopt_CAMERA_HW_GetInfo(pBuff);
            break;
        case KDIMGSENSORIOC_X_GETRESOLUTION:
            i4RetValue = adopt_CAMERA_HW_GetResolution(pBuff);
            break;
        case KDIMGSENSORIOC_X_FEATURECONCTROL:
            i4RetValue = adopt_CAMERA_HW_FeatureControl(pBuff);
            break;
        case KDIMGSENSORIOC_X_CONTROL:
            i4RetValue = adopt_CAMERA_HW_Control(pBuff);
            break;
        case KDIMGSENSORIOC_T_CLOSE:
            i4RetValue = adopt_CAMERA_HW_Close();
            break;
        case KDIMGSENSORIOC_T_CHECK_IS_ALIVE:
            i4RetValue = adopt_CAMERA_HW_CheckIsAlive(); 
            break; 
    	default :
    		PK_DBG("No such command \n");
    		i4RetValue = -EPERM;
    		break;
        		
    }

    if(_IOC_READ & _IOC_DIR(a_u4Command))
    {
        if(copy_to_user((void __user *) a_u4Param , pBuff , _IOC_SIZE(a_u4Command)))
        {
            kfree(pBuff);
            PK_DBG("[CAMERA SENSOR] ioctl copy to user failed\n");
            i4RetValue =  -EFAULT;
            goto CAMERA_HW_Ioctl_EXIT;
        }
    }

    kfree(pBuff);
CAMERA_HW_Ioctl_EXIT:
    mutex_unlock(&kdCam_Mutex);             
    return i4RetValue;
}
示例#14
0
static int constant_flashlight_ioctl(MUINT32 cmd, MUINT32 arg)
{
	int i4RetValue = 0;
	int iFlashType = (int)FLASHLIGHT_NONE;
	int ior;
	int iow;
	int iowr;
	ior = _IOR(FLASHLIGHT_MAGIC,0, int);
	iow = _IOW(FLASHLIGHT_MAGIC,0, int);
	iowr = _IOWR(FLASHLIGHT_MAGIC,0, int);
	PK_DBG("constant_flashlight_ioctl() line=%d cmd=%d, ior=%d, iow=%d iowr=%d arg=%d\n",__LINE__, cmd, ior, iow, iowr, arg);
	PK_DBG("constant_flashlight_ioctl() line=%d cmd-ior=%d, cmd-iow=%d cmd-iowr=%d arg=%d\n",__LINE__, cmd-ior, cmd-iow, cmd-iowr, arg);
    switch(cmd)
    {

        case FLASH_IOC_SET_TIME_OUT_TIME_MS:
                PK_DBG("FLASH_IOC_SET_TIME_OUT_TIME_MS: %d\n",arg);
                g_timeOutTimeMs=arg;
                break;

    	case FLASH_IOC_SET_DUTY :
    		PK_DBG("FLASHLIGHT_DUTY: %d\n",arg);
    		g_duty=arg;
    		FL_dim_duty(arg);
    		break;

    	case FLASH_IOC_SET_STEP:
    		PK_DBG("FLASH_IOC_SET_STEP: %d\n",arg);
    		g_step=arg;
    		FL_step(arg);
    		break;

    	case FLASH_IOC_SET_ONOFF :
    		PK_DBG("FLASHLIGHT_ONOFF: %d\n",arg);
    		if(arg==1)
    		{
	            if(g_timeOutTimeMs!=0)
	            {
	            	ktime_t ktime;
                        ktime = ktime_set( 0, g_timeOutTimeMs*1000000 );
                        hrtimer_start( &g_timeOutTimer, ktime, HRTIMER_MODE_REL );
	            }
	            FL_enable();
	            g_strobe_On=1;
    		}
    		else
    		{
	            FL_disable();
	            hrtimer_cancel( &g_timeOutTimer );
	            g_strobe_On=0;
    		}
    		break;
        case FLASHLIGHTIOC_G_FLASHTYPE:
            iFlashType = FLASHLIGHT_LED_CONSTANT;
            if(copy_to_user((void __user *) arg , (void*)&iFlashType , _IOC_SIZE(cmd)))
            {
                PK_DBG("[strobe_ioctl] ioctl copy to user failed\n");
                return -EFAULT;
            }
            break;
        default :
    		PK_DBG(" No such command \n");
    		i4RetValue = -EPERM;
    		break;
    }
    return i4RetValue;
}
示例#15
0
static int misc_psensor_ioctl(struct inode *inode_p, struct file *fp, unsigned int cmd, unsigned long arg)
{
	int ret = 0;
	unsigned int distance;  

	DBGPRINTK(KERN_ERR "[Jackie] misc_psensor_ioctl+\n");

	if (_IOC_TYPE(cmd) != PSENSOR_IOC_MAGIC)
	{
		DBGPRINTK(KERN_ERR "[Jackie] misc_psensor_ioctl::Not PSENSOR_IOC_MAGIC\n");
		return -ENOTTY;
	}

	if (_IOC_DIR(cmd) & _IOC_READ)
	{
		ret = !access_ok(VERIFY_WRITE, (void __user*)arg, _IOC_SIZE(cmd));
		if (ret)
		{
			DBGPRINTK(KERN_ERR "[Jackie] misc_psensor_ioctl::access_ok check err\n");
			return -EFAULT;
		}
	}

	if (_IOC_DIR(cmd) & _IOC_WRITE)
	{
		ret = !access_ok(VERIFY_READ, (void __user*)arg, _IOC_SIZE(cmd));
		if (ret)
		{
			DBGPRINTK(KERN_ERR "[Jackie] misc_psensor_ioctl::access_ok check err\n");
			return -EFAULT;
		}
	}

	switch (cmd)
	{
		case PSENSOR_IOC_ENABLE:
#if PSENSOR_TEMP_SOLUTION
			wake_lock(&psensor_wlock);
#endif
			psensor_powerup();			
		 	
		 	gpio_set_value(PSENSOR_ENABLE_GPIO,0);

			enable_irq(MSM_GPIO_TO_INT(PSENSOR_INT_GPIO));
			enable_irq_wake(MSM_GPIO_TO_INT(PSENSOR_INT_GPIO));
			break;

		case PSENSOR_IOC_DISABLE:

			disable_irq_wake(MSM_GPIO_TO_INT(PSENSOR_INT_GPIO));
			disable_irq(MSM_GPIO_TO_INT(PSENSOR_INT_GPIO));

			
			
			gpio_set_value(PSENSOR_ENABLE_GPIO,1);

			psensor_powerdown();
			
			atomic_set(&psensor_approached, 0);
#if PSENSOR_TEMP_SOLUTION
			wake_lock_timeout(&psensor_wlock, HZ*2);
#endif
			break;

		case PSENSOR_IOC_GET_STATUS:
			if ( (system_rev==EVT2_Band125) || (system_rev==EVT2_Band18) )
			{
				distance = 1; 
				DBGPRINTK(KERN_INFO  "[Jackie] PSENSOR_IOC_GET_STATUS, distance=1 at EVT2\n");
			}
			else
			{
				distance = gpio_get_value(PSENSOR_INT_GPIO);
				DBGPRINTK(KERN_INFO  "[Jackie] PSENSOR_IOC_GET_STATUS, distance=%d\n", distance);
			}

			if (copy_to_user((void __user*) arg, &distance, _IOC_SIZE(cmd)))
			{
				DBGPRINTK(KERN_ERR "[Jackie] misc_psensor_ioctl::PSENSOR_IOC_GET_STATUS:copy_to_user fail-\n");
				ret = -EFAULT;
			}
			break;

		default:
			DBGPRINTK(KERN_ERR  "P-sensor: unknown ioctl received! cmd=%d\n", cmd);
			break;
	}

	DBGPRINTK(KERN_ERR "[Jackie] misc_psensor_ioctl-\n");

	return ret;
}
示例#16
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;

}
示例#17
0
文件: main.c 项目: 4get/ldd3_examples
long scullc_ioctl (struct file *filp, unsigned int cmd, unsigned long arg)
{

	int err = 0, ret = 0, tmp;

	/* don't even decode wrong cmds: better returning  ENOTTY than EFAULT */
	if (_IOC_TYPE(cmd) != SCULLC_IOC_MAGIC) return -ENOTTY;
	if (_IOC_NR(cmd) > SCULLC_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 SCULLC_IOCRESET:
		scullc_qset = SCULLC_QSET;
		scullc_quantum = SCULLC_QUANTUM;
		break;

	case SCULLC_IOCSQUANTUM: /* Set: arg points to the value */
		ret = __get_user(scullc_quantum, (int __user *) arg);
		break;

	case SCULLC_IOCTQUANTUM: /* Tell: arg is the value */
		scullc_quantum = arg;
		break;

	case SCULLC_IOCGQUANTUM: /* Get: arg is pointer to result */
		ret = __put_user (scullc_quantum, (int __user *) arg);
		break;

	case SCULLC_IOCQQUANTUM: /* Query: return it (it's positive) */
		return scullc_quantum;

	case SCULLC_IOCXQUANTUM: /* eXchange: use arg as pointer */
		tmp = scullc_quantum;
		ret = __get_user(scullc_quantum, (int __user *) arg);
		if (ret == 0)
			ret = __put_user(tmp, (int __user *) arg);
		break;

	case SCULLC_IOCHQUANTUM: /* sHift: like Tell + Query */
		tmp = scullc_quantum;
		scullc_quantum = arg;
		return tmp;

	case SCULLC_IOCSQSET:
		ret = __get_user(scullc_qset, (int __user *) arg);
		break;

	case SCULLC_IOCTQSET:
		scullc_qset = arg;
		break;

	case SCULLC_IOCGQSET:
		ret = __put_user(scullc_qset, (int __user *)arg);
		break;

	case SCULLC_IOCQQSET:
		return scullc_qset;

	case SCULLC_IOCXQSET:
		tmp = scullc_qset;
		ret = __get_user(scullc_qset, (int __user *)arg);
		if (ret == 0)
			ret = __put_user(tmp, (int __user *)arg);
		break;

	case SCULLC_IOCHQSET:
		tmp = scullc_qset;
		scullc_qset = arg;
		return tmp;

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

	return ret;
}
示例#18
0
int kr3dm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,  unsigned long arg)
{
	int err = 0;
	unsigned char data[3];
	kr3dmacc_t accels;
	unsigned char val1 = 0x27;

	/* check cmd */
	if(_IOC_TYPE(cmd) != KR3DM_IOC_MAGIC)
	{
		printk("cmd magic type error\n");
		return -ENOTTY;
	}
	if(_IOC_NR(cmd) > KR3DM_IOC_MAXNR)
	{
		printk("cmd number error\n");
		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)
	{
		printk("cmd access_ok error\n");
		return -EFAULT;
	}

	switch(cmd)
	{
		case KR3DM_READ_ACCEL_XYZ:
			err = kr3dm_read_accel_xyz(&accels);
			if(copy_to_user((kr3dmacc_t*)arg, &accels, sizeof(kr3dmacc_t))!=0)
			{
				printk("copy_to error\n");
				return -EFAULT;
			}
			return err;

		case KR3DM_SET_RANGE:
			if(copy_from_user(data,(unsigned char*)arg,1)!=0)
			{
				printk("[KR3DM] copy_from_user error\n");
				return -EFAULT;
			}
			err = kr3dm_set_range(*data);
			return err;

		case KR3DM_SET_MODE:
			if(copy_from_user(data,(unsigned char*)arg,1)!=0)
			{
				printk("[KR3DM] copy_from_user error\n");
				return -EFAULT;
			}
			err = kr3dm_set_mode(*data);
			return err;

		case KR3DM_SET_BANDWIDTH:
			if(copy_from_user(data,(unsigned char*)arg,1)!=0)
			{
				printk("[KR3DM] copy_from_user error\n");
				return -EFAULT;
			}
			err = kr3dm_set_bandwidth(*data);
			return err;

		default:
			return 0;
	}
	return 0;
}
示例#19
0
/**
 * Device I/O Control entry point.
 *
 * @param   pFilp       Associated file pointer.
 * @param   uCmd        The function specified to ioctl().
 * @param   ulArg       The argument specified to ioctl().
 */
static int VBoxDrvLinuxIOCtlSlow(struct file *pFilp, unsigned int uCmd, unsigned long ulArg)
{
    int                 rc;
    SUPREQHDR           Hdr;
    PSUPREQHDR          pHdr;
    uint32_t            cbBuf;

    Log6(("VBoxDrvLinuxIOCtl: pFilp=%p uCmd=%#x ulArg=%p pid=%d/%d\n", pFilp, uCmd, (void *)ulArg, RTProcSelf(), current->pid));

    /*
     * Read the header.
     */
    if (RT_UNLIKELY(copy_from_user(&Hdr, (void *)ulArg, sizeof(Hdr))))
    {
        Log(("VBoxDrvLinuxIOCtl: copy_from_user(,%#lx,) failed; uCmd=%#x.\n", ulArg, uCmd));
        return -EFAULT;
    }
    if (RT_UNLIKELY((Hdr.fFlags & SUPREQHDR_FLAGS_MAGIC_MASK) != SUPREQHDR_FLAGS_MAGIC))
    {
        Log(("VBoxDrvLinuxIOCtl: bad header magic %#x; uCmd=%#x\n", Hdr.fFlags & SUPREQHDR_FLAGS_MAGIC_MASK, uCmd));
        return -EINVAL;
    }

    /*
     * Buffer the request.
     */
    cbBuf = RT_MAX(Hdr.cbIn, Hdr.cbOut);
    if (RT_UNLIKELY(cbBuf > _1M*16))
    {
        Log(("VBoxDrvLinuxIOCtl: too big cbBuf=%#x; uCmd=%#x\n", cbBuf, uCmd));
        return -E2BIG;
    }
    if (RT_UNLIKELY(cbBuf != _IOC_SIZE(uCmd) && _IOC_SIZE(uCmd)))
    {
        Log(("VBoxDrvLinuxIOCtl: bad ioctl cbBuf=%#x _IOC_SIZE=%#x; uCmd=%#x.\n", cbBuf, _IOC_SIZE(uCmd), uCmd));
        return -EINVAL;
    }
    pHdr = RTMemAlloc(cbBuf);
    if (RT_UNLIKELY(!pHdr))
    {
        OSDBGPRINT(("VBoxDrvLinuxIOCtl: failed to allocate buffer of %d bytes for uCmd=%#x.\n", cbBuf, uCmd));
        return -ENOMEM;
    }
    if (RT_UNLIKELY(copy_from_user(pHdr, (void *)ulArg, Hdr.cbIn)))
    {
        Log(("VBoxDrvLinuxIOCtl: copy_from_user(,%#lx, %#x) failed; uCmd=%#x.\n", ulArg, Hdr.cbIn, uCmd));
        RTMemFree(pHdr);
        return -EFAULT;
    }

    /*
     * Process the IOCtl.
     */
    rc = supdrvIOCtl(uCmd, &g_DevExt, (PSUPDRVSESSION)pFilp->private_data, pHdr);

    /*
     * Copy ioctl data and output buffer back to user space.
     */
    if (RT_LIKELY(!rc))
    {
        uint32_t cbOut = pHdr->cbOut;
        if (RT_UNLIKELY(cbOut > cbBuf))
        {
            OSDBGPRINT(("VBoxDrvLinuxIOCtl: too much output! %#x > %#x; uCmd=%#x!\n", cbOut, cbBuf, uCmd));
            cbOut = cbBuf;
        }
        if (RT_UNLIKELY(copy_to_user((void *)ulArg, pHdr, cbOut)))
        {
            /* this is really bad! */
            OSDBGPRINT(("VBoxDrvLinuxIOCtl: copy_to_user(%#lx,,%#x); uCmd=%#x!\n", ulArg, cbOut, uCmd));
            rc = -EFAULT;
        }
    }
    else
    {
        Log(("VBoxDrvLinuxIOCtl: pFilp=%p uCmd=%#x ulArg=%p failed, rc=%d\n", pFilp, uCmd, (void *)ulArg, rc));
        rc = -EINVAL;
    }
    RTMemFree(pHdr);

    Log6(("VBoxDrvLinuxIOCtl: returns %d (pid=%d/%d)\n", rc, RTProcSelf(), current->pid));
    return rc;
}
示例#20
0
/**
 * Device I/O Control entry point.
 *
 * @param   pFilp       Associated file pointer.
 * @param   uCmd        The function specified to ioctl().
 * @param   ulArg       The argument specified to ioctl().
 */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36)
static int VBoxNetAdpLinuxIOCtl(struct inode *pInode, struct file *pFilp,
                                unsigned int uCmd, unsigned long ulArg)
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) */
static long VBoxNetAdpLinuxIOCtlUnlocked(struct file *pFilp,
                                         unsigned int uCmd, unsigned long ulArg)
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) */
{
    VBOXNETADPREQ Req;
    PVBOXNETADP pAdp;
    int rc;
    char *pszName = NULL;

    Log(("VBoxNetAdpLinuxIOCtl: param len %#x; uCmd=%#x; add=%#x\n", _IOC_SIZE(uCmd), uCmd, VBOXNETADP_CTL_ADD));
    if (RT_UNLIKELY(_IOC_SIZE(uCmd) != sizeof(Req))) /* paranoia */
    {
        Log(("VBoxNetAdpLinuxIOCtl: bad ioctl sizeof(Req)=%#x _IOC_SIZE=%#x; uCmd=%#x.\n", sizeof(Req), _IOC_SIZE(uCmd), uCmd));
        return -EINVAL;
    }

    switch (uCmd)
    {
        case VBOXNETADP_CTL_ADD:
            Log(("VBoxNetAdpLinuxIOCtl: _IOC_DIR(uCmd)=%#x; IOC_OUT=%#x\n", _IOC_DIR(uCmd), IOC_OUT));
            if (RT_UNLIKELY(copy_from_user(&Req, (void *)ulArg, sizeof(Req))))
            {
                Log(("VBoxNetAdpLinuxIOCtl: copy_from_user(,%#lx,) failed; uCmd=%#x.\n", ulArg, uCmd));
                return -EFAULT;
            }
            Log(("VBoxNetAdpLinuxIOCtl: Add %s\n", Req.szName));

            if (Req.szName[0])
            {
                pAdp = vboxNetAdpFindByName(Req.szName);
                if (pAdp)
                {
                    Log(("VBoxNetAdpLinuxIOCtl: '%s' already exists\n", Req.szName));
                    return -EINVAL;
                }
                pszName = Req.szName;
            }
            rc = vboxNetAdpCreate(&pAdp, pszName);
            if (RT_FAILURE(rc))
            {
                Log(("VBoxNetAdpLinuxIOCtl: vboxNetAdpCreate -> %Rrc\n", rc));
                return -(rc == VERR_OUT_OF_RESOURCES ? ENOMEM : EINVAL);
            }

            Assert(strlen(pAdp->szName) < sizeof(Req.szName));
            strncpy(Req.szName, pAdp->szName, sizeof(Req.szName) - 1);
            Req.szName[sizeof(Req.szName) - 1] = '\0';

            if (RT_UNLIKELY(copy_to_user((void *)ulArg, &Req, sizeof(Req))))
            {
                /* this is really bad! */
                /** @todo remove the adapter again? */
                printk(KERN_ERR "VBoxNetAdpLinuxIOCtl: copy_to_user(%#lx,,%#zx); uCmd=%#x!\n", ulArg, sizeof(Req), uCmd);
                return -EFAULT;
            }
            Log(("VBoxNetAdpLinuxIOCtl: Successfully added '%s'\n", Req.szName));
            break;

        case VBOXNETADP_CTL_REMOVE:
            if (RT_UNLIKELY(copy_from_user(&Req, (void *)ulArg, sizeof(Req))))
            {
                Log(("VBoxNetAdpLinuxIOCtl: copy_from_user(,%#lx,) failed; uCmd=%#x.\n", ulArg, uCmd));
                return -EFAULT;
            }
            Log(("VBoxNetAdpLinuxIOCtl: Remove %s\n", Req.szName));

            pAdp = vboxNetAdpFindByName(Req.szName);
            if (!pAdp)
            {
                Log(("VBoxNetAdpLinuxIOCtl: '%s' not found\n", Req.szName));
                return -EINVAL;
            }

            rc = vboxNetAdpDestroy(pAdp);
            if (RT_FAILURE(rc))
            {
                Log(("VBoxNetAdpLinuxIOCtl: vboxNetAdpDestroy('%s') -> %Rrc\n", Req.szName, rc));
                return -EINVAL;
            }
            Log(("VBoxNetAdpLinuxIOCtl: Successfully removed '%s'\n", Req.szName));
            break;

        default:
            printk(KERN_ERR "VBoxNetAdpLinuxIOCtl: unknown command %x.\n", uCmd);
            return -EINVAL;
    }

    return 0;
}
示例#21
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);
}
/*@return, 0:operate successfully
/         > 0: the length of memory size ioctl has accessed,
/         error otherwise.*/
static long gt1x_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	u32 value = 0;
	s32 ret = 0;		/*the initial value must be 0*/
	u8 *data = NULL;
	static struct ratelimit_state ratelimit = {
		.lock = __RAW_SPIN_LOCK_UNLOCKED(ratelimit.lock),
		.interval = HZ/2,
		.burst = 1,
		.begin = 1,
	};

	GTP_DEBUG("IOCTL CMD:%x", cmd);
	/*GTP_DEBUG("command:%d, length:%d, rw:%s", _IOC_NR(cmd), _IOC_SIZE(cmd),
		(_IOC_DIR(cmd) & _IOC_READ) ? "read" : (_IOC_DIR(cmd) & _IOC_WRITE) ? "write" : "-");*/

	if (_IOC_DIR(cmd)) {
		s32 err = -1;
		s32 data_length = _IOC_SIZE(cmd);

		data = kzalloc(data_length, GFP_KERNEL);
		memset(data, 0, data_length);

		if (_IOC_DIR(cmd) & _IOC_WRITE) {
			err = copy_from_user(data, (void __user *)arg, data_length);
			if (err) {
				GTP_DEBUG("Can't access the memory.");
				kfree(data);
				return -1;
			}
		}
	} else {
		value = (u32) arg;
	}

	switch (cmd & NEGLECT_SIZE_MASK) {
	case IO_GET_VERSION:
		if ((u8 __user *) arg) {
			ret = copy_to_user(((u8 __user *) arg), IO_VERSION, sizeof(IO_VERSION));
			if (!ret)
				ret = sizeof(IO_VERSION);
			GTP_INFO("%s", IO_VERSION);
		}
		break;
	case IO_IIC_READ:
		if (1 == gt1x_is_tpd_halt()) {
			if (__ratelimit(&ratelimit))
				GTP_ERROR("touch is suspended.");
			break;
		}
		ret = io_iic_read(data, (void __user *)arg);
		break;

	case IO_IIC_WRITE:
		if (1 == gt1x_is_tpd_halt()) {
			if (__ratelimit(&ratelimit))
				GTP_ERROR("touch is suspended.");
			break;
		}
		ret = io_iic_write(data);
		break;

	case IO_RESET_GUITAR:
		gt1x_reset_guitar();
		break;

	case IO_DISABLE_IRQ:
		gt1x_irq_disable();
#ifdef CONFIG_GTP_ESD_PROTECT
		gt1x_esd_switch(SWITCH_OFF);
#endif
		break;

	case IO_ENABLE_IRQ:
		gt1x_irq_enable();
#ifdef CONFIG_GTP_ESD_PROTECT
		gt1x_esd_switch(SWITCH_ON);
#endif
		break;

		/*print a string to syc log messages between application and kernel.*/
	case IO_PRINT:
		if (data)
			GTP_INFO("%s", (char *)data);
		break;

#ifdef CONFIG_GTP_GESTURE_WAKEUP
	case GESTURE_ENABLE_TOTALLY:
		GTP_DEBUG("ENABLE_GESTURE_TOTALLY");
		gesture_enabled = (is_all_dead(gestures_flag, sizeof(gestures_flag)) ? 0 : 1);
		break;

	case GESTURE_DISABLE_TOTALLY:
		GTP_DEBUG("DISABLE_GESTURE_TOTALLY");
		gesture_enabled = 0;
		break;

	case GESTURE_ENABLE_PARTLY:
		SETBIT(gestures_flag, (u8) value);
		gesture_enabled = 1;
		GTP_DEBUG("ENABLE_GESTURE_PARTLY, gesture = 0x%02X, gesture_enabled = %d", value, gesture_enabled);
		break;

	case GESTURE_DISABLE_PARTLY:
		ret = QUERYBIT(gestures_flag, (u8) value);
		if (!ret)
			break;
		CLEARBIT(gestures_flag, (u8) value);
		if (is_all_dead(gestures_flag, sizeof(gestures_flag)))
			gesture_enabled = 0;
		GTP_DEBUG("DISABLE_GESTURE_PARTLY, gesture = 0x%02X, gesture_enabled = %d", value, gesture_enabled);
		break;

	case GESTURE_DATA_OBTAIN:
		GTP_DEBUG("OBTAIN_GESTURE_DATA");

		mutex_lock(&gesture_data_mutex);
		if (gesture_data.data[1] > GESTURE_MAX_POINT_COUNT)
			gesture_data.data[1] = GESTURE_MAX_POINT_COUNT;
		if (gesture_data.data[3] > 80)
			gesture_data.data[3] = 80;
		ret =
		    copy_to_user(((u8 __user *) arg), &gesture_data.data,
				 4 + gesture_data.data[1] * 4 + gesture_data.data[3]);
		mutex_unlock(&gesture_data_mutex);
		if (ret) {
			GTP_ERROR("ERROR when copy gesture data to user.");
			ret = ERROR_MEM;
		} else {
			ret = 4 + gesture_data.data[1] * 4 + gesture_data.data[3];
		}
		break;

	case GESTURE_DATA_ERASE:
		GTP_DEBUG("ERASE_GESTURE_DATA");
		gesture_clear_wakeup_data();
		break;
#endif				/*CONFIG_GTP_GESTURE_WAKEUP*/

#ifdef CONFIG_GTP_HOTKNOT
	case HOTKNOT_LOAD_HOTKNOT:
		ret = hotknot_load_hotknot_subsystem();
		break;

	case HOTKNOT_LOAD_AUTHENTICATION:
		if (1 == gt1x_is_tpd_halt()) {
			GTP_ERROR("touch is suspended.");
			break;
		}
#ifdef CONFIG_GTP_ESD_PROTECT
		gt1x_esd_switch(SWITCH_ON);
#endif
		ret = hotknot_load_authentication_subsystem();
		break;

	case HOTKNOT_RECOVERY_MAIN:
		if (1 == gt1x_is_tpd_halt()) {
			GTP_ERROR("touch is suspended.");
			break;
		}
		ret = hotknot_recovery_main_system();
		break;
#ifdef CONFIG_HOTKNOT_BLOCK_RW
	case HOTKNOT_DEVICES_PAIRED:
		hotknot_paired_flag = 0;
		force_wake_flag = 0;
		block_enable = 1;
		ret = hotknot_block_rw(HN_DEVICE_PAIRED, (s32) value);
		break;

	case HOTKNOT_MASTER_SEND:
		ret = hotknot_block_rw(HN_MASTER_SEND, (s32) value);
		if (!ret)
			ret = got_hotknot_extra_state;
		break;

	case HOTKNOT_SLAVE_RECEIVE:
		ret = hotknot_block_rw(HN_SLAVE_RECEIVED, (s32) value);
		if (!ret)
			ret = got_hotknot_extra_state;
		break;

	case HOTKNOT_MASTER_DEPARTED:
		ret = hotknot_block_rw(HN_MASTER_DEPARTED, (s32) value);
		break;

	case HOTKNOT_SLAVE_DEPARTED:
		ret = hotknot_block_rw(HN_SLAVE_DEPARTED, (s32) value);
		break;

	case HOTKNOT_WAKEUP_BLOCK:
		hotknot_wakeup_block();
		break;
#endif				/*CONFIG_HOTKNOT_BLOCK_RW*/
#endif				/*CONFIG_GTP_HOTKNOT*/

	default:
		GTP_INFO("Unknown cmd.");
		ret = -1;
		break;
	}

	if (data != NULL)
		kfree(data);
	return ret;
}
#ifdef CONFIG_GTP_HOTKNOT
#ifdef CONFIG_COMPAT
static long gt1x_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	long ret;
	void __user *arg32 = NULL;

	GTP_DEBUG("gt1x_compat_ioctl cmd = %x, arg: 0x%lx\n", cmd, arg);
	arg32 = compat_ptr(arg);
	if (!file->f_op || !file->f_op->unlocked_ioctl)
		return -ENOTTY;

	/*GTP_DEBUG("gt1x_compat_ioctl arg: 0x%lx, arg32: 0x%p\n",arg, arg32);*/

	switch (cmd & NEGLECT_SIZE_MASK) {
	case COMPAT_IO_GET_VERSION:
		/*GTP_DEBUG("gt1x_compat_ioctl COMPAT_IO_GET_VERSION\n");*/
		if (arg32 == NULL) {
			GTP_ERROR("invalid argument.");
			return -EINVAL;
		}

		ret = file->f_op->unlocked_ioctl(file, cmd, (unsigned long)arg32);
		break;
	case COMPAT_IO_IIC_READ:
		/*GTP_DEBUG("gt1x_compat_ioctl COMPAT_IO_IIC_READ\n");*/
		if (arg32 == NULL) {
			GTP_ERROR("invalid argument.");
			return -EINVAL;
		}

		ret = file->f_op->unlocked_ioctl(file, cmd, (unsigned long)arg32);
		break;
	case COMPAT_IO_IIC_WRITE:
		/*GTP_DEBUG("gt1x_compat_ioctl COMPAT_IO_IIC_WRITE\n");*/
		if (arg32 == NULL) {
			GTP_ERROR("invalid argument.");
			return -EINVAL;
		}
		ret = file->f_op->unlocked_ioctl(file, cmd, (unsigned long)arg32);
		break;
	case COMPAT_IO_RESET_GUITAR:
		/*GTP_DEBUG("gt1x_compat_ioctl COMPAT_IO_RESET_GUITAR\n");*/
		ret = file->f_op->unlocked_ioctl(file, cmd, (unsigned long)arg32);
		break;
	case COMPAT_IO_DISABLE_IRQ:
		/*GTP_DEBUG("gt1x_compat_ioctl COMPAT_IO_DISABLE_IRQ\n");*/
		ret = file->f_op->unlocked_ioctl(file, cmd, (unsigned long)arg32);
		break;
	case COMPAT_IO_ENABLE_IRQ:
		/*GTP_DEBUG("gt1x_compat_ioctl COMPAT_IO_ENABLE_IRQ\n");*/
		ret = file->f_op->unlocked_ioctl(file, cmd, (unsigned long)arg32);
		break;
	case COMPAT_IO_PRINT:
		/*GTP_DEBUG("gt1x_compat_ioctl COMPAT_IO_PRINT\n");*/
		ret = file->f_op->unlocked_ioctl(file, cmd, (unsigned long)arg32);
		break;
	case COMPAT_GESTURE_ENABLE_TOTALLY:
		/*GTP_DEBUG("gt1x_compat_ioctl COMPAT_GESTURE_ENABLE_TOTALLY\n");*/
		ret = file->f_op->unlocked_ioctl(file, cmd, (unsigned long)arg32);
		break;
	case COMPAT_GESTURE_DISABLE_TOTALLY:
		/*GTP_DEBUG("gt1x_compat_ioctl COMPAT_GESTURE_DISABLE_TOTALLY\n");*/
		ret = file->f_op->unlocked_ioctl(file, cmd, (unsigned long)arg32);
		break;
	case COMPAT_GESTURE_ENABLE_PARTLY:
		/*GTP_DEBUG("gt1x_compat_ioctl COMPAT_GESTURE_ENABLE_PARTLY\n");*/
		ret = file->f_op->unlocked_ioctl(file, cmd, (unsigned long)arg32);
		break;
	case COMPAT_GESTURE_DISABLE_PARTLY:
		/*GTP_DEBUG("gt1x_compat_ioctl COMPAT_GESTURE_DISABLE_PARTLY\n");*/
		ret = file->f_op->unlocked_ioctl(file, cmd, (unsigned long)arg32);
		break;
	case COMPAT_GESTURE_DATA_OBTAIN:
		if (arg32 == NULL) {
			GTP_ERROR("invalid argument.");
			return -EINVAL;
		}
		/*GTP_DEBUG("gt1x_compat_ioctl COMPAT_GESTURE_DATA_OBTAIN\n");*/
		ret = file->f_op->unlocked_ioctl(file, cmd, (unsigned long)arg32);
		break;
	case COMPAT_GESTURE_DATA_ERASE:
		/*GTP_DEBUG("gt1x_compat_ioctl COMPAT_GESTURE_DATA_ERASE\n");*/
		ret = file->f_op->unlocked_ioctl(file, cmd, (unsigned long)arg32);
		break;
	case COMPAT_HOTKNOT_LOAD_HOTKNOT:
		/*GTP_DEBUG("gt1x_compat_ioctl COMPAT_HOTKNOT_LOAD_HOTKNOT\n");*/
		ret = file->f_op->unlocked_ioctl(file, cmd, (unsigned long)arg32);
		break;
	case COMPAT_HOTKNOT_LOAD_AUTHENTICATION:
		/*GTP_DEBUG("gt1x_compat_ioctl COMPAT_HOTKNOT_LOAD_AUTHENTICATION\n");*/
		ret = file->f_op->unlocked_ioctl(file, cmd, (unsigned long)arg32);
		break;
	case COMPAT_HOTKNOT_RECOVERY_MAIN:
		/*GTP_DEBUG("gt1x_compat_ioctl COMPAT_HOTKNOT_RECOVERY_MAIN\n");*/
		ret = file->f_op->unlocked_ioctl(file, cmd, (unsigned long)arg32);
		break;
	case COMPAT_HOTKNOT_DEVICES_PAIRED:
		/*GTP_DEBUG("gt1x_compat_ioctl COMPAT_HOTKNOT_DEVICES_PAIRED\n");*/
		ret = file->f_op->unlocked_ioctl(file, cmd, (unsigned long)arg32);
		break;
	case COMPAT_HOTKNOT_MASTER_SEND:
		/*GTP_DEBUG("gt1x_compat_ioctl COMPAT_HOTKNOT_MASTER_SEND\n");*/
		ret = file->f_op->unlocked_ioctl(file, cmd, (unsigned long)arg32);
		break;
	case COMPAT_HOTKNOT_SLAVE_RECEIVE:
		/*GTP_DEBUG("gt1x_compat_ioctl COMPAT_HOTKNOT_SLAVE_RECEIVE\n");*/
		ret = file->f_op->unlocked_ioctl(file, cmd, (unsigned long)arg32);
		break;
	case COMPAT_HOTKNOT_MASTER_DEPARTED:
		/*GTP_DEBUG("gt1x_compat_ioctl COMPAT_HOTKNOT_MASTER_DEPARTED\n");*/
		ret = file->f_op->unlocked_ioctl(file, cmd, (unsigned long)arg32);
		break;
	case COMPAT_HOTKNOT_SLAVE_DEPARTED:
		/*GTP_DEBUG("gt1x_compat_ioctl COMPAT_HOTKNOT_SLAVE_DEPARTED\n");*/
		ret = file->f_op->unlocked_ioctl(file, cmd, (unsigned long)arg32);
		break;
	case COMPAT_HOTKNOT_WAKEUP_BLOCK:
		/*GTP_DEBUG("gt1x_compat_ioctl COMPAT_HOTKNOT_WAKEUP_BLOCK\n");*/
		ret = file->f_op->unlocked_ioctl(file, cmd, (unsigned long)arg32);
		break;
	default:
		GTP_INFO("Unknown cmd.");
		ret = -1;
		break;
	}
	return ret;
}
示例#23
0
static long kfd_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
{
	struct kfd_process *process;
	amdkfd_ioctl_t *func;
	const struct amdkfd_ioctl_desc *ioctl = NULL;
	unsigned int nr = _IOC_NR(cmd);
	char stack_kdata[128];
	char *kdata = NULL;
	unsigned int usize, asize;
	int retcode = -EINVAL;

	if (nr >= AMDKFD_CORE_IOCTL_COUNT)
		goto err_i1;

	if ((nr >= AMDKFD_COMMAND_START) && (nr < AMDKFD_COMMAND_END)) {
		u32 amdkfd_size;

		ioctl = &amdkfd_ioctls[nr];

		amdkfd_size = _IOC_SIZE(ioctl->cmd);
		usize = asize = _IOC_SIZE(cmd);
		if (amdkfd_size > asize)
			asize = amdkfd_size;

		cmd = ioctl->cmd;
	} else
		goto err_i1;

	dev_dbg(kfd_device, "ioctl cmd 0x%x (#%d), arg 0x%lx\n", cmd, nr, arg);

	process = kfd_get_process(current);
	if (IS_ERR(process)) {
		dev_dbg(kfd_device, "no process\n");
		goto err_i1;
	}

	/* Do not trust userspace, use our own definition */
	func = ioctl->func;

	if (unlikely(!func)) {
		dev_dbg(kfd_device, "no function\n");
		retcode = -EINVAL;
		goto err_i1;
	}

	if (cmd & (IOC_IN | IOC_OUT)) {
		if (asize <= sizeof(stack_kdata)) {
			kdata = stack_kdata;
		} else {
			kdata = kmalloc(asize, GFP_KERNEL);
			if (!kdata) {
				retcode = -ENOMEM;
				goto err_i1;
			}
		}
		if (asize > usize)
			memset(kdata + usize, 0, asize - usize);
	}

	if (cmd & IOC_IN) {
		if (copy_from_user(kdata, (void __user *)arg, usize) != 0) {
			retcode = -EFAULT;
			goto err_i1;
		}
	} else if (cmd & IOC_OUT) {
		memset(kdata, 0, usize);
	}

	retcode = func(filep, process, kdata);

	if (cmd & IOC_OUT)
		if (copy_to_user((void __user *)arg, kdata, usize) != 0)
			retcode = -EFAULT;

err_i1:
	if (!ioctl)
		dev_dbg(kfd_device, "invalid ioctl: pid=%d, cmd=0x%02x, nr=0x%02x\n",
			  task_pid_nr(current), cmd, nr);

	if (kdata != stack_kdata)
		kfree(kdata);

	if (retcode)
		dev_dbg(kfd_device, "ret = %d\n", retcode);

	return retcode;
}
static int vgdrvLinuxIOCtl(struct inode *pInode, struct file *pFilp, unsigned int uCmd, unsigned long ulArg)
#endif
{
    PVBOXGUESTSESSION   pSession = (PVBOXGUESTSESSION)pFilp->private_data;
    uint32_t            cbData   = _IOC_SIZE(uCmd);
    void               *pvBufFree;
    void               *pvBuf;
    int                 rc;
    uint64_t            au64Buf[32/sizeof(uint64_t)];

    Log6(("vgdrvLinuxIOCtl: pFilp=%p uCmd=%#x ulArg=%p pid=%d/%d\n", pFilp, uCmd, (void *)ulArg, RTProcSelf(), current->pid));

    /*
     * Buffer the request.
     */
    if (cbData <= sizeof(au64Buf))
    {
        pvBufFree = NULL;
        pvBuf = &au64Buf[0];
    }
    else
    {
        pvBufFree = pvBuf = RTMemTmpAlloc(cbData);
        if (RT_UNLIKELY(!pvBuf))
        {
            LogRel((DEVICE_NAME "::IOCtl: RTMemTmpAlloc failed to alloc %u bytes.\n", cbData));
            return -ENOMEM;
        }
    }
    if (RT_LIKELY(copy_from_user(pvBuf, (void *)ulArg, cbData) == 0))
    {
        /*
         * Process the IOCtl.
         */
        size_t cbDataReturned;
        rc = VGDrvCommonIoCtl(uCmd, &g_DevExt, pSession, pvBuf, cbData, &cbDataReturned);

        /*
         * Copy ioctl data and output buffer back to user space.
         */
        if (RT_SUCCESS(rc))
        {
            rc = 0;
            if (RT_UNLIKELY(cbDataReturned > cbData))
            {
                LogRel((DEVICE_NAME "::IOCtl: too much output data %u expected %u\n", cbDataReturned, cbData));
                cbDataReturned = cbData;
            }
            if (cbDataReturned > 0)
            {
                if (RT_UNLIKELY(copy_to_user((void *)ulArg, pvBuf, cbDataReturned) != 0))
                {
                    LogRel((DEVICE_NAME "::IOCtl: copy_to_user failed; pvBuf=%p ulArg=%p cbDataReturned=%u uCmd=%d\n",
                            pvBuf, (void *)ulArg, cbDataReturned, uCmd, rc));
                    rc = -EFAULT;
                }
            }
        }
        else
        {
            Log(("vgdrvLinuxIOCtl: pFilp=%p uCmd=%#x ulArg=%p failed, rc=%d\n", pFilp, uCmd, (void *)ulArg, rc));
            rc = -rc; Assert(rc > 0); /* Positive returns == negated VBox error status codes. */
        }
    }
    else
    {
        Log((DEVICE_NAME "::IOCtl: copy_from_user(,%#lx, %#x) failed; uCmd=%#x.\n", ulArg, cbData, uCmd));
        rc = -EFAULT;
    }
    if (pvBufFree)
        RTMemFree(pvBufFree);

    Log6(("vgdrvLinuxIOCtl: returns %d (pid=%d/%d)\n", rc, RTProcSelf(), current->pid));
    return rc;
}
示例#25
0
static inline long
mycdrv_unlocked_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
{
	int i, rc, direction;
	int size;
	char *buffer;
	void __user *ioargp = (void __user *)arg;

	/* make sure it is a valid command */

	if (_IOC_TYPE(cmd) != MYIOC_TYPE) {
		printk(KERN_WARNING " got invalid case, CMD=%d\n", cmd);
		return -EINVAL;
	}

	/* get the size of the buffer and kmalloc it */

	size = _IOC_SIZE(cmd);
	buffer = kmalloc((size_t) size, GFP_KERNEL);
	if (!buffer) {
		printk(KERN_ERR "Kmalloc failed for buffer\n");
		return -ENOMEM;
	}

	/* fill it with X */

	memset(buffer, 'X', size);

	direction = _IOC_DIR(cmd);

	switch (direction) {

	case _IOC_WRITE:
		printk
		    (KERN_INFO
		     " reading = %d bytes from user-space and writing to device\n",
		     size);
		rc = copy_from_user(buffer, ioargp, size);
		printk(KERN_INFO "rc from copy_from_user = %d\n", rc);
		break;

	case _IOC_READ:
		printk(KERN_INFO
		       " reading device and writing = %d bytes to user-space\n",
		       size);
		rc = copy_to_user(ioargp, buffer, size);
		printk(KERN_INFO "rc from copy_to_user = %d\n", rc);
		break;

	default:
		printk(KERN_WARNING " got invalid case, CMD=%d\n", cmd);
		return -EINVAL;
	}
	for (i = 0; i < size; i++)
		printk(KERN_INFO "%c", buffer[i]);
	printk(KERN_INFO "\n");

	if (buffer)
		kfree(buffer);
	return rc;
}
示例#26
0
文件: vmwgfx_drv.c 项目: 020gzh/linux
static long vmw_generic_ioctl(struct file *filp, unsigned int cmd,
			      unsigned long arg,
			      long (*ioctl_func)(struct file *, unsigned int,
						 unsigned long))
{
	struct drm_file *file_priv = filp->private_data;
	struct drm_device *dev = file_priv->minor->dev;
	unsigned int nr = DRM_IOCTL_NR(cmd);
	struct vmw_master *vmaster;
	unsigned int flags;
	long ret;

	/*
	 * Do extra checking on driver private ioctls.
	 */

	if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END)
	    && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) {
		const struct drm_ioctl_desc *ioctl =
			&vmw_ioctls[nr - DRM_COMMAND_BASE];

		if (nr == DRM_COMMAND_BASE + DRM_VMW_EXECBUF) {
			ret = (long) drm_ioctl_permit(ioctl->flags, file_priv);
			if (unlikely(ret != 0))
				return ret;

			if (unlikely((cmd & (IOC_IN | IOC_OUT)) != IOC_IN))
				goto out_io_encoding;

			return (long) vmw_execbuf_ioctl(dev, arg, file_priv,
							_IOC_SIZE(cmd));
		}

		if (unlikely(ioctl->cmd != cmd))
			goto out_io_encoding;

		flags = ioctl->flags;
	} else if (!drm_ioctl_flags(nr, &flags))
		return -EINVAL;

	vmaster = vmw_master_check(dev, file_priv, flags);
	if (IS_ERR(vmaster)) {
		ret = PTR_ERR(vmaster);

		if (ret != -ERESTARTSYS)
			DRM_INFO("IOCTL ERROR Command %d, Error %ld.\n",
				 nr, ret);
		return ret;
	}

	ret = ioctl_func(filp, cmd, arg);
	if (vmaster)
		ttm_read_unlock(&vmaster->lock);

	return ret;

out_io_encoding:
	DRM_ERROR("Invalid command format, ioctl %d\n",
		  nr - DRM_COMMAND_BASE);

	return -EINVAL;
}
示例#27
0
文件: main.c 项目: outingwei/test_pro
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;

}
示例#28
0
long scull_ioctl(struct file* filp, unsigned	int cmd, unsigned long arg)
{
	int err = 1, tmp;
	int retval = 0;
	
#ifdef __DEBUG_INFO
	printk(KERN_ALERT "In scull_ioctl, the cmd is %i\n", cmd);
#endif

	if(_IOC_TYPE(cmd)  != SCULL_IOC_MAGIK)
	{	
		printk(KERN_ALERT "ERROR 1\n");
		return -ENOTTY;
	}
		

	if(_IOC_NR(cmd) > SCULL_IOC_MAXNR)
	{	
		printk(KERN_ALERT "ERROR 2\n");
		return -ENOTTY;
	}
	
	if(_IOC_DIR(cmd) & _IOC_READ)
		err = access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
	else if(_IOC_DIR(cmd) & _IOC_WRITE)
		err = access_ok(VIRIFY_WRITE, (void __user*)arg, _IOC_SIZE(cmd));

	if(!err)
	{	
		printk(KERN_ALERT "ERROR 3\n");
		return -EFAULT;
	}

	switch(cmd)
	{
		case SCULL_IOCRESET:
			scull_quantum = 1000;
			scull_qset = 4;
			break;
			
		case SCULL_IOCSQUANTUM:
			if(!capable(CAP_SYS_ADMIN))
				return -EPERM;
			retval = __get_user(scull_quantum, (int __user*)arg);
			break;
			
		case SCULL_IOCSQSET:
			if(!capable(CAP_SYS_ADMIN))
				return -EPERM;
			retval = __get_user(scull_qset, (int __user*)arg);
			break;
			
		case SCULL_IOCTQUANTUM:
			if(!capable(CAP_SYS_ADMIN))
				return -EPERM;
			scull_quantum = arg;
			break;
			
		case SCULL_IOCGQUANTUM:
			if(!capable(CAP_SYS_ADMIN))
				return -EPERM;
			retval = __put_user(scull_quantum, (int __user*)arg);
			break;
			
		case SCULL_IOCQQUANTUM:
		//	if(!capable(CAP_SYS_ADMIN))
			//	return -EPERM;
			printk("In SCULL_IOCQQUANTUM, %d\n", scull_quantum);
			return scull_quantum;
			
		case SCULL_IOCXQUANTUM:
			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:
			if(!capable(CAP_SYS_ADMIN))
				return -EPERM;
			tmp = scull_quantum;
			scull_quantum = arg;
			return tmp;

		default:
			return -ENOTTY;
	}

	return retval;
}
示例#29
0
static long tpd_unlocked_ioctl(struct file *file, unsigned int cmd,
                               unsigned long arg)
{
    //char strbuf[256];
    void __user *data;

    long err = 0;

    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("tpd: access error: %08X, (%2d, %2d)\n", cmd, _IOC_DIR(cmd), _IOC_SIZE(cmd));
        return -EFAULT;
    }

    switch (cmd)
    {
        case TPD_GET_VELOCITY_CUSTOM_X:
            data = (void __user *) arg;

            if (data == NULL)
            {
                err = -EINVAL;
                break;
            }

            if (copy_to_user(data, &tpd_v_magnify_x, sizeof(tpd_v_magnify_x)))
            {
                err = -EFAULT;
                break;
            }

            break;

        case TPD_GET_VELOCITY_CUSTOM_Y:
            data = (void __user *) arg;

            if (data == NULL)
            {
                err = -EINVAL;
                break;
            }

            if (copy_to_user(data, &tpd_v_magnify_y, sizeof(tpd_v_magnify_y)))
            {
                err = -EFAULT;
                break;
            }

            break;

        default:
            printk("tpd: unknown IOCTL: 0x%08x\n", cmd);
            err = -ENOIOCTLCMD;
            break;

    }

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