Messages in this thread | | | Subject | Re: [PATCH v2 1/2] Bluetooth: Disable LE Advertising in hci_suspend_dev() | From | Kai-Heng Feng <> | Date | Fri, 5 Jul 2019 14:58:27 +0800 |
| |
at 11:00, Kai Heng Feng <kai.heng.feng@canonical.com> wrote:
> Hi Marcel, > > at 5:25 PM, Kai-Heng Feng <kai.heng.feng@canonical.com> wrote: > >> LE Advertising may wake up system during system-wide sleep, disable it >> to prevent this issue from happening. >> >> Do the reverse in hci_resume_dev(). > > Do you have any suggestion for this patch?
Please let me know where I can do further improvement.
This can solve a hard freeze during system suspend.
Kai-Heng
> > Kai-Heng > >> Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com> >> --- >> v2: >> - Abstract away enabling/disabling LE advertising from btusb. >> >> include/net/bluetooth/hci_core.h | 1 + >> net/bluetooth/hci_core.c | 47 ++++++++++++++++++++++++++++++++ >> 2 files changed, 48 insertions(+) >> >> diff --git a/include/net/bluetooth/hci_core.h >> b/include/net/bluetooth/hci_core.h >> index 094e61e07030..65574943131d 100644 >> --- a/include/net/bluetooth/hci_core.h >> +++ b/include/net/bluetooth/hci_core.h >> @@ -269,6 +269,7 @@ struct hci_dev { >> __u16 le_max_rx_time; >> __u8 le_max_key_size; >> __u8 le_min_key_size; >> + __u8 le_events[8]; >> __u16 discov_interleaved_timeout; >> __u16 conn_info_min_age; >> __u16 conn_info_max_age; >> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c >> index d6b2540ba7f8..7c19e3b9294c 100644 >> --- a/net/bluetooth/hci_core.c >> +++ b/net/bluetooth/hci_core.c >> @@ -412,6 +412,49 @@ static void hci_setup_event_mask(struct hci_request >> *req) >> hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events); >> } >> >> +static int hci_enable_le_advertising_req(struct hci_request *req, >> unsigned long opt) >> +{ >> + struct hci_dev *hdev = req->hdev; >> + u8 events[8]; >> + memcpy(events, hdev->le_events, sizeof(events)); >> + >> + hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, sizeof(events), >> + events); >> + >> + return 0; >> +} >> + >> +static int hci_disable_le_advertising_req(struct hci_request *req, >> unsigned long opt) >> +{ >> + struct hci_dev *hdev = req->hdev; >> + >> + u8 events[8]; >> + memcpy(events, hdev->le_events, sizeof(events)); >> + >> + events[0] &= ~(u8)0x02; /* LE Advertising Report */ >> + >> + hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, sizeof(events), >> + events); >> + >> + return 0; >> +} >> + >> +static int hci_enable_le_advertising(struct hci_dev *hdev) >> +{ >> + if (!lmp_le_capable(hdev)) >> + return 0; >> + >> + return __hci_req_sync(hdev, hci_enable_le_advertising_req, 0, >> HCI_CMD_TIMEOUT, NULL); >> +} >> + >> +static int hci_disable_le_advertising(struct hci_dev *hdev) >> +{ >> + if (!lmp_le_capable(hdev)) >> + return 0; >> + >> + return __hci_req_sync(hdev, hci_disable_le_advertising_req, 0, >> HCI_CMD_TIMEOUT, NULL); >> +} >> + >> static int hci_init2_req(struct hci_request *req, unsigned long opt) >> { >> struct hci_dev *hdev = req->hdev; >> @@ -772,6 +815,8 @@ static int hci_init3_req(struct hci_request *req, >> unsigned long opt) >> } >> >> hci_set_le_support(req); >> + >> + memcpy(hdev->le_events, events, sizeof(events)); >> } >> >> /* Read features beyond page 1 if available */ >> @@ -3431,6 +3476,7 @@ EXPORT_SYMBOL(hci_unregister_dev); >> /* Suspend HCI device */ >> int hci_suspend_dev(struct hci_dev *hdev) >> { >> + hci_disable_le_advertising(hdev); >> hci_sock_dev_event(hdev, HCI_DEV_SUSPEND); >> return 0; >> } >> @@ -3440,6 +3486,7 @@ EXPORT_SYMBOL(hci_suspend_dev); >> int hci_resume_dev(struct hci_dev *hdev) >> { >> hci_sock_dev_event(hdev, HCI_DEV_RESUME); >> + hci_enable_le_advertising(hdev); >> return 0; >> } >> EXPORT_SYMBOL(hci_resume_dev); >> -- >> 2.17.1
| |