Bluetooth: Enable Atheros 0cf3:311e for firmware upload
[pandora-kernel.git] / drivers / bluetooth / btusb.c
index 3980fd1..cc7ddd7 100644 (file)
@@ -144,12 +144,14 @@ static const struct usb_device_id blacklist_table[] = {
        { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0cf3, 0x311e), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0x817a), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
@@ -164,6 +166,7 @@ static const struct usb_device_id blacklist_table[] = {
        { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 },
 
        /* Atheros AR5BBU12 with sflash firmware */
        { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
@@ -224,6 +227,7 @@ static const struct usb_device_id blacklist_table[] = {
 
        /* Intel Bluetooth device */
        { USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL },
+       { USB_DEVICE(0x8087, 0x0a2a), .driver_info = BTUSB_INTEL },
 
        { }     /* Terminating entry */
 };
@@ -962,6 +966,45 @@ static int btusb_setup_bcm92035(struct hci_dev *hdev)
        return 0;
 }
 
+static int btusb_setup_csr(struct hci_dev *hdev)
+{
+       struct hci_rp_read_local_version *rp;
+       struct sk_buff *skb;
+       int ret;
+
+       BT_DBG("%s", hdev->name);
+
+       skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL,
+                            HCI_INIT_TIMEOUT);
+       if (IS_ERR(skb)) {
+               BT_ERR("Reading local version failed (%ld)", -PTR_ERR(skb));
+               return -PTR_ERR(skb);
+       }
+
+       rp = (struct hci_rp_read_local_version *) skb->data;
+
+       if (!rp->status) {
+               if (le16_to_cpu(rp->manufacturer) != 10) {
+                       /* Clear the reset quirk since this is not an actual
+                        * early Bluetooth 1.1 device from CSR.
+                        */
+                       clear_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
+
+                       /* These fake CSR controllers have all a broken
+                        * stored link key handling and so just disable it.
+                        */
+                       set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY,
+                               &hdev->quirks);
+               }
+       }
+
+       ret = -bt_to_errno(rp->status);
+
+       kfree_skb(skb);
+
+       return ret;
+}
+
 struct intel_version {
        u8 status;
        u8 hw_platform;
@@ -1436,8 +1479,10 @@ static int btusb_probe(struct usb_interface *intf,
        if (id->driver_info & BTUSB_BCM92035)
                hdev->setup = btusb_setup_bcm92035;
 
-       if (id->driver_info & BTUSB_INTEL)
+       if (id->driver_info & BTUSB_INTEL) {
+               usb_enable_autosuspend(data->udev);
                hdev->setup = btusb_setup_intel;
+       }
 
        /* Interface numbers are hardcoded in the specification */
        data->isoc = usb_ifnum_to_if(data->udev, 1);
@@ -1460,10 +1505,15 @@ static int btusb_probe(struct usb_interface *intf,
 
        if (id->driver_info & BTUSB_CSR) {
                struct usb_device *udev = data->udev;
+               u16 bcdDevice = le16_to_cpu(udev->descriptor.bcdDevice);
 
                /* Old firmware would otherwise execute USB reset */
-               if (le16_to_cpu(udev->descriptor.bcdDevice) < 0x117)
+               if (bcdDevice < 0x117)
                        set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
+
+               /* Fake CSR devices with broken commands */
+               if (bcdDevice <= 0x100)
+                       hdev->setup = btusb_setup_csr;
        }
 
        if (id->driver_info & BTUSB_SNIFFER) {