Commit 039fada5 authored by Chan-yeol Park's avatar Chan-yeol Park Committed by Johan Hedberg

Bluetooth: Fix hci_sync missing wakeup interrupt

__hci_cmd_sync_ev(), __hci_req_sync() could miss wake_up_interrupt from
hci_req_sync_complete() because hci_cmd_work() workqueue and its response
could be completed before they are ready to get the signal through
add_wait_queue(), set_current_state(TASK_INTERRUPTIBLE).
Signed-off-by: default avatarChan-yeol Park <chanyeol.park@samsung.com>
Signed-off-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: default avatarJohan Hedberg <johan.hedberg@intel.com>
parent 6bc6c49f
......@@ -1147,13 +1147,15 @@ struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
hdev->req_status = HCI_REQ_PEND;
err = hci_req_run(&req, hci_req_sync_complete);
if (err < 0)
return ERR_PTR(err);
add_wait_queue(&hdev->req_wait_q, &wait);
set_current_state(TASK_INTERRUPTIBLE);
err = hci_req_run(&req, hci_req_sync_complete);
if (err < 0) {
remove_wait_queue(&hdev->req_wait_q, &wait);
return ERR_PTR(err);
}
schedule_timeout(timeout);
remove_wait_queue(&hdev->req_wait_q, &wait);
......@@ -1211,10 +1213,15 @@ static int __hci_req_sync(struct hci_dev *hdev,
func(&req, opt);
add_wait_queue(&hdev->req_wait_q, &wait);
set_current_state(TASK_INTERRUPTIBLE);
err = hci_req_run(&req, hci_req_sync_complete);
if (err < 0) {
hdev->req_status = 0;
remove_wait_queue(&hdev->req_wait_q, &wait);
/* ENODATA means the HCI request command queue is empty.
* This can happen when a request with conditionals doesn't
* trigger any commands to be sent. This is normal behavior
......@@ -1226,9 +1233,6 @@ static int __hci_req_sync(struct hci_dev *hdev,
return err;
}
add_wait_queue(&hdev->req_wait_q, &wait);
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(timeout);
remove_wait_queue(&hdev->req_wait_q, &wait);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment