diff options
author | John W. Linville <linville@tuxdriver.com> | 2012-09-24 14:39:16 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-09-24 14:39:16 -0400 |
commit | 791ef39cd18ae2745a63c51a5dbbd23312be0744 (patch) | |
tree | 195a547ce1bde51ba3f37cd771648c18d84cc947 | |
parent | e5a876250d05d9708895da3d5408bdf67f1180f3 (diff) | |
parent | 0c1abbd1aa0416258881c303a88e618cbca0759c (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
-rw-r--r-- | drivers/bluetooth/bluecard_cs.c | 2 | ||||
-rw-r--r-- | drivers/bluetooth/btmrvl_sdio.c | 3 | ||||
-rw-r--r-- | drivers/bluetooth/btuart_cs.c | 2 | ||||
-rw-r--r-- | drivers/bluetooth/btusb.c | 3 | ||||
-rw-r--r-- | drivers/bluetooth/btwilink.c | 16 | ||||
-rw-r--r-- | drivers/bluetooth/hci_ldisc.c | 2 | ||||
-rw-r--r-- | drivers/bluetooth/hci_ll.c | 2 | ||||
-rw-r--r-- | drivers/bluetooth/hci_vhci.c | 2 | ||||
-rw-r--r-- | include/net/bluetooth/hci.h | 21 | ||||
-rw-r--r-- | include/net/bluetooth/hci_core.h | 26 | ||||
-rw-r--r-- | include/net/bluetooth/l2cap.h | 3 | ||||
-rw-r--r-- | include/net/bluetooth/mgmt.h | 16 | ||||
-rw-r--r-- | net/bluetooth/af_bluetooth.c | 10 | ||||
-rw-r--r-- | net/bluetooth/hci_conn.c | 100 | ||||
-rw-r--r-- | net/bluetooth/hci_core.c | 6 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 99 | ||||
-rw-r--r-- | net/bluetooth/l2cap_core.c | 17 | ||||
-rw-r--r-- | net/bluetooth/mgmt.c | 28 |
18 files changed, 255 insertions, 103 deletions
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index 0c0838d9b56c..0d26851d6e49 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c | |||
@@ -681,7 +681,7 @@ static int bluecard_hci_send_frame(struct sk_buff *skb) | |||
681 | case HCI_SCODATA_PKT: | 681 | case HCI_SCODATA_PKT: |
682 | hdev->stat.sco_tx++; | 682 | hdev->stat.sco_tx++; |
683 | break; | 683 | break; |
684 | }; | 684 | } |
685 | 685 | ||
686 | /* Prepend skb with frame type */ | 686 | /* Prepend skb with frame type */ |
687 | memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); | 687 | memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); |
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index 03b3acba6143..3f4bfc814dc7 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c | |||
@@ -600,8 +600,7 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) | |||
600 | exit: | 600 | exit: |
601 | if (ret) { | 601 | if (ret) { |
602 | hdev->stat.err_rx++; | 602 | hdev->stat.err_rx++; |
603 | if (skb) | 603 | kfree_skb(skb); |
604 | kfree_skb(skb); | ||
605 | } | 604 | } |
606 | 605 | ||
607 | return ret; | 606 | return ret; |
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c index 2f510a87b28f..35a553a90616 100644 --- a/drivers/bluetooth/btuart_cs.c +++ b/drivers/bluetooth/btuart_cs.c | |||
@@ -446,7 +446,7 @@ static int btuart_hci_send_frame(struct sk_buff *skb) | |||
446 | case HCI_SCODATA_PKT: | 446 | case HCI_SCODATA_PKT: |
447 | hdev->stat.sco_tx++; | 447 | hdev->stat.sco_tx++; |
448 | break; | 448 | break; |
449 | }; | 449 | } |
450 | 450 | ||
451 | /* Prepend skb with frame type */ | 451 | /* Prepend skb with frame type */ |
452 | memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); | 452 | memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); |
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index e5921d681ddb..debda27df9b0 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
@@ -96,11 +96,12 @@ static struct usb_device_id btusb_table[] = { | |||
96 | { USB_DEVICE(0x0c10, 0x0000) }, | 96 | { USB_DEVICE(0x0c10, 0x0000) }, |
97 | 97 | ||
98 | /* Broadcom BCM20702A0 */ | 98 | /* Broadcom BCM20702A0 */ |
99 | { USB_DEVICE(0x04ca, 0x2003) }, | ||
99 | { USB_DEVICE(0x0489, 0xe042) }, | 100 | { USB_DEVICE(0x0489, 0xe042) }, |
100 | { USB_DEVICE(0x413c, 0x8197) }, | 101 | { USB_DEVICE(0x413c, 0x8197) }, |
101 | 102 | ||
102 | /* Foxconn - Hon Hai */ | 103 | /* Foxconn - Hon Hai */ |
103 | { USB_DEVICE(0x0489, 0xe033) }, | 104 | { USB_VENDOR_AND_INTERFACE_INFO(0x0489, 0xff, 0x01, 0x01) }, |
104 | 105 | ||
105 | /*Broadcom devices with vendor specific id */ | 106 | /*Broadcom devices with vendor specific id */ |
106 | { USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01) }, | 107 | { USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01) }, |
diff --git a/drivers/bluetooth/btwilink.c b/drivers/bluetooth/btwilink.c index 4ad7b35cfc0e..60abf596f60e 100644 --- a/drivers/bluetooth/btwilink.c +++ b/drivers/bluetooth/btwilink.c | |||
@@ -358,21 +358,7 @@ static struct platform_driver btwilink_driver = { | |||
358 | }, | 358 | }, |
359 | }; | 359 | }; |
360 | 360 | ||
361 | /* ------- Module Init/Exit interfaces ------ */ | 361 | module_platform_driver(btwilink_driver); |
362 | static int __init btwilink_init(void) | ||
363 | { | ||
364 | BT_INFO("Bluetooth Driver for TI WiLink - Version %s", VERSION); | ||
365 | |||
366 | return platform_driver_register(&btwilink_driver); | ||
367 | } | ||
368 | |||
369 | static void __exit btwilink_exit(void) | ||
370 | { | ||
371 | platform_driver_unregister(&btwilink_driver); | ||
372 | } | ||
373 | |||
374 | module_init(btwilink_init); | ||
375 | module_exit(btwilink_exit); | ||
376 | 362 | ||
377 | /* ------ Module Info ------ */ | 363 | /* ------ Module Info ------ */ |
378 | 364 | ||
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 74e0966b3ead..c8abce3d2d9c 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c | |||
@@ -531,7 +531,7 @@ static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file, | |||
531 | default: | 531 | default: |
532 | err = n_tty_ioctl_helper(tty, file, cmd, arg); | 532 | err = n_tty_ioctl_helper(tty, file, cmd, arg); |
533 | break; | 533 | break; |
534 | }; | 534 | } |
535 | 535 | ||
536 | return err; | 536 | return err; |
537 | } | 537 | } |
diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c index ff6d589c34a5..cfc767938589 100644 --- a/drivers/bluetooth/hci_ll.c +++ b/drivers/bluetooth/hci_ll.c | |||
@@ -481,7 +481,7 @@ static int ll_recv(struct hci_uart *hu, void *data, int count) | |||
481 | hu->hdev->stat.err_rx++; | 481 | hu->hdev->stat.err_rx++; |
482 | ptr++; count--; | 482 | ptr++; count--; |
483 | continue; | 483 | continue; |
484 | }; | 484 | } |
485 | 485 | ||
486 | ptr++; count--; | 486 | ptr++; count--; |
487 | 487 | ||
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c index 3f72595a6017..d8b7aed6e4a9 100644 --- a/drivers/bluetooth/hci_vhci.c +++ b/drivers/bluetooth/hci_vhci.c | |||
@@ -156,7 +156,7 @@ static inline ssize_t vhci_put_user(struct vhci_data *data, | |||
156 | case HCI_SCODATA_PKT: | 156 | case HCI_SCODATA_PKT: |
157 | data->hdev->stat.sco_tx++; | 157 | data->hdev->stat.sco_tx++; |
158 | break; | 158 | break; |
159 | }; | 159 | } |
160 | 160 | ||
161 | return total; | 161 | return total; |
162 | } | 162 | } |
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 23cf413e2acf..76b2b6bdcf36 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h | |||
@@ -302,8 +302,11 @@ enum { | |||
302 | 302 | ||
303 | /* ---- HCI Error Codes ---- */ | 303 | /* ---- HCI Error Codes ---- */ |
304 | #define HCI_ERROR_AUTH_FAILURE 0x05 | 304 | #define HCI_ERROR_AUTH_FAILURE 0x05 |
305 | #define HCI_ERROR_CONNECTION_TIMEOUT 0x08 | ||
305 | #define HCI_ERROR_REJ_BAD_ADDR 0x0f | 306 | #define HCI_ERROR_REJ_BAD_ADDR 0x0f |
306 | #define HCI_ERROR_REMOTE_USER_TERM 0x13 | 307 | #define HCI_ERROR_REMOTE_USER_TERM 0x13 |
308 | #define HCI_ERROR_REMOTE_LOW_RESOURCES 0x14 | ||
309 | #define HCI_ERROR_REMOTE_POWER_OFF 0x15 | ||
307 | #define HCI_ERROR_LOCAL_HOST_TERM 0x16 | 310 | #define HCI_ERROR_LOCAL_HOST_TERM 0x16 |
308 | #define HCI_ERROR_PAIRING_NOT_ALLOWED 0x18 | 311 | #define HCI_ERROR_PAIRING_NOT_ALLOWED 0x18 |
309 | 312 | ||
@@ -1246,6 +1249,24 @@ struct hci_ev_simple_pair_complete { | |||
1246 | bdaddr_t bdaddr; | 1249 | bdaddr_t bdaddr; |
1247 | } __packed; | 1250 | } __packed; |
1248 | 1251 | ||
1252 | #define HCI_EV_USER_PASSKEY_NOTIFY 0x3b | ||
1253 | struct hci_ev_user_passkey_notify { | ||
1254 | bdaddr_t bdaddr; | ||
1255 | __le32 passkey; | ||
1256 | } __packed; | ||
1257 | |||
1258 | #define HCI_KEYPRESS_STARTED 0 | ||
1259 | #define HCI_KEYPRESS_ENTERED 1 | ||
1260 | #define HCI_KEYPRESS_ERASED 2 | ||
1261 | #define HCI_KEYPRESS_CLEARED 3 | ||
1262 | #define HCI_KEYPRESS_COMPLETED 4 | ||
1263 | |||
1264 | #define HCI_EV_KEYPRESS_NOTIFY 0x3c | ||
1265 | struct hci_ev_keypress_notify { | ||
1266 | bdaddr_t bdaddr; | ||
1267 | __u8 type; | ||
1268 | } __packed; | ||
1269 | |||
1249 | #define HCI_EV_REMOTE_HOST_FEATURES 0x3d | 1270 | #define HCI_EV_REMOTE_HOST_FEATURES 0x3d |
1250 | struct hci_ev_remote_host_features { | 1271 | struct hci_ev_remote_host_features { |
1251 | bdaddr_t bdaddr; | 1272 | bdaddr_t bdaddr; |
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 41d943926d2c..e7d454609881 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -303,6 +303,8 @@ struct hci_conn { | |||
303 | __u8 pin_length; | 303 | __u8 pin_length; |
304 | __u8 enc_key_size; | 304 | __u8 enc_key_size; |
305 | __u8 io_capability; | 305 | __u8 io_capability; |
306 | __u32 passkey_notify; | ||
307 | __u8 passkey_entered; | ||
306 | __u16 disc_timeout; | 308 | __u16 disc_timeout; |
307 | unsigned long flags; | 309 | unsigned long flags; |
308 | 310 | ||
@@ -428,15 +430,6 @@ static inline bool hci_conn_ssp_enabled(struct hci_conn *conn) | |||
428 | test_bit(HCI_CONN_SSP_ENABLED, &conn->flags); | 430 | test_bit(HCI_CONN_SSP_ENABLED, &conn->flags); |
429 | } | 431 | } |
430 | 432 | ||
431 | static inline void hci_conn_hash_init(struct hci_dev *hdev) | ||
432 | { | ||
433 | struct hci_conn_hash *h = &hdev->conn_hash; | ||
434 | INIT_LIST_HEAD(&h->list); | ||
435 | h->acl_num = 0; | ||
436 | h->sco_num = 0; | ||
437 | h->le_num = 0; | ||
438 | } | ||
439 | |||
440 | static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c) | 433 | static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c) |
441 | { | 434 | { |
442 | struct hci_conn_hash *h = &hdev->conn_hash; | 435 | struct hci_conn_hash *h = &hdev->conn_hash; |
@@ -551,9 +544,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev, | |||
551 | return NULL; | 544 | return NULL; |
552 | } | 545 | } |
553 | 546 | ||
554 | void hci_acl_connect(struct hci_conn *conn); | ||
555 | void hci_acl_disconn(struct hci_conn *conn, __u8 reason); | 547 | void hci_acl_disconn(struct hci_conn *conn, __u8 reason); |
556 | void hci_add_sco(struct hci_conn *conn, __u16 handle); | ||
557 | void hci_setup_sync(struct hci_conn *conn, __u16 handle); | 548 | void hci_setup_sync(struct hci_conn *conn, __u16 handle); |
558 | void hci_sco_setup(struct hci_conn *conn, __u8 status); | 549 | void hci_sco_setup(struct hci_conn *conn, __u8 status); |
559 | 550 | ||
@@ -563,7 +554,7 @@ void hci_conn_hash_flush(struct hci_dev *hdev); | |||
563 | void hci_conn_check_pending(struct hci_dev *hdev); | 554 | void hci_conn_check_pending(struct hci_dev *hdev); |
564 | 555 | ||
565 | struct hci_chan *hci_chan_create(struct hci_conn *conn); | 556 | struct hci_chan *hci_chan_create(struct hci_conn *conn); |
566 | int hci_chan_del(struct hci_chan *chan); | 557 | void hci_chan_del(struct hci_chan *chan); |
567 | void hci_chan_list_flush(struct hci_conn *conn); | 558 | void hci_chan_list_flush(struct hci_conn *conn); |
568 | 559 | ||
569 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, | 560 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, |
@@ -614,11 +605,17 @@ static inline void hci_conn_put(struct hci_conn *conn) | |||
614 | /* ----- HCI Devices ----- */ | 605 | /* ----- HCI Devices ----- */ |
615 | static inline void hci_dev_put(struct hci_dev *d) | 606 | static inline void hci_dev_put(struct hci_dev *d) |
616 | { | 607 | { |
608 | BT_DBG("%s orig refcnt %d", d->name, | ||
609 | atomic_read(&d->dev.kobj.kref.refcount)); | ||
610 | |||
617 | put_device(&d->dev); | 611 | put_device(&d->dev); |
618 | } | 612 | } |
619 | 613 | ||
620 | static inline struct hci_dev *hci_dev_hold(struct hci_dev *d) | 614 | static inline struct hci_dev *hci_dev_hold(struct hci_dev *d) |
621 | { | 615 | { |
616 | BT_DBG("%s orig refcnt %d", d->name, | ||
617 | atomic_read(&d->dev.kobj.kref.refcount)); | ||
618 | |||
622 | get_device(&d->dev); | 619 | get_device(&d->dev); |
623 | return d; | 620 | return d; |
624 | } | 621 | } |
@@ -1004,7 +1001,7 @@ int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | |||
1004 | u8 addr_type, u32 flags, u8 *name, u8 name_len, | 1001 | u8 addr_type, u32 flags, u8 *name, u8 name_len, |
1005 | u8 *dev_class); | 1002 | u8 *dev_class); |
1006 | int mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, | 1003 | int mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, |
1007 | u8 link_type, u8 addr_type); | 1004 | u8 link_type, u8 addr_type, u8 reason); |
1008 | int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, | 1005 | int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, |
1009 | u8 link_type, u8 addr_type, u8 status); | 1006 | u8 link_type, u8 addr_type, u8 status); |
1010 | int mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | 1007 | int mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, |
@@ -1027,6 +1024,9 @@ int mgmt_user_passkey_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, | |||
1027 | u8 link_type, u8 addr_type, u8 status); | 1024 | u8 link_type, u8 addr_type, u8 status); |
1028 | int mgmt_user_passkey_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, | 1025 | int mgmt_user_passkey_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, |
1029 | u8 link_type, u8 addr_type, u8 status); | 1026 | u8 link_type, u8 addr_type, u8 status); |
1027 | int mgmt_user_passkey_notify(struct hci_dev *hdev, bdaddr_t *bdaddr, | ||
1028 | u8 link_type, u8 addr_type, u32 passkey, | ||
1029 | u8 entered); | ||
1030 | int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | 1030 | int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, |
1031 | u8 addr_type, u8 status); | 1031 | u8 addr_type, u8 status); |
1032 | int mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status); | 1032 | int mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status); |
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index d206296137e2..7ed8e356425a 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h | |||
@@ -433,11 +433,10 @@ struct l2cap_chan { | |||
433 | struct sock *sk; | 433 | struct sock *sk; |
434 | 434 | ||
435 | struct l2cap_conn *conn; | 435 | struct l2cap_conn *conn; |
436 | struct kref kref; | ||
436 | 437 | ||
437 | __u8 state; | 438 | __u8 state; |
438 | 439 | ||
439 | atomic_t refcnt; | ||
440 | |||
441 | __le16 psm; | 440 | __le16 psm; |
442 | __u16 dcid; | 441 | __u16 dcid; |
443 | __u16 scid; | 442 | __u16 scid; |
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index 4348ee8bda69..22980a7c3873 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h | |||
@@ -405,7 +405,16 @@ struct mgmt_ev_device_connected { | |||
405 | __u8 eir[0]; | 405 | __u8 eir[0]; |
406 | } __packed; | 406 | } __packed; |
407 | 407 | ||
408 | #define MGMT_DEV_DISCONN_UNKNOWN 0x00 | ||
409 | #define MGMT_DEV_DISCONN_TIMEOUT 0x01 | ||
410 | #define MGMT_DEV_DISCONN_LOCAL_HOST 0x02 | ||
411 | #define MGMT_DEV_DISCONN_REMOTE 0x03 | ||
412 | |||
408 | #define MGMT_EV_DEVICE_DISCONNECTED 0x000C | 413 | #define MGMT_EV_DEVICE_DISCONNECTED 0x000C |
414 | struct mgmt_ev_device_disconnected { | ||
415 | struct mgmt_addr_info addr; | ||
416 | __u8 reason; | ||
417 | } __packed; | ||
409 | 418 | ||
410 | #define MGMT_EV_CONNECT_FAILED 0x000D | 419 | #define MGMT_EV_CONNECT_FAILED 0x000D |
411 | struct mgmt_ev_connect_failed { | 420 | struct mgmt_ev_connect_failed { |
@@ -469,3 +478,10 @@ struct mgmt_ev_device_unblocked { | |||
469 | struct mgmt_ev_device_unpaired { | 478 | struct mgmt_ev_device_unpaired { |
470 | struct mgmt_addr_info addr; | 479 | struct mgmt_addr_info addr; |
471 | } __packed; | 480 | } __packed; |
481 | |||
482 | #define MGMT_EV_PASSKEY_NOTIFY 0x0017 | ||
483 | struct mgmt_ev_passkey_notify { | ||
484 | struct mgmt_addr_info addr; | ||
485 | __le32 passkey; | ||
486 | __u8 entered; | ||
487 | } __packed; | ||
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 58f9762b339a..9d49ee6d7219 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c | |||
@@ -567,8 +567,6 @@ static void bt_seq_stop(struct seq_file *seq, void *v) | |||
567 | 567 | ||
568 | static int bt_seq_show(struct seq_file *seq, void *v) | 568 | static int bt_seq_show(struct seq_file *seq, void *v) |
569 | { | 569 | { |
570 | struct sock *sk; | ||
571 | struct bt_sock *bt; | ||
572 | struct bt_seq_state *s = seq->private; | 570 | struct bt_seq_state *s = seq->private; |
573 | struct bt_sock_list *l = s->l; | 571 | struct bt_sock_list *l = s->l; |
574 | bdaddr_t src_baswapped, dst_baswapped; | 572 | bdaddr_t src_baswapped, dst_baswapped; |
@@ -583,8 +581,8 @@ static int bt_seq_show(struct seq_file *seq, void *v) | |||
583 | 581 | ||
584 | seq_putc(seq, '\n'); | 582 | seq_putc(seq, '\n'); |
585 | } else { | 583 | } else { |
586 | sk = sk_entry(v); | 584 | struct sock *sk = sk_entry(v); |
587 | bt = bt_sk(sk); | 585 | struct bt_sock *bt = bt_sk(sk); |
588 | baswap(&src_baswapped, &bt->src); | 586 | baswap(&src_baswapped, &bt->src); |
589 | baswap(&dst_baswapped, &bt->dst); | 587 | baswap(&dst_baswapped, &bt->dst); |
590 | 588 | ||
@@ -624,7 +622,7 @@ static int bt_seq_open(struct inode *inode, struct file *file) | |||
624 | sk_list = PDE(inode)->data; | 622 | sk_list = PDE(inode)->data; |
625 | s = __seq_open_private(file, &bt_seq_ops, | 623 | s = __seq_open_private(file, &bt_seq_ops, |
626 | sizeof(struct bt_seq_state)); | 624 | sizeof(struct bt_seq_state)); |
627 | if (s == NULL) | 625 | if (!s) |
628 | return -ENOMEM; | 626 | return -ENOMEM; |
629 | 627 | ||
630 | s->l = sk_list; | 628 | s->l = sk_list; |
@@ -646,7 +644,7 @@ int bt_procfs_init(struct module* module, struct net *net, const char *name, | |||
646 | sk_list->fops.release = seq_release_private; | 644 | sk_list->fops.release = seq_release_private; |
647 | 645 | ||
648 | pde = proc_net_fops_create(net, name, 0, &sk_list->fops); | 646 | pde = proc_net_fops_create(net, name, 0, &sk_list->fops); |
649 | if (pde == NULL) | 647 | if (!pde) |
650 | return -ENOMEM; | 648 | return -ENOMEM; |
651 | 649 | ||
652 | pde->data = sk_list; | 650 | pde->data = sk_list; |
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 3c094e78dde9..b9196a44f759 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <net/bluetooth/a2mp.h> | 31 | #include <net/bluetooth/a2mp.h> |
32 | #include <net/bluetooth/smp.h> | 32 | #include <net/bluetooth/smp.h> |
33 | 33 | ||
34 | static void hci_le_connect(struct hci_conn *conn) | 34 | static void hci_le_create_connection(struct hci_conn *conn) |
35 | { | 35 | { |
36 | struct hci_dev *hdev = conn->hdev; | 36 | struct hci_dev *hdev = conn->hdev; |
37 | struct hci_cp_le_create_conn cp; | 37 | struct hci_cp_le_create_conn cp; |
@@ -55,12 +55,12 @@ static void hci_le_connect(struct hci_conn *conn) | |||
55 | hci_send_cmd(hdev, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp); | 55 | hci_send_cmd(hdev, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp); |
56 | } | 56 | } |
57 | 57 | ||
58 | static void hci_le_connect_cancel(struct hci_conn *conn) | 58 | static void hci_le_create_connection_cancel(struct hci_conn *conn) |
59 | { | 59 | { |
60 | hci_send_cmd(conn->hdev, HCI_OP_LE_CREATE_CONN_CANCEL, 0, NULL); | 60 | hci_send_cmd(conn->hdev, HCI_OP_LE_CREATE_CONN_CANCEL, 0, NULL); |
61 | } | 61 | } |
62 | 62 | ||
63 | void hci_acl_connect(struct hci_conn *conn) | 63 | static void hci_acl_create_connection(struct hci_conn *conn) |
64 | { | 64 | { |
65 | struct hci_dev *hdev = conn->hdev; | 65 | struct hci_dev *hdev = conn->hdev; |
66 | struct inquiry_entry *ie; | 66 | struct inquiry_entry *ie; |
@@ -104,7 +104,7 @@ void hci_acl_connect(struct hci_conn *conn) | |||
104 | hci_send_cmd(hdev, HCI_OP_CREATE_CONN, sizeof(cp), &cp); | 104 | hci_send_cmd(hdev, HCI_OP_CREATE_CONN, sizeof(cp), &cp); |
105 | } | 105 | } |
106 | 106 | ||
107 | static void hci_acl_connect_cancel(struct hci_conn *conn) | 107 | static void hci_acl_create_connection_cancel(struct hci_conn *conn) |
108 | { | 108 | { |
109 | struct hci_cp_create_conn_cancel cp; | 109 | struct hci_cp_create_conn_cancel cp; |
110 | 110 | ||
@@ -130,7 +130,7 @@ void hci_acl_disconn(struct hci_conn *conn, __u8 reason) | |||
130 | hci_send_cmd(conn->hdev, HCI_OP_DISCONNECT, sizeof(cp), &cp); | 130 | hci_send_cmd(conn->hdev, HCI_OP_DISCONNECT, sizeof(cp), &cp); |
131 | } | 131 | } |
132 | 132 | ||
133 | void hci_add_sco(struct hci_conn *conn, __u16 handle) | 133 | static void hci_add_sco(struct hci_conn *conn, __u16 handle) |
134 | { | 134 | { |
135 | struct hci_dev *hdev = conn->hdev; | 135 | struct hci_dev *hdev = conn->hdev; |
136 | struct hci_cp_add_sco cp; | 136 | struct hci_cp_add_sco cp; |
@@ -246,9 +246,9 @@ static void hci_conn_timeout(struct work_struct *work) | |||
246 | case BT_CONNECT2: | 246 | case BT_CONNECT2: |
247 | if (conn->out) { | 247 | if (conn->out) { |
248 | if (conn->type == ACL_LINK) | 248 | if (conn->type == ACL_LINK) |
249 | hci_acl_connect_cancel(conn); | 249 | hci_acl_create_connection_cancel(conn); |
250 | else if (conn->type == LE_LINK) | 250 | else if (conn->type == LE_LINK) |
251 | hci_le_connect_cancel(conn); | 251 | hci_le_create_connection_cancel(conn); |
252 | } | 252 | } |
253 | break; | 253 | break; |
254 | case BT_CONFIG: | 254 | case BT_CONFIG: |
@@ -471,40 +471,37 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src) | |||
471 | } | 471 | } |
472 | EXPORT_SYMBOL(hci_get_route); | 472 | EXPORT_SYMBOL(hci_get_route); |
473 | 473 | ||
474 | /* Create SCO, ACL or LE connection. | 474 | static struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst, |
475 | * Device _must_ be locked */ | 475 | u8 dst_type, u8 sec_level, u8 auth_type) |
476 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, | ||
477 | __u8 dst_type, __u8 sec_level, __u8 auth_type) | ||
478 | { | 476 | { |
479 | struct hci_conn *acl; | ||
480 | struct hci_conn *sco; | ||
481 | struct hci_conn *le; | 477 | struct hci_conn *le; |
482 | 478 | ||
483 | BT_DBG("%s dst %s", hdev->name, batostr(dst)); | 479 | le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst); |
480 | if (!le) { | ||
481 | le = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT); | ||
482 | if (le) | ||
483 | return ERR_PTR(-EBUSY); | ||
484 | 484 | ||
485 | if (type == LE_LINK) { | 485 | le = hci_conn_add(hdev, LE_LINK, dst); |
486 | le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst); | 486 | if (!le) |
487 | if (!le) { | 487 | return ERR_PTR(-ENOMEM); |
488 | le = hci_conn_hash_lookup_state(hdev, LE_LINK, | ||
489 | BT_CONNECT); | ||
490 | if (le) | ||
491 | return ERR_PTR(-EBUSY); | ||
492 | 488 | ||
493 | le = hci_conn_add(hdev, LE_LINK, dst); | 489 | le->dst_type = bdaddr_to_le(dst_type); |
494 | if (!le) | 490 | hci_le_create_connection(le); |
495 | return ERR_PTR(-ENOMEM); | 491 | } |
496 | 492 | ||
497 | le->dst_type = bdaddr_to_le(dst_type); | 493 | le->pending_sec_level = sec_level; |
498 | hci_le_connect(le); | 494 | le->auth_type = auth_type; |
499 | } | ||
500 | 495 | ||
501 | le->pending_sec_level = sec_level; | 496 | hci_conn_hold(le); |
502 | le->auth_type = auth_type; | ||
503 | 497 | ||
504 | hci_conn_hold(le); | 498 | return le; |
499 | } | ||
505 | 500 | ||
506 | return le; | 501 | static struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst, |
507 | } | 502 | u8 sec_level, u8 auth_type) |
503 | { | ||
504 | struct hci_conn *acl; | ||
508 | 505 | ||
509 | acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); | 506 | acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); |
510 | if (!acl) { | 507 | if (!acl) { |
@@ -519,10 +516,20 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, | |||
519 | acl->sec_level = BT_SECURITY_LOW; | 516 | acl->sec_level = BT_SECURITY_LOW; |
520 | acl->pending_sec_level = sec_level; | 517 | acl->pending_sec_level = sec_level; |
521 | acl->auth_type = auth_type; | 518 | acl->auth_type = auth_type; |
522 | hci_acl_connect(acl); | 519 | hci_acl_create_connection(acl); |
523 | } | 520 | } |
524 | 521 | ||
525 | if (type == ACL_LINK) | 522 | return acl; |
523 | } | ||
524 | |||
525 | static struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, | ||
526 | bdaddr_t *dst, u8 sec_level, u8 auth_type) | ||
527 | { | ||
528 | struct hci_conn *acl; | ||
529 | struct hci_conn *sco; | ||
530 | |||
531 | acl = hci_connect_acl(hdev, dst, sec_level, auth_type); | ||
532 | if (IS_ERR(acl)) | ||
526 | return acl; | 533 | return acl; |
527 | 534 | ||
528 | sco = hci_conn_hash_lookup_ba(hdev, type, dst); | 535 | sco = hci_conn_hash_lookup_ba(hdev, type, dst); |
@@ -556,6 +563,25 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, | |||
556 | return sco; | 563 | return sco; |
557 | } | 564 | } |
558 | 565 | ||
566 | /* Create SCO, ACL or LE connection. */ | ||
567 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, | ||
568 | __u8 dst_type, __u8 sec_level, __u8 auth_type) | ||
569 | { | ||
570 | BT_DBG("%s dst %s type 0x%x", hdev->name, batostr(dst), type); | ||
571 | |||
572 | switch (type) { | ||
573 | case LE_LINK: | ||
574 | return hci_connect_le(hdev, dst, dst_type, sec_level, auth_type); | ||
575 | case ACL_LINK: | ||
576 | return hci_connect_acl(hdev, dst, sec_level, auth_type); | ||
577 | case SCO_LINK: | ||
578 | case ESCO_LINK: | ||
579 | return hci_connect_sco(hdev, type, dst, sec_level, auth_type); | ||
580 | } | ||
581 | |||
582 | return ERR_PTR(-EINVAL); | ||
583 | } | ||
584 | |||
559 | /* Check link security requirement */ | 585 | /* Check link security requirement */ |
560 | int hci_conn_check_link_mode(struct hci_conn *conn) | 586 | int hci_conn_check_link_mode(struct hci_conn *conn) |
561 | { | 587 | { |
@@ -775,7 +801,7 @@ void hci_conn_check_pending(struct hci_dev *hdev) | |||
775 | 801 | ||
776 | conn = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2); | 802 | conn = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2); |
777 | if (conn) | 803 | if (conn) |
778 | hci_acl_connect(conn); | 804 | hci_acl_create_connection(conn); |
779 | 805 | ||
780 | hci_dev_unlock(hdev); | 806 | hci_dev_unlock(hdev); |
781 | } | 807 | } |
@@ -913,7 +939,7 @@ struct hci_chan *hci_chan_create(struct hci_conn *conn) | |||
913 | return chan; | 939 | return chan; |
914 | } | 940 | } |
915 | 941 | ||
916 | int hci_chan_del(struct hci_chan *chan) | 942 | void hci_chan_del(struct hci_chan *chan) |
917 | { | 943 | { |
918 | struct hci_conn *conn = chan->conn; | 944 | struct hci_conn *conn = chan->conn; |
919 | struct hci_dev *hdev = conn->hdev; | 945 | struct hci_dev *hdev = conn->hdev; |
@@ -926,8 +952,6 @@ int hci_chan_del(struct hci_chan *chan) | |||
926 | 952 | ||
927 | skb_queue_purge(&chan->data_q); | 953 | skb_queue_purge(&chan->data_q); |
928 | kfree(chan); | 954 | kfree(chan); |
929 | |||
930 | return 0; | ||
931 | } | 955 | } |
932 | 956 | ||
933 | void hci_chan_list_flush(struct hci_conn *conn) | 957 | void hci_chan_list_flush(struct hci_conn *conn) |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index fa974a19d365..e4070517ff3b 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -231,6 +231,9 @@ static void amp_init(struct hci_dev *hdev) | |||
231 | 231 | ||
232 | /* Read Local AMP Info */ | 232 | /* Read Local AMP Info */ |
233 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL); | 233 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL); |
234 | |||
235 | /* Read Data Blk size */ | ||
236 | hci_send_cmd(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL); | ||
234 | } | 237 | } |
235 | 238 | ||
236 | static void hci_init_req(struct hci_dev *hdev, unsigned long opt) | 239 | static void hci_init_req(struct hci_dev *hdev, unsigned long opt) |
@@ -268,7 +271,6 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt) | |||
268 | BT_ERR("Unknown device type %d", hdev->dev_type); | 271 | BT_ERR("Unknown device type %d", hdev->dev_type); |
269 | break; | 272 | break; |
270 | } | 273 | } |
271 | |||
272 | } | 274 | } |
273 | 275 | ||
274 | static void hci_le_init_req(struct hci_dev *hdev, unsigned long opt) | 276 | static void hci_le_init_req(struct hci_dev *hdev, unsigned long opt) |
@@ -1652,6 +1654,7 @@ struct hci_dev *hci_alloc_dev(void) | |||
1652 | INIT_LIST_HEAD(&hdev->link_keys); | 1654 | INIT_LIST_HEAD(&hdev->link_keys); |
1653 | INIT_LIST_HEAD(&hdev->long_term_keys); | 1655 | INIT_LIST_HEAD(&hdev->long_term_keys); |
1654 | INIT_LIST_HEAD(&hdev->remote_oob_data); | 1656 | INIT_LIST_HEAD(&hdev->remote_oob_data); |
1657 | INIT_LIST_HEAD(&hdev->conn_hash.list); | ||
1655 | 1658 | ||
1656 | INIT_WORK(&hdev->rx_work, hci_rx_work); | 1659 | INIT_WORK(&hdev->rx_work, hci_rx_work); |
1657 | INIT_WORK(&hdev->cmd_work, hci_cmd_work); | 1660 | INIT_WORK(&hdev->cmd_work, hci_cmd_work); |
@@ -1674,7 +1677,6 @@ struct hci_dev *hci_alloc_dev(void) | |||
1674 | 1677 | ||
1675 | hci_init_sysfs(hdev); | 1678 | hci_init_sysfs(hdev); |
1676 | discovery_init(hdev); | 1679 | discovery_init(hdev); |
1677 | hci_conn_hash_init(hdev); | ||
1678 | 1680 | ||
1679 | return hdev; | 1681 | return hdev; |
1680 | } | 1682 | } |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 4fd2cf3bcd05..2022b43c7353 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -29,6 +29,7 @@ | |||
29 | 29 | ||
30 | #include <net/bluetooth/bluetooth.h> | 30 | #include <net/bluetooth/bluetooth.h> |
31 | #include <net/bluetooth/hci_core.h> | 31 | #include <net/bluetooth/hci_core.h> |
32 | #include <net/bluetooth/mgmt.h> | ||
32 | 33 | ||
33 | /* Handle HCI Event packets */ | 34 | /* Handle HCI Event packets */ |
34 | 35 | ||
@@ -303,7 +304,7 @@ static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb) | |||
303 | 304 | ||
304 | hci_dev_lock(hdev); | 305 | hci_dev_lock(hdev); |
305 | 306 | ||
306 | if (status != 0) { | 307 | if (status) { |
307 | mgmt_write_scan_failed(hdev, param, status); | 308 | mgmt_write_scan_failed(hdev, param, status); |
308 | hdev->discov_timeout = 0; | 309 | hdev->discov_timeout = 0; |
309 | goto done; | 310 | goto done; |
@@ -925,7 +926,7 @@ static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb) | |||
925 | if (test_bit(HCI_MGMT, &hdev->dev_flags)) | 926 | if (test_bit(HCI_MGMT, &hdev->dev_flags)) |
926 | mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status); | 927 | mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status); |
927 | 928 | ||
928 | if (rp->status != 0) | 929 | if (rp->status) |
929 | goto unlock; | 930 | goto unlock; |
930 | 931 | ||
931 | cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY); | 932 | cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY); |
@@ -1891,6 +1892,22 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
1891 | } | 1892 | } |
1892 | } | 1893 | } |
1893 | 1894 | ||
1895 | static u8 hci_to_mgmt_reason(u8 err) | ||
1896 | { | ||
1897 | switch (err) { | ||
1898 | case HCI_ERROR_CONNECTION_TIMEOUT: | ||
1899 | return MGMT_DEV_DISCONN_TIMEOUT; | ||
1900 | case HCI_ERROR_REMOTE_USER_TERM: | ||
1901 | case HCI_ERROR_REMOTE_LOW_RESOURCES: | ||
1902 | case HCI_ERROR_REMOTE_POWER_OFF: | ||
1903 | return MGMT_DEV_DISCONN_REMOTE; | ||
1904 | case HCI_ERROR_LOCAL_HOST_TERM: | ||
1905 | return MGMT_DEV_DISCONN_LOCAL_HOST; | ||
1906 | default: | ||
1907 | return MGMT_DEV_DISCONN_UNKNOWN; | ||
1908 | } | ||
1909 | } | ||
1910 | |||
1894 | static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 1911 | static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) |
1895 | { | 1912 | { |
1896 | struct hci_ev_disconn_complete *ev = (void *) skb->data; | 1913 | struct hci_ev_disconn_complete *ev = (void *) skb->data; |
@@ -1909,12 +1926,15 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
1909 | 1926 | ||
1910 | if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) && | 1927 | if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) && |
1911 | (conn->type == ACL_LINK || conn->type == LE_LINK)) { | 1928 | (conn->type == ACL_LINK || conn->type == LE_LINK)) { |
1912 | if (ev->status != 0) | 1929 | if (ev->status) { |
1913 | mgmt_disconnect_failed(hdev, &conn->dst, conn->type, | 1930 | mgmt_disconnect_failed(hdev, &conn->dst, conn->type, |
1914 | conn->dst_type, ev->status); | 1931 | conn->dst_type, ev->status); |
1915 | else | 1932 | } else { |
1933 | u8 reason = hci_to_mgmt_reason(ev->reason); | ||
1934 | |||
1916 | mgmt_device_disconnected(hdev, &conn->dst, conn->type, | 1935 | mgmt_device_disconnected(hdev, &conn->dst, conn->type, |
1917 | conn->dst_type); | 1936 | conn->dst_type, reason); |
1937 | } | ||
1918 | } | 1938 | } |
1919 | 1939 | ||
1920 | if (ev->status == 0) { | 1940 | if (ev->status == 0) { |
@@ -3259,6 +3279,65 @@ static void hci_user_passkey_request_evt(struct hci_dev *hdev, | |||
3259 | mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0); | 3279 | mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0); |
3260 | } | 3280 | } |
3261 | 3281 | ||
3282 | static void hci_user_passkey_notify_evt(struct hci_dev *hdev, | ||
3283 | struct sk_buff *skb) | ||
3284 | { | ||
3285 | struct hci_ev_user_passkey_notify *ev = (void *) skb->data; | ||
3286 | struct hci_conn *conn; | ||
3287 | |||
3288 | BT_DBG("%s", hdev->name); | ||
3289 | |||
3290 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); | ||
3291 | if (!conn) | ||
3292 | return; | ||
3293 | |||
3294 | conn->passkey_notify = __le32_to_cpu(ev->passkey); | ||
3295 | conn->passkey_entered = 0; | ||
3296 | |||
3297 | if (test_bit(HCI_MGMT, &hdev->dev_flags)) | ||
3298 | mgmt_user_passkey_notify(hdev, &conn->dst, conn->type, | ||
3299 | conn->dst_type, conn->passkey_notify, | ||
3300 | conn->passkey_entered); | ||
3301 | } | ||
3302 | |||
3303 | static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) | ||
3304 | { | ||
3305 | struct hci_ev_keypress_notify *ev = (void *) skb->data; | ||
3306 | struct hci_conn *conn; | ||
3307 | |||
3308 | BT_DBG("%s", hdev->name); | ||
3309 | |||
3310 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); | ||
3311 | if (!conn) | ||
3312 | return; | ||
3313 | |||
3314 | switch (ev->type) { | ||
3315 | case HCI_KEYPRESS_STARTED: | ||
3316 | conn->passkey_entered = 0; | ||
3317 | return; | ||
3318 | |||
3319 | case HCI_KEYPRESS_ENTERED: | ||
3320 | conn->passkey_entered++; | ||
3321 | break; | ||
3322 | |||
3323 | case HCI_KEYPRESS_ERASED: | ||
3324 | conn->passkey_entered--; | ||
3325 | break; | ||
3326 | |||
3327 | case HCI_KEYPRESS_CLEARED: | ||
3328 | conn->passkey_entered = 0; | ||
3329 | break; | ||
3330 | |||
3331 | case HCI_KEYPRESS_COMPLETED: | ||
3332 | return; | ||
3333 | } | ||
3334 | |||
3335 | if (test_bit(HCI_MGMT, &hdev->dev_flags)) | ||
3336 | mgmt_user_passkey_notify(hdev, &conn->dst, conn->type, | ||
3337 | conn->dst_type, conn->passkey_notify, | ||
3338 | conn->passkey_entered); | ||
3339 | } | ||
3340 | |||
3262 | static void hci_simple_pair_complete_evt(struct hci_dev *hdev, | 3341 | static void hci_simple_pair_complete_evt(struct hci_dev *hdev, |
3263 | struct sk_buff *skb) | 3342 | struct sk_buff *skb) |
3264 | { | 3343 | { |
@@ -3278,7 +3357,7 @@ static void hci_simple_pair_complete_evt(struct hci_dev *hdev, | |||
3278 | * initiated the authentication. A traditional auth_complete | 3357 | * initiated the authentication. A traditional auth_complete |
3279 | * event gets always produced as initiator and is also mapped to | 3358 | * event gets always produced as initiator and is also mapped to |
3280 | * the mgmt_auth_failed event */ | 3359 | * the mgmt_auth_failed event */ |
3281 | if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0) | 3360 | if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status) |
3282 | mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type, | 3361 | mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type, |
3283 | ev->status); | 3362 | ev->status); |
3284 | 3363 | ||
@@ -3623,6 +3702,14 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
3623 | hci_user_passkey_request_evt(hdev, skb); | 3702 | hci_user_passkey_request_evt(hdev, skb); |
3624 | break; | 3703 | break; |
3625 | 3704 | ||
3705 | case HCI_EV_USER_PASSKEY_NOTIFY: | ||
3706 | hci_user_passkey_notify_evt(hdev, skb); | ||
3707 | break; | ||
3708 | |||
3709 | case HCI_EV_KEYPRESS_NOTIFY: | ||
3710 | hci_keypress_notify_evt(hdev, skb); | ||
3711 | break; | ||
3712 | |||
3626 | case HCI_EV_SIMPLE_PAIR_COMPLETE: | 3713 | case HCI_EV_SIMPLE_PAIR_COMPLETE: |
3627 | hci_simple_pair_complete_evt(hdev, skb); | 3714 | hci_simple_pair_complete_evt(hdev, skb); |
3628 | break; | 3715 | break; |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index e0abaf3cb6a5..7a59e929febc 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -406,7 +406,7 @@ struct l2cap_chan *l2cap_chan_create(void) | |||
406 | 406 | ||
407 | chan->state = BT_OPEN; | 407 | chan->state = BT_OPEN; |
408 | 408 | ||
409 | atomic_set(&chan->refcnt, 1); | 409 | kref_init(&chan->kref); |
410 | 410 | ||
411 | /* This flag is cleared in l2cap_chan_ready() */ | 411 | /* This flag is cleared in l2cap_chan_ready() */ |
412 | set_bit(CONF_NOT_COMPLETE, &chan->conf_state); | 412 | set_bit(CONF_NOT_COMPLETE, &chan->conf_state); |
@@ -416,8 +416,10 @@ struct l2cap_chan *l2cap_chan_create(void) | |||
416 | return chan; | 416 | return chan; |
417 | } | 417 | } |
418 | 418 | ||
419 | static void l2cap_chan_destroy(struct l2cap_chan *chan) | 419 | static void l2cap_chan_destroy(struct kref *kref) |
420 | { | 420 | { |
421 | struct l2cap_chan *chan = container_of(kref, struct l2cap_chan, kref); | ||
422 | |||
421 | BT_DBG("chan %p", chan); | 423 | BT_DBG("chan %p", chan); |
422 | 424 | ||
423 | write_lock(&chan_list_lock); | 425 | write_lock(&chan_list_lock); |
@@ -429,17 +431,16 @@ static void l2cap_chan_destroy(struct l2cap_chan *chan) | |||
429 | 431 | ||
430 | void l2cap_chan_hold(struct l2cap_chan *c) | 432 | void l2cap_chan_hold(struct l2cap_chan *c) |
431 | { | 433 | { |
432 | BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->refcnt)); | 434 | BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount)); |
433 | 435 | ||
434 | atomic_inc(&c->refcnt); | 436 | kref_get(&c->kref); |
435 | } | 437 | } |
436 | 438 | ||
437 | void l2cap_chan_put(struct l2cap_chan *c) | 439 | void l2cap_chan_put(struct l2cap_chan *c) |
438 | { | 440 | { |
439 | BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->refcnt)); | 441 | BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount)); |
440 | 442 | ||
441 | if (atomic_dec_and_test(&c->refcnt)) | 443 | kref_put(&c->kref, l2cap_chan_destroy); |
442 | l2cap_chan_destroy(c); | ||
443 | } | 444 | } |
444 | 445 | ||
445 | void l2cap_chan_set_defaults(struct l2cap_chan *chan) | 446 | void l2cap_chan_set_defaults(struct l2cap_chan *chan) |
@@ -1448,7 +1449,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, | |||
1448 | int err; | 1449 | int err; |
1449 | 1450 | ||
1450 | BT_DBG("%s -> %s (type %u) psm 0x%2.2x", batostr(src), batostr(dst), | 1451 | BT_DBG("%s -> %s (type %u) psm 0x%2.2x", batostr(src), batostr(dst), |
1451 | dst_type, __le16_to_cpu(chan->psm)); | 1452 | dst_type, __le16_to_cpu(psm)); |
1452 | 1453 | ||
1453 | hdev = hci_get_route(dst, src); | 1454 | hdev = hci_get_route(dst, src); |
1454 | if (!hdev) | 1455 | if (!hdev) |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index a3329cbd3e4d..8934343be0ea 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -35,7 +35,7 @@ | |||
35 | bool enable_hs; | 35 | bool enable_hs; |
36 | 36 | ||
37 | #define MGMT_VERSION 1 | 37 | #define MGMT_VERSION 1 |
38 | #define MGMT_REVISION 1 | 38 | #define MGMT_REVISION 2 |
39 | 39 | ||
40 | static const u16 mgmt_commands[] = { | 40 | static const u16 mgmt_commands[] = { |
41 | MGMT_OP_READ_INDEX_LIST, | 41 | MGMT_OP_READ_INDEX_LIST, |
@@ -99,6 +99,7 @@ static const u16 mgmt_events[] = { | |||
99 | MGMT_EV_DEVICE_BLOCKED, | 99 | MGMT_EV_DEVICE_BLOCKED, |
100 | MGMT_EV_DEVICE_UNBLOCKED, | 100 | MGMT_EV_DEVICE_UNBLOCKED, |
101 | MGMT_EV_DEVICE_UNPAIRED, | 101 | MGMT_EV_DEVICE_UNPAIRED, |
102 | MGMT_EV_PASSKEY_NOTIFY, | ||
102 | }; | 103 | }; |
103 | 104 | ||
104 | /* | 105 | /* |
@@ -3077,16 +3078,17 @@ static void unpair_device_rsp(struct pending_cmd *cmd, void *data) | |||
3077 | } | 3078 | } |
3078 | 3079 | ||
3079 | int mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, | 3080 | int mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, |
3080 | u8 link_type, u8 addr_type) | 3081 | u8 link_type, u8 addr_type, u8 reason) |
3081 | { | 3082 | { |
3082 | struct mgmt_addr_info ev; | 3083 | struct mgmt_ev_device_disconnected ev; |
3083 | struct sock *sk = NULL; | 3084 | struct sock *sk = NULL; |
3084 | int err; | 3085 | int err; |
3085 | 3086 | ||
3086 | mgmt_pending_foreach(MGMT_OP_DISCONNECT, hdev, disconnect_rsp, &sk); | 3087 | mgmt_pending_foreach(MGMT_OP_DISCONNECT, hdev, disconnect_rsp, &sk); |
3087 | 3088 | ||
3088 | bacpy(&ev.bdaddr, bdaddr); | 3089 | bacpy(&ev.addr.bdaddr, bdaddr); |
3089 | ev.type = link_to_bdaddr(link_type, addr_type); | 3090 | ev.addr.type = link_to_bdaddr(link_type, addr_type); |
3091 | ev.reason = reason; | ||
3090 | 3092 | ||
3091 | err = mgmt_event(MGMT_EV_DEVICE_DISCONNECTED, hdev, &ev, sizeof(ev), | 3093 | err = mgmt_event(MGMT_EV_DEVICE_DISCONNECTED, hdev, &ev, sizeof(ev), |
3092 | sk); | 3094 | sk); |
@@ -3275,6 +3277,22 @@ int mgmt_user_passkey_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, | |||
3275 | MGMT_OP_USER_PASSKEY_NEG_REPLY); | 3277 | MGMT_OP_USER_PASSKEY_NEG_REPLY); |
3276 | } | 3278 | } |
3277 | 3279 | ||
3280 | int mgmt_user_passkey_notify(struct hci_dev *hdev, bdaddr_t *bdaddr, | ||
3281 | u8 link_type, u8 addr_type, u32 passkey, | ||
3282 | u8 entered) | ||
3283 | { | ||
3284 | struct mgmt_ev_passkey_notify ev; | ||
3285 | |||
3286 | BT_DBG("%s", hdev->name); | ||
3287 | |||
3288 | bacpy(&ev.addr.bdaddr, bdaddr); | ||
3289 | ev.addr.type = link_to_bdaddr(link_type, addr_type); | ||
3290 | ev.passkey = __cpu_to_le32(passkey); | ||
3291 | ev.entered = entered; | ||
3292 | |||
3293 | return mgmt_event(MGMT_EV_PASSKEY_NOTIFY, hdev, &ev, sizeof(ev), NULL); | ||
3294 | } | ||
3295 | |||
3278 | int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | 3296 | int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, |
3279 | u8 addr_type, u8 status) | 3297 | u8 addr_type, u8 status) |
3280 | { | 3298 | { |