Merge branch 'x86-fpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[firefly-linux-kernel-4.4.55.git] / drivers / bluetooth / btusb.c
index 6250fc2fb93a7257697fa2efe34acfae204dfe7f..edfc17bfcd44e02a8c8fb8748687cf265770863d 100644 (file)
@@ -30,9 +30,6 @@
 
 #define VERSION "0.6"
 
-static bool ignore_dga;
-static bool ignore_csr;
-static bool ignore_sniffer;
 static bool disable_scofix;
 static bool force_scofix;
 
@@ -49,7 +46,9 @@ static struct usb_driver btusb_driver;
 #define BTUSB_WRONG_SCO_MTU    0x40
 #define BTUSB_ATH3012          0x80
 #define BTUSB_INTEL            0x100
-#define BTUSB_BCM_PATCHRAM     0x200
+#define BTUSB_INTEL_BOOT       0x200
+#define BTUSB_BCM_PATCHRAM     0x400
+#define BTUSB_MARVELL          0x800
 
 static const struct usb_device_id btusb_table[] = {
        /* Generic Bluetooth USB device */
@@ -115,12 +114,19 @@ static const struct usb_device_id btusb_table[] = {
        { USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01),
          .driver_info = BTUSB_BCM_PATCHRAM },
 
+       /* ASUSTek Computer - Broadcom based */
+       { USB_VENDOR_AND_INTERFACE_INFO(0x0b05, 0xff, 0x01, 0x01) },
+
        /* Belkin F8065bf - Broadcom based */
        { USB_VENDOR_AND_INTERFACE_INFO(0x050d, 0xff, 0x01, 0x01) },
 
        /* IMC Networks - Broadcom based */
        { USB_VENDOR_AND_INTERFACE_INFO(0x13d3, 0xff, 0x01, 0x01) },
 
+       /* Intel Bluetooth USB Bootloader (RAM module) */
+       { USB_DEVICE(0x8087, 0x0a5a),
+         .driver_info = BTUSB_INTEL_BOOT | BTUSB_BROKEN_ISOC },
+
        { }     /* Terminating entry */
 };
 
