mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 20:54:03 +02:00
Bluetooth: MGMT: Fix holding hci_conn reference while command is queued
This removes the use of hci_conn_hold from Get Conn Info and Get Clock Info since the callback can just do a lookup by address using the cmd data and only then set cmd->user_data to pass to the complete callback. Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
1f7435c8f6
commit
7b445e220d
|
|
@ -6711,11 +6711,6 @@ static void get_conn_info_complete(struct hci_dev *hdev, void *data, int err)
|
||||||
mgmt_cmd_complete(cmd->sk, cmd->index, MGMT_OP_GET_CONN_INFO, status,
|
mgmt_cmd_complete(cmd->sk, cmd->index, MGMT_OP_GET_CONN_INFO, status,
|
||||||
&rp, sizeof(rp));
|
&rp, sizeof(rp));
|
||||||
|
|
||||||
if (conn) {
|
|
||||||
hci_conn_drop(conn);
|
|
||||||
hci_conn_put(conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
mgmt_pending_free(cmd);
|
mgmt_pending_free(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -6734,15 +6729,10 @@ static int get_conn_info_sync(struct hci_dev *hdev, void *data)
|
||||||
else
|
else
|
||||||
conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr);
|
conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr);
|
||||||
|
|
||||||
if (!conn || conn != cmd->user_data || conn->state != BT_CONNECTED) {
|
if (!conn || conn->state != BT_CONNECTED)
|
||||||
if (cmd->user_data) {
|
|
||||||
hci_conn_drop(cmd->user_data);
|
|
||||||
hci_conn_put(cmd->user_data);
|
|
||||||
cmd->user_data = NULL;
|
|
||||||
}
|
|
||||||
return MGMT_STATUS_NOT_CONNECTED;
|
return MGMT_STATUS_NOT_CONNECTED;
|
||||||
}
|
|
||||||
|
|
||||||
|
cmd->user_data = conn;
|
||||||
handle = cpu_to_le16(conn->handle);
|
handle = cpu_to_le16(conn->handle);
|
||||||
|
|
||||||
/* Refresh RSSI each time */
|
/* Refresh RSSI each time */
|
||||||
|
|
@ -6824,8 +6814,6 @@ static int get_conn_info(struct sock *sk, struct hci_dev *hdev, void *data,
|
||||||
if (!cmd) {
|
if (!cmd) {
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
} else {
|
} else {
|
||||||
hci_conn_hold(conn);
|
|
||||||
cmd->user_data = hci_conn_get(conn);
|
|
||||||
err = hci_cmd_sync_queue(hdev, get_conn_info_sync,
|
err = hci_cmd_sync_queue(hdev, get_conn_info_sync,
|
||||||
cmd, get_conn_info_complete);
|
cmd, get_conn_info_complete);
|
||||||
}
|
}
|
||||||
|
|
@ -6878,8 +6866,6 @@ static void get_clock_info_complete(struct hci_dev *hdev, void *data, int err)
|
||||||
if (conn) {
|
if (conn) {
|
||||||
rp.piconet_clock = cpu_to_le32(conn->clock);
|
rp.piconet_clock = cpu_to_le32(conn->clock);
|
||||||
rp.accuracy = cpu_to_le16(conn->clock_accuracy);
|
rp.accuracy = cpu_to_le16(conn->clock_accuracy);
|
||||||
hci_conn_drop(conn);
|
|
||||||
hci_conn_put(conn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
complete:
|
complete:
|
||||||
|
|
@ -6894,30 +6880,21 @@ static int get_clock_info_sync(struct hci_dev *hdev, void *data)
|
||||||
struct mgmt_pending_cmd *cmd = data;
|
struct mgmt_pending_cmd *cmd = data;
|
||||||
struct mgmt_cp_get_clock_info *cp = cmd->param;
|
struct mgmt_cp_get_clock_info *cp = cmd->param;
|
||||||
struct hci_cp_read_clock hci_cp;
|
struct hci_cp_read_clock hci_cp;
|
||||||
struct hci_conn *conn = cmd->user_data;
|
struct hci_conn *conn;
|
||||||
int err;
|
|
||||||
|
|
||||||
memset(&hci_cp, 0, sizeof(hci_cp));
|
memset(&hci_cp, 0, sizeof(hci_cp));
|
||||||
err = hci_read_clock_sync(hdev, &hci_cp);
|
hci_read_clock_sync(hdev, &hci_cp);
|
||||||
|
|
||||||
if (conn) {
|
/* Make sure connection still exists */
|
||||||
/* Make sure connection still exists */
|
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->addr.bdaddr);
|
||||||
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
|
if (!conn || conn->state != BT_CONNECTED)
|
||||||
&cp->addr.bdaddr);
|
return MGMT_STATUS_NOT_CONNECTED;
|
||||||
|
|
||||||
if (conn && conn == cmd->user_data &&
|
cmd->user_data = conn;
|
||||||
conn->state == BT_CONNECTED) {
|
hci_cp.handle = cpu_to_le16(conn->handle);
|
||||||
hci_cp.handle = cpu_to_le16(conn->handle);
|
hci_cp.which = 0x01; /* Piconet clock */
|
||||||
hci_cp.which = 0x01; /* Piconet clock */
|
|
||||||
err = hci_read_clock_sync(hdev, &hci_cp);
|
|
||||||
} else if (cmd->user_data) {
|
|
||||||
hci_conn_drop(cmd->user_data);
|
|
||||||
hci_conn_put(cmd->user_data);
|
|
||||||
cmd->user_data = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
return hci_read_clock_sync(hdev, &hci_cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_clock_info(struct sock *sk, struct hci_dev *hdev, void *data,
|
static int get_clock_info(struct sock *sk, struct hci_dev *hdev, void *data,
|
||||||
|
|
@ -6976,10 +6953,6 @@ static int get_clock_info(struct sock *sk, struct hci_dev *hdev, void *data,
|
||||||
|
|
||||||
if (cmd)
|
if (cmd)
|
||||||
mgmt_pending_free(cmd);
|
mgmt_pending_free(cmd);
|
||||||
|
|
||||||
} else if (conn) {
|
|
||||||
hci_conn_hold(conn);
|
|
||||||
cmd->user_data = hci_conn_get(conn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user