Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit be1f985f authored by Jarod Wilson's avatar Jarod Wilson Committed by Mauro Carvalho Chehab
Browse files

[media] IR/lirc: further ioctl portability fixups



>From Joris van Rantwijk <jorispubl@xs4all.nl>:

	I tested lirc_serial and found that it works fine.
	Except the LIRC ioctls do not work in my 64-bit-kernel/32-bit-user
	setup. I added compat_ioctl entries in the drivers to fix this.

	While doing so, I noticed inconsistencies in the argument type of
	the LIRC ioctls. All ioctls are declared in lirc.h as having argument
	type __u32, however there are a few places where the driver calls
	get_user/put_user with an unsigned long argument.

	The patch below changes lirc_dev and lirc_serial to use __u32 for all
	ioctl arguments, and adds compat_ioctl entries.
	It should probably also be done in the other low-level drivers,
	but I don't have hardware to test those.

I've dropped the .compat_ioctl addition from Joris' original patch,
as I swear the non-compat definition should now work for both 32-bit
and 64-bit userspace. Technically, I think we still need/want a
in getting a reply to you).

Reported-by: default avatarJoris van Rantwijk <jorispubl@xs4all.nl>
Signed-off-by: default avatarJarod Wilson <jarod@redhat.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent d322bf4a
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -102,7 +102,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
	struct ir_input_dev *ir_dev;
	int ret = 0;
	void *drv_data;
	unsigned long val = 0;
	__u32 val = 0;

	lirc = lirc_get_pdata(filep);
	if (!lirc)
@@ -115,7 +115,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
	drv_data = ir_dev->props->priv;

	if (_IOC_DIR(cmd) & _IOC_WRITE) {
		ret = get_user(val, (unsigned long *)arg);
		ret = get_user(val, (__u32 *)arg);
		if (ret)
			return ret;
	}
@@ -135,14 +135,14 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
	/* TX settings */
	case LIRC_SET_TRANSMITTER_MASK:
		if (ir_dev->props->s_tx_mask)
			ret = ir_dev->props->s_tx_mask(drv_data, (u32)val);
			ret = ir_dev->props->s_tx_mask(drv_data, val);
		else
			return -EINVAL;
		break;

	case LIRC_SET_SEND_CARRIER:
		if (ir_dev->props->s_tx_carrier)
			ir_dev->props->s_tx_carrier(drv_data, (u32)val);
			ir_dev->props->s_tx_carrier(drv_data, val);
		else
			return -EINVAL;
		break;
@@ -212,7 +212,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
	}

	if (_IOC_DIR(cmd) & _IOC_READ)
		ret = put_user(val, (unsigned long *)arg);
		ret = put_user(val, (__u32 *)arg);

	return ret;
}
+7 −7
Original line number Diff line number Diff line
@@ -524,7 +524,7 @@ EXPORT_SYMBOL(lirc_dev_fop_poll);

long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	unsigned long mode;
	__u32 mode;
	int result = 0;
	struct irctl *ir = file->private_data;

@@ -541,7 +541,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)

	switch (cmd) {
	case LIRC_GET_FEATURES:
		result = put_user(ir->d.features, (unsigned long *)arg);
		result = put_user(ir->d.features, (__u32 *)arg);
		break;
	case LIRC_GET_REC_MODE:
		if (!(ir->d.features & LIRC_CAN_REC_MASK)) {
@@ -551,7 +551,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)

		result = put_user(LIRC_REC2MODE
				  (ir->d.features & LIRC_CAN_REC_MASK),
				  (unsigned long *)arg);
				  (__u32 *)arg);
		break;
	case LIRC_SET_REC_MODE:
		if (!(ir->d.features & LIRC_CAN_REC_MASK)) {
@@ -559,7 +559,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
			break;
		}

		result = get_user(mode, (unsigned long *)arg);
		result = get_user(mode, (__u32 *)arg);
		if (!result && !(LIRC_MODE2REC(mode) & ir->d.features))
			result = -EINVAL;
		/*
@@ -568,7 +568,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
		 */
		break;
	case LIRC_GET_LENGTH:
		result = put_user(ir->d.code_length, (unsigned long *)arg);
		result = put_user(ir->d.code_length, (__u32 *)arg);
		break;
	case LIRC_GET_MIN_TIMEOUT:
		if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) ||
@@ -577,7 +577,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
			break;
		}

		result = put_user(ir->d.min_timeout, (unsigned long *)arg);
		result = put_user(ir->d.min_timeout, (__u32 *)arg);
		break;
	case LIRC_GET_MAX_TIMEOUT:
		if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) ||
@@ -586,7 +586,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
			break;
		}

		result = put_user(ir->d.max_timeout, (unsigned long *)arg);
		result = put_user(ir->d.max_timeout, (__u32 *)arg);
		break;
	default:
		result = -EINVAL;
+2 −2
Original line number Diff line number Diff line
@@ -125,10 +125,10 @@ static inline unsigned int lirc_buffer_write(struct lirc_buffer *buf,
struct lirc_driver {
	char name[40];
	int minor;
	unsigned long code_length;
	__u32 code_length;
	unsigned int buffer_size; /* in chunks holding one code each */
	int sample_rate;
	unsigned long features;
	__u32 features;

	unsigned int chunk_size;