Bluetooth: Call shutdown for HCI_USER_CHANNEL
Some drivers depend on shutdown being called for proper operation. Unset HCI_USER_CHANNEL and call the full close routine since shutdown is complementary to setup. Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
4b8af331bb
commit
8dbc3e75a0
@ -4727,6 +4727,31 @@ static void hci_pend_le_actions_clear(struct hci_dev *hdev)
|
||||
BT_DBG("All LE pending actions cleared");
|
||||
}
|
||||
|
||||
static int hci_dev_shutdown(struct hci_dev *hdev)
|
||||
{
|
||||
int err = 0;
|
||||
/* Similar to how we first do setup and then set the exclusive access
|
||||
* bit for userspace, we must first unset userchannel and then clean up.
|
||||
* Otherwise, the kernel can't properly use the hci channel to clean up
|
||||
* the controller (some shutdown routines require sending additional
|
||||
* commands to the controller for example).
|
||||
*/
|
||||
bool was_userchannel =
|
||||
hci_dev_test_and_clear_flag(hdev, HCI_USER_CHANNEL);
|
||||
|
||||
if (!hci_dev_test_flag(hdev, HCI_UNREGISTER) &&
|
||||
test_bit(HCI_UP, &hdev->flags)) {
|
||||
/* Execute vendor specific shutdown routine */
|
||||
if (hdev->shutdown)
|
||||
err = hdev->shutdown(hdev);
|
||||
}
|
||||
|
||||
if (was_userchannel)
|
||||
hci_dev_set_flag(hdev, HCI_USER_CHANNEL);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int hci_dev_close_sync(struct hci_dev *hdev)
|
||||
{
|
||||
bool auto_off;
|
||||
@ -4746,13 +4771,7 @@ int hci_dev_close_sync(struct hci_dev *hdev)
|
||||
hdev->adv_instance_timeout = 0;
|
||||
}
|
||||
|
||||
if (!hci_dev_test_flag(hdev, HCI_UNREGISTER) &&
|
||||
!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
|
||||
test_bit(HCI_UP, &hdev->flags)) {
|
||||
/* Execute vendor specific shutdown routine */
|
||||
if (hdev->shutdown)
|
||||
err = hdev->shutdown(hdev);
|
||||
}
|
||||
err = hci_dev_shutdown(hdev);
|
||||
|
||||
if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
|
||||
cancel_delayed_work_sync(&hdev->cmd_timer);
|
||||
|
Loading…
x
Reference in New Issue
Block a user