From patchwork Mon Nov 19 23:04:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajat Jain X-Patchwork-Id: 10689607 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5C59D6C5 for ; Mon, 19 Nov 2018 23:04:36 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4E67A2A782 for ; Mon, 19 Nov 2018 23:04:36 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 42B162A7BB; Mon, 19 Nov 2018 23:04:36 +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=-15.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, USER_IN_DEF_DKIM_WL 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 D6C442A782 for ; Mon, 19 Nov 2018 23:04:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732120AbeKTJaa (ORCPT ); Tue, 20 Nov 2018 04:30:30 -0500 Received: from mail-qk1-f201.google.com ([209.85.222.201]:41473 "EHLO mail-qk1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732079AbeKTJa3 (ORCPT ); Tue, 20 Nov 2018 04:30:29 -0500 Received: by mail-qk1-f201.google.com with SMTP id n68so71498449qkn.8 for ; Mon, 19 Nov 2018 15:04:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=/jmvSk73ZJvN/rJikoGCnBxiMJ8mGKQz9fKupKHZVnc=; b=qXY1/LFiLarQRhLrkWROxeQeHmYfzgfPgdLh4bHm5Scg9+m1STMxr9SnF6o28Nqe/A /B9/Um33GOCytCDB/1bgNYsyXpINQq8NykqhWbCeo29WJKN3kgMGs5U4ejeZPqtrrurw wxv/OQsjYMtY9phIeW3T2o+MJOXSYGQcRROkyofom9Nvri7gguq2z0V2r6MvuhcJ9mgi +vir91iYwnQH6SO/rSFbN454vx2qQEALJa3Eji5528kEp7k6Ne2LZmvFuM7EgTZD1f+5 9SSEqja1Oep0Et8s93A4r2EIA1slufqUtEddwugxAGN862OrY3HPrW4NqITlWV5EN6J/ TA1Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=/jmvSk73ZJvN/rJikoGCnBxiMJ8mGKQz9fKupKHZVnc=; b=e82ba/WnT2h6276EtJqDEL5VdUycF2VMQGEf5/T/YYyOZuxHsal9OyODvK7tag8ymI ETg/fJOXfq45qa2/SOcNwAAQLAq7Yjig4tT1x1CSAqdaYjfisQzlPEzGvdjfTHc79SEw phYhZvGR5K2gLLvRfDYBqcSQeQg+0YOpuDjuVE75tHnvPaoonFgzC+agX9SBIzbCQ1t4 C7EIb1yUHxcQ10D7XDaZboQsrngBdlq3hAmuTpCK3q+W7MIHzuxVJQrRbYE6v51CnSE4 9vTC5ALidwwnht56ILEe+Hz+1tU3umqTdWQtDrrhNP+XG7DdP7E2NrdWaF5Vsr4CBwVb KWjA== X-Gm-Message-State: AGRZ1gJA1ZhASZe8+zGw9oVHDZXukcJAAm80813y23GtMdZ82hMBwZHo WXTilGDG6H+mDlQslQ56+BpCIdgkGWSD X-Google-Smtp-Source: AFSGD/Va7z8PSmAcKHGrEIJjGnGQ2ajacMfWtcwgJvkglit2D6XwXzEKf0fAdwfTe6LOle4ydkE6yf4YDgKJ X-Received: by 2002:ac8:244a:: with SMTP id d10mr10227616qtd.15.1542668670179; Mon, 19 Nov 2018 15:04:30 -0800 (PST) Date: Mon, 19 Nov 2018 15:04:07 -0800 In-Reply-To: <20181119230409.258121-1-rajatja@google.com> Message-Id: <20181119230409.258121-3-rajatja@google.com> Mime-Version: 1.0 References: <20181117010748.24347-1-rajatja@google.com> <20181119230409.258121-1-rajatja@google.com> X-Mailer: git-send-email 2.19.1.1215.g8438c0b245-goog Subject: [PATCH v2 3/5] Bluetooth: Reset Bluetooth chip after multiple command timeouts From: Rajat Jain To: Marcel Holtmann , Johan Hedberg , Greg Kroah-Hartman , "David S. Miller" , Dmitry Torokhov , Rajat Jain , Alex Hung , linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org, netdev@vger.kernel.org Cc: rajatxjain@gmail.com, dtor@google.com, raghuram.hegde@intel.com, chethan.tumkur.narayan@intel.com, sukumar.ghorai@intel.com Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add a quirk and a hook to allow the HCI core to reset the BT chip if needed (after a number of timed out commands). Use that new hook to initiate BT chip reset if the controller fails to respond to certain number of commands (currently 5) including the HCI reset commands. This is done based on a newly introduced quirk. This is done based on some initial work by Intel. Signed-off-by: Rajat Jain --- v2: same as v1 include/net/bluetooth/hci.h | 8 ++++++++ include/net/bluetooth/hci_core.h | 2 ++ net/bluetooth/hci_core.c | 15 +++++++++++++-- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index c36dc1e20556..af02fa5ffe54 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -192,6 +192,14 @@ enum { * */ HCI_QUIRK_NON_PERSISTENT_SETUP, + + /* When this quirk is set, hw_reset() would be run to reset the + * hardware, after a certain number of commands (currently 5) + * time out because the device fails to respond. + * + * This quirk should be set before hci_register_dev is called. + */ + HCI_QUIRK_HW_RESET_ON_TIMEOUT, }; /* HCI device flags */ diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index e5ea633ea368..b86218304b80 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -313,6 +313,7 @@ struct hci_dev { unsigned int acl_cnt; unsigned int sco_cnt; unsigned int le_cnt; + unsigned int timeout_cnt; unsigned int acl_mtu; unsigned int sco_mtu; @@ -437,6 +438,7 @@ struct hci_dev { int (*post_init)(struct hci_dev *hdev); int (*set_diag)(struct hci_dev *hdev, bool enable); int (*set_bdaddr)(struct hci_dev *hdev, const bdaddr_t *bdaddr); + void (*hw_reset)(struct hci_dev *hdev); }; #define HCI_PHY_HANDLE(handle) (handle & 0xff) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 7352fe85674b..ab3a6a8b7ba6 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -2569,13 +2569,24 @@ static void hci_cmd_timeout(struct work_struct *work) struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_timer.work); + hdev->timeout_cnt++; if (hdev->sent_cmd) { struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; u16 opcode = __le16_to_cpu(sent->opcode); - bt_dev_err(hdev, "command 0x%4.4x tx timeout", opcode); + bt_dev_err(hdev, "command 0x%4.4x tx timeout (cnt = %u)", + opcode, hdev->timeout_cnt); } else { - bt_dev_err(hdev, "command tx timeout"); + bt_dev_err(hdev, "command tx timeout (cnt = %u)", + hdev->timeout_cnt); + } + + if (test_bit(HCI_QUIRK_HW_RESET_ON_TIMEOUT, &hdev->quirks) && + hdev->timeout_cnt >= 5) { + hdev->timeout_cnt = 0; + if (hdev->hw_reset) + hdev->hw_reset(hdev); + return; } atomic_set(&hdev->cmd_cnt, 1);