diff options
-rw-r--r-- | drivers/bluetooth/hci_usb.c | 19 | ||||
-rw-r--r-- | drivers/bluetooth/hci_usb.h | 5 | ||||
-rw-r--r-- | include/net/bluetooth/hci.h | 11 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 33 | ||||
-rw-r--r-- | net/bluetooth/rfcomm/sock.c | 30 |
5 files changed, 90 insertions, 8 deletions
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c index 67d96b5cbb96..57c48bbf6fe6 100644 --- a/drivers/bluetooth/hci_usb.c +++ b/drivers/bluetooth/hci_usb.c | |||
@@ -65,13 +65,15 @@ | |||
65 | #endif | 65 | #endif |
66 | 66 | ||
67 | static int ignore = 0; | 67 | static int ignore = 0; |
68 | static int ignore_csr = 0; | ||
69 | static int ignore_sniffer = 0; | ||
68 | static int reset = 0; | 70 | static int reset = 0; |
69 | 71 | ||
70 | #ifdef CONFIG_BT_HCIUSB_SCO | 72 | #ifdef CONFIG_BT_HCIUSB_SCO |
71 | static int isoc = 2; | 73 | static int isoc = 2; |
72 | #endif | 74 | #endif |
73 | 75 | ||
74 | #define VERSION "2.8" | 76 | #define VERSION "2.9" |
75 | 77 | ||
76 | static struct usb_driver hci_usb_driver; | 78 | static struct usb_driver hci_usb_driver; |
77 | 79 | ||
@@ -98,6 +100,9 @@ static struct usb_device_id bluetooth_ids[] = { | |||
98 | MODULE_DEVICE_TABLE (usb, bluetooth_ids); | 100 | MODULE_DEVICE_TABLE (usb, bluetooth_ids); |
99 | 101 | ||
100 | static struct usb_device_id blacklist_ids[] = { | 102 | static struct usb_device_id blacklist_ids[] = { |
103 | /* CSR BlueCore devices */ | ||
104 | { USB_DEVICE(0x0a12, 0x0001), .driver_info = HCI_CSR }, | ||
105 | |||
101 | /* Broadcom BCM2033 without firmware */ | 106 | /* Broadcom BCM2033 without firmware */ |
102 | { USB_DEVICE(0x0a5c, 0x2033), .driver_info = HCI_IGNORE }, | 107 | { USB_DEVICE(0x0a5c, 0x2033), .driver_info = HCI_IGNORE }, |
103 | 108 | ||
@@ -836,6 +841,12 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id | |||
836 | if (ignore || id->driver_info & HCI_IGNORE) | 841 | if (ignore || id->driver_info & HCI_IGNORE) |
837 | return -ENODEV; | 842 | return -ENODEV; |
838 | 843 | ||
844 | if (ignore_csr && id->driver_info & HCI_CSR) | ||
845 | return -ENODEV; | ||
846 | |||
847 | if (ignore_sniffer && id->driver_info & HCI_SNIFFER) | ||
848 | return -ENODEV; | ||
849 | |||
839 | if (intf->cur_altsetting->desc.bInterfaceNumber > 0) | 850 | if (intf->cur_altsetting->desc.bInterfaceNumber > 0) |
840 | return -ENODEV; | 851 | return -ENODEV; |
841 | 852 | ||
@@ -1061,6 +1072,12 @@ module_exit(hci_usb_exit); | |||
1061 | module_param(ignore, bool, 0644); | 1072 | module_param(ignore, bool, 0644); |
1062 | MODULE_PARM_DESC(ignore, "Ignore devices from the matching table"); | 1073 | MODULE_PARM_DESC(ignore, "Ignore devices from the matching table"); |
1063 | 1074 | ||
1075 | module_param(ignore_csr, bool, 0644); | ||
1076 | MODULE_PARM_DESC(ignore_csr, "Ignore devices with id 0a12:0001"); | ||
1077 | |||
1078 | module_param(ignore_sniffer, bool, 0644); | ||
1079 | MODULE_PARM_DESC(ignore_sniffer, "Ignore devices with id 0a12:0002"); | ||
1080 | |||
1064 | module_param(reset, bool, 0644); | 1081 | module_param(reset, bool, 0644); |
1065 | MODULE_PARM_DESC(reset, "Send HCI reset command on initialization"); | 1082 | MODULE_PARM_DESC(reset, "Send HCI reset command on initialization"); |
1066 | 1083 | ||
diff --git a/drivers/bluetooth/hci_usb.h b/drivers/bluetooth/hci_usb.h index 29936b43d4f8..37100a6ea1a8 100644 --- a/drivers/bluetooth/hci_usb.h +++ b/drivers/bluetooth/hci_usb.h | |||
@@ -31,9 +31,10 @@ | |||
31 | #define HCI_IGNORE 0x01 | 31 | #define HCI_IGNORE 0x01 |
32 | #define HCI_RESET 0x02 | 32 | #define HCI_RESET 0x02 |
33 | #define HCI_DIGIANSWER 0x04 | 33 | #define HCI_DIGIANSWER 0x04 |
34 | #define HCI_SNIFFER 0x08 | 34 | #define HCI_CSR 0x08 |
35 | #define HCI_BROKEN_ISOC 0x10 | 35 | #define HCI_SNIFFER 0x10 |
36 | #define HCI_BCM92035 0x20 | 36 | #define HCI_BCM92035 0x20 |
37 | #define HCI_BROKEN_ISOC 0x40 | ||
37 | 38 | ||
38 | #define HCI_MAX_IFACE_NUM 3 | 39 | #define HCI_MAX_IFACE_NUM 3 |
39 | 40 | ||
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 371e7d3f2e6f..fa2d12b0579b 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h | |||
@@ -463,6 +463,17 @@ struct inquiry_info_with_rssi_and_pscan_mode { | |||
463 | __s8 rssi; | 463 | __s8 rssi; |
464 | } __attribute__ ((packed)); | 464 | } __attribute__ ((packed)); |
465 | 465 | ||
466 | #define HCI_EV_EXTENDED_INQUIRY_RESULT 0x2F | ||
467 | struct extended_inquiry_info { | ||
468 | bdaddr_t bdaddr; | ||
469 | __u8 pscan_rep_mode; | ||
470 | __u8 pscan_period_mode; | ||
471 | __u8 dev_class[3]; | ||
472 | __u16 clock_offset; | ||
473 | __s8 rssi; | ||
474 | __u8 data[240]; | ||
475 | } __attribute__ ((packed)); | ||
476 | |||
466 | #define HCI_EV_CONN_COMPLETE 0x03 | 477 | #define HCI_EV_CONN_COMPLETE 0x03 |
467 | struct hci_ev_conn_complete { | 478 | struct hci_ev_conn_complete { |
468 | __u8 status; | 479 | __u8 status; |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index d6da0939216d..b61b4e8e36fd 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -558,6 +558,35 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct | |||
558 | hci_dev_unlock(hdev); | 558 | hci_dev_unlock(hdev); |
559 | } | 559 | } |
560 | 560 | ||
561 | /* Extended Inquiry Result */ | ||
562 | static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) | ||
563 | { | ||
564 | struct inquiry_data data; | ||
565 | struct extended_inquiry_info *info = (struct extended_inquiry_info *) (skb->data + 1); | ||
566 | int num_rsp = *((__u8 *) skb->data); | ||
567 | |||
568 | BT_DBG("%s num_rsp %d", hdev->name, num_rsp); | ||
569 | |||
570 | if (!num_rsp) | ||
571 | return; | ||
572 | |||
573 | hci_dev_lock(hdev); | ||
574 | |||
575 | for (; num_rsp; num_rsp--) { | ||
576 | bacpy(&data.bdaddr, &info->bdaddr); | ||
577 | data.pscan_rep_mode = info->pscan_rep_mode; | ||
578 | data.pscan_period_mode = info->pscan_period_mode; | ||
579 | data.pscan_mode = 0x00; | ||
580 | memcpy(data.dev_class, info->dev_class, 3); | ||
581 | data.clock_offset = info->clock_offset; | ||
582 | data.rssi = info->rssi; | ||
583 | info++; | ||
584 | hci_inquiry_cache_update(hdev, &data); | ||
585 | } | ||
586 | |||
587 | hci_dev_unlock(hdev); | ||
588 | } | ||
589 | |||
561 | /* Connect Request */ | 590 | /* Connect Request */ |
562 | static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) | 591 | static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) |
563 | { | 592 | { |
@@ -940,6 +969,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
940 | hci_inquiry_result_with_rssi_evt(hdev, skb); | 969 | hci_inquiry_result_with_rssi_evt(hdev, skb); |
941 | break; | 970 | break; |
942 | 971 | ||
972 | case HCI_EV_EXTENDED_INQUIRY_RESULT: | ||
973 | hci_extended_inquiry_result_evt(hdev, skb); | ||
974 | break; | ||
975 | |||
943 | case HCI_EV_CONN_REQUEST: | 976 | case HCI_EV_CONN_REQUEST: |
944 | hci_conn_request_evt(hdev, skb); | 977 | hci_conn_request_evt(hdev, skb); |
945 | break; | 978 | break; |
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 90e19eb6d3cc..f49e7e938bfb 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -363,6 +363,11 @@ static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr | |||
363 | goto done; | 363 | goto done; |
364 | } | 364 | } |
365 | 365 | ||
366 | if (sk->sk_type != SOCK_STREAM) { | ||
367 | err = -EINVAL; | ||
368 | goto done; | ||
369 | } | ||
370 | |||
366 | write_lock_bh(&rfcomm_sk_list.lock); | 371 | write_lock_bh(&rfcomm_sk_list.lock); |
367 | 372 | ||
368 | if (sa->rc_channel && __rfcomm_get_sock_by_addr(sa->rc_channel, &sa->rc_bdaddr)) { | 373 | if (sa->rc_channel && __rfcomm_get_sock_by_addr(sa->rc_channel, &sa->rc_bdaddr)) { |
@@ -393,13 +398,17 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a | |||
393 | if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_rc)) | 398 | if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_rc)) |
394 | return -EINVAL; | 399 | return -EINVAL; |
395 | 400 | ||
396 | if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND) | 401 | lock_sock(sk); |
397 | return -EBADFD; | ||
398 | 402 | ||
399 | if (sk->sk_type != SOCK_STREAM) | 403 | if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND) { |
400 | return -EINVAL; | 404 | err = -EBADFD; |
405 | goto done; | ||
406 | } | ||
401 | 407 | ||
402 | lock_sock(sk); | 408 | if (sk->sk_type != SOCK_STREAM) { |
409 | err = -EINVAL; | ||
410 | goto done; | ||
411 | } | ||
403 | 412 | ||
404 | sk->sk_state = BT_CONNECT; | 413 | sk->sk_state = BT_CONNECT; |
405 | bacpy(&bt_sk(sk)->dst, &sa->rc_bdaddr); | 414 | bacpy(&bt_sk(sk)->dst, &sa->rc_bdaddr); |
@@ -410,6 +419,7 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a | |||
410 | err = bt_sock_wait_state(sk, BT_CONNECTED, | 419 | err = bt_sock_wait_state(sk, BT_CONNECTED, |
411 | sock_sndtimeo(sk, flags & O_NONBLOCK)); | 420 | sock_sndtimeo(sk, flags & O_NONBLOCK)); |
412 | 421 | ||
422 | done: | ||
413 | release_sock(sk); | 423 | release_sock(sk); |
414 | return err; | 424 | return err; |
415 | } | 425 | } |
@@ -428,6 +438,11 @@ static int rfcomm_sock_listen(struct socket *sock, int backlog) | |||
428 | goto done; | 438 | goto done; |
429 | } | 439 | } |
430 | 440 | ||
441 | if (sk->sk_type != SOCK_STREAM) { | ||
442 | err = -EINVAL; | ||
443 | goto done; | ||
444 | } | ||
445 | |||
431 | if (!rfcomm_pi(sk)->channel) { | 446 | if (!rfcomm_pi(sk)->channel) { |
432 | bdaddr_t *src = &bt_sk(sk)->src; | 447 | bdaddr_t *src = &bt_sk(sk)->src; |
433 | u8 channel; | 448 | u8 channel; |
@@ -472,6 +487,11 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f | |||
472 | goto done; | 487 | goto done; |
473 | } | 488 | } |
474 | 489 | ||
490 | if (sk->sk_type != SOCK_STREAM) { | ||
491 | err = -EINVAL; | ||
492 | goto done; | ||
493 | } | ||
494 | |||
475 | timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); | 495 | timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); |
476 | 496 | ||
477 | BT_DBG("sk %p timeo %ld", sk, timeo); | 497 | BT_DBG("sk %p timeo %ld", sk, timeo); |