static long pps_cdev_compat_ioctl()

in pps.c [249:294]


static long pps_cdev_compat_ioctl(struct file *file,
		unsigned int cmd, unsigned long arg)
{
	struct pps_device *pps = file->private_data;
	void __user *uarg = (void __user *) arg;

	cmd = _IOC(_IOC_DIR(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd), sizeof(void *));

	if (cmd == PPS_FETCH) {
		struct pps_fdata_compat compat;
		struct pps_fdata fdata;
		int err;

		dev_dbg(pps->dev, "PPS_FETCH\n");

		err = copy_from_user(&compat, uarg, sizeof(struct pps_fdata_compat));
		if (err)
			return -EFAULT;

		memcpy(&fdata.timeout, &compat.timeout,
					sizeof(struct pps_ktime_compat));

		err = pps_cdev_pps_fetch(pps, &fdata);
		if (err)
			return err;

		/* Return the fetched timestamp */
		spin_lock_irq(&pps->lock);

		compat.info.assert_sequence = pps->assert_sequence;
		compat.info.clear_sequence = pps->clear_sequence;
		compat.info.current_mode = pps->current_mode;

		memcpy(&compat.info.assert_tu, &pps->assert_tu,
				sizeof(struct pps_ktime_compat));
		memcpy(&compat.info.clear_tu, &pps->clear_tu,
				sizeof(struct pps_ktime_compat));

		spin_unlock_irq(&pps->lock);

		return copy_to_user(uarg, &compat,
				sizeof(struct pps_fdata_compat)) ? -EFAULT : 0;
	}

	return pps_cdev_ioctl(file, cmd, arg);
}