|
@@ -172,6 +172,7 @@ static struct usb_device_id blacklist_table[] = {
|
|
struct btusb_data {
|
|
struct btusb_data {
|
|
struct hci_dev *hdev;
|
|
struct hci_dev *hdev;
|
|
struct usb_device *udev;
|
|
struct usb_device *udev;
|
|
|
|
+ struct usb_interface *intf;
|
|
struct usb_interface *isoc;
|
|
struct usb_interface *isoc;
|
|
|
|
|
|
spinlock_t lock;
|
|
spinlock_t lock;
|
|
@@ -826,6 +827,7 @@ static int btusb_probe(struct usb_interface *intf,
|
|
}
|
|
}
|
|
|
|
|
|
data->udev = interface_to_usbdev(intf);
|
|
data->udev = interface_to_usbdev(intf);
|
|
|
|
+ data->intf = intf;
|
|
|
|
|
|
spin_lock_init(&data->lock);
|
|
spin_lock_init(&data->lock);
|
|
|
|
|
|
@@ -894,7 +896,7 @@ static int btusb_probe(struct usb_interface *intf,
|
|
|
|
|
|
if (data->isoc) {
|
|
if (data->isoc) {
|
|
err = usb_driver_claim_interface(&btusb_driver,
|
|
err = usb_driver_claim_interface(&btusb_driver,
|
|
- data->isoc, NULL);
|
|
|
|
|
|
+ data->isoc, data);
|
|
if (err < 0) {
|
|
if (err < 0) {
|
|
hci_free_dev(hdev);
|
|
hci_free_dev(hdev);
|
|
kfree(data);
|
|
kfree(data);
|
|
@@ -926,13 +928,22 @@ static void btusb_disconnect(struct usb_interface *intf)
|
|
|
|
|
|
hdev = data->hdev;
|
|
hdev = data->hdev;
|
|
|
|
|
|
- if (data->isoc)
|
|
|
|
- usb_driver_release_interface(&btusb_driver, data->isoc);
|
|
|
|
|
|
+ __hci_dev_hold(hdev);
|
|
|
|
|
|
- usb_set_intfdata(intf, NULL);
|
|
|
|
|
|
+ usb_set_intfdata(data->intf, NULL);
|
|
|
|
+
|
|
|
|
+ if (data->isoc)
|
|
|
|
+ usb_set_intfdata(data->isoc, NULL);
|
|
|
|
|
|
hci_unregister_dev(hdev);
|
|
hci_unregister_dev(hdev);
|
|
|
|
|
|
|
|
+ if (intf == data->isoc)
|
|
|
|
+ usb_driver_release_interface(&btusb_driver, data->intf);
|
|
|
|
+ else if (data->isoc)
|
|
|
|
+ usb_driver_release_interface(&btusb_driver, data->isoc);
|
|
|
|
+
|
|
|
|
+ __hci_dev_put(hdev);
|
|
|
|
+
|
|
hci_free_dev(hdev);
|
|
hci_free_dev(hdev);
|
|
}
|
|
}
|
|
|
|
|