From patchwork Fri Sep 23 00:18:08 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frank Praznik X-Patchwork-Id: 9347223 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 6F1B2601C2 for ; Fri, 23 Sep 2016 00:18:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 691452AD1E for ; Fri, 23 Sep 2016 00:18:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5DC0E2AD1F; Fri, 23 Sep 2016 00:18:41 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.3 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D40F12AD1B for ; Fri, 23 Sep 2016 00:18:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S937881AbcIWASi (ORCPT ); Thu, 22 Sep 2016 20:18:38 -0400 Received: from mail-qk0-f193.google.com ([209.85.220.193]:34351 "EHLO mail-qk0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933536AbcIWASh (ORCPT ); Thu, 22 Sep 2016 20:18:37 -0400 Received: by mail-qk0-f193.google.com with SMTP id b204so6205893qkc.1 for ; Thu, 22 Sep 2016 17:18:37 -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:in-reply-to:references; bh=Q4jwUJj+GcleqxOvCmT9Zl8idgkJYcRsnkRUCMjrDx4=; b=UQHj+yg7sdjX7a/cN1YjcNUiF571k549/4Aayy9NSPGmlNzs2XRR+IiVTvSDoOj6di l27SIroOj37/+QusXSt5LoqPRFZ9IN11TumJcv4IlBXJKlj6ohYdgwEwaAf7B9Dd7p6A 8XgIBGOwz4O1B5/yEIXuBnZUp1umS+DnfkS5kKBc63X5NBzAdVx7He3mlD5Z9FZlDtn0 fRVcBcwE4M//8nekE52xnq6lrM8DRqOSE5FUtuLbLm9xprnMaIDNB4ShD3zi994vxhet QiPi0jYmsqGs24DevG17+jRfcxOjDJo6hI5mikBplZm6LMk7lWm/VfRzaBonukNWaCk+ GCjA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Q4jwUJj+GcleqxOvCmT9Zl8idgkJYcRsnkRUCMjrDx4=; b=dWlqME4pd8A74rJhkMSIuvIEo5D+nr/SYoC02Akz5W4J5KxwFQt3PPitJRthKnsCds Mw3XBsmeu9wGqKaBCBXBwjKEjuiqAtCXfSCMrvSN2Dg6RRzRl1ykpG3j4S+RRuXs3ynV nWIBfSqKeIP/z2SxgGJSznNpYUQBNmG+3oKvOsIHnHVxx6XXs+TgFXFsr4TKh3IhC0I2 Kb1y1y0DBU90c8Rv3OwYoFoJY/xKAhyQA9lhadg32/JVAk/Ael8Lt/Adhy2eNoWhJVcW TXLYWepPabc8IRhW5bWhDh/19w1gqIkjNS4dcPbZTVG0unLN23f/VijJQPghu7z/P3Yp Yk/w== X-Gm-Message-State: AA6/9Rn9UR237XB4ANsR8PA2dPck+Y+UQo5AuTjXkJWoApoxbtDSQcDDscwwlqcwHJHe+w== X-Received: by 10.55.181.194 with SMTP id e185mr4736158qkf.299.1474589916553; Thu, 22 Sep 2016 17:18:36 -0700 (PDT) Received: from localhost.localdomain.localdomain (cpe-104-231-99-148.neo.res.rr.com. [104.231.99.148]) by smtp.gmail.com with ESMTPSA id m12sm2375892qtc.8.2016.09.22.17.18.35 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 22 Sep 2016 17:18:36 -0700 (PDT) From: Frank Praznik To: linux-input@vger.kernel.org Cc: jikos@kernel.org, benjamin.tissoires@redhat.com, Frank Praznik Subject: [PATCH 1/3] hid: sony: Relax duplicate checking for USB-only devices Date: Thu, 22 Sep 2016 20:18:08 -0400 Message-Id: <1474589890-7141-2-git-send-email-frank.praznik@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1474589890-7141-1-git-send-email-frank.praznik@gmail.com> References: <1474589890-7141-1-git-send-email-frank.praznik@gmail.com> Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Some USB-only devices which masquerade as Sixaxis controllers report the same generic Bluetooth address for all hardware when queried via the HID report. This causes these devices to be wrongly rejected as duplicates when more than one is connected at once. This introduces a connection type comparison when checking for duplicates and only rejects the newly connected device if the existing matching device is connected using a different connection protocol. The results of the connection type comparison are also used when registering power supply info as the device Bluetooth address is used as the unique identifier string. In cases where more than one valid device has the same Bluetooth address the device ID is now appended to the power supply name string to avoid name collisions when registering the power supply information. Signed-off-by: Frank Praznik --- drivers/hid/hid-sony.c | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 310436a..92f27b7 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -65,6 +65,8 @@ MOTION_CONTROLLER_BT | NAVIGATION_CONTROLLER) #define SONY_FF_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER |\ MOTION_CONTROLLER) +#define SONY_BT_DEVICE (SIXAXIS_CONTROLLER_BT | DUALSHOCK4_CONTROLLER_BT |\ + MOTION_CONTROLLER_BT | NAVIGATION_CONTROLLER_BT) #define MAX_LEDS 4 @@ -2039,8 +2041,11 @@ static int sony_battery_get_property(struct power_supply *psy, return ret; } -static int sony_battery_probe(struct sony_sc *sc) +static int sony_battery_probe(struct sony_sc *sc, int append_dev_id) { + const char *battery_str_fmt = append_dev_id ? + "sony_controller_battery_%pMR_%i" : + "sony_controller_battery_%pMR"; struct power_supply_config psy_cfg = { .drv_data = sc, }; struct hid_device *hdev = sc->hdev; int ret; @@ -2056,9 +2061,8 @@ static int sony_battery_probe(struct sony_sc *sc) sc->battery_desc.get_property = sony_battery_get_property; sc->battery_desc.type = POWER_SUPPLY_TYPE_BATTERY; sc->battery_desc.use_for_apm = 0; - sc->battery_desc.name = kasprintf(GFP_KERNEL, - "sony_controller_battery_%pMR", - sc->mac_address); + sc->battery_desc.name = kasprintf(GFP_KERNEL, battery_str_fmt, + sc->mac_address, sc->device_id); if (!sc->battery_desc.name) return -ENOMEM; @@ -2094,7 +2098,21 @@ static void sony_battery_remove(struct sony_sc *sc) * it will show up as two devices. A global list of connected controllers and * their MAC addresses is maintained to ensure that a device is only connected * once. + * + * Some USB-only devices masquerade as Sixaxis controllers and all have the + * same dummy Bluetooth address, so a comparison of the connection type is + * required. Devices are only rejected in the case where two devices have + * matching Bluetooth addresses on different bus types. */ +static inline int sony_compare_connection_type(struct sony_sc *sc0, + struct sony_sc *sc1) +{ + const int sc0_not_bt = !(sc0->quirks & SONY_BT_DEVICE); + const int sc1_not_bt = !(sc1->quirks & SONY_BT_DEVICE); + + return sc0_not_bt == sc1_not_bt; +} + static int sony_check_add_dev_list(struct sony_sc *sc) { struct sony_sc *entry; @@ -2107,9 +2125,14 @@ static int sony_check_add_dev_list(struct sony_sc *sc) ret = memcmp(sc->mac_address, entry->mac_address, sizeof(sc->mac_address)); if (!ret) { - ret = -EEXIST; - hid_info(sc->hdev, "controller with MAC address %pMR already connected\n", + if (sony_compare_connection_type(sc, entry)) { + ret = 1; + } else { + ret = -EEXIST; + hid_info(sc->hdev, + "controller with MAC address %pMR already connected\n", sc->mac_address); + } goto unlock; } } @@ -2285,6 +2308,7 @@ static inline void sony_cancel_work_sync(struct sony_sc *sc) static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) { int ret; + int append_dev_id; unsigned long quirks = id->driver_data; struct sony_sc *sc; unsigned int connect_mask = HID_CONNECT_DEFAULT; @@ -2379,7 +2403,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) if (ret < 0) goto err_stop; - ret = sony_check_add(sc); + ret = append_dev_id = sony_check_add(sc); if (ret < 0) goto err_stop; @@ -2390,7 +2414,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) } if (sc->quirks & SONY_BATTERY_SUPPORT) { - ret = sony_battery_probe(sc); + ret = sony_battery_probe(sc, append_dev_id); if (ret < 0) goto err_stop;