2 Copyright (c) 2011,2012 Intel Corp.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License version 2 and
6 only version 2 as published by the Free Software Foundation.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
14 #include <net/bluetooth/bluetooth.h>
15 #include <net/bluetooth/hci.h>
16 #include <net/bluetooth/hci_core.h>
17 #include <net/bluetooth/a2mp.h>
18 #include <net/bluetooth/amp.h>
20 /* Remote AMP Controllers interface */
21 static void amp_ctrl_get(struct amp_ctrl
*ctrl
)
23 BT_DBG("ctrl %p orig refcnt %d", ctrl
,
24 atomic_read(&ctrl
->kref
.refcount
));
26 kref_get(&ctrl
->kref
);
29 static void amp_ctrl_destroy(struct kref
*kref
)
31 struct amp_ctrl
*ctrl
= container_of(kref
, struct amp_ctrl
, kref
);
33 BT_DBG("ctrl %p", ctrl
);
39 int amp_ctrl_put(struct amp_ctrl
*ctrl
)
41 BT_DBG("ctrl %p orig refcnt %d", ctrl
,
42 atomic_read(&ctrl
->kref
.refcount
));
44 return kref_put(&ctrl
->kref
, &_ctrl_destroy
);
47 struct amp_ctrl
*amp_ctrl_add(struct amp_mgr
*mgr
)
49 struct amp_ctrl
*ctrl
;
51 ctrl
= kzalloc(sizeof(*ctrl
), GFP_KERNEL
);
55 mutex_lock(&mgr
->amp_ctrls_lock
);
56 list_add(&ctrl
->list
, &mgr
->amp_ctrls
);
57 mutex_unlock(&mgr
->amp_ctrls_lock
);
59 kref_init(&ctrl
->kref
);
61 BT_DBG("mgr %p ctrl %p", mgr
, ctrl
);
66 void amp_ctrl_list_flush(struct amp_mgr
*mgr
)
68 struct amp_ctrl
*ctrl
, *n
;
70 BT_DBG("mgr %p", mgr
);
72 mutex_lock(&mgr
->amp_ctrls_lock
);
73 list_for_each_entry_safe(ctrl
, n
, &mgr
->amp_ctrls
, list
) {
74 list_del(&ctrl
->list
);
77 mutex_unlock(&mgr
->amp_ctrls_lock
);
80 struct amp_ctrl
*amp_ctrl_lookup(struct amp_mgr
*mgr
, u8 id
)
82 struct amp_ctrl
*ctrl
;
84 BT_DBG("mgr %p id %d", mgr
, id
);
86 mutex_lock(&mgr
->amp_ctrls_lock
);
87 list_for_each_entry(ctrl
, &mgr
->amp_ctrls
, list
) {
90 mutex_unlock(&mgr
->amp_ctrls_lock
);
94 mutex_unlock(&mgr
->amp_ctrls_lock
);
99 /* Physical Link interface */
100 static u8
__next_handle(struct amp_mgr
*mgr
)
102 if (++mgr
->handle
== 0)
108 struct hci_conn
*phylink_add(struct hci_dev
*hdev
, struct amp_mgr
*mgr
,
111 bdaddr_t
*dst
= mgr
->l2cap_conn
->dst
;
112 struct hci_conn
*hcon
;
114 hcon
= hci_conn_add(hdev
, AMP_LINK
, dst
);
118 hcon
->state
= BT_CONNECT
;
121 hcon
->handle
= __next_handle(mgr
);
122 hcon
->remote_id
= remote_id
;
128 void amp_read_loc_assoc_frag(struct hci_dev
*hdev
, u8 phy_handle
)
130 struct hci_cp_read_local_amp_assoc cp
;
131 struct amp_assoc
*loc_assoc
= &hdev
->loc_assoc
;
133 BT_DBG("%s handle %d", hdev
->name
, phy_handle
);
135 cp
.phy_handle
= phy_handle
;
136 cp
.max_len
= cpu_to_le16(hdev
->amp_assoc_size
);
137 cp
.len_so_far
= cpu_to_le16(loc_assoc
->offset
);
139 hci_send_cmd(hdev
, HCI_OP_READ_LOCAL_AMP_ASSOC
, sizeof(cp
), &cp
);
142 void amp_read_loc_assoc(struct hci_dev
*hdev
, struct amp_mgr
*mgr
)
144 struct hci_cp_read_local_amp_assoc cp
;
146 memset(&hdev
->loc_assoc
, 0, sizeof(struct amp_assoc
));
147 memset(&cp
, 0, sizeof(cp
));
149 cp
.max_len
= cpu_to_le16(hdev
->amp_assoc_size
);
151 mgr
->state
= READ_LOC_AMP_ASSOC
;
152 hci_send_cmd(hdev
, HCI_OP_READ_LOCAL_AMP_ASSOC
, sizeof(cp
), &cp
);