aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth/hci_usb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/bluetooth/hci_usb.c')
-rw-r--r--drivers/bluetooth/hci_usb.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
index a7d9d7e99e72..6a0c2230f82f 100644
--- a/drivers/bluetooth/hci_usb.c
+++ b/drivers/bluetooth/hci_usb.c
@@ -122,6 +122,9 @@ static struct usb_device_id blacklist_ids[] = {
122 /* RTX Telecom based adapter with buggy SCO support */ 122 /* RTX Telecom based adapter with buggy SCO support */
123 { USB_DEVICE(0x0400, 0x0807), .driver_info = HCI_BROKEN_ISOC }, 123 { USB_DEVICE(0x0400, 0x0807), .driver_info = HCI_BROKEN_ISOC },
124 124
125 /* Belkin F8T012 */
126 { USB_DEVICE(0x050d, 0x0012), .driver_info = HCI_WRONG_SCO_MTU },
127
125 /* Digianswer devices */ 128 /* Digianswer devices */
126 { USB_DEVICE(0x08fd, 0x0001), .driver_info = HCI_DIGIANSWER }, 129 { USB_DEVICE(0x08fd, 0x0001), .driver_info = HCI_DIGIANSWER },
127 { USB_DEVICE(0x08fd, 0x0002), .driver_info = HCI_IGNORE }, 130 { USB_DEVICE(0x08fd, 0x0002), .driver_info = HCI_IGNORE },
@@ -129,6 +132,9 @@ static struct usb_device_id blacklist_ids[] = {
129 /* CSR BlueCore Bluetooth Sniffer */ 132 /* CSR BlueCore Bluetooth Sniffer */
130 { USB_DEVICE(0x0a12, 0x0002), .driver_info = HCI_SNIFFER }, 133 { USB_DEVICE(0x0a12, 0x0002), .driver_info = HCI_SNIFFER },
131 134
135 /* Frontline ComProbe Bluetooth Sniffer */
136 { USB_DEVICE(0x16d3, 0x0002), .driver_info = HCI_SNIFFER },
137
132 { } /* Terminating entry */ 138 { } /* Terminating entry */
133}; 139};
134 140
@@ -984,6 +990,9 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id
984 if (reset || id->driver_info & HCI_RESET) 990 if (reset || id->driver_info & HCI_RESET)
985 set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks); 991 set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks);
986 992
993 if (id->driver_info & HCI_WRONG_SCO_MTU)
994 set_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks);
995
987 if (id->driver_info & HCI_SNIFFER) { 996 if (id->driver_info & HCI_SNIFFER) {
988 if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997) 997 if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997)
989 set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); 998 set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
@@ -1042,10 +1051,81 @@ static void hci_usb_disconnect(struct usb_interface *intf)
1042 hci_free_dev(hdev); 1051 hci_free_dev(hdev);
1043} 1052}
1044 1053
1054static int hci_usb_suspend(struct usb_interface *intf, pm_message_t message)
1055{
1056 struct hci_usb *husb = usb_get_intfdata(intf);
1057 struct list_head killed;
1058 unsigned long flags;
1059 int i;
1060
1061 if (!husb || intf == husb->isoc_iface)
1062 return 0;
1063
1064 hci_suspend_dev(husb->hdev);
1065
1066 INIT_LIST_HEAD(&killed);
1067
1068 for (i = 0; i < 4; i++) {
1069 struct _urb_queue *q = &husb->pending_q[i];
1070 struct _urb *_urb, *_tmp;
1071
1072 while ((_urb = _urb_dequeue(q))) {
1073 /* reset queue since _urb_dequeue sets it to NULL */
1074 _urb->queue = q;
1075 usb_kill_urb(&_urb->urb);
1076 list_add(&_urb->list, &killed);
1077 }
1078
1079 spin_lock_irqsave(&q->lock, flags);
1080
1081 list_for_each_entry_safe(_urb, _tmp, &killed, list) {
1082 list_move_tail(&_urb->list, &q->head);
1083 }
1084
1085 spin_unlock_irqrestore(&q->lock, flags);
1086 }
1087
1088 return 0;
1089}
1090
1091static int hci_usb_resume(struct usb_interface *intf)
1092{
1093 struct hci_usb *husb = usb_get_intfdata(intf);
1094 unsigned long flags;
1095 int i, err = 0;
1096
1097 if (!husb || intf == husb->isoc_iface)
1098 return 0;
1099
1100 for (i = 0; i < 4; i++) {
1101 struct _urb_queue *q = &husb->pending_q[i];
1102 struct _urb *_urb;
1103
1104 spin_lock_irqsave(&q->lock, flags);
1105
1106 list_for_each_entry(_urb, &q->head, list) {
1107 err = usb_submit_urb(&_urb->urb, GFP_ATOMIC);
1108 if (err)
1109 break;
1110 }
1111
1112 spin_unlock_irqrestore(&q->lock, flags);
1113
1114 if (err)
1115 return -EIO;
1116 }
1117
1118 hci_resume_dev(husb->hdev);
1119
1120 return 0;
1121}
1122
1045static struct usb_driver hci_usb_driver = { 1123static struct usb_driver hci_usb_driver = {
1046 .name = "hci_usb", 1124 .name = "hci_usb",
1047 .probe = hci_usb_probe, 1125 .probe = hci_usb_probe,
1048 .disconnect = hci_usb_disconnect, 1126 .disconnect = hci_usb_disconnect,
1127 .suspend = hci_usb_suspend,
1128 .resume = hci_usb_resume,
1049 .id_table = bluetooth_ids, 1129 .id_table = bluetooth_ids,
1050}; 1130};
1051 1131