Bluetooth: close HCI device when user channel socket gets closed
With 9380f9eacfbbee701daa416edd6625efcd3e29e1 the order of unsetting the HCI_USER_CHANNEL flag of the HCI device was reverted to ensure the device is first closed before making it available again. Due to hci_dev_close checking for HCI_USER_CHANNEL being set on the device it was never really closed and was kept opened. We're now calling hci_dev_do_close directly to make sure the device is correctly closed and we keep the correct order to unset the flag on our device object. Signed-off-by: Simon Fels <simon.fels@canonical.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org> (cherry picked from bluetooth-next 4c63f83c2c2e16a13ce274ee678e28246bd33645) BugLink: http://bugs.launchpad.net/bugs/1489327 Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
This commit is contained in:
@@ -961,6 +961,7 @@ int hci_resume_dev(struct hci_dev *hdev);
|
|||||||
int hci_reset_dev(struct hci_dev *hdev);
|
int hci_reset_dev(struct hci_dev *hdev);
|
||||||
int hci_dev_open(__u16 dev);
|
int hci_dev_open(__u16 dev);
|
||||||
int hci_dev_close(__u16 dev);
|
int hci_dev_close(__u16 dev);
|
||||||
|
int hci_dev_do_close(struct hci_dev *hdev);
|
||||||
int hci_dev_reset(__u16 dev);
|
int hci_dev_reset(__u16 dev);
|
||||||
int hci_dev_reset_stat(__u16 dev);
|
int hci_dev_reset_stat(__u16 dev);
|
||||||
int hci_dev_cmd(unsigned int cmd, void __user *arg);
|
int hci_dev_cmd(unsigned int cmd, void __user *arg);
|
||||||
|
|||||||
@@ -1548,7 +1548,7 @@ static void hci_pend_le_actions_clear(struct hci_dev *hdev)
|
|||||||
BT_DBG("All LE pending actions cleared");
|
BT_DBG("All LE pending actions cleared");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hci_dev_do_close(struct hci_dev *hdev)
|
int hci_dev_do_close(struct hci_dev *hdev)
|
||||||
{
|
{
|
||||||
BT_DBG("%s %p", hdev->name, hdev);
|
BT_DBG("%s %p", hdev->name, hdev);
|
||||||
|
|
||||||
|
|||||||
@@ -503,7 +503,16 @@ static int hci_sock_release(struct socket *sock)
|
|||||||
|
|
||||||
if (hdev) {
|
if (hdev) {
|
||||||
if (hci_pi(sk)->channel == HCI_CHANNEL_USER) {
|
if (hci_pi(sk)->channel == HCI_CHANNEL_USER) {
|
||||||
hci_dev_close(hdev->id);
|
/* When releasing an user channel exclusive access,
|
||||||
|
* call hci_dev_do_close directly instead of calling
|
||||||
|
* hci_dev_close to ensure the exclusive access will
|
||||||
|
* be released and the controller brought back down.
|
||||||
|
*
|
||||||
|
* The checking of HCI_AUTO_OFF is not needed in this
|
||||||
|
* case since it will have been cleared already when
|
||||||
|
* opening the user channel.
|
||||||
|
*/
|
||||||
|
hci_dev_do_close(hdev);
|
||||||
hci_dev_clear_flag(hdev, HCI_USER_CHANNEL);
|
hci_dev_clear_flag(hdev, HCI_USER_CHANNEL);
|
||||||
mgmt_index_added(hdev);
|
mgmt_index_added(hdev);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user