@@ -159,6 +165,7 @@ static const struct usb_device_id blacklist_table[] = {
        { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0930, 0x0227), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
@@ -175,6 +182,7 @@ static const struct usb_device_id blacklist_table[] = {
        { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 },
 
        /* Atheros AR5BBU12 with sflash firmware */
        { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
@@ -228,15 +236,21 @@ static const struct usb_device_id blacklist_table[] = {
        { USB_DEVICE(0x08fd, 0x0002), .driver_info = BTUSB_IGNORE },
 
        /* CSR BlueCore Bluetooth Sniffer */
-       { USB_DEVICE(0x0a12, 0x0002), .driver_info = BTUSB_SNIFFER },
+       { USB_DEVICE(0x0a12, 0x0002),
+         .driver_info = BTUSB_SNIFFER | BTUSB_BROKEN_ISOC },
 
        /* Frontline ComProbe Bluetooth Sniffer */
-       { USB_DEVICE(0x16d3, 0x0002), .driver_info = BTUSB_SNIFFER },
+       { USB_DEVICE(0x16d3, 0x0002),
+         .driver_info = BTUSB_SNIFFER | BTUSB_BROKEN_ISOC },
 
        /* Intel Bluetooth device */
        { USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL },
        { USB_DEVICE(0x8087, 0x0a2a), .driver_info = BTUSB_INTEL },
 
+       /* Marvell device */
+       { USB_DEVICE(0x1286, 0x2044), .driver_info = BTUSB_MARVELL },
+       { USB_DEVICE(0x1286, 0x2046), .driver_info = BTUSB_MARVELL },
+
        { }     /* Terminating entry */
 };
 
@@ -254,20 +268,24 @@ struct btusb_data {
        struct usb_interface *intf;
        struct usb_interface *isoc;
 
-       spinlock_t lock;
-
        unsigned long flags;
 
        struct work_struct work;
        struct work_struct waker;
 
+       struct usb_anchor deferred;
        struct usb_anchor tx_anchor;
+       int tx_in_flight;
+       spinlock_t txlock;
+
        struct usb_anchor intr_anchor;
        struct usb_anchor bulk_anchor;
        struct usb_anchor isoc_anchor;
-       struct usb_anchor deferred;
-       int tx_in_flight;
-       spinlock_t txlock;
+       spinlock_t rxlock;
+
+       struct sk_buff *evt_skb;
+       struct sk_buff *acl_skb;
+       struct sk_buff *sco_skb;
 
        struct usb_endpoint_descriptor *intr_ep;
        struct usb_endpoint_descriptor *bulk_tx_ep;
@@ -282,18 +300,189 @@ struct btusb_data {
        int suspend_count;
 };
 
-static int inc_tx(struct btusb_data *data)
+static inline void btusb_free_frags(struct btusb_data *data)
 {
        unsigned long flags;
-       int rv;
 
-       spin_lock_irqsave(&data->txlock, flags);
-       rv = test_bit(BTUSB_SUSPENDING, &data->flags);
-       if (!rv)
-               data->tx_in_flight++;
-       spin_unlock_irqrestore(&data->txlock, flags);
+       spin_lock_irqsave(&data->rxlock, flags);
+
+       kfree_skb(data->evt_skb);
+       data->evt_skb = NULL;
+
+       kfree_skb(data->acl_skb);
+       data->acl_skb = NULL;
+
+       kfree_skb(data->sco_skb);
+       data->sco_skb = NULL;
+
+       spin_unlock_irqrestore(&data->rxlock, flags);
+}
+
+static int btusb_recv_intr(struct btusb_data *data, void *buffer, int count)
+{
+       struct sk_buff *skb;
+       int err = 0;
+
+       spin_lock(&data->rxlock);
+       skb = data->evt_skb;
+
+       while (count) {
+               int len;
+
+               if (!skb) {
+                       skb = bt_skb_alloc(HCI_MAX_EVENT_SIZE, GFP_ATOMIC);
+                       if (!skb) {
+                               err = -ENOMEM;
+                               break;
+                       }
+
+                       bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
+                       bt_cb(skb)->expect = HCI_EVENT_HDR_SIZE;
+               }
+
+               len = min_t(uint, bt_cb(skb)->expect, count);
+               memcpy(skb_put(skb, len), buffer, len);
+
+               count -= len;
+               buffer += len;
+               bt_cb(skb)->expect -= len;
+
+               if (skb->len == HCI_EVENT_HDR_SIZE) {
+                       /* Complete event header */
+                       bt_cb(skb)->expect = hci_event_hdr(skb)->plen;
+
+                       if (skb_tailroom(skb) < bt_cb(skb)->expect) {
+                               kfree_skb(skb);
+                               skb = NULL;
+
+                               err = -EILSEQ;
+                               break;
+                       }
+               }
+
+               if (bt_cb(skb)->expect == 0) {
+                       /* Complete frame */
+                       hci_recv_frame(data->hdev, skb);
+                       skb = NULL;
+               }
+       }
+
+       data->evt_skb = skb;
+       spin_unlock(&data->rxlock);
+
+       return err;
+}
+
+static int btusb_recv_bulk(struct btusb_data *data, void *buffer, int count)
+{
+       struct sk_buff *skb;
+       int err = 0;
+
+       spin_lock(&data->rxlock);
+       skb = data->acl_skb;
+
+       while (count) {
+               int len;
+
+               if (!skb) {
+                       skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
+                       if (!skb) {
+                               err = -ENOMEM;
+                               break;
+                       }
+
+                       bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
+                       bt_cb(skb)->expect = HCI_ACL_HDR_SIZE;
+               }
+
+               len = min_t(uint, bt_cb(skb)->expect, count);
+               memcpy(skb_put(skb, len), buffer, len);
+
+               count -= len;
+               buffer += len;
+               bt_cb(skb)->expect -= len;
+
+               if (skb->len == HCI_ACL_HDR_SIZE) {
+                       __le16 dlen = hci_acl_hdr(skb)->dlen;
+
+                       /* Complete ACL header */
+                       bt_cb(skb)->expect = __le16_to_cpu(dlen);
+
+                       if (skb_tailroom(skb) < bt_cb(skb)->expect) {
+                               kfree_skb(skb);
+                               skb = NULL;
+
+                               err = -EILSEQ;
+                               break;
+                       }
+               }
+
+               if (bt_cb(skb)->expect == 0) {
+                       /* Complete frame */
+                       hci_recv_frame(data->hdev, skb);
+                       skb = NULL;
+               }
+       }
+
+       data->acl_skb = skb;
+       spin_unlock(&data->rxlock);
+
+       return err;
+}
+
+static int btusb_recv_isoc(struct btusb_data *data, void *buffer, int count)
+{
+       struct sk_buff *skb;
+       int err = 0;
 
-       return rv;
+       spin_lock(&data->rxlock);
+       skb = data->sco_skb;
+
+       while (count) {
+               int len;
+
+               if (!skb) {
+                       skb = bt_skb_alloc(HCI_MAX_SCO_SIZE, GFP_ATOMIC);
+                       if (!skb) {
+                               err = -ENOMEM;
+                               break;
+                       }
+
+                       bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
+                       bt_cb(skb)->expect = HCI_SCO_HDR_SIZE;
+               }
+
+               len = min_t(uint, bt_cb(skb)->expect, count);
+               memcpy(skb_put(skb, len), buffer, len);
+
+               count -= len;
+               buffer += len;
+               bt_cb(skb)->expect -= len;
+
+               if (skb->len == HCI_SCO_HDR_SIZE) {
+                       /* Complete SCO header */
+                       bt_cb(skb)->expect = hci_sco_hdr(skb)->dlen;
+
+                       if (skb_tailroom(skb) < bt_cb(skb)->expect) {
+                               kfree_skb(skb);
+                               skb = NULL;
+
+                               err = -EILSEQ;
+                               break;
+                       }
+               }
+
+               if (bt_cb(skb)->expect == 0) {
+                       /* Complete frame */
+                       hci_recv_frame(data->hdev, skb);
+                       skb = NULL;
+               }
+       }
+
+       data->sco_skb = skb;
+       spin_unlock(&data->rxlock);
+
+       return err;
 }
 
 static void btusb_intr_complete(struct urb *urb)
@@ -302,8 +491,8 @@ static void btusb_intr_complete(struct urb *urb)
        struct btusb_data *data = hci_get_drvdata(hdev);
        int err;
 
-       BT_DBG("%s urb %p status %d count %d", hdev->name,
-                                       urb, urb->status, urb->actual_length);
+       BT_DBG("%s urb %p status %d count %d", hdev->name, urb, urb->status,
+              urb->actual_length);
 
        if (!test_bit(HCI_RUNNING, &hdev->flags))
                return;
@@ -311,12 +500,14 @@ static void btusb_intr_complete(struct urb *urb)
        if (urb->status == 0) {
                hdev->stat.byte_rx += urb->actual_length;
 
-               if (hci_recv_fragment(hdev, HCI_EVENT_PKT,
-                                               urb->transfer_buffer,
-                                               urb->actual_length) < 0) {
+               if (btusb_recv_intr(data, urb->transfer_buffer,
+                                   urb->actual_length) < 0) {
                        BT_ERR("%s corrupted event packet", hdev->name);
                        hdev->stat.err_rx++;
                }
+       } else if (urb->status == -ENOENT) {
+               /* Avoid suspend failed when usb_kill_urb */
+               return;
        }
 
        if (!test_bit(BTUSB_INTR_RUNNING, &data->flags))
@@ -331,7 +522,7 @@ static void btusb_intr_complete(struct urb *urb)
                 * -ENODEV: device got disconnected */
                if (err != -EPERM && err != -ENODEV)
                        BT_ERR("%s urb %p failed to resubmit (%d)",
-                                               hdev->name, urb, -err);
+                              hdev->name, urb, -err);
                usb_unanchor_urb(urb);
        }
 }
@@ -364,8 +555,7 @@ static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags)
        pipe = usb_rcvintpipe(data->udev, data->intr_ep->bEndpointAddress);
 
        usb_fill_int_urb(urb, data->udev, pipe, buf, size,
-                                               btusb_intr_complete, hdev,
-                                               data->intr_ep->bInterval);
+                        btusb_intr_complete, hdev, data->intr_ep->bInterval);
 
        urb->transfer_flags |= URB_FREE_BUFFER;
 
@@ -375,7 +565,7 @@ static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags)
        if (err < 0) {
                if (err != -EPERM && err != -ENODEV)
                        BT_ERR("%s urb %p submission failed (%d)",
-                                               hdev->name, urb, -err);
+                              hdev->name, urb, -err);
                usb_unanchor_urb(urb);
        }
 
@@ -390,8 +580,8 @@ static void btusb_bulk_complete(struct urb *urb)
        struct btusb_data *data = hci_get_drvdata(hdev);
        int err;
 
-       BT_DBG("%s urb %p status %d count %d", hdev->name,
-                                       urb, urb->status, urb->actual_length);
+       BT_DBG("%s urb %p status %d count %d", hdev->name, urb, urb->status,
+              urb->actual_length);
 
        if (!test_bit(HCI_RUNNING, &hdev->flags))
                return;
@@ -399,12 +589,14 @@ static void btusb_bulk_complete(struct urb *urb)
        if (urb->status == 0) {
                hdev->stat.byte_rx += urb->actual_length;
 
-               if (hci_recv_fragment(hdev, HCI_ACLDATA_PKT,
-                                               urb->transfer_buffer,
-                                               urb->actual_length) < 0) {
+               if (btusb_recv_bulk(data, urb->transfer_buffer,
+                                   urb->actual_length) < 0) {
                        BT_ERR("%s corrupted ACL packet", hdev->name);
                        hdev->stat.err_rx++;
                }
+       } else if (urb->status == -ENOENT) {
+               /* Avoid suspend failed when usb_kill_urb */
+               return;
        }
 
        if (!test_bit(BTUSB_BULK_RUNNING, &data->flags))
@@ -419,7 +611,7 @@ static void btusb_bulk_complete(struct urb *urb)
                 * -ENODEV: device got disconnected */
                if (err != -EPERM && err != -ENODEV)
                        BT_ERR("%s urb %p failed to resubmit (%d)",
-                                               hdev->name, urb, -err);
+                              hdev->name, urb, -err);
                usb_unanchor_urb(urb);
        }
 }
@@ -449,8 +641,8 @@ static int btusb_submit_bulk_urb(struct hci_dev *hdev, gfp_t mem_flags)
 
        pipe = usb_rcvbulkpipe(data->udev, data->bulk_rx_ep->bEndpointAddress);
 
-       usb_fill_bulk_urb(urb, data->udev, pipe,
-                                       buf, size, btusb_bulk_complete, hdev);
+       usb_fill_bulk_urb(urb, data->udev, pipe, buf, size,
+                         btusb_bulk_complete, hdev);
 
        urb->transfer_flags |= URB_FREE_BUFFER;
 
@@ -461,7 +653,7 @@ static int btusb_submit_bulk_urb(struct hci_dev *hdev, gfp_t mem_flags)
        if (err < 0) {
                if (err != -EPERM && err != -ENODEV)
                        BT_ERR("%s urb %p submission failed (%d)",
-                                               hdev->name, urb, -err);
+                              hdev->name, urb, -err);
                usb_unanchor_urb(urb);
        }
 
@@ -476,8 +668,8 @@ static void btusb_isoc_complete(struct urb *urb)
        struct btusb_data *data = hci_get_drvdata(hdev);
        int i, err;
 
-       BT_DBG("%s urb %p status %d count %d", hdev->name,
-                                       urb, urb->status, urb->actual_length);
+       BT_DBG("%s urb %p status %d count %d", hdev->name, urb, urb->status,
+              urb->actual_length);
 
        if (!test_bit(HCI_RUNNING, &hdev->flags))
                return;
@@ -492,13 +684,15 @@ static void btusb_isoc_complete(struct urb *urb)
 
                        hdev->stat.byte_rx += length;
 
-                       if (hci_recv_fragment(hdev, HCI_SCODATA_PKT,
-                                               urb->transfer_buffer + offset,
-                                                               length) < 0) {
+                       if (btusb_recv_isoc(data, urb->transfer_buffer + offset,
+                                           length) < 0) {
                                BT_ERR("%s corrupted SCO packet", hdev->name);
                                hdev->stat.err_rx++;
                        }
                }
+       } else if (urb->status == -ENOENT) {
+               /* Avoid suspend failed when usb_kill_urb */
+               return;
        }
 
        if (!test_bit(BTUSB_ISOC_RUNNING, &data->flags))
@@ -512,7 +706,7 @@ static void btusb_isoc_complete(struct urb *urb)
                 * -ENODEV: device got disconnected */
                if (err != -EPERM && err != -ENODEV)
                        BT_ERR("%s urb %p failed to resubmit (%d)",
-                                               hdev->name, urb, -err);
+                              hdev->name, urb, -err);
                usb_unanchor_urb(urb);
        }
 }
@@ -567,12 +761,12 @@ static int btusb_submit_isoc_urb(struct hci_dev *hdev, gfp_t mem_flags)
        pipe = usb_rcvisocpipe(data->udev, data->isoc_rx_ep->bEndpointAddress);
 
        usb_fill_int_urb(urb, data->udev, pipe, buf, size, btusb_isoc_complete,
-                               hdev, data->isoc_rx_ep->bInterval);
+                        hdev, data->isoc_rx_ep->bInterval);
 
