aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2010-07-28 16:17:49 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-07-28 16:17:49 -0400
commit099284bdecf6e0af78662371ed3f45b71d796aad (patch)
tree90c336885d8dd6daf46ea4b94f71bb8f986b5ba9
parent073730d771d97bb5bbef080bd5d6d0a5af7cba7d (diff)
parent4ebaa4edf8799cab19d5a0642dc95f04fd284e06 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/holtmann/bluetooth-next-2.6
-rw-r--r--[-rwxr-xr-x]drivers/bluetooth/hci_ath.c6
-rw-r--r--drivers/bluetooth/hci_bcsp.c4
-rw-r--r--drivers/bluetooth/hci_h4.c107
-rw-r--r--drivers/bluetooth/hci_ll.c4
-rw-r--r--include/net/bluetooth/hci_core.h2
-rw-r--r--net/bluetooth/hci_conn.c32
-rw-r--r--net/bluetooth/hci_core.c8
-rw-r--r--net/bluetooth/hci_event.c31
-rw-r--r--net/bluetooth/rfcomm/sock.c2
-rw-r--r--net/bluetooth/rfcomm/tty.c4
10 files changed, 63 insertions, 137 deletions
diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c
index 5ab258bccccb..6a160c17ea94 100755..100644
--- a/drivers/bluetooth/hci_ath.c
+++ b/drivers/bluetooth/hci_ath.c
@@ -163,7 +163,7 @@ static int ath_enqueue(struct hci_uart *hu, struct sk_buff *skb)
163 struct ath_struct *ath = hu->priv; 163 struct ath_struct *ath = hu->priv;
164 164
165 if (bt_cb(skb)->pkt_type == HCI_SCODATA_PKT) { 165 if (bt_cb(skb)->pkt_type == HCI_SCODATA_PKT) {
166 kfree(skb); 166 kfree_skb(skb);
167 return 0; 167 return 0;
168 } 168 }
169 169
@@ -217,7 +217,7 @@ static struct hci_uart_proto athp = {
217 .flush = ath_flush, 217 .flush = ath_flush,
218}; 218};
219 219
220int ath_init(void) 220int __init ath_init(void)
221{ 221{
222 int err = hci_uart_register_proto(&athp); 222 int err = hci_uart_register_proto(&athp);
223 223
@@ -229,7 +229,7 @@ int ath_init(void)
229 return err; 229 return err;
230} 230}
231 231
232int ath_deinit(void) 232int __exit ath_deinit(void)
233{ 233{
234 return hci_uart_unregister_proto(&athp); 234 return hci_uart_unregister_proto(&athp);
235} 235}
diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c
index 42d69d4de05c..9c5b2dc38e29 100644
--- a/drivers/bluetooth/hci_bcsp.c
+++ b/drivers/bluetooth/hci_bcsp.c
@@ -739,7 +739,7 @@ static struct hci_uart_proto bcsp = {
739 .flush = bcsp_flush 739 .flush = bcsp_flush
740}; 740};
741 741
742int bcsp_init(void) 742int __init bcsp_init(void)
743{ 743{
744 int err = hci_uart_register_proto(&bcsp); 744 int err = hci_uart_register_proto(&bcsp);
745 745
@@ -751,7 +751,7 @@ int bcsp_init(void)
751 return err; 751 return err;
752} 752}
753 753
754int bcsp_deinit(void) 754int __exit bcsp_deinit(void)
755{ 755{
756 return hci_uart_unregister_proto(&bcsp); 756 return hci_uart_unregister_proto(&bcsp);
757} 757}
diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c
index 3f038f5308a4..7b8ad93e2c36 100644
--- a/drivers/bluetooth/hci_h4.c
+++ b/drivers/bluetooth/hci_h4.c
@@ -151,107 +151,8 @@ static inline int h4_check_data_len(struct h4_struct *h4, int len)
151/* Recv data */ 151/* Recv data */
152static int h4_recv(struct hci_uart *hu, void *data, int count) 152static int h4_recv(struct hci_uart *hu, void *data, int count)
153{ 153{
154 struct h4_struct *h4 = hu->priv; 154 if (hci_recv_stream_fragment(hu->hdev, data, count) < 0)
155 register char *ptr; 155 BT_ERR("Frame Reassembly Failed");
156 struct hci_event_hdr *eh;
157 struct hci_acl_hdr *ah;
158 struct hci_sco_hdr *sh;
159 register int len, type, dlen;
160
161 BT_DBG("hu %p count %d rx_state %ld rx_count %ld",
162 hu, count, h4->rx_state, h4->rx_count);
163
164 ptr = data;
165 while (count) {
166 if (h4->rx_count) {
167 len = min_t(unsigned int, h4->rx_count, count);
168 memcpy(skb_put(h4->rx_skb, len), ptr, len);
169 h4->rx_count -= len; count -= len; ptr += len;
170
171 if (h4->rx_count)
172 continue;
173
174 switch (h4->rx_state) {
175 case H4_W4_DATA:
176 BT_DBG("Complete data");
177
178 hci_recv_frame(h4->rx_skb);
179
180 h4->rx_state = H4_W4_PACKET_TYPE;
181 h4->rx_skb = NULL;
182 continue;
183
184 case H4_W4_EVENT_HDR:
185 eh = hci_event_hdr(h4->rx_skb);
186
187 BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
188
189 h4_check_data_len(h4, eh->plen);
190 continue;
191
192 case H4_W4_ACL_HDR:
193 ah = hci_acl_hdr(h4->rx_skb);
194 dlen = __le16_to_cpu(ah->dlen);
195
196 BT_DBG("ACL header: dlen %d", dlen);
197
198 h4_check_data_len(h4, dlen);
199 continue;
200
201 case H4_W4_SCO_HDR:
202 sh = hci_sco_hdr(h4->rx_skb);
203
204 BT_DBG("SCO header: dlen %d", sh->dlen);
205
206 h4_check_data_len(h4, sh->dlen);
207 continue;
208 }
209 }
210
211 /* H4_W4_PACKET_TYPE */
212 switch (*ptr) {
213 case HCI_EVENT_PKT:
214 BT_DBG("Event packet");
215 h4->rx_state = H4_W4_EVENT_HDR;
216 h4->rx_count = HCI_EVENT_HDR_SIZE;
217 type = HCI_EVENT_PKT;
218 break;
219
220 case HCI_ACLDATA_PKT:
221 BT_DBG("ACL packet");
222 h4->rx_state = H4_W4_ACL_HDR;
223 h4->rx_count = HCI_ACL_HDR_SIZE;
224 type = HCI_ACLDATA_PKT;
225 break;
226
227 case HCI_SCODATA_PKT:
228 BT_DBG("SCO packet");
229 h4->rx_state = H4_W4_SCO_HDR;
230 h4->rx_count = HCI_SCO_HDR_SIZE;
231 type = HCI_SCODATA_PKT;
232 break;
233
234 default:
235 BT_ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
236 hu->hdev->stat.err_rx++;
237 ptr++; count--;
238 continue;
239 };
240
241 ptr++; count--;
242
243 /* Allocate packet */
244 h4->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
245 if (!h4->rx_skb) {
246 BT_ERR("Can't allocate mem for new packet");
247 h4->rx_state = H4_W4_PACKET_TYPE;
248 h4->rx_count = 0;
249 return -ENOMEM;
250 }
251
252 h4->rx_skb->dev = (void *) hu->hdev;
253 bt_cb(h4->rx_skb)->pkt_type = type;
254 }
255 156
256 return count; 157 return count;
257} 158}
@@ -272,7 +173,7 @@ static struct hci_uart_proto h4p = {
272 .flush = h4_flush, 173 .flush = h4_flush,
273}; 174};
274 175
275int h4_init(void) 176int __init h4_init(void)
276{ 177{
277 int err = hci_uart_register_proto(&h4p); 178 int err = hci_uart_register_proto(&h4p);
278 179
@@ -284,7 +185,7 @@ int h4_init(void)
284 return err; 185 return err;
285} 186}
286 187
287int h4_deinit(void) 188int __exit h4_deinit(void)
288{ 189{
289 return hci_uart_unregister_proto(&h4p); 190 return hci_uart_unregister_proto(&h4p);
290} 191}
diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c
index 5744aba8272e..38595e782d02 100644
--- a/drivers/bluetooth/hci_ll.c
+++ b/drivers/bluetooth/hci_ll.c
@@ -517,7 +517,7 @@ static struct hci_uart_proto llp = {
517 .flush = ll_flush, 517 .flush = ll_flush,
518}; 518};
519 519
520int ll_init(void) 520int __init ll_init(void)
521{ 521{
522 int err = hci_uart_register_proto(&llp); 522 int err = hci_uart_register_proto(&llp);
523 523
@@ -529,7 +529,7 @@ int ll_init(void)
529 return err; 529 return err;
530} 530}
531 531
532int ll_deinit(void) 532int __exit ll_deinit(void)
533{ 533{
534 return hci_uart_unregister_proto(&llp); 534 return hci_uart_unregister_proto(&llp);
535} 535}
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 350b3e6964bd..8b28962e737e 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -256,6 +256,7 @@ enum {
256 HCI_CONN_ENCRYPT_PEND, 256 HCI_CONN_ENCRYPT_PEND,
257 HCI_CONN_RSWITCH_PEND, 257 HCI_CONN_RSWITCH_PEND,
258 HCI_CONN_MODE_CHANGE_PEND, 258 HCI_CONN_MODE_CHANGE_PEND,
259 HCI_CONN_SCO_SETUP_PEND,
259}; 260};
260 261
261static inline void hci_conn_hash_init(struct hci_dev *hdev) 262static inline void hci_conn_hash_init(struct hci_dev *hdev)
@@ -336,6 +337,7 @@ void hci_acl_connect(struct hci_conn *conn);
336void hci_acl_disconn(struct hci_conn *conn, __u8 reason); 337void hci_acl_disconn(struct hci_conn *conn, __u8 reason);
337void hci_add_sco(struct hci_conn *conn, __u16 handle); 338void hci_add_sco(struct hci_conn *conn, __u16 handle);
338void hci_setup_sync(struct hci_conn *conn, __u16 handle); 339void hci_setup_sync(struct hci_conn *conn, __u16 handle);
340void hci_sco_setup(struct hci_conn *conn, __u8 status);
339 341
340struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst); 342struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst);
341int hci_conn_del(struct hci_conn *conn); 343int hci_conn_del(struct hci_conn *conn);
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index e9fef83449f8..0b1e460fe440 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -155,6 +155,27 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle)
155 hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp); 155 hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp);
156} 156}
157 157
158/* Device _must_ be locked */
159void hci_sco_setup(struct hci_conn *conn, __u8 status)
160{
161 struct hci_conn *sco = conn->link;
162
163 BT_DBG("%p", conn);
164
165 if (!sco)
166 return;
167
168 if (!status) {
169 if (lmp_esco_capable(conn->hdev))
170 hci_setup_sync(sco, conn->handle);
171 else
172 hci_add_sco(sco, conn->handle);
173 } else {
174 hci_proto_connect_cfm(sco, status);
175 hci_conn_del(sco);
176 }
177}
178
158static void hci_conn_timeout(unsigned long arg) 179static void hci_conn_timeout(unsigned long arg)
159{ 180{
160 struct hci_conn *conn = (void *) arg; 181 struct hci_conn *conn = (void *) arg;
@@ -385,10 +406,13 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
385 acl->power_save = 1; 406 acl->power_save = 1;
386 hci_conn_enter_active_mode(acl); 407 hci_conn_enter_active_mode(acl);
387 408
388 if (lmp_esco_capable(hdev)) 409 if (test_bit(HCI_CONN_MODE_CHANGE_PEND, &acl->pend)) {
389 hci_setup_sync(sco, acl->handle); 410 /* defer SCO setup until mode change completed */
390 else 411 set_bit(HCI_CONN_SCO_SETUP_PEND, &acl->pend);
391 hci_add_sco(sco, acl->handle); 412 return sco;
413 }
414
415 hci_sco_setup(acl, 0x00);
392 } 416 }
393 417
394 return sco; 418 return sco;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 995c9f9b84d0..8303f1c9ef54 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1149,7 +1149,7 @@ int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
1149 if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) 1149 if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
1150 return -EILSEQ; 1150 return -EILSEQ;
1151 1151
1152 do { 1152 while (count) {
1153 rem = hci_reassembly(hdev, type, data, count, 1153 rem = hci_reassembly(hdev, type, data, count,
1154 type - 1, GFP_ATOMIC); 1154 type - 1, GFP_ATOMIC);
1155 if (rem < 0) 1155 if (rem < 0)
@@ -1157,7 +1157,7 @@ int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
1157 1157
1158 data += (count - rem); 1158 data += (count - rem);
1159 count = rem; 1159 count = rem;
1160 } while (count); 1160 };
1161 1161
1162 return rem; 1162 return rem;
1163} 1163}
@@ -1170,7 +1170,7 @@ int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
1170 int type; 1170 int type;
1171 int rem = 0; 1171 int rem = 0;
1172 1172
1173 do { 1173 while (count) {
1174 struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY]; 1174 struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
1175 1175
1176 if (!skb) { 1176 if (!skb) {
@@ -1192,7 +1192,7 @@ int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
1192 1192
1193 data += (count - rem); 1193 data += (count - rem);
1194 count = rem; 1194 count = rem;
1195 } while (count); 1195 };
1196 1196
1197 return rem; 1197 return rem;
1198} 1198}
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 2069c3b05fda..bfef5bae0b3a 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -785,9 +785,13 @@ static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
785 hci_dev_lock(hdev); 785 hci_dev_lock(hdev);
786 786
787 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 787 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
788 if (conn) 788 if (conn) {
789 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend); 789 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
790 790
791 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
792 hci_sco_setup(conn, status);
793 }
794
791 hci_dev_unlock(hdev); 795 hci_dev_unlock(hdev);
792} 796}
793 797
@@ -808,9 +812,13 @@ static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
808 hci_dev_lock(hdev); 812 hci_dev_lock(hdev);
809 813
810 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 814 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
811 if (conn) 815 if (conn) {
812 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend); 816 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
813 817
818 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
819 hci_sco_setup(conn, status);
820 }
821
814 hci_dev_unlock(hdev); 822 hci_dev_unlock(hdev);
815} 823}
816 824
@@ -915,20 +923,8 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
915 } else 923 } else
916 conn->state = BT_CLOSED; 924 conn->state = BT_CLOSED;
917 925
918 if (conn->type == ACL_LINK) { 926 if (conn->type == ACL_LINK)
919 struct hci_conn *sco = conn->link; 927 hci_sco_setup(conn, ev->status);
920 if (sco) {
921 if (!ev->status) {
922 if (lmp_esco_capable(hdev))
923 hci_setup_sync(sco, conn->handle);
924 else
925 hci_add_sco(sco, conn->handle);
926 } else {
927 hci_proto_connect_cfm(sco, ev->status);
928 hci_conn_del(sco);
929 }
930 }
931 }
932 928
933 if (ev->status) { 929 if (ev->status) {
934 hci_proto_connect_cfm(conn, ev->status); 930 hci_proto_connect_cfm(conn, ev->status);
@@ -1481,6 +1477,9 @@ static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb
1481 else 1477 else
1482 conn->power_save = 0; 1478 conn->power_save = 0;
1483 } 1479 }
1480
1481 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1482 hci_sco_setup(conn, ev->status);
1484 } 1483 }
1485 1484
1486 hci_dev_unlock(hdev); 1485 hci_dev_unlock(hdev);
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 43fbf6b4b4bf..44a623275951 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -1152,7 +1152,7 @@ error:
1152 return err; 1152 return err;
1153} 1153}
1154 1154
1155void rfcomm_cleanup_sockets(void) 1155void __exit rfcomm_cleanup_sockets(void)
1156{ 1156{
1157 debugfs_remove(rfcomm_sock_debugfs); 1157 debugfs_remove(rfcomm_sock_debugfs);
1158 1158
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index 309b6c261b25..026205c18b78 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -1153,7 +1153,7 @@ static const struct tty_operations rfcomm_ops = {
1153 .tiocmset = rfcomm_tty_tiocmset, 1153 .tiocmset = rfcomm_tty_tiocmset,
1154}; 1154};
1155 1155
1156int rfcomm_init_ttys(void) 1156int __init rfcomm_init_ttys(void)
1157{ 1157{
1158 rfcomm_tty_driver = alloc_tty_driver(RFCOMM_TTY_PORTS); 1158 rfcomm_tty_driver = alloc_tty_driver(RFCOMM_TTY_PORTS);
1159 if (!rfcomm_tty_driver) 1159 if (!rfcomm_tty_driver)
@@ -1183,7 +1183,7 @@ int rfcomm_init_ttys(void)
1183 return 0; 1183 return 0;
1184} 1184}
1185 1185
1186void rfcomm_cleanup_ttys(void) 1186void __exit rfcomm_cleanup_ttys(void)
1187{ 1187{
1188 tty_unregister_driver(rfcomm_tty_driver); 1188 tty_unregister_driver(rfcomm_tty_driver);
1189 put_tty_driver(rfcomm_tty_driver); 1189 put_tty_driver(rfcomm_tty_driver);