mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
Bluetooth: MGMT: Fix Add Device to responding before completing
Add Device with LE type requires updating resolving/accept list which
requires quite a number of commands to complete and each of them may
fail, so instead of pretending it would always work this checks the
return of hci_update_passive_scan_sync which indicates if everything
worked as intended.
Fixes: e8907f7654
("Bluetooth: hci_sync: Make use of hci_cmd_sync_queue set 3")
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
c2994b0084
commit
a182d9c84f
1 changed files with 36 additions and 2 deletions
|
@ -7655,6 +7655,24 @@ static void device_added(struct sock *sk, struct hci_dev *hdev,
|
|||
mgmt_event(MGMT_EV_DEVICE_ADDED, hdev, &ev, sizeof(ev), sk);
|
||||
}
|
||||
|
||||
static void add_device_complete(struct hci_dev *hdev, void *data, int err)
|
||||
{
|
||||
struct mgmt_pending_cmd *cmd = data;
|
||||
struct mgmt_cp_add_device *cp = cmd->param;
|
||||
|
||||
if (!err) {
|
||||
device_added(cmd->sk, hdev, &cp->addr.bdaddr, cp->addr.type,
|
||||
cp->action);
|
||||
device_flags_changed(NULL, hdev, &cp->addr.bdaddr,
|
||||
cp->addr.type, hdev->conn_flags,
|
||||
PTR_UINT(cmd->user_data));
|
||||
}
|
||||
|
||||
mgmt_cmd_complete(cmd->sk, hdev->id, MGMT_OP_ADD_DEVICE,
|
||||
mgmt_status(err), &cp->addr, sizeof(cp->addr));
|
||||
mgmt_pending_free(cmd);
|
||||
}
|
||||
|
||||
static int add_device_sync(struct hci_dev *hdev, void *data)
|
||||
{
|
||||
return hci_update_passive_scan_sync(hdev);
|
||||
|
@ -7663,6 +7681,7 @@ static int add_device_sync(struct hci_dev *hdev, void *data)
|
|||
static int add_device(struct sock *sk, struct hci_dev *hdev,
|
||||
void *data, u16 len)
|
||||
{
|
||||
struct mgmt_pending_cmd *cmd;
|
||||
struct mgmt_cp_add_device *cp = data;
|
||||
u8 auto_conn, addr_type;
|
||||
struct hci_conn_params *params;
|
||||
|
@ -7743,9 +7762,24 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
|
|||
current_flags = params->flags;
|
||||
}
|
||||
|
||||
err = hci_cmd_sync_queue(hdev, add_device_sync, NULL, NULL);
|
||||
if (err < 0)
|
||||
cmd = mgmt_pending_new(sk, MGMT_OP_ADD_DEVICE, hdev, data, len);
|
||||
if (!cmd) {
|
||||
err = -ENOMEM;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
cmd->user_data = UINT_PTR(current_flags);
|
||||
|
||||
err = hci_cmd_sync_queue(hdev, add_device_sync, cmd,
|
||||
add_device_complete);
|
||||
if (err < 0) {
|
||||
err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE,
|
||||
MGMT_STATUS_FAILED, &cp->addr,
|
||||
sizeof(cp->addr));
|
||||
mgmt_pending_free(cmd);
|
||||
}
|
||||
|
||||
goto unlock;
|
||||
|
||||
added:
|
||||
device_added(sk, hdev, &cp->addr.bdaddr, cp->addr.type, cp->action);
|
||||
|
|
Loading…
Add table
Reference in a new issue