From patchwork Thu Jan 14 16:48:16 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aniroop Mathur X-Patchwork-Id: 8034051 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 6EB54BEEE5 for ; Thu, 14 Jan 2016 16:48:36 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 85BD420499 for ; Thu, 14 Jan 2016 16:48:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 89A5A20497 for ; Thu, 14 Jan 2016 16:48:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754406AbcANQsd (ORCPT ); Thu, 14 Jan 2016 11:48:33 -0500 Received: from mailout3.samsung.com ([203.254.224.33]:57910 "EHLO mailout3.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752394AbcANQsd (ORCPT ); Thu, 14 Jan 2016 11:48:33 -0500 Received: from epcpsbgm2new.samsung.com (epcpsbgm2 [203.254.230.27]) by mailout3.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0O0Y01JMHC0RRI70@mailout3.samsung.com>; Fri, 15 Jan 2016 01:48:31 +0900 (KST) X-AuditID: cbfee61b-f793c6d00000236c-05-5697d15f408e Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm2new.samsung.com (EPCPMTA) with SMTP id B4.82.09068.F51D7965; Fri, 15 Jan 2016 01:48:31 +0900 (KST) Received: from localhost.localdomain ([107.108.166.41]) by mmp1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0O0Y00NEDC0J5840@mmp1.samsung.com>; Fri, 15 Jan 2016 01:48:31 +0900 (KST) From: Aniroop Mathur To: dmitry.torokhov@gmail.com Cc: linux-input@vger.kernel.org, linux-kernel@vger.kernel.org, aniroop.mathur@gmail.com, s.samuel@samsung.com, r.mahale@samsung.com, Aniroop Mathur Subject: [PATCH] [v7] Input: evdev: fix bug of dropping full valid packet after syn_dropped Date: Thu, 14 Jan 2016 22:18:16 +0530 Message-id: <1452790096-13463-1-git-send-email-a.mathur@samsung.com> X-Mailer: git-send-email 1.7.9.5 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrAJMWRmVeSWpSXmKPExsVy+t9jAd34i9PDDP5dFrS4+OMci8XP3TNY LA4vesFocfPTN1aLy7vmsFmcetfAZLF571UWB3aPnbPusnv0bVnF6PF5k1wAcxSXTUpqTmZZ apG+XQJXxtO/P9kK7shWbDk3kb2BsUuii5GDQ0LARGLj+ZguRk4gU0ziwr31bF2MXBxCAksZ JbacPALl/GSUOHprFjtIA5uAtsT7z2wgDSICshIdx2cxg9QwC6xjlJj45SAbSI2wQKzEyleZ ICaLgKrEkQnKICavgIvEy+XGEFsVJOZMspnAyL2AkWEVo0RqQXJBcVJ6rlFearlecWJucWle ul5yfu4mRnA4PJPewXh4l/shRgEORiUe3gW3p4UJsSaWFVfmHmKU4GBWEuHdeHB6mBBvSmJl VWpRfnxRaU5q8SFGaQ4WJXHefZciw4QE0hNLUrNTUwtSi2CyTBycUg2MUck2oWdbLtSr94R/ mGRXdXFr6K3NRW0bYq/m+J1xmhnz53nB5JPrb/yYaXY+0nkKM7PYjsKbzy6tsnz6PWGqUZ5i HFPcz+8STUETb17/P/H8ByNe8wkKRZFmiRPuKS99XibJmFZvPU+lcVnn76UBy1x+H1ou+KPt zO+r0usiM5fejs/Re2frrMRSnJFoqMVcVJwIAMQ5lPIDAgAA 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, 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 If last event in old queue that was dropped was EV_SYN/SYN_REPORT, then lets generate EV_SYN/SYN_REPORT immediately after queing EV_SYN/SYN_DROPPED so that clients would not ignore next valid full packet events. v7: Includes change only in clock_change and pass_event function (not for evdev_handle_get_val to be on safer side) Signed-off-by: Aniroop Mathur --- drivers/input/evdev.c | 57 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 11 deletions(-) diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index e9ae3d5..0a376e7 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -192,6 +192,7 @@ static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid) { unsigned long flags; unsigned int clk_type; + struct input_event ev; switch (clkid) { @@ -218,8 +219,25 @@ static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid) spin_lock_irqsave(&client->buffer_lock, flags); if (client->head != client->tail) { - client->packet_head = client->head = client->tail; + /* Store last event occurred */ + client->head--; + client->head &= client->bufsize - 1; + ev = client->buffer[client->head]; + + client->packet_head = client->tail = client->head = 0; __evdev_queue_syn_dropped(client); + + /* + * If last packet is completely stored, queue SYN_REPORT + * so that clients would not ignore next full packet. + * Use SYN_DROPPED time for SYN_REPORT event and no need + * to check for head overflow as it was set to 0 index. + */ + if (ev.type == EV_SYN && ev.code == SYN_REPORT) { + ev.time = client->buffer[0].time; + client->buffer[client->head++] = ev; + client->packet_head = client->head; + } } spin_unlock_irqrestore(&client->buffer_lock, flags); @@ -231,22 +249,39 @@ static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid) static void __pass_event(struct evdev_client *client, const struct input_event *event) { + struct input_event *prev_ev; + unsigned int mask = client->bufsize - 1; + client->buffer[client->head++] = *event; - client->head &= client->bufsize - 1; + client->head &= mask; if (unlikely(client->head == client->tail)) { + /* Store previous event occurred before newest event */ + prev_ev = &client->buffer[(client->head - 2) & mask]; + + client->packet_head = client->tail = client->head; + + /* Queue SYN_DROPPED event */ + client->buffer[client->head].time = event->time; + client->buffer[client->head].type = EV_SYN; + client->buffer[client->head].code = SYN_DROPPED; + client->buffer[client->head++].value = 0; + client->head &= mask; + /* - * This effectively "drops" all unconsumed events, leaving - * EV_SYN/SYN_DROPPED plus the newest event in the queue. + * Queue SYN_REPORT event, if last packet was completely stored + * so that clients would not ignore upcoming full packet */ - client->tail = (client->head - 2) & (client->bufsize - 1); - - client->buffer[client->tail].time = event->time; - client->buffer[client->tail].type = EV_SYN; - client->buffer[client->tail].code = SYN_DROPPED; - client->buffer[client->tail].value = 0; + if (prev_ev->type == EV_SYN && prev_ev->code == SYN_REPORT) { + prev_ev->time = event->time; + client->buffer[client->head++] = *prev_ev; + client->head &= mask; + client->packet_head = client->head; + } - client->packet_head = client->tail; + /* Queue newest event (Empty SYN_REPORT are already dropped) */ + client->buffer[client->head++] = *event; + client->head &= mask; } if (event->type == EV_SYN && event->code == SYN_REPORT) {