Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp1928315ybl; Tue, 3 Dec 2019 15:09:49 -0800 (PST) X-Google-Smtp-Source: APXvYqxi/3zpaJI3OVHp1vic1Zs8g9hH4JLin7lSCQfZ95HTbKJ/2Xhdgd4nErIWxA3DAXXqSi1X X-Received: by 2002:a05:6830:1db3:: with SMTP id z19mr317043oti.152.1575414589500; Tue, 03 Dec 2019 15:09:49 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1575414589; cv=none; d=google.com; s=arc-20160816; b=eonyIiYPZLo4OTKH9uzZMTEEj9cAs8xoV7A4RRPXlW7Q6ULyjxDVkD5LsTv9LqeecG HqVSLqZ4z8CO4wlIZ2my2qtUJVaeSBYWhI6u5VV/pssnMhyu+FEgxHLJVrP9//TpxWyk oGe3XyOjh6UzoQ/UzfOa5e/xFIkZS77nADagCNd5yNkj2b14fUrh2KWgQRt0kzlRkkXT +ZDcyjNRCM9uDLalgNILZ+EojBfyvoLaJJ1ktYlyacp4fI2cycqkpKJPBI7eUQsXYIqk YNc03hgc+0xyp+PTf21dbLTqiEklAMmnJMKy7tQ1aV2zqbAU970y9G4wGaiv9CjrfmqI sFwA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=4N8jeLEAbfuL4P9IN2yBr+Fy49RAdc0O/oGJQCBe6eM=; b=a/SD606qcmVF6+6GLMxet8YDtpbjguTng9205dxnXSgLuw035wNQFRtOA+fImOFu1x KlHggGBrDln+fbHMKB+ecrWtSW5N5IGhqfZxs7NLKwI+f1Sbufdbk7vRl+QCNxFwjVsX L/sr9i50lhOaM5Thj+ASKbOl8RAayDMxdS9sN9xudhTxjygo76iHg0O4NvD5M7JFHRnc E0/fof0w4zN2am4VPcycQOpGCy8xCL1HoemaZfp6FHaaQVgJIUWAjXnCL6tcSW/fIG5n SBErGuoTT3WrFyEJuiHIYjFewa9iyNGZ+sPtHqIR2NZJOhME929NYZscMqwfuXwv9PZN au0g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=2a127N5p; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h11si2303332otr.197.2019.12.03.15.09.37; Tue, 03 Dec 2019 15:09:49 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=2a127N5p; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728581AbfLCWpX (ORCPT + 99 others); Tue, 3 Dec 2019 17:45:23 -0500 Received: from mail.kernel.org ([198.145.29.99]:33886 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729032AbfLCWpV (ORCPT ); Tue, 3 Dec 2019 17:45:21 -0500 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 15D8220803; Tue, 3 Dec 2019 22:45:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1575413120; bh=MP99nh/TM0pE6NtJsYqybo9a6kDwZHzSSkrdsojSgnY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=2a127N5pBW+yyL0dMYkngzWpfgdifzJ50DVvK9vywry3/JsJlDhRLMPjZLeF9dJLt 5mwSqvqZTfIySC+0bhqIuInP2byH3LSdgIehIaHlrYJXRciuk8WMwfhXj6sDG61GF0 /weuv7l76Ns6OSK8Vf1cCqcQaVwlpAwYCEH1e208= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Candle Sun , Nianfu Bai , Benjamin Tissoires , Jiri Kosina , Siarhei Vishniakou Subject: [PATCH 5.3 133/135] HID: core: check whether Usage Page item is after Usage ID items Date: Tue, 3 Dec 2019 23:36:13 +0100 Message-Id: <20191203213045.992118661@linuxfoundation.org> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191203213005.828543156@linuxfoundation.org> References: <20191203213005.828543156@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Candle Sun commit 1cb0d2aee26335d0bccf29100c7bed00ebece851 upstream. Upstream commit 58e75155009c ("HID: core: move Usage Page concatenation to Main item") adds support for Usage Page item after Usage ID items (such as keyboards manufactured by Primax). Usage Page concatenation in Main item works well for following report descriptor patterns: USAGE_PAGE (Keyboard) 05 07 USAGE_MINIMUM (Keyboard LeftControl) 19 E0 USAGE_MAXIMUM (Keyboard Right GUI) 29 E7 LOGICAL_MINIMUM (0) 15 00 LOGICAL_MAXIMUM (1) 25 01 REPORT_SIZE (1) 75 01 REPORT_COUNT (8) 95 08 INPUT (Data,Var,Abs) 81 02 ------------- USAGE_MINIMUM (Keyboard LeftControl) 19 E0 USAGE_MAXIMUM (Keyboard Right GUI) 29 E7 LOGICAL_MINIMUM (0) 15 00 LOGICAL_MAXIMUM (1) 25 01 REPORT_SIZE (1) 75 01 REPORT_COUNT (8) 95 08 USAGE_PAGE (Keyboard) 05 07 INPUT (Data,Var,Abs) 81 02 But it makes the parser act wrong for the following report descriptor pattern(such as some Gamepads): USAGE_PAGE (Button) 05 09 USAGE (Button 1) 09 01 USAGE (Button 2) 09 02 USAGE (Button 4) 09 04 USAGE (Button 5) 09 05 USAGE (Button 7) 09 07 USAGE (Button 8) 09 08 USAGE (Button 14) 09 0E USAGE (Button 15) 09 0F USAGE (Button 13) 09 0D USAGE_PAGE (Consumer Devices) 05 0C USAGE (Back) 0a 24 02 USAGE (HomePage) 0a 23 02 LOGICAL_MINIMUM (0) 15 00 LOGICAL_MAXIMUM (1) 25 01 REPORT_SIZE (1) 75 01 REPORT_COUNT (11) 95 0B INPUT (Data,Var,Abs) 81 02 With Usage Page concatenation in Main item, parser recognizes all the 11 Usages as consumer keys, it is not the HID device's real intention. This patch checks whether Usage Page is really defined after Usage ID items by comparing usage page using status. Usage Page concatenation on currently defined Usage Page will always do in local parsing when Usage ID items encountered. When Main item is parsing, concatenation will do again with last defined Usage Page if this page has not been used in the previous usages concatenation. Signed-off-by: Candle Sun Signed-off-by: Nianfu Bai Cc: Benjamin Tissoires Signed-off-by: Jiri Kosina Cc: Siarhei Vishniakou Signed-off-by: Greg Kroah-Hartman --- drivers/hid/hid-core.c | 51 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 6 deletions(-) --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -212,6 +212,18 @@ static unsigned hid_lookup_collection(st } /* + * Concatenate usage which defines 16 bits or less with the + * currently defined usage page to form a 32 bit usage + */ + +static void complete_usage(struct hid_parser *parser, unsigned int index) +{ + parser->local.usage[index] &= 0xFFFF; + parser->local.usage[index] |= + (parser->global.usage_page & 0xFFFF) << 16; +} + +/* * Add a usage to the temporary parser table. */ @@ -222,6 +234,14 @@ static int hid_add_usage(struct hid_pars return -1; } parser->local.usage[parser->local.usage_index] = usage; + + /* + * If Usage item only includes usage id, concatenate it with + * currently defined usage page + */ + if (size <= 2) + complete_usage(parser, parser->local.usage_index); + parser->local.usage_size[parser->local.usage_index] = size; parser->local.collection_index[parser->local.usage_index] = parser->collection_stack_ptr ? @@ -543,13 +563,32 @@ static int hid_parser_local(struct hid_p * usage value." */ -static void hid_concatenate_usage_page(struct hid_parser *parser) +static void hid_concatenate_last_usage_page(struct hid_parser *parser) { int i; + unsigned int usage_page; + unsigned int current_page; + + if (!parser->local.usage_index) + return; - for (i = 0; i < parser->local.usage_index; i++) - if (parser->local.usage_size[i] <= 2) - parser->local.usage[i] += parser->global.usage_page << 16; + usage_page = parser->global.usage_page; + + /* + * Concatenate usage page again only if last declared Usage Page + * has not been already used in previous usages concatenation + */ + for (i = parser->local.usage_index - 1; i >= 0; i--) { + if (parser->local.usage_size[i] > 2) + /* Ignore extended usages */ + continue; + + current_page = parser->local.usage[i] >> 16; + if (current_page == usage_page) + break; + + complete_usage(parser, i); + } } /* @@ -561,7 +600,7 @@ static int hid_parser_main(struct hid_pa __u32 data; int ret; - hid_concatenate_usage_page(parser); + hid_concatenate_last_usage_page(parser); data = item_udata(item); @@ -772,7 +811,7 @@ static int hid_scan_main(struct hid_pars __u32 data; int i; - hid_concatenate_usage_page(parser); + hid_concatenate_last_usage_page(parser); data = item_udata(item);