-       urb->transfer_flags  = URB_FREE_BUFFER | URB_ISO_ASAP;
+       urb->transfer_flags = URB_FREE_BUFFER | URB_ISO_ASAP;
 
        __fill_isoc_descriptor(urb, size,
-                       le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize));
+                              le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize));
 
        usb_anchor_urb(urb, &data->isoc_anchor);
 
@@ -580,7 +774,7 @@ static int btusb_submit_isoc_urb(struct hci_dev *hdev, gfp_t mem_flags)
        if (err < 0) {
                if (err != -EPERM && err != -ENODEV)
                        BT_ERR("%s urb %p submission failed (%d)",
-                                               hdev->name, urb, -err);
+                              hdev->name, urb, -err);
                usb_unanchor_urb(urb);
        }
 
@@ -592,11 +786,11 @@ static int btusb_submit_isoc_urb(struct hci_dev *hdev, gfp_t mem_flags)
 static void btusb_tx_complete(struct urb *urb)
 {
        struct sk_buff *skb = urb->context;
-       struct hci_dev *hdev = (struct hci_dev *) skb->dev;
+       struct hci_dev *hdev = (struct hci_dev *)skb->dev;
        struct btusb_data *data = hci_get_drvdata(hdev);
 
-       BT_DBG("%s urb %p status %d count %d", hdev->name,
-                                       urb, urb->status, urb->actual_length);
+       BT_DBG("%s urb %p status %d count %d", hdev->name, urb, urb->status,
+              urb->actual_length);
 
        if (!test_bit(HCI_RUNNING, &hdev->flags))
                goto done;
@@ -619,10 +813,10 @@ done:
 static void btusb_isoc_tx_complete(struct urb *urb)
 {
        struct sk_buff *skb = urb->context;
-       struct hci_dev *hdev = (struct hci_dev *) skb->dev;
+       struct hci_dev *hdev = (struct hci_dev *)skb->dev;
 
-       BT_DBG("%s urb %p status %d count %d", hdev->name,
-                                       urb, urb->status, urb->actual_length);
+       BT_DBG("%s urb %p status %d count %d", hdev->name, urb, urb->status,
+              urb->actual_length);
 
        if (!test_bit(HCI_RUNNING, &hdev->flags))
                goto done;
@@ -706,6 +900,8 @@ static int btusb_close(struct hci_dev *hdev)
        clear_bit(BTUSB_INTR_RUNNING, &data->flags);
 
        btusb_stop_traffic(data);
+       btusb_free_frags(data);
+
        err = usb_autopm_get_interface(data->intf);
        if (err < 0)
                goto failed;
@@ -725,122 +921,181 @@ static int btusb_flush(struct hci_dev *hdev)
        BT_DBG("%s", hdev->name);
 
        usb_kill_anchored_urbs(&data->tx_anchor);
+       btusb_free_frags(data);
 
        return 0;
 }
 
-static int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
+static struct urb *alloc_ctrl_urb(struct hci_dev *hdev, struct sk_buff *skb)
 {
        struct btusb_data *data = hci_get_drvdata(hdev);
        struct usb_ctrlrequest *dr;
        struct urb *urb;
        unsigned int pipe;
-       int err;
 
-       BT_DBG("%s", hdev->name);
+       urb = usb_alloc_urb(0, GFP_KERNEL);
+       if (!urb)
+               return ERR_PTR(-ENOMEM);
 
-       if (!test_bit(HCI_RUNNING, &hdev->flags))
-               return -EBUSY;
+       dr = kmalloc(sizeof(*dr), GFP_KERNEL);
+       if (!dr) {
+               usb_free_urb(urb);
+               return ERR_PTR(-ENOMEM);
+       }
 
-       skb->dev = (void *) hdev;
+       dr->bRequestType = data->cmdreq_type;
+       dr->bRequest     = 0;
+       dr->wIndex       = 0;
+       dr->wValue       = 0;
+       dr->wLength      = __cpu_to_le16(skb->len);
 
-       switch (bt_cb(skb)->pkt_type) {
-       case HCI_COMMAND_PKT:
-               urb = usb_alloc_urb(0, GFP_ATOMIC);
-               if (!urb)
-                       return -ENOMEM;
-
-               dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
-               if (!dr) {
-                       usb_free_urb(urb);
-                       return -ENOMEM;
-               }
+       pipe = usb_sndctrlpipe(data->udev, 0x00);
 
-               dr->bRequestType = data->cmdreq_type;
-               dr->bRequest     = 0;
-               dr->wIndex       = 0;
-               dr->wValue       = 0;
-               dr->wLength      = __cpu_to_le16(skb->len);
+       usb_fill_control_urb(urb, data->udev, pipe, (void *)dr,
+                            skb->data, skb->len, btusb_tx_complete, skb);
 
-               pipe = usb_sndctrlpipe(data->udev, 0x00);
+       skb->dev = (void *)hdev;
 
-               usb_fill_control_urb(urb, data->udev, pipe, (void *) dr,
-                               skb->data, skb->len, btusb_tx_complete, skb);
+       return urb;
+}
 
-               hdev->stat.cmd_tx++;
-               break;
+static struct urb *alloc_bulk_urb(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       struct btusb_data *data = hci_get_drvdata(hdev);
+       struct urb *urb;
+       unsigned int pipe;
 
-       case HCI_ACLDATA_PKT:
-               if (!data->bulk_tx_ep)
-                       return -ENODEV;
+       if (!data->bulk_tx_ep)
+               return ERR_PTR(-ENODEV);
 
-               urb = usb_alloc_urb(0, GFP_ATOMIC);
-               if (!urb)
-                       return -ENOMEM;
+       urb = usb_alloc_urb(0, GFP_KERNEL);
+       if (!urb)
+               return ERR_PTR(-ENOMEM);
 
-               pipe = usb_sndbulkpipe(data->udev,
-                                       data->bulk_tx_ep->bEndpointAddress);
+       pipe = usb_sndbulkpipe(data->udev, data->bulk_tx_ep->bEndpointAddress);
 
-               usb_fill_bulk_urb(urb, data->udev, pipe,
-                               skb->data, skb->len, btusb_tx_complete, skb);
+       usb_fill_bulk_urb(urb, data->udev, pipe,
+                         skb->data, skb->len, btusb_tx_complete, skb);
 
-               hdev->stat.acl_tx++;
-               break;
+       skb->dev = (void *)hdev;
 
-       case HCI_SCODATA_PKT:
-               if (!data->isoc_tx_ep || hci_conn_num(hdev, SCO_LINK) < 1)
-                       return -ENODEV;
+       return urb;
+}
 
-               urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_ATOMIC);
-               if (!urb)
-                       return -ENOMEM;
+static struct urb *alloc_isoc_urb(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       struct btusb_data *data = hci_get_drvdata(hdev);
+       struct urb *urb;
+       unsigned int pipe;
 
-               pipe = usb_sndisocpipe(data->udev,
-                                       data->isoc_tx_ep->bEndpointAddress);
+       if (!data->isoc_tx_ep)
+               return ERR_PTR(-ENODEV);
 
-               usb_fill_int_urb(urb, data->udev, pipe,
-                               skb->data, skb->len, btusb_isoc_tx_complete,
-                               skb, data->isoc_tx_ep->bInterval);
+       urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_KERNEL);
+       if (!urb)
+               return ERR_PTR(-ENOMEM);
 
-               urb->transfer_flags  = URB_ISO_ASAP;
+       pipe = usb_sndisocpipe(data->udev, data->isoc_tx_ep->bEndpointAddress);
 
-               __fill_isoc_descriptor(urb, skb->len,
-                               le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize));
+       usb_fill_int_urb(urb, data->udev, pipe,
+                        skb->data, skb->len, btusb_isoc_tx_complete,
+                        skb, data->isoc_tx_ep->bInterval);
 
