Bluetooth: Ensure socket pointer is set during callback
Fix issue where when setting up an AMP link the socket pointer
is not set when the logical link complete callback is called,
resulting in the L2CAP channel being disconnected.
The socket pointer must be set before the HCI logical link
create command is sent, as it is possible for the logical link
complete event to arrive before the HCI command send logic
has returned.
Change-Id: I5d89c14d45bd6b4cf47d5754f822b435ce8076a8
Signed-off-by: Peter Krystad <pkrystad@codeaurora.org>
CRs-fixed: 344553
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 2854395..f87be20 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -520,6 +520,7 @@
return chan;
}
+EXPORT_SYMBOL(hci_chan_add);
int hci_chan_del(struct hci_chan *chan)
{
@@ -1001,18 +1002,12 @@
}
}
-struct hci_chan *hci_chan_accept(struct hci_conn *conn,
+struct hci_chan *hci_chan_create(struct hci_chan *chan,
struct hci_ext_fs *tx_fs, struct hci_ext_fs *rx_fs)
{
- struct hci_chan *chan;
struct hci_cp_create_logical_link cp;
- chan = hci_chan_add(conn->hdev);
- if (!chan)
- return NULL;
-
chan->state = BT_CONNECT;
- chan->conn = conn;
chan->tx_fs = *tx_fs;
chan->rx_fs = *rx_fs;
cp.phy_handle = chan->conn->handle;
@@ -1029,40 +1024,12 @@
cp.rx_fs.acc_latency = cpu_to_le32(chan->rx_fs.acc_latency);
cp.rx_fs.flush_to = cpu_to_le32(chan->rx_fs.flush_to);
hci_conn_hold(chan->conn);
- hci_send_cmd(conn->hdev, HCI_OP_ACCEPT_LOGICAL_LINK, sizeof(cp), &cp);
- return chan;
-}
-EXPORT_SYMBOL(hci_chan_accept);
-
-struct hci_chan *hci_chan_create(struct hci_conn *conn,
- struct hci_ext_fs *tx_fs, struct hci_ext_fs *rx_fs)
-{
- struct hci_chan *chan;
- struct hci_cp_create_logical_link cp;
-
- chan = hci_chan_add(conn->hdev);
- if (!chan)
- return NULL;
-
- chan->state = BT_CONNECT;
- chan->conn = conn;
- chan->tx_fs = *tx_fs;
- chan->rx_fs = *rx_fs;
- cp.phy_handle = chan->conn->handle;
- cp.tx_fs.id = chan->tx_fs.id;
- cp.tx_fs.type = chan->tx_fs.type;
- cp.tx_fs.max_sdu = cpu_to_le16(chan->tx_fs.max_sdu);
- cp.tx_fs.sdu_arr_time = cpu_to_le32(chan->tx_fs.sdu_arr_time);
- cp.tx_fs.acc_latency = cpu_to_le32(chan->tx_fs.acc_latency);
- cp.tx_fs.flush_to = cpu_to_le32(chan->tx_fs.flush_to);
- cp.rx_fs.id = chan->rx_fs.id;
- cp.rx_fs.type = chan->rx_fs.type;
- cp.rx_fs.max_sdu = cpu_to_le16(chan->rx_fs.max_sdu);
- cp.rx_fs.sdu_arr_time = cpu_to_le32(chan->rx_fs.sdu_arr_time);
- cp.rx_fs.acc_latency = cpu_to_le32(chan->rx_fs.acc_latency);
- cp.rx_fs.flush_to = cpu_to_le32(chan->rx_fs.flush_to);
- hci_conn_hold(chan->conn);
- hci_send_cmd(conn->hdev, HCI_OP_CREATE_LOGICAL_LINK, sizeof(cp), &cp);
+ if (chan->conn->out)
+ hci_send_cmd(chan->conn->hdev, HCI_OP_CREATE_LOGICAL_LINK,
+ sizeof(cp), &cp);
+ else
+ hci_send_cmd(chan->conn->hdev, HCI_OP_ACCEPT_LOGICAL_LINK,
+ sizeof(cp), &cp);
return chan;
}
EXPORT_SYMBOL(hci_chan_create);