aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth/btusb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/bluetooth/btusb.c')
-rw-r--r--drivers/bluetooth/btusb.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 6a010681ecf3..29ae99817c60 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -104,6 +104,9 @@ static struct usb_device_id blacklist_table[] = {
104 /* Broadcom BCM2046 */ 104 /* Broadcom BCM2046 */
105 { USB_DEVICE(0x0a5c, 0x2151), .driver_info = BTUSB_RESET }, 105 { USB_DEVICE(0x0a5c, 0x2151), .driver_info = BTUSB_RESET },
106 106
107 /* Apple MacBook Pro with Broadcom chip */
108 { USB_DEVICE(0x05ac, 0x820f), .driver_info = BTUSB_RESET },
109
107 /* IBM/Lenovo ThinkPad with Broadcom chip */ 110 /* IBM/Lenovo ThinkPad with Broadcom chip */
108 { USB_DEVICE(0x0a5c, 0x201e), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, 111 { 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 }, 112 { USB_DEVICE(0x0a5c, 0x2110), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
@@ -169,6 +172,7 @@ static struct usb_device_id blacklist_table[] = {
169struct btusb_data { 172struct btusb_data {
170 struct hci_dev *hdev; 173 struct hci_dev *hdev;
171 struct usb_device *udev; 174 struct usb_device *udev;
175 struct usb_interface *intf;
172 struct usb_interface *isoc; 176 struct usb_interface *isoc;
173 177
174 spinlock_t lock; 178 spinlock_t lock;
@@ -516,7 +520,7 @@ static int btusb_open(struct hci_dev *hdev)
516 520
517 err = btusb_submit_intr_urb(hdev); 521 err = btusb_submit_intr_urb(hdev);
518 if (err < 0) { 522 if (err < 0) {
519 clear_bit(BTUSB_INTR_RUNNING, &hdev->flags); 523 clear_bit(BTUSB_INTR_RUNNING, &data->flags);
520 clear_bit(HCI_RUNNING, &hdev->flags); 524 clear_bit(HCI_RUNNING, &hdev->flags);
521 } 525 }
522 526
@@ -532,8 +536,10 @@ static int btusb_close(struct hci_dev *hdev)
532 if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) 536 if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
533 return 0; 537 return 0;
534 538
539 cancel_work_sync(&data->work);
540
535 clear_bit(BTUSB_ISOC_RUNNING, &data->flags); 541 clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
536 usb_kill_anchored_urbs(&data->intr_anchor); 542 usb_kill_anchored_urbs(&data->isoc_anchor);
537 543
538 clear_bit(BTUSB_BULK_RUNNING, &data->flags); 544 clear_bit(BTUSB_BULK_RUNNING, &data->flags);
539 usb_kill_anchored_urbs(&data->bulk_anchor); 545 usb_kill_anchored_urbs(&data->bulk_anchor);
@@ -821,6 +827,7 @@ static int btusb_probe(struct usb_interface *intf,
821 } 827 }
822 828
823 data->udev = interface_to_usbdev(intf); 829 data->udev = interface_to_usbdev(intf);
830 data->intf = intf;
824 831
825 spin_lock_init(&data->lock); 832 spin_lock_init(&data->lock);
826 833
@@ -889,7 +896,7 @@ static int btusb_probe(struct usb_interface *intf,
889 896
890 if (data->isoc) { 897 if (data->isoc) {
891 err = usb_driver_claim_interface(&btusb_driver, 898 err = usb_driver_claim_interface(&btusb_driver,
892 data->isoc, NULL); 899 data->isoc, data);
893 if (err < 0) { 900 if (err < 0) {
894 hci_free_dev(hdev); 901 hci_free_dev(hdev);
895 kfree(data); 902 kfree(data);
@@ -921,13 +928,22 @@ static void btusb_disconnect(struct usb_interface *intf)
921 928
922 hdev = data->hdev; 929 hdev = data->hdev;
923 930
924 if (data->isoc) 931 __hci_dev_hold(hdev);
925 usb_driver_release_interface(&btusb_driver, data->isoc);
926 932
927 usb_set_intfdata(intf, NULL); 933 usb_set_intfdata(data->intf, NULL);
934
935 if (data->isoc)
936 usb_set_intfdata(data->isoc, NULL);
928 937
929 hci_unregister_dev(hdev); 938 hci_unregister_dev(hdev);
930 939
940 if (intf == data->isoc)
941 usb_driver_release_interface(&btusb_driver, data->intf);
942 else if (data->isoc)
943 usb_driver_release_interface(&btusb_driver, data->isoc);
944
945 __hci_dev_put(hdev);
946
931 hci_free_dev(hdev); 947 hci_free_dev(hdev);
932} 948}
933 949