diff options
Diffstat (limited to 'drivers/bluetooth')
| -rw-r--r-- | drivers/bluetooth/bluecard_cs.c | 1 | ||||
| -rw-r--r-- | drivers/bluetooth/bt3c_cs.c | 1 | ||||
| -rw-r--r-- | drivers/bluetooth/btuart_cs.c | 1 | ||||
| -rw-r--r-- | drivers/bluetooth/dtl1_cs.c | 1 | ||||
| -rw-r--r-- | drivers/bluetooth/hci_usb.c | 80 | ||||
| -rw-r--r-- | drivers/bluetooth/hci_usb.h | 1 | ||||
| -rw-r--r-- | drivers/bluetooth/hci_vhci.c | 1 | 
7 files changed, 85 insertions, 1 deletions
| diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index 2830f58d6f77..8eebf9ca3786 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c @@ -739,6 +739,7 @@ static int bluecard_open(bluecard_info_t *info)  	hdev->type = HCI_PCCARD;  	hdev->driver_data = info; +	SET_HCIDEV_DEV(hdev, &info->p_dev->dev);  	hdev->open     = bluecard_hci_open;  	hdev->close    = bluecard_hci_close; diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index c9dba5565cac..df7bb016df49 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c @@ -582,6 +582,7 @@ static int bt3c_open(bt3c_info_t *info)  	hdev->type = HCI_PCCARD;  	hdev->driver_data = info; +	SET_HCIDEV_DEV(hdev, &info->p_dev->dev);  	hdev->open     = bt3c_hci_open;  	hdev->close    = bt3c_hci_close; diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c index c889bf8109a1..746ccca97f6f 100644 --- a/drivers/bluetooth/btuart_cs.c +++ b/drivers/bluetooth/btuart_cs.c @@ -502,6 +502,7 @@ static int btuart_open(btuart_info_t *info)  	hdev->type = HCI_PCCARD;  	hdev->driver_data = info; +	SET_HCIDEV_DEV(hdev, &info->p_dev->dev);  	hdev->open     = btuart_hci_open;  	hdev->close    = btuart_hci_close; diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c index be6eed175aa3..0e99def8a1e3 100644 --- a/drivers/bluetooth/dtl1_cs.c +++ b/drivers/bluetooth/dtl1_cs.c @@ -484,6 +484,7 @@ static int dtl1_open(dtl1_info_t *info)  	hdev->type = HCI_PCCARD;  	hdev->driver_data = info; +	SET_HCIDEV_DEV(hdev, &info->p_dev->dev);  	hdev->open     = dtl1_hci_open;  	hdev->close    = dtl1_hci_close; 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[] = {  	/* RTX Telecom based adapter with buggy SCO support */  	{ USB_DEVICE(0x0400, 0x0807), .driver_info = HCI_BROKEN_ISOC }, +	/* Belkin F8T012 */ +	{ USB_DEVICE(0x050d, 0x0012), .driver_info = HCI_WRONG_SCO_MTU }, +  	/* Digianswer devices */  	{ USB_DEVICE(0x08fd, 0x0001), .driver_info = HCI_DIGIANSWER },  	{ USB_DEVICE(0x08fd, 0x0002), .driver_info = HCI_IGNORE }, @@ -129,6 +132,9 @@ static struct usb_device_id blacklist_ids[] = {  	/* CSR BlueCore Bluetooth Sniffer */  	{ USB_DEVICE(0x0a12, 0x0002), .driver_info = HCI_SNIFFER }, +	/* Frontline ComProbe Bluetooth Sniffer */ +	{ USB_DEVICE(0x16d3, 0x0002), .driver_info = HCI_SNIFFER }, +  	{ }	/* Terminating entry */  }; @@ -984,6 +990,9 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id  	if (reset || id->driver_info & HCI_RESET)  		set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks); +	if (id->driver_info & HCI_WRONG_SCO_MTU) +		set_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks); +  	if (id->driver_info & HCI_SNIFFER) {  		if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997)  			set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); @@ -1042,10 +1051,81 @@ static void hci_usb_disconnect(struct usb_interface *intf)  	hci_free_dev(hdev);  } +static int hci_usb_suspend(struct usb_interface *intf, pm_message_t message) +{ +	struct hci_usb *husb = usb_get_intfdata(intf); +	struct list_head killed; +	unsigned long flags; +	int i; + +	if (!husb || intf == husb->isoc_iface) +		return 0; + +	hci_suspend_dev(husb->hdev); + +	INIT_LIST_HEAD(&killed); + +	for (i = 0; i < 4; i++) { +		struct _urb_queue *q = &husb->pending_q[i]; +		struct _urb *_urb, *_tmp; + +		while ((_urb = _urb_dequeue(q))) { +			/* reset queue since _urb_dequeue sets it to NULL */ +			_urb->queue = q; +			usb_kill_urb(&_urb->urb); +			list_add(&_urb->list, &killed); +		} + +		spin_lock_irqsave(&q->lock, flags); + +		list_for_each_entry_safe(_urb, _tmp, &killed, list) { +			list_move_tail(&_urb->list, &q->head); +		} + +		spin_unlock_irqrestore(&q->lock, flags); +	} + +	return 0; +} + +static int hci_usb_resume(struct usb_interface *intf) +{ +	struct hci_usb *husb = usb_get_intfdata(intf); +	unsigned long flags; +	int i, err = 0; + +	if (!husb || intf == husb->isoc_iface) +		return 0; +	 +	for (i = 0; i < 4; i++) { +		struct _urb_queue *q = &husb->pending_q[i]; +		struct _urb *_urb; + +		spin_lock_irqsave(&q->lock, flags); + +		list_for_each_entry(_urb, &q->head, list) { +			err = usb_submit_urb(&_urb->urb, GFP_ATOMIC); +			if (err) +				break; +		} + +		spin_unlock_irqrestore(&q->lock, flags); + +		if (err) +			return -EIO; +	} + +	hci_resume_dev(husb->hdev); + +	return 0; +} +  static struct usb_driver hci_usb_driver = {  	.name		= "hci_usb",  	.probe		= hci_usb_probe,  	.disconnect	= hci_usb_disconnect, +	.suspend	= hci_usb_suspend, +	.resume		= hci_usb_resume,  	.id_table	= bluetooth_ids,  }; diff --git a/drivers/bluetooth/hci_usb.h b/drivers/bluetooth/hci_usb.h index 37100a6ea1a8..963fc55cdc85 100644 --- a/drivers/bluetooth/hci_usb.h +++ b/drivers/bluetooth/hci_usb.h @@ -35,6 +35,7 @@  #define HCI_SNIFFER		0x10  #define HCI_BCM92035		0x20  #define HCI_BROKEN_ISOC		0x40 +#define HCI_WRONG_SCO_MTU	0x80  #define HCI_MAX_IFACE_NUM	3 diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c index ea589007fa26..aac67a3a6019 100644 --- a/drivers/bluetooth/hci_vhci.c +++ b/drivers/bluetooth/hci_vhci.c @@ -277,7 +277,6 @@ static int vhci_open(struct inode *inode, struct file *file)  	hdev->type = HCI_VHCI;  	hdev->driver_data = vhci; -	SET_HCIDEV_DEV(hdev, vhci_miscdev.dev);  	hdev->open     = vhci_open_dev;  	hdev->close    = vhci_close_dev; | 
