From patchwork Sat Dec 15 00:17:23 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shawn Nematbakhsh X-Patchwork-Id: 1882001 Return-Path: X-Original-To: patchwork-linux-input@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 0FC84DF230 for ; Sat, 15 Dec 2012 00:19:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756913Ab2LOATM (ORCPT ); Fri, 14 Dec 2012 19:19:12 -0500 Received: from mail-we0-f202.google.com ([74.125.82.202]:62804 "EHLO mail-we0-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756797Ab2LOATL (ORCPT ); Fri, 14 Dec 2012 19:19:11 -0500 Received: by mail-we0-f202.google.com with SMTP id t57so210616wey.1 for ; Fri, 14 Dec 2012 16:19:10 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:x-gm-message-state; bh=ejBWdczADatwzgUnCSKTkGtJ5GolvyXsNPPpa0W2H0Q=; b=Vz6QyNg+uM1T5RVgxf94XtIpFu7/y/6AkCd9c33y0T9sDBOgfZ+HRKiYvTPAZLf8PS U/tp/qqTW9l+/P3Byne2qkD9ZoWYK845cjsf4nMVjn8QlXCy3K6oDNt3+E+gnRL95vay cxJPMIMmRuvz8Go6OoYraoHchASX1MU/BAhqjb7tcXFMiKSyxGIYyA8vGKu4U5w0O643 7FQEH5ezJpNXYFrmGKYrSGQbe8PHJSwEYzL+CwgQbTr8D/DAFC7XfFUDm0jFg1UD+Zwa o551FcoNOQW+eDhKTI6piLnkivrJsms9CyXmTHvbnfi+kwbnt49dtCuznV24NW45K/AE OpHA== Received: by 10.14.180.2 with SMTP id i2mr7062335eem.1.1355530750263; Fri, 14 Dec 2012 16:19:10 -0800 (PST) Received: from hpza10.eem.corp.google.com ([74.125.121.33]) by gmr-mx.google.com with ESMTPS id g9si1546542eeo.1.2012.12.14.16.19.10 (version=TLSv1/SSLv3 cipher=AES128-SHA); Fri, 14 Dec 2012 16:19:10 -0800 (PST) Received: from brainstorm.mtv.corp.google.com (brainstorm.mtv.corp.google.com [172.22.77.67]) by hpza10.eem.corp.google.com (Postfix) with ESMTP id DEA98200059; Fri, 14 Dec 2012 16:19:09 -0800 (PST) Received: by brainstorm.mtv.corp.google.com (Postfix, from userid 167876) id 1EDDA142E6C; Fri, 14 Dec 2012 16:19:08 -0800 (PST) From: Shawn Nematbakhsh To: Dmitry Torokhov Cc: Shawn Nematbakhsh , Jesper Juhl , linux-input@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] atkbd: Fix multi-char scancode handling on reconnect. Date: Fri, 14 Dec 2012 16:17:23 -0800 Message-Id: <1355530643-8177-1-git-send-email-shawnn@chromium.org> X-Mailer: git-send-email 1.7.7.3 X-Gm-Message-State: ALoCoQlei8LQsY/82JT54CslnHje7vNA4BGImpv0JHkD6GYjlentZNb6A9tY1p6J4FedyuOeNDA921lkCpW2993t0eDxjv8E9e38/zZP8O5JV03ndzeGAyx6oNa0GuUa2a2+gVLT50ZIjcaoUdp1vbqubQCRDQYI4hEeY1ETIV+OrmYzLQxWw2x3T+GlLl9LIlRUYzwHR+nZdGw4PsDvcb97AXrWpQTblQ== Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org On resume from suspend there is a possibility for multi-byte scancodes to be handled incorrectly. atkbd_reconnect disables the processing of scancodes in software by calling atkbd_disable, but the keyboard may still be active because no disconnect command was sent. Later, software handling is re-enabled. If a multi-byte scancode sent from the keyboard straddles the re-enable, only the latter byte(s) will be handled. In practice, this leads to cases where multi-byte break codes (ex. "e0 4d" - break code for right-arrow) are misread as make codes ("4d" - make code for numeric 6), leading to one or more unwanted, untyped characters being interpreted. The solution implemented here involves sending command f5 (reset disable) to the keyboard prior to disabling software handling of codes. Later, the command to re-enable the keyboard is sent only after we are prepared to handle scancodes. Signed-off-by: Shawn Nematbakhsh --- drivers/input/keyboard/atkbd.c | 26 ++++++++++++++++++++++++-- 1 files changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index add5ffd..da49e8b 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -844,6 +844,24 @@ static int atkbd_activate(struct atkbd *atkbd) } /* + * atkbd_deactivate() resets and disables the keyboard from sending + * keystrokes. + */ +static int atkbd_deactivate(struct atkbd *atkbd) +{ + struct ps2dev *ps2dev = &atkbd->ps2dev; + + if (ps2_command(ps2dev, NULL, ATKBD_CMD_RESET_DIS)) { + dev_err(&ps2dev->serio->dev, + "Failed to deactivate keyboard on %s\n", + ps2dev->serio->phys); + return -1; + } + + return 0; +} + +/* * atkbd_cleanup() restores the keyboard state so that BIOS is happy after a * reboot. */ @@ -1199,6 +1217,9 @@ static int atkbd_reconnect(struct serio *serio) mutex_lock(&atkbd->mutex); + if (atkbd->write) + atkbd_deactivate(atkbd); + atkbd_disable(atkbd); if (atkbd->write) { @@ -1208,8 +1229,6 @@ static int atkbd_reconnect(struct serio *serio) if (atkbd->set != atkbd_select_set(atkbd, atkbd->set, atkbd->extra)) goto out; - atkbd_activate(atkbd); - /* * Restore LED state and repeat rate. While input core * will do this for us at resume time reconnect may happen @@ -1224,6 +1243,9 @@ static int atkbd_reconnect(struct serio *serio) } atkbd_enable(atkbd); + if (atkbd->write) + atkbd_activate(atkbd); + retval = 0; out: