From patchwork Mon Mar 30 18:54:15 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Tissoires X-Patchwork-Id: 6123751 Return-Path: X-Original-To: patchwork-linux-input@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id DB4B7BF4A6 for ; Mon, 30 Mar 2015 18:54:44 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id ED3472034C for ; Mon, 30 Mar 2015 18:54:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id ECE6E20303 for ; Mon, 30 Mar 2015 18:54:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753419AbbC3Syb (ORCPT ); Mon, 30 Mar 2015 14:54:31 -0400 Received: from mx1.redhat.com ([209.132.183.28]:45960 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753170AbbC3SyR (ORCPT ); Mon, 30 Mar 2015 14:54:17 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id BD784C2E26; Mon, 30 Mar 2015 18:54:16 +0000 (UTC) Received: from t540p.bos.redhat.com (dhcp-25-166.bos.redhat.com [10.18.25.166]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t2UIsFc3005917; Mon, 30 Mar 2015 14:54:15 -0400 From: Benjamin Tissoires To: Jiri Kosina , Henrik Rydberg , Dmitry Torokhov Cc: linux-input@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2] Input - mt: Fix input_mt_get_slot_by_key Date: Mon, 30 Mar 2015 14:54:15 -0400 Message-Id: <1427741655-4142-1-git-send-email-benjamin.tissoires@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The case occurred recently with a touchscreen using twice a slot during a single EV_SYN event: E: 0.288415 0000 0000 0000 # ------------ SYN_REPORT (0) ---------- E: 0.296207 0003 002f 0000 # EV_ABS / ABS_MT_SLOT 0 E: 0.296207 0003 0039 -001 # EV_ABS / ABS_MT_TRACKING_ID -1 E: 0.296207 0003 002f 0001 # EV_ABS / ABS_MT_SLOT 1 E: 0.296207 0003 0035 0908 # EV_ABS / ABS_MT_POSITION_X 908 E: 0.296207 0003 0036 1062 # EV_ABS / ABS_MT_POSITION_Y 1062 E: 0.296207 0003 002f 0000 # EV_ABS / ABS_MT_SLOT 0 E: 0.296207 0003 0039 8787 # EV_ABS / ABS_MT_TRACKING_ID 8787 E: 0.296207 0003 0035 1566 # EV_ABS / ABS_MT_POSITION_X 1566 E: 0.296207 0003 0036 0861 # EV_ABS / ABS_MT_POSITION_Y 861 E: 0.296207 0003 0000 0908 # EV_ABS / ABS_X 908 E: 0.296207 0003 0001 1062 # EV_ABS / ABS_Y 1062 E: 0.296207 0000 0000 0000 # ------------ SYN_REPORT (0) ---------- This occurred because while having already slots 0 and 1 assigned, the touchscreen sent: 0.293377 Tip Switch: 0 | Contact Id: 0 | X: 539 | Y: 1960 | Contact Count: 3 0.294783 Tip Switch: 1 | Contact Id: 1 | X: 908 | Y: 1062 | Contact Count: 0 0.296187 Tip Switch: 1 | Contact Id: 2 | X: 1566 | Y: 861 | Contact Count: 0 Slot 0 is released correclty, but when we look for Contact ID 2, the slot 0 is then picked up again because it is marked as inactive (trackingID < 0). This is wrong, and we should not reuse a slot in the same frame. The test should also check for input_mt_is_used(). In addition, we need to initialize mt->frame to an other value than 0. With mt->frame being 0, all slots are tags as currently used, and so input_mt_get_slot_by_key() would return -1 for all requests. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=88903 Signed-off-by: Benjamin Tissoires Acked-by: Dmitry Torokhov --- Changes in v2: - add note in input_mt_get_slot_by_key that input_mt_sync_frame() is required Hi Dmitry, Henrik, Jiri, With https://git.kernel.org/cgit/linux/kernel/git/jikos/hid.git/commit/?h=for-4.1/wacom&id=9a1c001298fd567c0f0776ab54ab9965eeb9019f in Jiri's tree, scheduled for 4.1, this patch should not break any existing driver. I'd like us to stage it somewhere so that it doesn't get forgotten. Henrik's previous concerns were that input_mt_sync_frame() may not be called by a driver using input_mt_get_slot_by_key(), and now, no driver should be in this case. Cheers, Benjamin drivers/input/input-mt.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c index cb150a1..34feb3e 100644 --- a/drivers/input/input-mt.c +++ b/drivers/input/input-mt.c @@ -88,10 +88,13 @@ int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots, goto err_mem; } - /* Mark slots as 'unused' */ + /* Mark slots as 'inactive' */ for (i = 0; i < num_slots; i++) input_mt_set_value(&mt->slots[i], ABS_MT_TRACKING_ID, -1); + /* Mark slots as 'unused' */ + mt->frame = 1; + dev->mt = mt; return 0; err_mem: @@ -439,6 +442,8 @@ EXPORT_SYMBOL(input_mt_assign_slots); * set the key on the first unused slot and return. * * If no available slot can be found, -1 is returned. + * Note that for this function to work properly, input_mt_sync_frame() has + * to be called at each frame. */ int input_mt_get_slot_by_key(struct input_dev *dev, int key) { @@ -453,7 +458,7 @@ int input_mt_get_slot_by_key(struct input_dev *dev, int key) return s - mt->slots; for (s = mt->slots; s != mt->slots + mt->num_slots; s++) - if (!input_mt_is_active(s)) { + if (!input_mt_is_active(s) && !input_mt_is_used(mt, s)) { s->key = key; return s - mt->slots; }