From patchwork Sat Sep 7 07:45:08 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Moiseev X-Patchwork-Id: 2856031 Return-Path: X-Original-To: patchwork-linux-input@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 548C09F4D4 for ; Sat, 7 Sep 2013 07:45:50 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 844E0203D9 for ; Sat, 7 Sep 2013 07:45:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9499B203B5 for ; Sat, 7 Sep 2013 07:45:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751014Ab3IGHpr (ORCPT ); Sat, 7 Sep 2013 03:45:47 -0400 Received: from mail-lb0-f176.google.com ([209.85.217.176]:35705 "EHLO mail-lb0-f176.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751002Ab3IGHpq (ORCPT ); Sat, 7 Sep 2013 03:45:46 -0400 Received: by mail-lb0-f176.google.com with SMTP id y6so3478882lbh.7 for ; Sat, 07 Sep 2013 00:45:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=N9p8Xx9kWAk/VDO3rFJ5AIwxHVRRHTD66u2AREuiXBM=; b=OpwJRg7LqecTo6UY4XuLFrSjMt/jD89qmli9Z7g88VkUiVYdLBtRNqfTdPJY4wYLcB a+//6T3nlkHLEMWW5bYAUCnWfzJsnF477MNlpIssQbiXjKVAEfQLYFM0i3aU6tWPpCeJ PeQ77eBCXDPnoivRmrd5YcUSVItelYL9mZnkhtxq6wrKqEv6WQJ3KkUK62cwEl26JIGW DxkjMff0361yjVeqNDH8/OMV0PihvC3aUCjhA/cVDmB/mJ1ObO9eevv+nO+Yjn6ZbqGv 2ykHs5Apx6L4sHa9rAkEnnI13eomGHe5gqJJLMdnUBEQW3TnFN01qvbdurNeNtEqZN4E taww== X-Received: by 10.112.57.49 with SMTP id f17mr6462223lbq.26.1378539943925; Sat, 07 Sep 2013 00:45:43 -0700 (PDT) Received: from localhost.localdomain (37-146-214-122.broadband.corbina.ru. [37.146.214.122]) by mx.google.com with ESMTPSA id b1sm753074lah.6.1969.12.31.16.00.00 (version=TLSv1.2 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sat, 07 Sep 2013 00:45:43 -0700 (PDT) From: Andrey Moiseev To: dmitry.torokhov@gmail.com Cc: linux-input@vger.kernel.org, linux-kernel@vger.kernel.org, Andrey Moiseev Subject: [PATCH] Input: i8042 - i8042_flush fix for a full 8042 buffer Date: Sat, 7 Sep 2013 11:45:08 +0400 Message-Id: <1378539908-9431-1-git-send-email-o2g.org.ru@gmail.com> X-Mailer: git-send-email 1.8.4 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Spam-Status: No, score=-9.2 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham 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 When 8042 internal data buffer is full, the driver erroneously decides that the controller is not present. i8042_flush returns the number of flushed bytes, which is in 0 - I8042_BUFFER_SIZE range inclusive. Therefore, i8042_flush has no way to indicate an error. Moreover i8042_controller_check takes initially full buffer (i8042_flush returned I8042_BUFFER_SIZE) as a sign of absence of the controller. The fix: i8042_flush should perform one more status check after I8042_BUFFER_SIZE bytes have been read, and, if it succeeds, indicate the error by returning -1. i8042_controller_check should be changed appropriately. Signed-off-by: Andrey Moiseev diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 78e4de4..cdda786 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -222,29 +222,32 @@ static int i8042_wait_write(void) static int i8042_flush(void) { unsigned long flags; unsigned char data, str; int i = 0; spin_lock_irqsave(&i8042_lock, flags); - while (((str = i8042_read_status()) & I8042_STR_OBF) && (i < I8042_BUFFER_SIZE)) { + while (((str = i8042_read_status()) & I8042_STR_OBF) && (i <= I8042_BUFFER_SIZE)) { udelay(50); data = i8042_read_data(); i++; dbg("%02x <- i8042 (flush, %s)\n", data, str & I8042_STR_AUXDATA ? "aux" : "kbd"); } spin_unlock_irqrestore(&i8042_lock, flags); + if (i == I8042_BUFFER_SIZE + 1) + return -1; + return i; } /* * i8042_command() executes a command on the i8042. It also sends the input * parameter(s) of the commands to it, and receives the output value(s). The * parameters are to be stored in the param array, and the output is placed * into the same array. The number of the parameters and output values is * encoded in bits 8-11 of the command number. */ @@ -849,11 +852,11 @@ static int __init i8042_check_aux(void) static int i8042_controller_check(void) { - if (i8042_flush() == I8042_BUFFER_SIZE) { + if (i8042_flush() == -1) { pr_err("No controller found\n"); return -ENODEV; } return 0; }