diff options
author | David S. Miller <davem@davemloft.net> | 2015-01-18 08:25:30 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-01-18 08:25:30 +0300 |
commit | e445dd5f6745922bf4d8c18e1f071b28c5a061bb (patch) | |
tree | dfb23a2d6375807fb05d07951f35a4dd29e4631b /drivers | |
parent | 3aeb66176ffa8fefd7a9f7d37bda1d8adcf469a1 (diff) | |
parent | 0026b6551b51a9520b912f41b8d447b89a825f5a (diff) | |
download | linux-e445dd5f6745922bf4d8c18e1f071b28c5a061bb.tar.xz |
Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
Johan Hedberg says:
====================
pull request: bluetooth-next 2015-01-16
Here are some more bluetooth & ieee802154 patches intended for 3.20:
- Refactoring & cleanups of ieee802154 & 6lowpan code
- Various fixes to the btmrvl driver
- Fixes for Bluetooth Low Energy Privacy feature handling
- Added build-time sanity checks for sockaddr sizes
- Fixes for Security Manager registration on LE-only controllers
- Refactoring of broken inquiry mode handling to a generic quirk
Please let me know if there are any issues pulling. Thanks.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/bluetooth/btmrvl_drv.h | 5 | ||||
-rw-r--r-- | drivers/bluetooth/btmrvl_main.c | 32 | ||||
-rw-r--r-- | drivers/bluetooth/btmrvl_sdio.c | 6 | ||||
-rw-r--r-- | drivers/bluetooth/btusb.c | 15 |
4 files changed, 44 insertions, 14 deletions
diff --git a/drivers/bluetooth/btmrvl_drv.h b/drivers/bluetooth/btmrvl_drv.h index 330f8f84928d..e75f8ee2512c 100644 --- a/drivers/bluetooth/btmrvl_drv.h +++ b/drivers/bluetooth/btmrvl_drv.h @@ -28,9 +28,9 @@ #define BTM_UPLD_SIZE 2312 /* Time to wait until Host Sleep state change in millisecond */ -#define WAIT_UNTIL_HS_STATE_CHANGED 5000 +#define WAIT_UNTIL_HS_STATE_CHANGED msecs_to_jiffies(5000) /* Time to wait for command response in millisecond */ -#define WAIT_UNTIL_CMD_RESP 5000 +#define WAIT_UNTIL_CMD_RESP msecs_to_jiffies(5000) enum rdwr_status { RDWR_STATUS_SUCCESS = 0, @@ -104,6 +104,7 @@ struct btmrvl_private { #ifdef CONFIG_DEBUG_FS void *debugfs_data; #endif + bool surprise_removed; }; #define MRVL_VENDOR_PKT 0xFE diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c index 30939c993d94..413597789c61 100644 --- a/drivers/bluetooth/btmrvl_main.c +++ b/drivers/bluetooth/btmrvl_main.c @@ -178,6 +178,11 @@ static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 opcode, struct sk_buff *skb; struct hci_command_hdr *hdr; + if (priv->surprise_removed) { + BT_ERR("Card is removed"); + return -EFAULT; + } + skb = bt_skb_alloc(HCI_COMMAND_HDR_SIZE + len, GFP_ATOMIC); if (skb == NULL) { BT_ERR("No free skb"); @@ -202,10 +207,14 @@ static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 opcode, wake_up_interruptible(&priv->main_thread.wait_q); if (!wait_event_interruptible_timeout(priv->adapter->cmd_wait_q, - priv->adapter->cmd_complete, - msecs_to_jiffies(WAIT_UNTIL_CMD_RESP))) + priv->adapter->cmd_complete || + priv->surprise_removed, + WAIT_UNTIL_CMD_RESP)) return -ETIMEDOUT; + if (priv->surprise_removed) + return -EFAULT; + return 0; } @@ -287,9 +296,10 @@ int btmrvl_enable_hs(struct btmrvl_private *priv) } ret = wait_event_interruptible_timeout(adapter->event_hs_wait_q, - adapter->hs_state, - msecs_to_jiffies(WAIT_UNTIL_HS_STATE_CHANGED)); - if (ret < 0) { + adapter->hs_state || + priv->surprise_removed, + WAIT_UNTIL_HS_STATE_CHANGED); + if (ret < 0 || priv->surprise_removed) { BT_ERR("event_hs_wait_q terminated (%d): %d,%d,%d", ret, adapter->hs_state, adapter->ps_state, adapter->wakeup_tries); @@ -538,8 +548,11 @@ static int btmrvl_check_device_tree(struct btmrvl_private *priv) static int btmrvl_setup(struct hci_dev *hdev) { struct btmrvl_private *priv = hci_get_drvdata(hdev); + int ret; - btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ); + ret = btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ); + if (ret) + return ret; priv->btmrvl_dev.gpio_gap = 0xffff; @@ -597,7 +610,7 @@ static int btmrvl_service_main_thread(void *data) add_wait_queue(&thread->wait_q, &wait); set_current_state(TASK_INTERRUPTIBLE); - if (kthread_should_stop()) { + if (kthread_should_stop() || priv->surprise_removed) { BT_DBG("main_thread: break from main thread"); break; } @@ -616,6 +629,11 @@ static int btmrvl_service_main_thread(void *data) BT_DBG("main_thread woke up"); + if (kthread_should_stop() || priv->surprise_removed) { + BT_DBG("main_thread: break from main thread"); + break; + } + spin_lock_irqsave(&priv->driver_lock, flags); if (adapter->int_count) { adapter->int_count = 0; diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index 0057c0b7a776..01d6da577eeb 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c @@ -573,7 +573,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) offset += txlen; } while (true); - BT_DBG("FW download over, size %d bytes", offset); + BT_INFO("FW download over, size %d bytes", offset); ret = 0; @@ -798,6 +798,9 @@ static void btmrvl_sdio_interrupt(struct sdio_func *func) priv = card->priv; + if (priv->surprise_removed) + return; + if (card->reg->int_read_to_clear) ret = btmrvl_sdio_read_to_clear(card, &ireg); else @@ -1466,6 +1469,7 @@ static void btmrvl_sdio_remove(struct sdio_func *func) btmrvl_sdio_disable_host_int(card); } BT_DBG("unregester dev"); + card->priv->surprise_removed = true; btmrvl_sdio_unregister_dev(card); btmrvl_remove_card(card->priv); } diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index f051a93c6cad..4a6495ab9726 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -49,7 +49,7 @@ static struct usb_driver btusb_driver; #define BTUSB_INTEL_BOOT 0x200 #define BTUSB_BCM_PATCHRAM 0x400 #define BTUSB_MARVELL 0x800 -#define BTUSB_AVM 0x1000 +#define BTUSB_SWAVE 0x1000 static const struct usb_device_id btusb_table[] = { /* Generic Bluetooth USB device */ @@ -86,7 +86,7 @@ static const struct usb_device_id btusb_table[] = { { USB_DEVICE(0x05ac, 0x8281) }, /* AVM BlueFRITZ! USB v2.0 */ - { USB_DEVICE(0x057c, 0x3800), .driver_info = BTUSB_AVM }, + { USB_DEVICE(0x057c, 0x3800), .driver_info = BTUSB_SWAVE }, /* Bluetooth Ultraport Module from IBM */ { USB_DEVICE(0x04bf, 0x030a) }, @@ -238,6 +238,9 @@ static const struct usb_device_id blacklist_table[] = { /* CONWISE Technology based adapters with buggy SCO support */ { USB_DEVICE(0x0e5e, 0x6622), .driver_info = BTUSB_BROKEN_ISOC }, + /* Roper Class 1 Bluetooth Dongle (Silicon Wave based) */ + { USB_DEVICE(0x1300, 0x0001), .driver_info = BTUSB_SWAVE }, + /* Digianswer devices */ { USB_DEVICE(0x08fd, 0x0001), .driver_info = BTUSB_DIGIANSWER }, { USB_DEVICE(0x08fd, 0x0002), .driver_info = BTUSB_IGNORE }, @@ -306,6 +309,7 @@ struct btusb_data { int isoc_altsetting; int suspend_count; + int (*recv_event)(struct hci_dev *hdev, struct sk_buff *skb); int (*recv_bulk)(struct btusb_data *data, void *buffer, int count); }; @@ -371,7 +375,7 @@ static int btusb_recv_intr(struct btusb_data *data, void *buffer, int count) if (bt_cb(skb)->expect == 0) { /* Complete frame */ - hci_recv_frame(data->hdev, skb); + data->recv_event(data->hdev, skb); skb = NULL; } } @@ -2045,6 +2049,7 @@ static int btusb_probe(struct usb_interface *intf, init_usb_anchor(&data->isoc_anchor); spin_lock_init(&data->rxlock); + data->recv_event = hci_recv_frame; data->recv_bulk = btusb_recv_bulk; hdev = hci_alloc_dev(); @@ -2081,8 +2086,10 @@ static int btusb_probe(struct usb_interface *intf, if (id->driver_info & BTUSB_MARVELL) hdev->set_bdaddr = btusb_set_bdaddr_marvell; - if (id->driver_info & BTUSB_AVM) + if (id->driver_info & BTUSB_SWAVE) { + set_bit(HCI_QUIRK_FIXUP_INQUIRY_MODE, &hdev->quirks); set_bit(HCI_QUIRK_BROKEN_LOCAL_COMMANDS, &hdev->quirks); + } if (id->driver_info & BTUSB_INTEL_BOOT) set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); |