Commit 5a750137 authored by Brian Gix's avatar Brian Gix Committed by Marcel Holtmann

Bluetooth: hci_sync: Convert MGMT_OP_GET_CLOCK_INFO

Synchronous version of MGMT_OP_GET_CLOCK_INFO.
Signed-off-by: default avatarBrian Gix <brian.gix@intel.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent 2f2eb0c9
...@@ -70,6 +70,7 @@ int hci_update_passive_scan(struct hci_dev *hdev); ...@@ -70,6 +70,7 @@ int hci_update_passive_scan(struct hci_dev *hdev);
int hci_read_rssi_sync(struct hci_dev *hdev, __le16 handle); int hci_read_rssi_sync(struct hci_dev *hdev, __le16 handle);
int hci_read_tx_power_sync(struct hci_dev *hdev, __le16 handle, u8 type); int hci_read_tx_power_sync(struct hci_dev *hdev, __le16 handle, u8 type);
int hci_write_sc_support_sync(struct hci_dev *hdev, u8 val); int hci_write_sc_support_sync(struct hci_dev *hdev, u8 val);
int hci_read_clock_sync(struct hci_dev *hdev, struct hci_cp_read_clock *cp);
int hci_write_fast_connectable_sync(struct hci_dev *hdev, bool enable); int hci_write_fast_connectable_sync(struct hci_dev *hdev, bool enable);
int hci_update_scan_sync(struct hci_dev *hdev); int hci_update_scan_sync(struct hci_dev *hdev);
......
...@@ -1318,6 +1318,12 @@ int hci_read_rssi_sync(struct hci_dev *hdev, __le16 handle) ...@@ -1318,6 +1318,12 @@ int hci_read_rssi_sync(struct hci_dev *hdev, __le16 handle)
sizeof(cp), &cp, HCI_CMD_TIMEOUT); sizeof(cp), &cp, HCI_CMD_TIMEOUT);
} }
int hci_read_clock_sync(struct hci_dev *hdev, struct hci_cp_read_clock *cp)
{
return __hci_cmd_sync_status(hdev, HCI_OP_READ_CLOCK,
sizeof(*cp), cp, HCI_CMD_TIMEOUT);
}
int hci_read_tx_power_sync(struct hci_dev *hdev, __le16 handle, u8 type) int hci_read_tx_power_sync(struct hci_dev *hdev, __le16 handle, u8 type)
{ {
struct hci_cp_read_tx_power cp; struct hci_cp_read_tx_power cp;
......
...@@ -927,13 +927,6 @@ static struct mgmt_pending_cmd *pending_find(u16 opcode, struct hci_dev *hdev) ...@@ -927,13 +927,6 @@ static struct mgmt_pending_cmd *pending_find(u16 opcode, struct hci_dev *hdev)
return mgmt_pending_find(HCI_CHANNEL_CONTROL, opcode, hdev); return mgmt_pending_find(HCI_CHANNEL_CONTROL, opcode, hdev);
} }
static struct mgmt_pending_cmd *pending_find_data(u16 opcode,
struct hci_dev *hdev,
const void *data)
{
return mgmt_pending_find_data(HCI_CHANNEL_CONTROL, opcode, hdev, data);
}
u8 mgmt_get_adv_discov_flags(struct hci_dev *hdev) u8 mgmt_get_adv_discov_flags(struct hci_dev *hdev)
{ {
struct mgmt_pending_cmd *cmd; struct mgmt_pending_cmd *cmd;
...@@ -6702,72 +6695,68 @@ static int get_conn_info(struct sock *sk, struct hci_dev *hdev, void *data, ...@@ -6702,72 +6695,68 @@ static int get_conn_info(struct sock *sk, struct hci_dev *hdev, void *data,
return err; return err;
} }
static int clock_info_cmd_complete(struct mgmt_pending_cmd *cmd, u8 status) static void get_clock_info_complete(struct hci_dev *hdev, void *data, int err)
{ {
struct hci_conn *conn = cmd->user_data; struct mgmt_pending_cmd *cmd = data;
struct mgmt_cp_get_clock_info *cp = cmd->param;
struct mgmt_rp_get_clock_info rp; struct mgmt_rp_get_clock_info rp;
struct hci_dev *hdev; struct hci_conn *conn = cmd->user_data;
int err; u8 status = mgmt_status(err);
bt_dev_dbg(hdev, "err %d", err);
memset(&rp, 0, sizeof(rp)); memset(&rp, 0, sizeof(rp));
memcpy(&rp.addr, cmd->param, sizeof(rp.addr)); bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
rp.addr.type = cp->addr.type;
if (status) if (err)
goto complete; goto complete;
hdev = hci_dev_get(cmd->index);
if (hdev) {
rp.local_clock = cpu_to_le32(hdev->clock); rp.local_clock = cpu_to_le32(hdev->clock);
hci_dev_put(hdev);
}
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:
err = mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, &rp, mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, &rp,
sizeof(rp)); sizeof(rp));
if (conn) { mgmt_pending_free(cmd);
hci_conn_drop(conn);
hci_conn_put(conn);
}
return err;
} }
static void get_clock_info_complete(struct hci_dev *hdev, u8 status, u16 opcode) static int get_clock_info_sync(struct hci_dev *hdev, void *data)
{ {
struct hci_cp_read_clock *hci_cp; struct mgmt_pending_cmd *cmd = data;
struct mgmt_pending_cmd *cmd; struct mgmt_cp_get_clock_info *cp = cmd->param;
struct hci_conn *conn; struct hci_cp_read_clock hci_cp;
struct hci_conn *conn = cmd->user_data;
bt_dev_dbg(hdev, "status %u", status); int err;
hci_dev_lock(hdev); memset(&hci_cp, 0, sizeof(hci_cp));
err = hci_read_clock_sync(hdev, &hci_cp);
hci_cp = hci_sent_cmd_data(hdev, HCI_OP_READ_CLOCK); if (conn) {
if (!hci_cp) /* Make sure connection still exists */
goto unlock; conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
&cp->addr.bdaddr);
if (hci_cp->which) { if (conn && conn == cmd->user_data &&
u16 handle = __le16_to_cpu(hci_cp->handle); conn->state == BT_CONNECTED) {
conn = hci_conn_hash_lookup_handle(hdev, handle); hci_cp.handle = cpu_to_le16(conn->handle);
} else { hci_cp.which = 0x01; /* Piconet clock */
conn = NULL; 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;
}
} }
cmd = pending_find_data(MGMT_OP_GET_CLOCK_INFO, hdev, conn); return err;
if (!cmd)
goto unlock;
cmd->cmd_complete(cmd, mgmt_status(status));
mgmt_pending_remove(cmd);
unlock:
hci_dev_unlock(hdev);
} }
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,
...@@ -6775,9 +6764,7 @@ static int get_clock_info(struct sock *sk, struct hci_dev *hdev, void *data, ...@@ -6775,9 +6764,7 @@ static int get_clock_info(struct sock *sk, struct hci_dev *hdev, void *data,
{ {
struct mgmt_cp_get_clock_info *cp = data; struct mgmt_cp_get_clock_info *cp = data;
struct mgmt_rp_get_clock_info rp; struct mgmt_rp_get_clock_info rp;
struct hci_cp_read_clock hci_cp;
struct mgmt_pending_cmd *cmd; struct mgmt_pending_cmd *cmd;
struct hci_request req;
struct hci_conn *conn; struct hci_conn *conn;
int err; int err;
...@@ -6815,31 +6802,25 @@ static int get_clock_info(struct sock *sk, struct hci_dev *hdev, void *data, ...@@ -6815,31 +6802,25 @@ static int get_clock_info(struct sock *sk, struct hci_dev *hdev, void *data,
conn = NULL; conn = NULL;
} }
cmd = mgmt_pending_add(sk, MGMT_OP_GET_CLOCK_INFO, hdev, data, len); cmd = mgmt_pending_new(sk, MGMT_OP_GET_CLOCK_INFO, hdev, data, len);
if (!cmd) { if (!cmd)
err = -ENOMEM; err = -ENOMEM;
goto unlock; else
} err = hci_cmd_sync_queue(hdev, get_clock_info_sync, cmd,
get_clock_info_complete);
cmd->cmd_complete = clock_info_cmd_complete;
hci_req_init(&req, hdev); if (err < 0) {
err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_CLOCK_INFO,
MGMT_STATUS_FAILED, &rp, sizeof(rp));
memset(&hci_cp, 0, sizeof(hci_cp)); if (cmd)
hci_req_add(&req, HCI_OP_READ_CLOCK, sizeof(hci_cp), &hci_cp); mgmt_pending_free(cmd);
if (conn) { } else if (conn) {
hci_conn_hold(conn); hci_conn_hold(conn);
cmd->user_data = hci_conn_get(conn); cmd->user_data = hci_conn_get(conn);
hci_cp.handle = cpu_to_le16(conn->handle);
hci_cp.which = 0x01; /* Piconet clock */
hci_req_add(&req, HCI_OP_READ_CLOCK, sizeof(hci_cp), &hci_cp);
} }
err = hci_req_run(&req, get_clock_info_complete);
if (err < 0)
mgmt_pending_remove(cmd);
unlock: unlock:
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
......
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