Skip to content

Commit e07a06b

Browse files
bgixVudentz
authored andcommitted
Bluetooth: Convert SCO configure_datapath to hci_sync
Recoding HCI cmds to offload SCO codec to use hci_sync mechanism rather than deprecated hci_request mechanism. Signed-off-by: Brian Gix <brian.gix@intel.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
1 parent 9e63767 commit e07a06b

File tree

3 files changed

+75
-60
lines changed

3 files changed

+75
-60
lines changed

net/bluetooth/hci_conn.c

Lines changed: 75 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ struct sco_param {
4444
u8 retrans_effort;
4545
};
4646

47+
struct conn_handle_t {
48+
struct hci_conn *conn;
49+
__u16 handle;
50+
};
51+
4752
static const struct sco_param esco_param_cvsd[] = {
4853
{ EDR_ESCO_MASK & ~ESCO_2EV3, 0x000a, 0x01 }, /* S3 */
4954
{ EDR_ESCO_MASK & ~ESCO_2EV3, 0x0007, 0x01 }, /* S2 */
@@ -316,17 +321,60 @@ static bool find_next_esco_param(struct hci_conn *conn,
316321
return conn->attempt <= size;
317322
}
318323

319-
static bool hci_enhanced_setup_sync_conn(struct hci_conn *conn, __u16 handle)
324+
static int configure_datapath_sync(struct hci_dev *hdev, struct bt_codec *codec)
320325
{
321-
struct hci_dev *hdev = conn->hdev;
326+
int err;
327+
__u8 vnd_len, *vnd_data = NULL;
328+
struct hci_op_configure_data_path *cmd = NULL;
329+
330+
err = hdev->get_codec_config_data(hdev, ESCO_LINK, codec, &vnd_len,
331+
&vnd_data);
332+
if (err < 0)
333+
goto error;
334+
335+
cmd = kzalloc(sizeof(*cmd) + vnd_len, GFP_KERNEL);
336+
if (!cmd) {
337+
err = -ENOMEM;
338+
goto error;
339+
}
340+
341+
err = hdev->get_data_path_id(hdev, &cmd->data_path_id);
342+
if (err < 0)
343+
goto error;
344+
345+
cmd->vnd_len = vnd_len;
346+
memcpy(cmd->vnd_data, vnd_data, vnd_len);
347+
348+
cmd->direction = 0x00;
349+
__hci_cmd_sync_status(hdev, HCI_CONFIGURE_DATA_PATH,
350+
sizeof(*cmd) + vnd_len, cmd, HCI_CMD_TIMEOUT);
351+
352+
cmd->direction = 0x01;
353+
err = __hci_cmd_sync_status(hdev, HCI_CONFIGURE_DATA_PATH,
354+
sizeof(*cmd) + vnd_len, cmd,
355+
HCI_CMD_TIMEOUT);
356+
error:
357+
358+
kfree(cmd);
359+
kfree(vnd_data);
360+
return err;
361+
}
362+
363+
static int hci_enhanced_setup_sync(struct hci_dev *hdev, void *data)
364+
{
365+
struct conn_handle_t *conn_handle = data;
366+
struct hci_conn *conn = conn_handle->conn;
367+
__u16 handle = conn_handle->handle;
322368
struct hci_cp_enhanced_setup_sync_conn cp;
323369
const struct sco_param *param;
324370

371+
kfree(conn_handle);
372+
325373
bt_dev_dbg(hdev, "hcon %p", conn);
326374

327375
/* for offload use case, codec needs to configured before opening SCO */
328376
if (conn->codec.data_path)
329-
hci_req_configure_datapath(hdev, &conn->codec);
377+
configure_datapath_sync(hdev, &conn->codec);
330378

331379
conn->state = BT_CONNECT;
332380
conn->out = true;
@@ -344,7 +392,7 @@ static bool hci_enhanced_setup_sync_conn(struct hci_conn *conn, __u16 handle)
344392
case BT_CODEC_MSBC:
345393
if (!find_next_esco_param(conn, esco_param_msbc,
346394
ARRAY_SIZE(esco_param_msbc)))
347-
return false;
395+
return -EINVAL;
348396

349397
param = &esco_param_msbc[conn->attempt - 1];
350398
cp.tx_coding_format.id = 0x05;
@@ -396,11 +444,11 @@ static bool hci_enhanced_setup_sync_conn(struct hci_conn *conn, __u16 handle)
396444
if (lmp_esco_capable(conn->link)) {
397445
if (!find_next_esco_param(conn, esco_param_cvsd,
398446
ARRAY_SIZE(esco_param_cvsd)))
399-
return false;
447+
return -EINVAL;
400448
param = &esco_param_cvsd[conn->attempt - 1];
401449
} else {
402450
if (conn->attempt > ARRAY_SIZE(sco_param_cvsd))
403-
return false;
451+
return -EINVAL;
404452
param = &sco_param_cvsd[conn->attempt - 1];
405453
}
406454
cp.tx_coding_format.id = 2;
@@ -423,17 +471,17 @@ static bool hci_enhanced_setup_sync_conn(struct hci_conn *conn, __u16 handle)
423471
cp.out_transport_unit_size = 16;
424472
break;
425473
default:
426-
return false;
474+
return -EINVAL;
427475
}
428476

429477
cp.retrans_effort = param->retrans_effort;
430478
cp.pkt_type = __cpu_to_le16(param->pkt_type);
431479
cp.max_latency = __cpu_to_le16(param->max_latency);
432480

433481
if (hci_send_cmd(hdev, HCI_OP_ENHANCED_SETUP_SYNC_CONN, sizeof(cp), &cp) < 0)
434-
return false;
482+
return -EIO;
435483

436-
return true;
484+
return 0;
437485
}
438486