-               hdev->stat.sco_tx++;
-               goto skip_waking;
+       urb->transfer_flags  = URB_ISO_ASAP;
 
-       default:
-               return -EILSEQ;
-       }
+       __fill_isoc_descriptor(urb, skb->len,
+                              le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize));
 
-       err = inc_tx(data);
-       if (err) {
-               usb_anchor_urb(urb, &data->deferred);
-               schedule_work(&data->waker);
-               err = 0;
-               goto done;
-       }
+       skb->dev = (void *)hdev;
+
+       return urb;
+}
+
+static int submit_tx_urb(struct hci_dev *hdev, struct urb *urb)
+{
+       struct btusb_data *data = hci_get_drvdata(hdev);
+       int err;
 
-skip_waking:
        usb_anchor_urb(urb, &data->tx_anchor);
 
-       err = usb_submit_urb(urb, GFP_ATOMIC);
+       err = usb_submit_urb(urb, GFP_KERNEL);
        if (err < 0) {
                if (err != -EPERM && err != -ENODEV)
                        BT_ERR("%s urb %p submission failed (%d)",
-                                               hdev->name, urb, -err);
+                              hdev->name, urb, -err);
                kfree(urb->setup_packet);
                usb_unanchor_urb(urb);
        } else {
                usb_mark_last_busy(data->udev);
        }
 
-done:
        usb_free_urb(urb);
        return err;
 }
 
+static int submit_or_queue_tx_urb(struct hci_dev *hdev, struct urb *urb)
+{
+       struct btusb_data *data = hci_get_drvdata(hdev);
+       unsigned long flags;
+       bool suspending;
+
+       spin_lock_irqsave(&data->txlock, flags);
+       suspending = test_bit(BTUSB_SUSPENDING, &data->flags);
+       if (!suspending)
+               data->tx_in_flight++;
+       spin_unlock_irqrestore(&data->txlock, flags);
+
+       if (!suspending)
+               return submit_tx_urb(hdev, urb);
+
+       usb_anchor_urb(urb, &data->deferred);
+       schedule_work(&data->waker);
+
+       usb_free_urb(urb);
+       return 0;
+}
+
+static int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       struct urb *urb;
+
+       BT_DBG("%s", hdev->name);
+
+       if (!test_bit(HCI_RUNNING, &hdev->flags))
+               return -EBUSY;
+
+       switch (bt_cb(skb)->pkt_type) {
+       case HCI_COMMAND_PKT:
+               urb = alloc_ctrl_urb(hdev, skb);
+               if (IS_ERR(urb))
+                       return PTR_ERR(urb);
+
+               hdev->stat.cmd_tx++;
+               return submit_or_queue_tx_urb(hdev, urb);
+
+       case HCI_ACLDATA_PKT:
+               urb = alloc_bulk_urb(hdev, skb);
+               if (IS_ERR(urb))
+                       return PTR_ERR(urb);
+
+               hdev->stat.acl_tx++;
+               return submit_or_queue_tx_urb(hdev, urb);
+
+       case HCI_SCODATA_PKT:
+               if (hci_conn_num(hdev, SCO_LINK) < 1)
+                       return -ENODEV;
+
+               urb = alloc_isoc_urb(hdev, skb);
+               if (IS_ERR(urb))
+                       return PTR_ERR(urb);
+
+               hdev->stat.sco_tx++;
+               return submit_tx_urb(hdev, urb);
+       }
+
+       return -EILSEQ;
+}
+
 static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
 {
        struct btusb_data *data = hci_get_drvdata(hdev);
@@ -917,6 +1172,7 @@ static void btusb_work(struct work_struct *work)
 
                if (hdev->voice_setting & 0x0020) {
                        static const int alts[3] = { 2, 4, 5 };
+
                        new_alts = alts[data->sco_num - 1];
                } else {
                        new_alts = data->sco_num;
@@ -989,7 +1245,7 @@ static int btusb_setup_csr(struct hci_dev *hdev)
                return -PTR_ERR(skb);
        }
 
-       rp = (struct hci_rp_read_local_version *) skb->data;
+       rp = (struct hci_rp_read_local_version *)skb->data;
 
        if (!rp->status) {
                if (le16_to_cpu(rp->manufacturer) != 10) {
@@ -1027,7 +1283,7 @@ struct intel_version {
 } __packed;
 
 static const struct firmware *btusb_setup_intel_get_fw(struct hci_dev *hdev,
-                                               struct intel_version *ver)
+                                                      struct intel_version *ver)
 {
        const struct firmware *fw;
        char fwname[64];
@@ -1182,6 +1438,51 @@ static int btusb_setup_intel_patching(struct hci_dev *hdev,
        return 0;
 }
 
+#define BDADDR_INTEL (&(bdaddr_t) {{0x00, 0x8b, 0x9e, 0x19, 0x03, 0x00}})
+
+static int btusb_check_bdaddr_intel(struct hci_dev *hdev)
+{
+       struct sk_buff *skb;
+       struct hci_rp_read_bd_addr *rp;
+
+       skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
+                            HCI_INIT_TIMEOUT);
+       if (IS_ERR(skb)) {
+               BT_ERR("%s reading Intel device address failed (%ld)",
+                      hdev->name, PTR_ERR(skb));
+               return PTR_ERR(skb);
+       }
+
+       if (skb->len != sizeof(*rp)) {
+               BT_ERR("%s Intel device address length mismatch", hdev->name);
+               kfree_skb(skb);
+               return -EIO;
+       }
+
+       rp = (struct hci_rp_read_bd_addr *)skb->data;
+       if (rp->status) {
+               BT_ERR("%s Intel device address result failed (%02x)",
+                      hdev->name, rp->status);
+               kfree_skb(skb);
+               return -bt_to_errno(rp->status);
+       }
+
+       /* For some Intel based controllers, the default Bluetooth device
+        * address 00:03:19:9E:8B:00 can be found. These controllers are
+        * fully operational, but have the danger of duplicate addresses
+        * and that in turn can cause problems with Bluetooth operation.
+        */
+       if (!bacmp(&rp->bdaddr, BDADDR_INTEL)) {
+               BT_ERR("%s found Intel default device address (%pMR)",
+                      hdev->name, &rp->bdaddr);
+               set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
+       }
+
+       kfree_skb(skb);
+
+       return 0;
+}
+
 static int btusb_setup_intel(struct hci_dev *hdev)
 {
        struct sk_buff *skb;
@@ -1254,6 +1555,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
                BT_INFO("%s: Intel device is already patched. patch num: %02x",
                        hdev->name, ver->fw_patch_num);
                kfree_skb(skb);
+               btusb_check_bdaddr_intel(hdev);
                return 0;
        }
 
@@ -1266,6 +1568,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
        fw = btusb_setup_intel_get_fw(hdev, ver);
        if (!fw) {
                kfree_skb(skb);
+               btusb_check_bdaddr_intel(hdev);
                return 0;
        }
        fw_ptr = fw->data;
@@ -1286,6 +1589,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
 
        if (skb->data[0]) {
                u8 evt_status = skb->data[0];
+
                BT_ERR("%s enable Intel manufacturer mode event failed (%02x)",
                       hdev->name, evt_status);
                kfree_skb(skb);
@@ -1345,6 +1649,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
        BT_INFO("%s: Intel Bluetooth firmware patch completed and activated",
                hdev->name);
 
+       btusb_check_bdaddr_intel(hdev);
        return 0;
 
 exit_mfg_disable:
@@ -1359,6 +1664,8 @@ exit_mfg_disable:
        kfree_skb(skb);
 
        BT_INFO("%s: Intel Bluetooth firmware patch completed", hdev->name);
+
+       btusb_check_bdaddr_intel(hdev);
        return 0;
 
 exit_mfg_deactivate:
@@ -1379,9 +1686,52 @@ exit_mfg_deactivate:
        BT_INFO("%s: Intel Bluetooth firmware patch completed and deactivated",
                hdev->name);
 
+       btusb_check_bdaddr_intel(hdev);
+       return 0;
+}
+
+static int btusb_set_bdaddr_intel(struct hci_dev *hdev, const bdaddr_t *bdaddr)
+{
+       struct sk_buff *skb;
+       long ret;
+
+       skb = __hci_cmd_sync(hdev, 0xfc31, 6, bdaddr, HCI_INIT_TIMEOUT);
+       if (IS_ERR(skb)) {
+               ret = PTR_ERR(skb);
+               BT_ERR("%s: changing Intel device address failed (%ld)",
+                      hdev->name, ret);
+               return ret;
+       }
+       kfree_skb(skb);
+
        return 0;
 }
 
+static int btusb_set_bdaddr_marvell(struct hci_dev *hdev,
+                                   const bdaddr_t *bdaddr)
+{
+       struct sk_buff *skb;
+       u8 buf[8];
+       long ret;
+
+       buf[0] = 0xfe;
+       buf[1] = sizeof(bdaddr_t);
+       memcpy(buf + 2, bdaddr, sizeof(bdaddr_t));
+
+       skb = __hci_cmd_sync(hdev, 0xfc22, sizeof(buf), buf, HCI_INIT_TIMEOUT);
+       if (IS_ERR(skb)) {
+               ret = PTR_ERR(skb);
+               BT_ERR("%s: changing Marvell device address failed (%ld)",
+                      hdev->name, ret);
+               return ret;
+       }
+       kfree_skb(skb);
+
+       return 0;
+}
+
+#define BDADDR_BCM20702A0 (&(bdaddr_t) {{0x00, 0xa0, 0x02, 0x70, 0x20, 0x00}})
+
 static int btusb_setup_bcm_patchram(struct hci_dev *hdev)
 {
        struct btusb_data *data = hci_get_drvdata(hdev);
@@ -1395,6 +1745,7 @@ static int btusb_setup_bcm_patchram(struct hci_dev *hdev)
        u16 opcode;
        struct sk_buff *skb;
        struct hci_rp_read_local_version *ver;
+       struct hci_rp_read_bd_addr *bda;
        long ret;
 
        snprintf(fw_name, sizeof(fw_name), "brcm/%s-%04x-%04x.hcd",
@@ -1404,8 +1755,7 @@ static int btusb_setup_bcm_patchram(struct hci_dev *hdev)
 
        ret = request_firmware(&fw, fw_name, &hdev->dev);
        if (ret < 0) {
-               BT_INFO("%s: BCM: patch %s not found", hdev->name,
-                       fw_name);
+               BT_INFO("%s: BCM: patch %s not found", hdev->name, fw_name);
                return 0;
        }
 
@@ -1424,19 +1774,19 @@ static int btusb_setup_bcm_patchram(struct hci_dev *hdev)
        if (IS_ERR(skb)) {
                ret = PTR_ERR(skb);
                BT_ERR("%s: HCI_OP_READ_LOCAL_VERSION failed (%ld)",
-                       hdev->name, ret);
+                      hdev->name, ret);
                goto done;
        }
 
        if (skb->len != sizeof(*ver)) {
                BT_ERR("%s: HCI_OP_READ_LOCAL_VERSION event length mismatch",
-                       hdev->name);
+                      hdev->name);
                kfree_skb(skb);
                ret = -EIO;
                goto done;
        }
 
-       ver = (struct hci_rp_read_local_version *) skb->data;
+       ver = (struct hci_rp_read_local_version *)skb->data;
        BT_INFO("%s: BCM: patching hci_ver=%02x hci_rev=%04x lmp_ver=%02x "
                "lmp_subver=%04x", hdev->name, ver->hci_ver, ver->hci_rev,
                ver->lmp_ver, ver->lmp_subver);
@@ -1447,7 +1797,7 @@ static int btusb_setup_bcm_patchram(struct hci_dev *hdev)
        if (IS_ERR(skb)) {
                ret = PTR_ERR(skb);
                BT_ERR("%s: BCM: Download Minidrv command failed (%ld)",
-                       hdev->name, ret);
+                      hdev->name, ret);
                goto reset_fw;
        }
        kfree_skb(skb);
@@ -1459,13 +1809,13 @@ static int btusb_setup_bcm_patchram(struct hci_dev *hdev)
        fw_size = fw->size;
 
        while (fw_size >= sizeof(*cmd)) {
-               cmd = (struct hci_command_hdr *) fw_ptr;
+               cmd = (struct hci_command_hdr *)fw_ptr;
                fw_ptr += sizeof(*cmd);
                fw_size -= sizeof(*cmd);
 
                if (fw_size < cmd->plen) {
                        BT_ERR("%s: BCM: patch %s is corrupted",
-                               hdev->name, fw_name);
+                              hdev->name, fw_name);
                        ret = -EINVAL;
                        goto reset_fw;
                }
@@ -1481,7 +1831,7 @@ static int btusb_setup_bcm_patchram(struct hci_dev *hdev)
                if (IS_ERR(skb)) {
                        ret = PTR_ERR(skb);
                        BT_ERR("%s: BCM: patch command %04x failed (%ld)",
-                               hdev->name, opcode, ret);
+                              hdev->name, opcode, ret);
                        goto reset_fw;
                }
                kfree_skb(skb);
@@ -1506,32 +1856,87 @@ reset_fw:
        if (IS_ERR(skb)) {
                ret = PTR_ERR(skb);
                BT_ERR("%s: HCI_OP_READ_LOCAL_VERSION failed (%ld)",
-                       hdev->name, ret);
+                      hdev->name, ret);
                goto done;
        }
 
        if (skb->len != sizeof(*ver)) {
                BT_ERR("%s: HCI_OP_READ_LOCAL_VERSION event length mismatch",
-                       hdev->name);
+                      hdev->name);
                kfree_skb(skb);
                ret = -EIO;
                goto done;
        }
 
-       ver = (struct hci_rp_read_local_version *) skb->data;
+       ver = (struct hci_rp_read_local_version *)skb->data;
        BT_INFO("%s: BCM: firmware hci_ver=%02x hci_rev=%04x lmp_ver=%02x "
                "lmp_subver=%04x", hdev->name, ver->hci_ver, ver->hci_rev,
                ver->lmp_ver, ver->lmp_subver);
        kfree_skb(skb);
 
+       /* Read BD Address */
+       skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
+                            HCI_INIT_TIMEOUT);
+       if (IS_ERR(skb)) {
+               ret = PTR_ERR(skb);
+               BT_ERR("%s: HCI_OP_READ_BD_ADDR failed (%ld)",
+                      hdev->name, ret);
+               goto done;
+       }
+
+       if (skb->len != sizeof(*bda)) {
+               BT_ERR("%s: HCI_OP_READ_BD_ADDR event length mismatch",
+                      hdev->name);
+               kfree_skb(skb);
+               ret = -EIO;
+               goto done;
+       }
+
+       bda = (struct hci_rp_read_bd_addr *)skb->data;
+       if (bda->status) {
+               BT_ERR("%s: HCI_OP_READ_BD_ADDR error status (%02x)",
+                      hdev->name, bda->status);
+               kfree_skb(skb);
+               ret = -bt_to_errno(bda->status);
+               goto done;
+       }
+
+       /* The address 00:20:70:02:A0:00 indicates a BCM20702A0 controller
+        * with no configured address.
+        */
+       if (!bacmp(&bda->bdaddr, BDADDR_BCM20702A0)) {
+               BT_INFO("%s: BCM: using default device address (%pMR)",
+                       hdev->name, &bda->bdaddr);
+               set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
+       }
+
+       kfree_skb(skb);
+
 done:
        release_firmware(fw);
 
        return ret;
 }
 
+static int btusb_set_bdaddr_bcm(struct hci_dev *hdev, const bdaddr_t *bdaddr)
+{
+       struct sk_buff *skb;
+       long ret;
+
+       skb = __hci_cmd_sync(hdev, 0xfc01, 6, bdaddr, HCI_INIT_TIMEOUT);
+       if (IS_ERR(skb)) {
+               ret = PTR_ERR(skb);
+               BT_ERR("%s: BCM: Change address command failed (%ld)",
+                      hdev->name, ret);
+               return ret;
+       }
+       kfree_skb(skb);
+
+       return 0;
+}
+
 static int btusb_probe(struct usb_interface *intf,
-                               const struct usb_device_id *id)
+                      const struct usb_device_id *id)
 {
        struct usb_endpoint_descriptor *ep_desc;
        struct btusb_data *data;
@@ -1546,6 +1951,7 @@ static int btusb_probe(struct usb_interface *intf,
 
        if (!id->driver_info) {
                const struct usb_device_id *match;
+
                match = usb_match_id(intf, blacklist_table);
                if (match)
                        id = match;
@@ -1554,15 +1960,6 @@ static int btusb_probe(struct usb_interface *intf,
        if (id->driver_info == BTUSB_IGNORE)
                return -ENODEV;
 
-       if (ignore_dga && id->driver_info & BTUSB_DIGIANSWER)
-               return -ENODEV;
-
-       if (ignore_csr && id->driver_info & BTUSB_CSR)
-               return -ENODEV;
-
-       if (ignore_sniffer && id->driver_info & BTUSB_SNIFFER)
-               return -ENODEV;
-
        if (id->driver_info & BTUSB_ATH3012) {
                struct usb_device *udev = interface_to_usbdev(intf);
 
@@ -1603,17 +2000,16 @@ static int btusb_probe(struct usb_interface *intf,
        data->udev = interface_to_usbdev(intf);
        data->intf = intf;
 
-       spin_lock_init(&data->lock);
-
        INIT_WORK(&data->work, btusb_work);
        INIT_WORK(&data->waker, btusb_waker);
+       init_usb_anchor(&data->deferred);
+       init_usb_anchor(&data->tx_anchor);
        spin_lock_init(&data->txlock);
 
-       init_usb_anchor(&data->tx_anchor);
        init_usb_anchor(&data->intr_anchor);
        init_usb_anchor(&data->bulk_anchor);
        init_usb_anchor(&data->isoc_anchor);
-       init_usb_anchor(&data->deferred);
+       spin_lock_init(&data->rxlock);
 
        hdev = hci_alloc_dev();
        if (!hdev)
@@ -1635,11 +2031,21 @@ static int btusb_probe(struct usb_interface *intf,
        if (id->driver_info & BTUSB_BCM92035)
                hdev->setup = btusb_setup_bcm92035;
 
-       if (id->driver_info & BTUSB_BCM_PATCHRAM)
+       if (id->driver_info & BTUSB_BCM_PATCHRAM) {
                hdev->setup = btusb_setup_bcm_patchram;
+               hdev->set_bdaddr = btusb_set_bdaddr_bcm;
+       }
 
-       if (id->driver_info & BTUSB_INTEL)
+       if (id->driver_info & BTUSB_INTEL) {
                hdev->setup = btusb_setup_intel;
+               hdev->set_bdaddr = btusb_set_bdaddr_intel;
+       }
+
+       if (id->driver_info & BTUSB_MARVELL)
+               hdev->set_bdaddr = btusb_set_bdaddr_marvell;
+
+       if (id->driver_info & BTUSB_INTEL_BOOT)
+               set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
 
        /* Interface numbers are hardcoded in the specification */
        data->isoc = usb_ifnum_to_if(data->udev, 1);
@@ -1679,13 +2085,23 @@ static int btusb_probe(struct usb_interface *intf,
                /* New sniffer firmware has crippled HCI interface */
                if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997)
                        set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
+       }
 
-               data->isoc = NULL;
+       if (id->driver_info & BTUSB_INTEL_BOOT) {
+               /* A bug in the bootloader causes that interrupt interface is
+                * only enabled after receiving SetInterface(0, AltSetting=0).
+                */
+               err = usb_set_interface(data->udev, 0, 0);
+               if (err < 0) {
+                       BT_ERR("failed to set interface 0, alt 0 %d", err);
+                       hci_free_dev(hdev);
+                       return err;
+               }
        }
 
        if (data->isoc) {
                err = usb_driver_claim_interface(&btusb_driver,
-                                                       data->isoc, data);
+                                                data->isoc, data);
                if (err < 0) {
                        hci_free_dev(hdev);
                        return err;
@@ -1726,6 +2142,7 @@ static void btusb_disconnect(struct usb_interface *intf)
        else if (data->isoc)
                usb_driver_release_interface(&btusb_driver, data->isoc);
 
+       btusb_free_frags(data);
        hci_free_dev(hdev);
 }
 
@@ -1845,15 +2262,6 @@ static struct usb_driver btusb_driver = {
 
 module_usb_driver(btusb_driver);
 
-module_param(ignore_dga, bool, 0644);
-MODULE_PARM_DESC(ignore_dga, "Ignore devices with id 08fd:0001");
-
-module_param(ignore_csr, bool, 0644);
-MODULE_PARM_DESC(ignore_csr, "Ignore devices with id 0a12:0001");
-
-module_param(ignore_sniffer, bool, 0644);
-MODULE_PARM_DESC(ignore_sniffer, "Ignore devices with id 0a12:0002");
-
 module_param(disable_scofix, bool, 0644);
 MODULE_PARM_DESC(disable_scofix, "Disable fixup of wrong SCO buffer size");