Bluetooth: AMP: Process Disc Logical Link
authorAndrei Emeltchenko <andrei.emeltchenko@intel.com>
Wed, 31 Oct 2012 13:46:31 +0000 (15:46 +0200)
committerGustavo Padovan <gustavo.padovan@collabora.co.uk>
Thu, 1 Nov 2012 22:27:07 +0000 (20:27 -0200)
Add processing for HCI Disconnection Logical Link Complete
Event.

Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
include/net/bluetooth/amp.h
net/bluetooth/amp.c
net/bluetooth/hci_event.c

index 70d5c153de151c3ce1b3e455a103cb5542f22cb6..405fb9c987effa9d98ef51ee1832dddaf6931d5a 100644 (file)
@@ -47,5 +47,6 @@ void amp_accept_phylink(struct hci_dev *hdev, struct amp_mgr *mgr,
 void amp_write_remote_assoc(struct hci_dev *hdev, u8 handle);
 void amp_write_rem_assoc_continue(struct hci_dev *hdev, u8 handle);
 void amp_create_logical_link(struct l2cap_chan *chan);
+void amp_destroy_logical_link(struct hci_chan *hchan, u8 reason);
 
 #endif /* __AMP_H */
index fbb63605a27e35e55f43a4cb3b2448f50299c360..0f3fef34eabc462ff9552bb3fa64eb5f6dd23b0b 100644 (file)
@@ -421,3 +421,10 @@ void amp_create_logical_link(struct l2cap_chan *chan)
 done:
        hci_dev_put(hdev);
 }
+
+void amp_destroy_logical_link(struct hci_chan *hchan, u8 reason)
+{
+       BT_DBG("hchan %p", hchan);
+
+       hci_chan_del(hchan);
+}
index 14cad155af3c714e163ec5ed68979cec888c244b..07dce614f81ad38ae660d1a08b79813100cc063b 100644 (file)
@@ -3741,6 +3741,30 @@ static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
        }
 }
 
+static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
+                                            struct sk_buff *skb)
+{
+       struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
+       struct hci_chan *hchan;
+
+       BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
+              le16_to_cpu(ev->handle), ev->status);
+
+       if (ev->status)
+               return;
+
+       hci_dev_lock(hdev);
+
+       hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
+       if (!hchan)
+               goto unlock;
+
+       amp_destroy_logical_link(hchan, ev->reason);
+
+unlock:
+       hci_dev_unlock(hdev);
+}
+
 static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
        struct hci_ev_le_conn_complete *ev = (void *) skb->data;
@@ -4076,6 +4100,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
                hci_loglink_complete_evt(hdev, skb);
                break;
 
+       case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
+               hci_disconn_loglink_complete_evt(hdev, skb);
+               break;
+
        case HCI_EV_NUM_COMP_BLOCKS:
                hci_num_comp_blocks_evt(hdev, skb);
                break;