Re: [PATCH v2] [media] rc: call input_sync after scancode reports

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Jun 23, 2011 at 05:13:24PM -0400, Jarod Wilson wrote:
> Due to commit cdda911c34006f1089f3c87b1a1f31ab3a4722f2, evdev only
> becomes readable when the buffer contains an EV_SYN/SYN_REPORT event. If
> we get a repeat or a scancode we don't have a mapping for, we never call
> input_sync, and thus those events don't get reported in a timely
> fashion.
> 
> For example, take an mceusb transceiver with a default rc6 keymap. Press
> buttons on an rc5 remote while monitoring with ir-keytable, and you'll
> see nothing. Now press a button on the rc6 remote matching the keymap.
> You'll suddenly get the rc5 key scancodes, the rc6 scancode and the rc6
> key spit out all at the same time.
> 
> Pressing and holding a button on a remote we do have a keymap for also
> works rather unreliably right now, due to repeat events also happening
> without a call to input_sync (we bail from ir_do_keydown before getting
> to the point where it calls input_sync).
> 
> Easy fix though, just add two strategically placed input_sync calls
> right after our input_event calls for EV_MSC, and all is well again.
> Technically, we probably should have been doing this all along, its just
> that it never caused any functional difference until the referenced
> change went into the input layer.
> 
> v2: rework code a bit, per Dmitry's example, so that we only call
> input_sync once per IR signal. There was another hidden bug in the code
> where we were calling input_report_key using last_keycode instead of our
> just discovered keycode, which manifested with the reordering of calling
> input_report_key and setting last_keycode.
> 
> Reported-by: Stephan Raue <sraue@xxxxxxxxxxx>
> CC: Stephan Raue <sraue@xxxxxxxxxxx>
> CC: Mauro Carvalho Chehab <mchehab@xxxxxxxxxx>
> CC: Jeff Brown <jeffbrown@xxxxxxxxxxx>
> CC: Dmitry Torokhov <dtor@xxxxxxx>
> Signed-off-by: Jarod Wilson <jarod@xxxxxxxxxx>

Acked-by: Dmitry Torokhov <dtor@xxxxxxx>

> ---
>  drivers/media/rc/rc-main.c |   48 ++++++++++++++++++++++---------------------
>  1 files changed, 25 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
> index f57cd56..3186ac7 100644
> --- a/drivers/media/rc/rc-main.c
> +++ b/drivers/media/rc/rc-main.c
> @@ -522,18 +522,20 @@ EXPORT_SYMBOL_GPL(rc_g_keycode_from_table);
>  /**
>   * ir_do_keyup() - internal function to signal the release of a keypress
>   * @dev:	the struct rc_dev descriptor of the device
> + * @sync:	whether or not to call input_sync
>   *
>   * This function is used internally to release a keypress, it must be
>   * called with keylock held.
>   */
> -static void ir_do_keyup(struct rc_dev *dev)
> +static void ir_do_keyup(struct rc_dev *dev, bool sync)
>  {
>  	if (!dev->keypressed)
>  		return;
>  
>  	IR_dprintk(1, "keyup key 0x%04x\n", dev->last_keycode);
>  	input_report_key(dev->input_dev, dev->last_keycode, 0);
> -	input_sync(dev->input_dev);
> +	if (sync)
> +		input_sync(dev->input_dev);
>  	dev->keypressed = false;
>  }
>  
> @@ -549,7 +551,7 @@ void rc_keyup(struct rc_dev *dev)
>  	unsigned long flags;
>  
>  	spin_lock_irqsave(&dev->keylock, flags);
> -	ir_do_keyup(dev);
> +	ir_do_keyup(dev, true);
>  	spin_unlock_irqrestore(&dev->keylock, flags);
>  }
>  EXPORT_SYMBOL_GPL(rc_keyup);
> @@ -578,7 +580,7 @@ static void ir_timer_keyup(unsigned long cookie)
>  	 */
>  	spin_lock_irqsave(&dev->keylock, flags);
>  	if (time_is_before_eq_jiffies(dev->keyup_jiffies))
> -		ir_do_keyup(dev);
> +		ir_do_keyup(dev, true);
>  	spin_unlock_irqrestore(&dev->keylock, flags);
>  }
>  
> @@ -597,6 +599,7 @@ void rc_repeat(struct rc_dev *dev)
>  	spin_lock_irqsave(&dev->keylock, flags);
>  
>  	input_event(dev->input_dev, EV_MSC, MSC_SCAN, dev->last_scancode);
> +	input_sync(dev->input_dev);
>  
>  	if (!dev->keypressed)
>  		goto out;
> @@ -622,29 +625,28 @@ EXPORT_SYMBOL_GPL(rc_repeat);
>  static void ir_do_keydown(struct rc_dev *dev, int scancode,
>  			  u32 keycode, u8 toggle)
>  {
> -	input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode);
> -
> -	/* Repeat event? */
> -	if (dev->keypressed &&
> -	    dev->last_scancode == scancode &&
> -	    dev->last_toggle == toggle)
> -		return;
> +	bool new_event = !dev->keypressed ||
> +			 dev->last_scancode != scancode ||
> +			 dev->last_toggle != toggle;
>  
> -	/* Release old keypress */
> -	ir_do_keyup(dev);
> +	if (new_event && dev->keypressed)
> +		ir_do_keyup(dev, false);
>  
> -	dev->last_scancode = scancode;
> -	dev->last_toggle = toggle;
> -	dev->last_keycode = keycode;
> +	input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode);
>  
> -	if (keycode == KEY_RESERVED)
> -		return;
> +	if (new_event && keycode != KEY_RESERVED) {
> +		/* Register a keypress */
> +		dev->keypressed = true;
> +		dev->last_scancode = scancode;
> +		dev->last_toggle = toggle;
> +		dev->last_keycode = keycode;
> +
> +		IR_dprintk(1, "%s: key down event, "
> +			   "key 0x%04x, scancode 0x%04x\n",
> +			   dev->input_name, keycode, scancode);
> +		input_report_key(dev->input_dev, keycode, 1);
> +	}
>  
> -	/* Register a keypress */
> -	dev->keypressed = true;
> -	IR_dprintk(1, "%s: key down event, key 0x%04x, scancode 0x%04x\n",
> -		   dev->input_name, keycode, scancode);
> -	input_report_key(dev->input_dev, dev->last_keycode, 1);
>  	input_sync(dev->input_dev);
>  }
>  
> -- 
> 1.7.5.4
> 

-- 
Dmitry
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux