media: rc: clean up leader pulse/space for manchester encoding
authorSean Young <sean@mess.org>
Fri, 5 Jan 2018 13:26:51 +0000 (08:26 -0500)
committerMauro Carvalho Chehab <mchehab@s-opensource.com>
Tue, 23 Jan 2018 12:26:50 +0000 (07:26 -0500)
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: Sean Young <sean@mess.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
drivers/media/rc/ir-mce_kbd-decoder.c
drivers/media/rc/ir-rc5-decoder.c
drivers/media/rc/ir-rc6-decoder.c
drivers/media/rc/rc-core-priv.h
drivers/media/rc/rc-ir-raw.c

index 8cf4cf358052ad0777a6341f38567b4ecd2e869e..2a279b3b9c0aff9d427d5246a48a323188f9b96c 100644 (file)
@@ -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,
index f589d99245eb7522b52494749cd92565247ec6fb..a1d6c955ffc8e77f3ef15ebd5872bdeac645c4b0 100644 (file)
@@ -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,
 };
index 665025303c281c96ae78750ca8826e73f1195d29..422dec08738cbe2094b9856404ce8c7853a7944f 100644 (file)
@@ -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)
index 3c3d2620f0e826daa58f3a055a92fc2fc8d3356c..458e9eb2d6a96282e604810b1d9fbbce8470ae12 100644 (file)
@@ -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;
index 3dabb783a1f0ff418703a4e3605096cf1a74120a..8500b57923c09a44df69c4332ab6b2effb0f2744 100644 (file)
@@ -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 {