diff options
Diffstat (limited to 'net/bluetooth/hci_conn.c')
-rw-r--r-- | net/bluetooth/hci_conn.c | 92 |
1 files changed, 53 insertions, 39 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index faff6247ac8f..b9517bd17190 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -36,19 +36,25 @@ | |||
36 | struct sco_param { | 36 | struct sco_param { |
37 | u16 pkt_type; | 37 | u16 pkt_type; |
38 | u16 max_latency; | 38 | u16 max_latency; |
39 | u8 retrans_effort; | ||
40 | }; | ||
41 | |||
42 | static const struct sco_param esco_param_cvsd[] = { | ||
43 | { EDR_ESCO_MASK & ~ESCO_2EV3, 0x000a, 0x01 }, /* S3 */ | ||
44 | { EDR_ESCO_MASK & ~ESCO_2EV3, 0x0007, 0x01 }, /* S2 */ | ||
45 | { EDR_ESCO_MASK | ESCO_EV3, 0x0007, 0x01 }, /* S1 */ | ||
46 | { EDR_ESCO_MASK | ESCO_HV3, 0xffff, 0x01 }, /* D1 */ | ||
47 | { EDR_ESCO_MASK | ESCO_HV1, 0xffff, 0x01 }, /* D0 */ | ||
39 | }; | 48 | }; |
40 | 49 | ||
41 | static const struct sco_param sco_param_cvsd[] = { | 50 | static const struct sco_param sco_param_cvsd[] = { |
42 | { EDR_ESCO_MASK & ~ESCO_2EV3, 0x000a }, /* S3 */ | 51 | { EDR_ESCO_MASK | ESCO_HV3, 0xffff, 0xff }, /* D1 */ |
43 | { EDR_ESCO_MASK & ~ESCO_2EV3, 0x0007 }, /* S2 */ | 52 | { EDR_ESCO_MASK | ESCO_HV1, 0xffff, 0xff }, /* D0 */ |
44 | { EDR_ESCO_MASK | ESCO_EV3, 0x0007 }, /* S1 */ | ||
45 | { EDR_ESCO_MASK | ESCO_HV3, 0xffff }, /* D1 */ | ||
46 | { EDR_ESCO_MASK | ESCO_HV1, 0xffff }, /* D0 */ | ||
47 | }; | 53 | }; |
48 | 54 | ||
49 | static const struct sco_param sco_param_wideband[] = { | 55 | static const struct sco_param esco_param_msbc[] = { |
50 | { EDR_ESCO_MASK & ~ESCO_2EV3, 0x000d }, /* T2 */ | 56 | { EDR_ESCO_MASK & ~ESCO_2EV3, 0x000d, 0x02 }, /* T2 */ |
51 | { EDR_ESCO_MASK | ESCO_EV3, 0x0008 }, /* T1 */ | 57 | { EDR_ESCO_MASK | ESCO_EV3, 0x0008, 0x02 }, /* T1 */ |
52 | }; | 58 | }; |
53 | 59 | ||
54 | static void hci_le_create_connection_cancel(struct hci_conn *conn) | 60 | static void hci_le_create_connection_cancel(struct hci_conn *conn) |
@@ -116,23 +122,36 @@ static void hci_reject_sco(struct hci_conn *conn) | |||
116 | { | 122 | { |
117 | struct hci_cp_reject_sync_conn_req cp; | 123 | struct hci_cp_reject_sync_conn_req cp; |
118 | 124 | ||
119 | cp.reason = HCI_ERROR_REMOTE_USER_TERM; | 125 | cp.reason = HCI_ERROR_REJ_LIMITED_RESOURCES; |
120 | bacpy(&cp.bdaddr, &conn->dst); | 126 | bacpy(&cp.bdaddr, &conn->dst); |
121 | 127 | ||
122 | hci_send_cmd(conn->hdev, HCI_OP_REJECT_SYNC_CONN_REQ, sizeof(cp), &cp); | 128 | hci_send_cmd(conn->hdev, HCI_OP_REJECT_SYNC_CONN_REQ, sizeof(cp), &cp); |
123 | } | 129 | } |
124 | 130 | ||
125 | void hci_disconnect(struct hci_conn *conn, __u8 reason) | 131 | int hci_disconnect(struct hci_conn *conn, __u8 reason) |
126 | { | 132 | { |
127 | struct hci_cp_disconnect cp; | 133 | struct hci_cp_disconnect cp; |
128 | 134 | ||
129 | BT_DBG("hcon %p", conn); | 135 | BT_DBG("hcon %p", conn); |
130 | 136 | ||
137 | /* When we are master of an established connection and it enters | ||
138 | * the disconnect timeout, then go ahead and try to read the | ||
139 | * current clock offset. Processing of the result is done | ||
140 | * within the event handling and hci_clock_offset_evt function. | ||
141 | */ | ||
142 | if (conn->type == ACL_LINK && conn->role == HCI_ROLE_MASTER) { | ||
143 | struct hci_dev *hdev = conn->hdev; | ||
144 | struct hci_cp_read_clock_offset cp; | ||
145 | |||
146 | cp.handle = cpu_to_le16(conn->handle); | ||
147 | hci_send_cmd(hdev, HCI_OP_READ_CLOCK_OFFSET, sizeof(cp), &cp); | ||
148 | } | ||
149 | |||
131 | conn->state = BT_DISCONN; | 150 | conn->state = BT_DISCONN; |
132 | 151 | ||
133 | cp.handle = cpu_to_le16(conn->handle); | 152 | cp.handle = cpu_to_le16(conn->handle); |
134 | cp.reason = reason; | 153 | cp.reason = reason; |
135 | hci_send_cmd(conn->hdev, HCI_OP_DISCONNECT, sizeof(cp), &cp); | 154 | return hci_send_cmd(conn->hdev, HCI_OP_DISCONNECT, sizeof(cp), &cp); |
136 | } | 155 | } |
137 | 156 | ||
138 | static void hci_amp_disconn(struct hci_conn *conn) | 157 | static void hci_amp_disconn(struct hci_conn *conn) |
@@ -188,21 +207,26 @@ bool hci_setup_sync(struct hci_conn *conn, __u16 handle) | |||
188 | 207 | ||
189 | switch (conn->setting & SCO_AIRMODE_MASK) { | 208 | switch (conn->setting & SCO_AIRMODE_MASK) { |
190 | case SCO_AIRMODE_TRANSP: | 209 | case SCO_AIRMODE_TRANSP: |
191 | if (conn->attempt > ARRAY_SIZE(sco_param_wideband)) | 210 | if (conn->attempt > ARRAY_SIZE(esco_param_msbc)) |
192 | return false; | 211 | return false; |
193 | cp.retrans_effort = 0x02; | 212 | param = &esco_param_msbc[conn->attempt - 1]; |
194 | param = &sco_param_wideband[conn->attempt - 1]; | ||
195 | break; | 213 | break; |
196 | case SCO_AIRMODE_CVSD: | 214 | case SCO_AIRMODE_CVSD: |
197 | if (conn->attempt > ARRAY_SIZE(sco_param_cvsd)) | 215 | if (lmp_esco_capable(conn->link)) { |
198 | return false; | 216 | if (conn->attempt > ARRAY_SIZE(esco_param_cvsd)) |
199 | cp.retrans_effort = 0x01; | 217 | return false; |
200 | param = &sco_param_cvsd[conn->attempt - 1]; | 218 | param = &esco_param_cvsd[conn->attempt - 1]; |
219 | } else { | ||
220 | if (conn->attempt > ARRAY_SIZE(sco_param_cvsd)) | ||
221 | return false; | ||
222 | param = &sco_param_cvsd[conn->attempt - 1]; | ||
223 | } | ||
201 | break; | 224 | break; |
202 | default: | 225 | default: |
203 | return false; | 226 | return false; |
204 | } | 227 | } |
205 | 228 | ||
229 | cp.retrans_effort = param->retrans_effort; | ||
206 | cp.pkt_type = __cpu_to_le16(param->pkt_type); | 230 | cp.pkt_type = __cpu_to_le16(param->pkt_type); |
207 | cp.max_latency = __cpu_to_le16(param->max_latency); | 231 | cp.max_latency = __cpu_to_le16(param->max_latency); |
208 | 232 | ||
@@ -325,25 +349,6 @@ static void hci_conn_timeout(struct work_struct *work) | |||
325 | hci_amp_disconn(conn); | 349 | hci_amp_disconn(conn); |
326 | } else { | 350 | } else { |
327 | __u8 reason = hci_proto_disconn_ind(conn); | 351 | __u8 reason = hci_proto_disconn_ind(conn); |
328 | |||
329 | /* When we are master of an established connection | ||
330 | * and it enters the disconnect timeout, then go | ||
331 | * ahead and try to read the current clock offset. | ||
332 | * | ||
333 | * Processing of the result is done within the | ||
334 | * event handling and hci_clock_offset_evt function. | ||
335 | */ | ||
336 | if (conn->type == ACL_LINK && | ||
337 | conn->role == HCI_ROLE_MASTER) { | ||
338 | struct hci_dev *hdev = conn->hdev; | ||
339 | struct hci_cp_read_clock_offset cp; | ||
340 | |||
341 | cp.handle = cpu_to_le16(conn->handle); | ||
342 | |||
343 | hci_send_cmd(hdev, HCI_OP_READ_CLOCK_OFFSET, | ||
344 | sizeof(cp), &cp); | ||
345 | } | ||
346 | |||
347 | hci_disconnect(conn, reason); | 352 | hci_disconnect(conn, reason); |
348 | } | 353 | } |
349 | break; | 354 | break; |
@@ -595,6 +600,7 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 status) | |||
595 | conn->dst_type); | 600 | conn->dst_type); |
596 | if (params && params->conn) { | 601 | if (params && params->conn) { |
597 | hci_conn_drop(params->conn); | 602 | hci_conn_drop(params->conn); |
603 | hci_conn_put(params->conn); | ||
598 | params->conn = NULL; | 604 | params->conn = NULL; |
599 | } | 605 | } |
600 | 606 | ||
@@ -1290,11 +1296,16 @@ struct hci_chan *hci_chan_create(struct hci_conn *conn) | |||
1290 | 1296 | ||
1291 | BT_DBG("%s hcon %p", hdev->name, conn); | 1297 | BT_DBG("%s hcon %p", hdev->name, conn); |
1292 | 1298 | ||
1299 | if (test_bit(HCI_CONN_DROP, &conn->flags)) { | ||
1300 | BT_DBG("Refusing to create new hci_chan"); | ||
1301 | return NULL; | ||
1302 | } | ||
1303 | |||
1293 | chan = kzalloc(sizeof(*chan), GFP_KERNEL); | 1304 | chan = kzalloc(sizeof(*chan), GFP_KERNEL); |
1294 | if (!chan) | 1305 | if (!chan) |
1295 | return NULL; | 1306 | return NULL; |
1296 | 1307 | ||
1297 | chan->conn = conn; | 1308 | chan->conn = hci_conn_get(conn); |
1298 | skb_queue_head_init(&chan->data_q); | 1309 | skb_queue_head_init(&chan->data_q); |
1299 | chan->state = BT_CONNECTED; | 1310 | chan->state = BT_CONNECTED; |
1300 | 1311 | ||
@@ -1314,7 +1325,10 @@ void hci_chan_del(struct hci_chan *chan) | |||
1314 | 1325 | ||
1315 | synchronize_rcu(); | 1326 | synchronize_rcu(); |
1316 | 1327 | ||
1317 | hci_conn_drop(conn); | 1328 | /* Prevent new hci_chan's to be created for this hci_conn */ |
1329 | set_bit(HCI_CONN_DROP, &conn->flags); | ||
1330 | |||
1331 | hci_conn_put(conn); | ||
1318 | 1332 | ||
1319 | skb_queue_purge(&chan->data_q); | 1333 | skb_queue_purge(&chan->data_q); |
1320 | kfree(chan); | 1334 | kfree(chan); |