439487
static bool hci_setup_sync_conn(struct hci_conn *conn, __u16 handle)
@@ -490,8 +538,24 @@ static bool hci_setup_sync_conn(struct hci_conn *conn, __u16 handle)
490538

491539
bool hci_setup_sync(struct hci_conn *conn, __u16 handle)
492540
{
493-
if (enhanced_sync_conn_capable(conn->hdev))
494-
return hci_enhanced_setup_sync_conn(conn, handle);
541+
int result;
542+
struct conn_handle_t *conn_handle;
543+
544+
if (enhanced_sync_conn_capable(conn->hdev)) {
545+
conn_handle = kzalloc(sizeof(*conn_handle), GFP_KERNEL);
546+
547+
if (!conn_handle)
548+
return false;
549+
550+
conn_handle->conn = conn;
551+
conn_handle->handle = handle;
552+
result = hci_cmd_sync_queue(conn->hdev, hci_enhanced_setup_sync,
553+
conn_handle, NULL);
554+
if (result < 0)
555+
kfree(conn_handle);
556+
557+
return result == 0;
558+
}
495559

496560
return hci_setup_sync_conn(conn, handle);
497561
}

net/bluetooth/hci_request.c

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1975,53 +1975,6 @@ int hci_abort_conn(struct hci_conn *conn, u8 reason)
19751975
return 0;
19761976
}
19771977

1978-
static void config_data_path_complete(struct hci_dev *hdev, u8 status,
1979-
u16 opcode)
1980-
{
1981-
bt_dev_dbg(hdev, "status %u", status);
1982-
}
1983-
1984-
int hci_req_configure_datapath(struct hci_dev *hdev, struct bt_codec *codec)
1985-
{
1986-
struct hci_request req;
1987-
int err;
1988-
__u8 vnd_len, *vnd_data = NULL;
1989-
struct hci_op_configure_data_path *cmd = NULL;
1990-
1991-
hci_req_init(&req, hdev);
1992-
1993-
err = hdev->get_codec_config_data(hdev, ESCO_LINK, codec, &vnd_len,
1994-
&vnd_data);
1995-
if (err < 0)
1996-
goto error;
1997-
1998-
cmd = kzalloc(sizeof(*cmd) + vnd_len, GFP_KERNEL);
1999-
if (!cmd) {
2000-
err = -ENOMEM;
2001-
goto error;
2002-
}
2003-
2004-
err = hdev->get_data_path_id(hdev, &cmd->data_path_id);
2005-
if (err < 0)
2006-
goto error;
2007-
2008-
cmd->vnd_len = vnd_len;
2009-
memcpy(cmd->vnd_data, vnd_data, vnd_len);
2010-
2011-
cmd->direction = 0x00;
2012-
hci_req_add(&req, HCI_CONFIGURE_DATA_PATH, sizeof(*cmd) + vnd_len, cmd);
2013-
2014-
cmd->direction = 0x01;
2015-
hci_req_add(&req, HCI_CONFIGURE_DATA_PATH, sizeof(*cmd) + vnd_len, cmd);
2016-
2017-
err = hci_req_run(&req, config_data_path_complete);
2018-
error:
2019-
2020-
kfree(cmd);
2021-
kfree(vnd_data);
2022-
return err;
2023-
}
2024-
20251978
void hci_request_setup(struct hci_dev *hdev)
20261979
{
20271980
INIT_DELAYED_WORK(&hdev->adv_instance_expire, adv_timeout_expire);

net/bluetooth/hci_request.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,6 @@ int hci_get_random_address(struct hci_dev *hdev, bool require_privacy,
113113
void __hci_req_update_class(struct hci_request *req);
114114

115115
/* Returns true if HCI commands were queued */
116-
int hci_req_configure_datapath(struct hci_dev *hdev, struct bt_codec *codec);
117-
118116
void __hci_req_update_scan(struct hci_request *req);
119117

120118
int hci_update_random_address(struct hci_request *req, bool require_privacy,

0 commit comments

Comments
 (0)