Commit 53502d69 authored by Andrei Emeltchenko's avatar Andrei Emeltchenko Committed by Gustavo Padovan

Bluetooth: AMP: Handle AMP_LINK timeout

When AMP_LINK timeouts execute HCI_OP_DISCONN_PHY_LINK as analog to
HCI_OP_DISCONNECT for ACL_LINK.
Signed-off-by: default avatarAndrei Emeltchenko <andrei.emeltchenko@intel.com>
Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
parent 12d59781
...@@ -285,6 +285,8 @@ struct hci_dev { ...@@ -285,6 +285,8 @@ struct hci_dev {
int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg); int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg);
}; };
#define HCI_PHY_HANDLE(handle) (handle & 0xff)
struct hci_conn { struct hci_conn {
struct list_head list; struct list_head list;
......
...@@ -130,6 +130,20 @@ void hci_acl_disconn(struct hci_conn *conn, __u8 reason) ...@@ -130,6 +130,20 @@ void hci_acl_disconn(struct hci_conn *conn, __u8 reason)
hci_send_cmd(conn->hdev, HCI_OP_DISCONNECT, sizeof(cp), &cp); hci_send_cmd(conn->hdev, HCI_OP_DISCONNECT, sizeof(cp), &cp);
} }
static void hci_amp_disconn(struct hci_conn *conn, __u8 reason)
{
struct hci_cp_disconn_phy_link cp;
BT_DBG("hcon %p", conn);
conn->state = BT_DISCONN;
cp.phy_handle = HCI_PHY_HANDLE(conn->handle);
cp.reason = reason;
hci_send_cmd(conn->hdev, HCI_OP_DISCONN_PHY_LINK,
sizeof(cp), &cp);
}
static void hci_add_sco(struct hci_conn *conn, __u16 handle) static void hci_add_sco(struct hci_conn *conn, __u16 handle)
{ {
struct hci_dev *hdev = conn->hdev; struct hci_dev *hdev = conn->hdev;
...@@ -230,11 +244,24 @@ void hci_sco_setup(struct hci_conn *conn, __u8 status) ...@@ -230,11 +244,24 @@ void hci_sco_setup(struct hci_conn *conn, __u8 status)
} }
} }
static void hci_conn_disconnect(struct hci_conn *conn)
{
__u8 reason = hci_proto_disconn_ind(conn);
switch (conn->type) {
case ACL_LINK:
hci_acl_disconn(conn, reason);
break;
case AMP_LINK:
hci_amp_disconn(conn, reason);
break;
}
}
static void hci_conn_timeout(struct work_struct *work) static void hci_conn_timeout(struct work_struct *work)
{ {
struct hci_conn *conn = container_of(work, struct hci_conn, struct hci_conn *conn = container_of(work, struct hci_conn,
disc_work.work); disc_work.work);
__u8 reason;
BT_DBG("hcon %p state %s", conn, state_to_string(conn->state)); BT_DBG("hcon %p state %s", conn, state_to_string(conn->state));
...@@ -253,8 +280,7 @@ static void hci_conn_timeout(struct work_struct *work) ...@@ -253,8 +280,7 @@ static void hci_conn_timeout(struct work_struct *work)
break; break;
case BT_CONFIG: case BT_CONFIG:
case BT_CONNECTED: case BT_CONNECTED:
reason = hci_proto_disconn_ind(conn); hci_conn_disconnect(conn);
hci_acl_disconn(conn, reason);
break; break;
default: default:
conn->state = BT_CLOSED; conn->state = BT_CLOSED;
......
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