diff options
Diffstat (limited to 'drivers/bluetooth/btusb.c')
-rw-r--r-- | drivers/bluetooth/btusb.c | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 6a010681ecf3..af472e052732 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
@@ -102,14 +102,19 @@ static struct usb_device_id blacklist_table[] = { | |||
102 | { USB_DEVICE(0x0a5c, 0x2101), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, | 102 | { USB_DEVICE(0x0a5c, 0x2101), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, |
103 | 103 | ||
104 | /* Broadcom BCM2046 */ | 104 | /* Broadcom BCM2046 */ |
105 | { USB_DEVICE(0x0a5c, 0x2146), .driver_info = BTUSB_RESET }, | ||
105 | { USB_DEVICE(0x0a5c, 0x2151), .driver_info = BTUSB_RESET }, | 106 | { USB_DEVICE(0x0a5c, 0x2151), .driver_info = BTUSB_RESET }, |
106 | 107 | ||
108 | /* Apple MacBook Pro with Broadcom chip */ | ||
109 | { USB_DEVICE(0x05ac, 0x820f), .driver_info = BTUSB_RESET }, | ||
110 | |||
107 | /* IBM/Lenovo ThinkPad with Broadcom chip */ | 111 | /* IBM/Lenovo ThinkPad with Broadcom chip */ |
108 | { USB_DEVICE(0x0a5c, 0x201e), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, | 112 | { USB_DEVICE(0x0a5c, 0x201e), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, |
109 | { USB_DEVICE(0x0a5c, 0x2110), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, | 113 | { USB_DEVICE(0x0a5c, 0x2110), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, |
110 | 114 | ||
111 | /* Targus ACB10US */ | 115 | /* Targus ACB10US */ |
112 | { USB_DEVICE(0x0a5c, 0x2100), .driver_info = BTUSB_RESET }, | 116 | { USB_DEVICE(0x0a5c, 0x2100), .driver_info = BTUSB_RESET }, |
117 | { USB_DEVICE(0x0a5c, 0x2154), .driver_info = BTUSB_RESET }, | ||
113 | 118 | ||
114 | /* ANYCOM Bluetooth USB-200 and USB-250 */ | 119 | /* ANYCOM Bluetooth USB-200 and USB-250 */ |
115 | { USB_DEVICE(0x0a5c, 0x2111), .driver_info = BTUSB_RESET }, | 120 | { USB_DEVICE(0x0a5c, 0x2111), .driver_info = BTUSB_RESET }, |
@@ -147,6 +152,9 @@ static struct usb_device_id blacklist_table[] = { | |||
147 | { USB_DEVICE(0x050d, 0x0012), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, | 152 | { USB_DEVICE(0x050d, 0x0012), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, |
148 | { USB_DEVICE(0x050d, 0x0013), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, | 153 | { USB_DEVICE(0x050d, 0x0013), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, |
149 | 154 | ||
155 | /* Belkin F8T016 device */ | ||
156 | { USB_DEVICE(0x050d, 0x016a), .driver_info = BTUSB_RESET }, | ||
157 | |||
150 | /* Digianswer devices */ | 158 | /* Digianswer devices */ |
151 | { USB_DEVICE(0x08fd, 0x0001), .driver_info = BTUSB_DIGIANSWER }, | 159 | { USB_DEVICE(0x08fd, 0x0001), .driver_info = BTUSB_DIGIANSWER }, |
152 | { USB_DEVICE(0x08fd, 0x0002), .driver_info = BTUSB_IGNORE }, | 160 | { USB_DEVICE(0x08fd, 0x0002), .driver_info = BTUSB_IGNORE }, |
@@ -169,6 +177,7 @@ static struct usb_device_id blacklist_table[] = { | |||
169 | struct btusb_data { | 177 | struct btusb_data { |
170 | struct hci_dev *hdev; | 178 | struct hci_dev *hdev; |
171 | struct usb_device *udev; | 179 | struct usb_device *udev; |
180 | struct usb_interface *intf; | ||
172 | struct usb_interface *isoc; | 181 | struct usb_interface *isoc; |
173 | 182 | ||
174 | spinlock_t lock; | 183 | spinlock_t lock; |
@@ -267,7 +276,6 @@ static int btusb_submit_intr_urb(struct hci_dev *hdev) | |||
267 | BT_ERR("%s urb %p submission failed (%d)", | 276 | BT_ERR("%s urb %p submission failed (%d)", |
268 | hdev->name, urb, -err); | 277 | hdev->name, urb, -err); |
269 | usb_unanchor_urb(urb); | 278 | usb_unanchor_urb(urb); |
270 | kfree(buf); | ||
271 | } | 279 | } |
272 | 280 | ||
273 | usb_free_urb(urb); | 281 | usb_free_urb(urb); |
@@ -350,7 +358,6 @@ static int btusb_submit_bulk_urb(struct hci_dev *hdev) | |||
350 | BT_ERR("%s urb %p submission failed (%d)", | 358 | BT_ERR("%s urb %p submission failed (%d)", |
351 | hdev->name, urb, -err); | 359 | hdev->name, urb, -err); |
352 | usb_unanchor_urb(urb); | 360 | usb_unanchor_urb(urb); |
353 | kfree(buf); | ||
354 | } | 361 | } |
355 | 362 | ||
356 | usb_free_urb(urb); | 363 | usb_free_urb(urb); |
@@ -471,7 +478,6 @@ static int btusb_submit_isoc_urb(struct hci_dev *hdev) | |||
471 | BT_ERR("%s urb %p submission failed (%d)", | 478 | BT_ERR("%s urb %p submission failed (%d)", |
472 | hdev->name, urb, -err); | 479 | hdev->name, urb, -err); |
473 | usb_unanchor_urb(urb); | 480 | usb_unanchor_urb(urb); |
474 | kfree(buf); | ||
475 | } | 481 | } |
476 | 482 | ||
477 | usb_free_urb(urb); | 483 | usb_free_urb(urb); |
@@ -516,7 +522,7 @@ static int btusb_open(struct hci_dev *hdev) | |||
516 | 522 | ||
517 | err = btusb_submit_intr_urb(hdev); | 523 | err = btusb_submit_intr_urb(hdev); |
518 | if (err < 0) { | 524 | if (err < 0) { |
519 | clear_bit(BTUSB_INTR_RUNNING, &hdev->flags); | 525 | clear_bit(BTUSB_INTR_RUNNING, &data->flags); |
520 | clear_bit(HCI_RUNNING, &hdev->flags); | 526 | clear_bit(HCI_RUNNING, &hdev->flags); |
521 | } | 527 | } |
522 | 528 | ||
@@ -532,8 +538,10 @@ static int btusb_close(struct hci_dev *hdev) | |||
532 | if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) | 538 | if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) |
533 | return 0; | 539 | return 0; |
534 | 540 | ||
541 | cancel_work_sync(&data->work); | ||
542 | |||
535 | clear_bit(BTUSB_ISOC_RUNNING, &data->flags); | 543 | clear_bit(BTUSB_ISOC_RUNNING, &data->flags); |
536 | usb_kill_anchored_urbs(&data->intr_anchor); | 544 | usb_kill_anchored_urbs(&data->isoc_anchor); |
537 | 545 | ||
538 | clear_bit(BTUSB_BULK_RUNNING, &data->flags); | 546 | clear_bit(BTUSB_BULK_RUNNING, &data->flags); |
539 | usb_kill_anchored_urbs(&data->bulk_anchor); | 547 | usb_kill_anchored_urbs(&data->bulk_anchor); |
@@ -821,6 +829,7 @@ static int btusb_probe(struct usb_interface *intf, | |||
821 | } | 829 | } |
822 | 830 | ||
823 | data->udev = interface_to_usbdev(intf); | 831 | data->udev = interface_to_usbdev(intf); |
832 | data->intf = intf; | ||
824 | 833 | ||
825 | spin_lock_init(&data->lock); | 834 | spin_lock_init(&data->lock); |
826 | 835 | ||
@@ -889,7 +898,7 @@ static int btusb_probe(struct usb_interface *intf, | |||
889 | 898 | ||
890 | if (data->isoc) { | 899 | if (data->isoc) { |
891 | err = usb_driver_claim_interface(&btusb_driver, | 900 | err = usb_driver_claim_interface(&btusb_driver, |
892 | data->isoc, NULL); | 901 | data->isoc, data); |
893 | if (err < 0) { | 902 | if (err < 0) { |
894 | hci_free_dev(hdev); | 903 | hci_free_dev(hdev); |
895 | kfree(data); | 904 | kfree(data); |
@@ -921,13 +930,22 @@ static void btusb_disconnect(struct usb_interface *intf) | |||
921 | 930 | ||
922 | hdev = data->hdev; | 931 | hdev = data->hdev; |
923 | 932 | ||
924 | if (data->isoc) | 933 | __hci_dev_hold(hdev); |
925 | usb_driver_release_interface(&btusb_driver, data->isoc); | ||
926 | 934 | ||
927 | usb_set_intfdata(intf, NULL); | 935 | usb_set_intfdata(data->intf, NULL); |
936 | |||
937 | if (data->isoc) | ||
938 | usb_set_intfdata(data->isoc, NULL); | ||
928 | 939 | ||
929 | hci_unregister_dev(hdev); | 940 | hci_unregister_dev(hdev); |
930 | 941 | ||
942 | if (intf == data->isoc) | ||
943 | usb_driver_release_interface(&btusb_driver, data->intf); | ||
944 | else if (data->isoc) | ||
945 | usb_driver_release_interface(&btusb_driver, data->isoc); | ||
946 | |||
947 | __hci_dev_put(hdev); | ||
948 | |||
931 | hci_free_dev(hdev); | 949 | hci_free_dev(hdev); |
932 | } | 950 | } |
933 | 951 | ||