Commit ddf9c1bb authored by Sean Young's avatar Sean Young Committed by Mauro Carvalho Chehab
Browse files

media: rc: clean up leader pulse/space for manchester encoding



The IR rc6 encoder sends the header using manchester encoding using 0
bits, which causes the following:

UBSAN: Undefined behaviour in drivers/media/rc/rc-ir-raw.c:247:6
shift exponent 4294967295 is too large for 64-bit type 'long long unsigned int'

So, allow the leader code to send a pulse and space and remove the unused
pulse_space_start field.

Cc: Antti Seppälä <a.seppala@gmail.com>
Signed-off-by: default avatarSean Young <sean@mess.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent e3cd9734
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -424,7 +424,7 @@ static int ir_mce_kbd_unregister(struct rc_dev *dev)
}

static const struct ir_raw_timings_manchester ir_mce_kbd_timings = {
	.leader		= MCIR2_PREFIX_PULSE,
	.leader_pulse	= MCIR2_PREFIX_PULSE,
	.invert		= 1,
	.clock		= MCIR2_UNIT,
	.trailer_space	= MCIR2_UNIT * 10,
+3 −6
Original line number Diff line number Diff line
@@ -173,16 +173,14 @@ out:
}

static const struct ir_raw_timings_manchester ir_rc5_timings = {
	.leader			= RC5_UNIT,
	.pulse_space_start	= 0,
	.leader_pulse		= RC5_UNIT,
	.clock			= RC5_UNIT,
	.trailer_space		= RC5_UNIT * 10,
};

static const struct ir_raw_timings_manchester ir_rc5x_timings[2] = {
	{
		.leader			= RC5_UNIT,
		.pulse_space_start	= 0,
		.leader_pulse		= RC5_UNIT,
		.clock			= RC5_UNIT,
		.trailer_space		= RC5X_SPACE,
	},
@@ -193,8 +191,7 @@ static const struct ir_raw_timings_manchester ir_rc5x_timings[2] = {
};

static const struct ir_raw_timings_manchester ir_rc5_sz_timings = {
	.leader				= RC5_UNIT,
	.pulse_space_start		= 0,
	.leader_pulse			= RC5_UNIT,
	.clock				= RC5_UNIT,
	.trailer_space			= RC5_UNIT * 10,
};
+10 −25
Original line number Diff line number Diff line
@@ -288,13 +288,8 @@ out:

static const struct ir_raw_timings_manchester ir_rc6_timings[4] = {
	{
		.leader			= RC6_PREFIX_PULSE,
		.pulse_space_start	= 0,
		.clock			= RC6_UNIT,
		.invert			= 1,
		.trailer_space		= RC6_PREFIX_SPACE,
	},
	{
		.leader_pulse		= RC6_PREFIX_PULSE,
		.leader_space		= RC6_PREFIX_SPACE,
		.clock			= RC6_UNIT,
		.invert			= 1,
	},
@@ -329,27 +324,22 @@ static int ir_rc6_encode(enum rc_proto protocol, u32 scancode,
	struct ir_raw_event *e = events;

	if (protocol == RC_PROTO_RC6_0) {
		/* Modulate the preamble */
		ret = ir_raw_gen_manchester(&e, max, &ir_rc6_timings[0], 0, 0);
		if (ret < 0)
			return ret;

		/* Modulate the header (Start Bit & Mode-0) */
		ret = ir_raw_gen_manchester(&e, max - (e - events),
					    &ir_rc6_timings[1],
					    RC6_HEADER_NBITS, (1 << 3));
					    &ir_rc6_timings[0],
					    RC6_HEADER_NBITS + 1, (1 << 3));
		if (ret < 0)
			return ret;

		/* Modulate Trailer Bit */
		ret = ir_raw_gen_manchester(&e, max - (e - events),
					    &ir_rc6_timings[2], 1, 0);
					    &ir_rc6_timings[1], 1, 0);
		if (ret < 0)
			return ret;

		/* Modulate rest of the data */
		ret = ir_raw_gen_manchester(&e, max - (e - events),
					    &ir_rc6_timings[3], RC6_0_NBITS,
					    &ir_rc6_timings[2], RC6_0_NBITS,
					    scancode);
		if (ret < 0)
			return ret;
@@ -372,27 +362,22 @@ static int ir_rc6_encode(enum rc_proto protocol, u32 scancode,
			return -EINVAL;
		}

		/* Modulate the preamble */
		ret = ir_raw_gen_manchester(&e, max, &ir_rc6_timings[0], 0, 0);
		if (ret < 0)
			return ret;

		/* Modulate the header (Start Bit & Header-version 6 */
		ret = ir_raw_gen_manchester(&e, max - (e - events),
					    &ir_rc6_timings[1],
					    RC6_HEADER_NBITS, (1 << 3 | 6));
					    &ir_rc6_timings[0],
					    RC6_HEADER_NBITS + 1, (1 << 3 | 6));
		if (ret < 0)
			return ret;

		/* Modulate Trailer Bit */
		ret = ir_raw_gen_manchester(&e, max - (e - events),
					    &ir_rc6_timings[2], 1, 0);
					    &ir_rc6_timings[1], 1, 0);
		if (ret < 0)
			return ret;

		/* Modulate rest of the data */
		ret = ir_raw_gen_manchester(&e, max - (e - events),
					    &ir_rc6_timings[3],
					    &ir_rc6_timings[2],
					    bits,
					    scancode);
		if (ret < 0)
+5 −5
Original line number Diff line number Diff line
@@ -166,17 +166,17 @@ static inline void init_ir_raw_event_duration(struct ir_raw_event *ev,

/**
 * struct ir_raw_timings_manchester - Manchester coding timings
 * @leader:		duration of leader pulse (if any) 0 if continuing
 *			existing signal (see @pulse_space_start)
 * @pulse_space_start:	1 for starting with pulse (0 for starting with space)
 * @leader_pulse:	duration of leader pulse (if any) 0 if continuing
 *			existing signal
 * @leader_space:	duration of leader space (if any)
 * @clock:		duration of each pulse/space in ns
 * @invert:		if set clock logic is inverted
 *			(0 = space + pulse, 1 = pulse + space)
 * @trailer_space:	duration of trailer space in ns
 */
struct ir_raw_timings_manchester {
	unsigned int leader;
	unsigned int pulse_space_start:1;
	unsigned int leader_pulse;
	unsigned int leader_space;
	unsigned int clock;
	unsigned int invert:1;
	unsigned int trailer_space;
+5 −7
Original line number Diff line number Diff line
@@ -246,17 +246,15 @@ int ir_raw_gen_manchester(struct ir_raw_event **ev, unsigned int max,

	i = BIT_ULL(n - 1);

	if (timings->leader) {
	if (timings->leader_pulse) {
		if (!max--)
			return ret;
		if (timings->pulse_space_start) {
			init_ir_raw_event_duration((*ev)++, 1, timings->leader);

		init_ir_raw_event_duration((*ev), 1, timings->leader_pulse);
		if (timings->leader_space) {
			if (!max--)
				return ret;
			init_ir_raw_event_duration((*ev), 0, timings->leader);
		} else {
			init_ir_raw_event_duration((*ev), 1, timings->leader);
			init_ir_raw_event_duration(++(*ev), 0,
						   timings->leader_space);
		}
		i >>= 1;
	} else {