From patchwork Tue Jan 28 01:58:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Abhishek Pandit-Subedi X-Patchwork-Id: 197411 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.9 required=3.0 tests=DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 08AE5C32771 for ; Tue, 28 Jan 2020 01:59:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D53002467B for ; Tue, 28 Jan 2020 01:59:20 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="A76cGmot" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726871AbgA1B67 (ORCPT ); Mon, 27 Jan 2020 20:58:59 -0500 Received: from mail-pf1-f193.google.com ([209.85.210.193]:45193 "EHLO mail-pf1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726240AbgA1B66 (ORCPT ); Mon, 27 Jan 2020 20:58:58 -0500 Received: by mail-pf1-f193.google.com with SMTP id 2so5792148pfg.12 for ; Mon, 27 Jan 2020 17:58:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=13vsGtNjHBWNnGhQUQncdMYzMSFZ56Uehul7bwbcBIo=; b=A76cGmotLM+qd5oIjZrrpVN7lIhqWOdmeIeYE1/uPdq7i0Q3+FIX1dnP6ZqXhYwRIr ErEcrsDOjS+LjeaQFSwOYwy5jPPBzH9i8TRidSWfo2q8Treb4Nz0rXBYsEMX8UMZAcfs QqHyG+bOlbqMdRY5jDSBOf6uiYn+Ct43ZMqCM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=13vsGtNjHBWNnGhQUQncdMYzMSFZ56Uehul7bwbcBIo=; b=XWjOcc0yrb5OlzK/XJgrGNWt/sZCTdwjihVi49bbjf1suryXE1epoFUCF5kWPtVpro WsXT2T2lOY2XrXI8kTuTadjuEaHDkcJvIFp382HsVOSky4BY7elPv6qieQ9O701Qg03r juf7tCzvfxRx0sKlR52iYJ7onWtXjgaKuFj7U1oEASzEZOv6bQes0iFr/eTkk6Nt8iJl YzoPiptm6ZEkUoCPozL+TLZcbKGkMb7WceA/bfUPxdMI2XbTvGiDtZozyG9DgAUDJXvg sQk5yNCvpmhLMEy20WUTzx6jt32og0fGQzgix9wbgpmbMZLIEt0cA/rZ8UmJQz2Gw2hf RjfA== X-Gm-Message-State: APjAAAUtVqtIYocFdcyWwG4t0KY5qCGmDmZQqCUUQgNvCgj25/lum4We NhgGgmBfIH2gaFHfWDfh7wCC0A== X-Google-Smtp-Source: APXvYqx68WjSazvmPWjVZ+X9JuOR0iPabbUsn7PYJqogyAGNlYcJXGikjPoqlhjRLQhvCpBudJn2UQ== X-Received: by 2002:a63:348c:: with SMTP id b134mr4310357pga.197.1580176737484; Mon, 27 Jan 2020 17:58:57 -0800 (PST) Received: from apsdesk.mtv.corp.google.com ([2620:15c:202:1:e09a:8d06:a338:aafb]) by smtp.gmail.com with ESMTPSA id a17sm364153pjv.6.2020.01.27.17.58.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Jan 2020 17:58:57 -0800 (PST) From: Abhishek Pandit-Subedi To: marcel@holtmann.org, luiz.dentz@gmail.com, alainm@chromium.org Cc: linux-bluetooth@vger.kernel.org, chromeos-bluetooth-upstreaming@chromium.org, Abhishek Pandit-Subedi , "David S. Miller" , Johan Hedberg , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Jakub Kicinski Subject: [RFC PATCH v2 1/4] Bluetooth: Add mgmt op set_wake_capable Date: Mon, 27 Jan 2020 17:58:45 -0800 Message-Id: <20200127175842.RFC.v2.1.I797e2f4cb824299043e771f3ab9cef86ee09f4db@changeid> X-Mailer: git-send-email 2.25.0.341.g760bfbb309-goog In-Reply-To: <20200128015848.226966-1-abhishekpandit@chromium.org> References: <20200128015848.226966-1-abhishekpandit@chromium.org> MIME-Version: 1.0 Sender: linux-bluetooth-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org When the system is suspended, only some connected Bluetooth devices cause user input that should wake the system (mostly HID devices). Add a list to keep track of devices that can wake the system and add a management API to let userspace tell the kernel whether a device is wake capable or not. Signed-off-by: Abhishek Pandit-Subedi --- Changes in v2: None include/net/bluetooth/hci_core.h | 1 + include/net/bluetooth/mgmt.h | 7 ++++++ net/bluetooth/hci_core.c | 1 + net/bluetooth/mgmt.c | 40 ++++++++++++++++++++++++++++++++ 4 files changed, 49 insertions(+) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 89ecf0a80aa1..ce4bebcb0265 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -394,6 +394,7 @@ struct hci_dev { struct list_head mgmt_pending; struct list_head blacklist; struct list_head whitelist; + struct list_head wakeable; struct list_head uuids; struct list_head link_keys; struct list_head long_term_keys; diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index a90666af05bd..283ba5320bdb 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h @@ -671,6 +671,13 @@ struct mgmt_cp_set_blocked_keys { } __packed; #define MGMT_OP_SET_BLOCKED_KEYS_SIZE 2 +#define MGMT_OP_SET_WAKE_CAPABLE 0x0047 +#define MGMT_SET_WAKE_CAPABLE_SIZE 8 +struct mgmt_cp_set_wake_capable { + struct mgmt_addr_info addr; + u8 wake_capable; +} __packed; + #define MGMT_EV_CMD_COMPLETE 0x0001 struct mgmt_ev_cmd_complete { __le16 opcode; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index cbbc34a006d1..2fceaf76644a 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -3299,6 +3299,7 @@ struct hci_dev *hci_alloc_dev(void) INIT_LIST_HEAD(&hdev->mgmt_pending); INIT_LIST_HEAD(&hdev->blacklist); INIT_LIST_HEAD(&hdev->whitelist); + INIT_LIST_HEAD(&hdev->wakeable); INIT_LIST_HEAD(&hdev->uuids); INIT_LIST_HEAD(&hdev->link_keys); INIT_LIST_HEAD(&hdev->long_term_keys); diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 3074363c68df..58468dfa112f 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -107,6 +107,7 @@ static const u16 mgmt_commands[] = { MGMT_OP_READ_EXT_INFO, MGMT_OP_SET_APPEARANCE, MGMT_OP_SET_BLOCKED_KEYS, + MGMT_OP_SET_WAKE_CAPABLE, }; static const u16 mgmt_events[] = { @@ -4663,6 +4664,37 @@ static int set_fast_connectable(struct sock *sk, struct hci_dev *hdev, return err; } +static int set_wake_capable(struct sock *sk, struct hci_dev *hdev, void *data, + u16 len) +{ + int err; + u8 status; + struct mgmt_cp_set_wake_capable *cp = data; + u8 addr_type = cp->addr.type == BDADDR_BREDR ? + cp->addr.type : + le_addr_type(cp->addr.type); + + BT_DBG("Set wake capable %pMR (type 0x%x) = 0x%x\n", &cp->addr.bdaddr, + addr_type, cp->wake_capable); + + if (cp->wake_capable) + err = hci_bdaddr_list_add(&hdev->wakeable, &cp->addr.bdaddr, + addr_type); + else + err = hci_bdaddr_list_del(&hdev->wakeable, &cp->addr.bdaddr, + addr_type); + + if (!err || err == -EEXIST || err == -ENOENT) + status = MGMT_STATUS_SUCCESS; + else + status = MGMT_STATUS_FAILED; + + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_SET_WAKE_CAPABLE, status, + cp, sizeof(*cp)); + + return err; +} + static void set_bredr_complete(struct hci_dev *hdev, u8 status, u16 opcode) { struct mgmt_pending_cmd *cmd; @@ -5791,6 +5823,13 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev, err = hci_bdaddr_list_del(&hdev->whitelist, &cp->addr.bdaddr, cp->addr.type); + + /* Don't check result since it either succeeds or device + * wasn't there (not wakeable or invalid params as + * covered by deleting from whitelist). + */ + hci_bdaddr_list_del(&hdev->wakeable, &cp->addr.bdaddr, + cp->addr.type); if (err) { err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_DEVICE, @@ -6990,6 +7029,7 @@ static const struct hci_mgmt_handler mgmt_handlers[] = { { set_phy_configuration, MGMT_SET_PHY_CONFIGURATION_SIZE }, { set_blocked_keys, MGMT_OP_SET_BLOCKED_KEYS_SIZE, HCI_MGMT_VAR_LEN }, + { set_wake_capable, MGMT_SET_WAKE_CAPABLE_SIZE }, }; void mgmt_index_added(struct hci_dev *hdev) From patchwork Tue Jan 28 01:58:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Abhishek Pandit-Subedi X-Patchwork-Id: 197412 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.9 required=3.0 tests=DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CEF37C33CB7 for ; Tue, 28 Jan 2020 01:59:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 995072467B for ; Tue, 28 Jan 2020 01:59:15 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="fcoQcbFD" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727680AbgA1B7N (ORCPT ); Mon, 27 Jan 2020 20:59:13 -0500 Received: from mail-pl1-f193.google.com ([209.85.214.193]:37506 "EHLO mail-pl1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727221AbgA1B7B (ORCPT ); Mon, 27 Jan 2020 20:59:01 -0500 Received: by mail-pl1-f193.google.com with SMTP id c23so4465589plz.4 for ; Mon, 27 Jan 2020 17:59:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=lpOZX+dHz9XxjRDtH5GLorxQ2Si7tonYbZOshKJtM8M=; b=fcoQcbFDoN5vbYWDPP9Wp2ic5JaIMTPATUx8ivh8JTvD8b+3c8cJLEyDd22ABwJVOi E5abq61sDd8zUEA+sJeWJ2RQEu5qL5oXz5yxCLDoJy1INeOgE6TXeJRIYjo7ZJqrHbZ1 dQ2a19ezKQtu7wrvIy1PKh7UCYdJqPd4XL8Eo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=lpOZX+dHz9XxjRDtH5GLorxQ2Si7tonYbZOshKJtM8M=; b=jjTGujU+3GWpb9dIuTtIBgd0BGPdLaZMBujd+XdGLfe/wZUO2oCrsm54wfBMSMGTma cjmn+s2PUzSW9LloFK83p19VVyhS6wx6JrGFowV6aRJ2nCOcHGNegQbuXxz3dEqisBcN t8fB6AjKlPnLZjilTSuRDB1YmerQn7xPr62YpZXj4J6r3d2gb50w9MTkEAOYSAyFwp67 lADk2tKtFTePDoSx+aYiWHpOtp3nC8TmKl/6tw13r9ZvfbxarKB99fUni7vghJWPGJAy oVP4xRSUwGO5RSrWTM5iP2g/oZbPRrMjUW5C70XjkktiNZqpC0Po+a1f7/xrMjsRrHZf twRQ== X-Gm-Message-State: APjAAAXAx1PmTe47dGlN0oTT+j0Y+3sDbwUzam8tLmxpOKbvcX6VeCvd OjOodPfIXH4pyvJHTpHj2aiAfA== X-Google-Smtp-Source: APXvYqzGkVvPG+VeW5WBWQ7FEUOErqJgtn8CgErajJWirEZi0wGmcm0S7JrkLLuZ+QkcMy0b4dXvZg== X-Received: by 2002:a17:902:222:: with SMTP id 31mr6454087plc.108.1580176740934; Mon, 27 Jan 2020 17:59:00 -0800 (PST) Received: from apsdesk.mtv.corp.google.com ([2620:15c:202:1:e09a:8d06:a338:aafb]) by smtp.gmail.com with ESMTPSA id a17sm364153pjv.6.2020.01.27.17.58.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Jan 2020 17:59:00 -0800 (PST) From: Abhishek Pandit-Subedi To: marcel@holtmann.org, luiz.dentz@gmail.com, alainm@chromium.org Cc: linux-bluetooth@vger.kernel.org, chromeos-bluetooth-upstreaming@chromium.org, Abhishek Pandit-Subedi , "David S. Miller" , Johan Hedberg , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Jakub Kicinski Subject: [RFC PATCH v2 4/4] Bluetooth: Pause discovery and advertising during suspend Date: Mon, 27 Jan 2020 17:58:48 -0800 Message-Id: <20200127175842.RFC.v2.4.Iccdad520469ca3524a7e5966c5f88e5bca756e13@changeid> X-Mailer: git-send-email 2.25.0.341.g760bfbb309-goog In-Reply-To: <20200128015848.226966-1-abhishekpandit@chromium.org> References: <20200128015848.226966-1-abhishekpandit@chromium.org> MIME-Version: 1.0 Sender: linux-bluetooth-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org To prevent spurious wake ups, we disable any discovery or advertising when we enter suspend and restore it when we exit suspend. While paused, we disable any management requests to modify discovery or advertising. Signed-off-by: Abhishek Pandit-Subedi --- Changes in v2: * Refactored pause discovery + advertising into its own patch include/net/bluetooth/hci_core.h | 11 ++++++++ net/bluetooth/hci_request.c | 43 ++++++++++++++++++++++++++++++++ net/bluetooth/mgmt.c | 41 ++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 49eae4a802ac..cbfaa80067d6 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -91,6 +91,12 @@ struct discovery_state { #define SUSPEND_NOTIFIER_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */ enum suspend_tasks { + SUSPEND_PAUSE_DISCOVERY, + SUSPEND_UNPAUSE_DISCOVERY, + + SUSPEND_PAUSE_ADVERTISING, + SUSPEND_UNPAUSE_ADVERTISING, + SUSPEND_LE_SET_SCAN_ENABLE, SUSPEND_DISCONNECTING, @@ -405,6 +411,11 @@ struct hci_dev { struct discovery_state discovery; + int discovery_old_state; + bool discovery_paused; + int advertising_old_state; + bool advertising_paused; + struct notifier_block suspend_notifier; struct work_struct suspend_prepare; enum suspended_state suspend_state_next; diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c index c930b9ff1cfd..487c84841351 100644 --- a/net/bluetooth/hci_request.c +++ b/net/bluetooth/hci_request.c @@ -1089,6 +1089,29 @@ void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next) hci_req_init(&req, hdev); if (next == BT_SUSPENDED) { + /* Pause discovery if not already stopped */ + old_state = hdev->discovery.state; + if (old_state != DISCOVERY_STOPPED) { + set_bit(SUSPEND_PAUSE_DISCOVERY, hdev->suspend_tasks); + hci_discovery_set_state(hdev, DISCOVERY_STOPPING); + queue_work(hdev->req_workqueue, &hdev->discov_update); + } + + hdev->discovery_paused = true; + hdev->discovery_old_state = old_state; + + /* Stop advertising */ + old_state = hci_dev_test_flag(hdev, HCI_ADVERTISING); + if (old_state) { + set_bit(SUSPEND_PAUSE_ADVERTISING, hdev->suspend_tasks); + cancel_delayed_work(&hdev->discov_off); + queue_delayed_work(hdev->req_workqueue, + &hdev->discov_off, 0); + } + + hdev->advertising_paused = true; + hdev->advertising_old_state = old_state; + /* Enable event filter for existing devices */ hci_req_set_event_filter(&req); @@ -1120,6 +1143,26 @@ void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next) /* Reset passive/background scanning to normal */ hci_req_enable_le_suspend_scan(&req, 0); + /* Unpause advertising */ + hdev->advertising_paused = false; + if (hdev->advertising_old_state) { + set_bit(SUSPEND_UNPAUSE_ADVERTISING, + hdev->suspend_tasks); + hci_dev_set_flag(hdev, HCI_ADVERTISING); + queue_work(hdev->req_workqueue, + &hdev->discoverable_update); + hdev->advertising_old_state = 0; + } + + /* Unpause discovery */ + hdev->discovery_paused = false; + if (hdev->discovery_old_state != DISCOVERY_STOPPED && + hdev->discovery_old_state != DISCOVERY_STOPPING) { + set_bit(SUSPEND_UNPAUSE_DISCOVERY, hdev->suspend_tasks); + hci_discovery_set_state(hdev, DISCOVERY_STARTING); + queue_work(hdev->req_workqueue, &hdev->discov_update); + } + hci_req_run(&req, le_suspend_req_complete); } diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 269ce70e501c..b3bd7a5ae718 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -1383,6 +1383,12 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data, goto failed; } + if (hdev->advertising_paused) { + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, + MGMT_STATUS_BUSY); + goto failed; + } + if (!hdev_is_powered(hdev)) { bool changed = false; @@ -3866,6 +3872,13 @@ void mgmt_start_discovery_complete(struct hci_dev *hdev, u8 status) } hci_dev_unlock(hdev); + + /* Handle suspend notifier */ + if (test_and_clear_bit(SUSPEND_UNPAUSE_DISCOVERY, + hdev->suspend_tasks)) { + BT_DBG("Unpaused discovery"); + wake_up(&hdev->suspend_wait_q); + } } static bool discovery_type_is_valid(struct hci_dev *hdev, uint8_t type, @@ -3927,6 +3940,13 @@ static int start_discovery_internal(struct sock *sk, struct hci_dev *hdev, goto failed; } + /* Can't start discovery when it is paused */ + if (hdev->discovery_paused) { + err = mgmt_cmd_complete(sk, hdev->id, op, MGMT_STATUS_BUSY, + &cp->type, sizeof(cp->type)); + goto failed; + } + /* Clear the discovery filter first to free any previously * allocated memory for the UUID list. */ @@ -4094,6 +4114,12 @@ void mgmt_stop_discovery_complete(struct hci_dev *hdev, u8 status) } hci_dev_unlock(hdev); + + /* Handle suspend notifier */ + if (test_and_clear_bit(SUSPEND_PAUSE_DISCOVERY, hdev->suspend_tasks)) { + BT_DBG("Paused discovery"); + wake_up(&hdev->suspend_wait_q); + } } static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data, @@ -4325,6 +4351,17 @@ static void set_advertising_complete(struct hci_dev *hdev, u8 status, if (match.sk) sock_put(match.sk); + /* Handle suspend notifier */ + if (test_and_clear_bit(SUSPEND_PAUSE_ADVERTISING, + hdev->suspend_tasks)) { + BT_DBG("Paused advertising"); + wake_up(&hdev->suspend_wait_q); + } else if (test_and_clear_bit(SUSPEND_UNPAUSE_ADVERTISING, + hdev->suspend_tasks)) { + BT_DBG("Unpaused advertising"); + wake_up(&hdev->suspend_wait_q); + } + /* If "Set Advertising" was just disabled and instance advertising was * set up earlier, then re-enable multi-instance advertising. */ @@ -4376,6 +4413,10 @@ static int set_advertising(struct sock *sk, struct hci_dev *hdev, void *data, return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING, MGMT_STATUS_INVALID_PARAMS); + if (hdev->advertising_paused) + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING, + MGMT_STATUS_BUSY); + hci_dev_lock(hdev); val = !!cp->val;