Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth...
authorJohn W. Linville <linville@tuxdriver.com>
Wed, 31 Jul 2013 19:11:50 +0000 (15:11 -0400)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 31 Jul 2013 19:11:50 +0000 (15:11 -0400)
Conflicts:
net/bluetooth/hci_core.c

1  2 
drivers/bluetooth/btusb.c
net/bluetooth/hci_core.c

@@@ -57,9 -57,6 +57,9 @@@ static struct usb_device_id btusb_table
        /* Apple-specific (Broadcom) devices */
        { USB_VENDOR_AND_INTERFACE_INFO(0x05ac, 0xff, 0x01, 0x01) },
  
 +      /* MediaTek MT76x0E */
 +      { USB_DEVICE(0x0e8d, 0x763f) },
 +
        /* Broadcom SoftSailing reporting vendor specific */
        { USB_DEVICE(0x0a5c, 0x21e1) },
  
@@@ -154,6 -151,10 +154,10 @@@ static struct usb_device_id blacklist_t
        { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 },
  
        /* Atheros AR5BBU12 with sflash firmware */
        { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
@@@ -1095,7 -1096,7 +1099,7 @@@ static int btusb_setup_intel_patching(s
        if (IS_ERR(skb)) {
                BT_ERR("%s sending Intel patch command (0x%4.4x) failed (%ld)",
                       hdev->name, cmd->opcode, PTR_ERR(skb));
-               return -PTR_ERR(skb);
+               return PTR_ERR(skb);
        }
  
        /* It ensures that the returned event matches the event data read from
@@@ -1147,7 -1148,7 +1151,7 @@@ static int btusb_setup_intel(struct hci
        if (IS_ERR(skb)) {
                BT_ERR("%s sending initial HCI reset command failed (%ld)",
                       hdev->name, PTR_ERR(skb));
-               return -PTR_ERR(skb);
+               return PTR_ERR(skb);
        }
        kfree_skb(skb);
  
        if (IS_ERR(skb)) {
                BT_ERR("%s reading Intel fw version command failed (%ld)",
                       hdev->name, PTR_ERR(skb));
-               return -PTR_ERR(skb);
+               return PTR_ERR(skb);
        }
  
        if (skb->len != sizeof(*ver)) {
                BT_ERR("%s entering Intel manufacturer mode failed (%ld)",
                       hdev->name, PTR_ERR(skb));
                release_firmware(fw);
-               return -PTR_ERR(skb);
+               return PTR_ERR(skb);
        }
  
        if (skb->data[0]) {
        if (IS_ERR(skb)) {
                BT_ERR("%s exiting Intel manufacturer mode failed (%ld)",
                       hdev->name, PTR_ERR(skb));
-               return -PTR_ERR(skb);
+               return PTR_ERR(skb);
        }
        kfree_skb(skb);
  
@@@ -1292,7 -1293,7 +1296,7 @@@ exit_mfg_disable
        if (IS_ERR(skb)) {
                BT_ERR("%s exiting Intel manufacturer mode failed (%ld)",
                       hdev->name, PTR_ERR(skb));
-               return -PTR_ERR(skb);
+               return PTR_ERR(skb);
        }
        kfree_skb(skb);
  
@@@ -1310,7 -1311,7 +1314,7 @@@ exit_mfg_deactivate
        if (IS_ERR(skb)) {
                BT_ERR("%s exiting Intel manufacturer mode failed (%ld)",
                       hdev->name, PTR_ERR(skb));
-               return -PTR_ERR(skb);
+               return PTR_ERR(skb);
        }
        kfree_skb(skb);
  
@@@ -1619,7 -1620,6 +1623,7 @@@ static struct usb_driver btusb_driver 
  #ifdef CONFIG_PM
        .suspend        = btusb_suspend,
        .resume         = btusb_resume,
 +      .reset_resume   = btusb_resume,
  #endif
        .id_table       = btusb_table,
        .supports_autosuspend = 1,
diff --combined net/bluetooth/hci_core.c
@@@ -513,7 -513,10 +513,10 @@@ static void hci_init2_req(struct hci_re
  
        hci_setup_event_mask(req);
  
-       if (hdev->hci_ver > BLUETOOTH_VER_1_1)
+       /* AVM Berlin (31), aka "BlueFRITZ!", doesn't support the read
+        * local supported commands HCI command.
+        */
+       if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1)
                hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
  
        if (lmp_ssp_capable(hdev)) {
@@@ -597,15 -600,7 +600,15 @@@ static void hci_init3_req(struct hci_re
        struct hci_dev *hdev = req->hdev;
        u8 p;
  
 -      /* Only send HCI_Delete_Stored_Link_Key if it is supported */
 +      /* Some Broadcom based Bluetooth controllers do not support the
 +       * Delete Stored Link Key command. They are clearly indicating its
 +       * absence in the bit mask of supported commands.
 +       *
 +       * Check the supported commands and only if the the command is marked
 +       * as supported send it. If not supported assume that the controller
 +       * does not have actual support for stored link keys which makes this
 +       * command redundant anyway.
 +         */
        if (hdev->commands[6] & 0x80) {
                struct hci_cp_delete_stored_link_key cp;
  
@@@ -759,7 -754,7 +762,7 @@@ void hci_discovery_set_state(struct hci
        hdev->discovery.state = state;
  }
  
 -static void inquiry_cache_flush(struct hci_dev *hdev)
 +void hci_inquiry_cache_flush(struct hci_dev *hdev)
  {
        struct discovery_state *cache = &hdev->discovery;
        struct inquiry_entry *p, *n;
@@@ -972,7 -967,7 +975,7 @@@ int hci_inquiry(void __user *arg
        hci_dev_lock(hdev);
        if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
            inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
 -              inquiry_cache_flush(hdev);
 +              hci_inquiry_cache_flush(hdev);
                do_inquiry = 1;
        }
        hci_dev_unlock(hdev);
@@@ -1209,6 -1204,8 +1212,6 @@@ static int hci_dev_do_close(struct hci_
  {
        BT_DBG("%s %p", hdev->name, hdev);
  
 -      cancel_work_sync(&hdev->le_scan);
 -
        cancel_delayed_work(&hdev->power_off);
  
        hci_req_cancel(hdev, ENODEV);
        cancel_delayed_work_sync(&hdev->le_scan_disable);
  
        hci_dev_lock(hdev);
 -      inquiry_cache_flush(hdev);
 +      hci_inquiry_cache_flush(hdev);
        hci_conn_hash_flush(hdev);
        hci_dev_unlock(hdev);
  
@@@ -1337,7 -1334,7 +1340,7 @@@ int hci_dev_reset(__u16 dev
        skb_queue_purge(&hdev->cmd_q);
  
        hci_dev_lock(hdev);
 -      inquiry_cache_flush(hdev);
 +      hci_inquiry_cache_flush(hdev);
        hci_conn_hash_flush(hdev);
        hci_dev_unlock(hdev);
  
@@@ -1997,59 -1994,80 +2000,59 @@@ int hci_blacklist_del(struct hci_dev *h
        return mgmt_device_unblocked(hdev, bdaddr, type);
  }
  
 -static void le_scan_param_req(struct hci_request *req, unsigned long opt)
 +static void inquiry_complete(struct hci_dev *hdev, u8 status)
  {
 -      struct le_scan_params *param =  (struct le_scan_params *) opt;
 -      struct hci_cp_le_set_scan_param cp;
 -
 -      memset(&cp, 0, sizeof(cp));
 -      cp.type = param->type;
 -      cp.interval = cpu_to_le16(param->interval);
 -      cp.window = cpu_to_le16(param->window);
 +      if (status) {
 +              BT_ERR("Failed to start inquiry: status %d", status);
  
 -      hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp);
 -}
 -
 -static void le_scan_enable_req(struct hci_request *req, unsigned long opt)
 -{
 -      struct hci_cp_le_set_scan_enable cp;
 -
 -      memset(&cp, 0, sizeof(cp));
 -      cp.enable = LE_SCAN_ENABLE;
 -      cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
 -
 -      hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
 +              hci_dev_lock(hdev);
 +              hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
 +              hci_dev_unlock(hdev);
 +              return;
 +      }
  }
  
 -static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval,
 -                        u16 window, int timeout)
 +static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status)
  {
 -      long timeo = msecs_to_jiffies(3000);
 -      struct le_scan_params param;
 +      /* General inquiry access code (GIAC) */
 +      u8 lap[3] = { 0x33, 0x8b, 0x9e };
 +      struct hci_request req;
 +      struct hci_cp_inquiry cp;
        int err;
  
 -      BT_DBG("%s", hdev->name);
 -
 -      if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
 -              return -EINPROGRESS;
 -
 -      param.type = type;
 -      param.interval = interval;
 -      param.window = window;
 -
 -      hci_req_lock(hdev);
 -
 -      err = __hci_req_sync(hdev, le_scan_param_req, (unsigned long) &param,
 -                           timeo);
 -      if (!err)
 -              err = __hci_req_sync(hdev, le_scan_enable_req, 0, timeo);
 -
 -      hci_req_unlock(hdev);
 +      if (status) {
 +              BT_ERR("Failed to disable LE scanning: status %d", status);
 +              return;
 +      }
  
 -      if (err < 0)
 -              return err;
 +      switch (hdev->discovery.type) {
 +      case DISCOV_TYPE_LE:
 +              hci_dev_lock(hdev);
 +              hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
 +              hci_dev_unlock(hdev);
 +              break;
  
 -      queue_delayed_work(hdev->workqueue, &hdev->le_scan_disable,
 -                         timeout);
 +      case DISCOV_TYPE_INTERLEAVED:
 +              hci_req_init(&req, hdev);
  
 -      return 0;
 -}
 +              memset(&cp, 0, sizeof(cp));
 +              memcpy(&cp.lap, lap, sizeof(cp.lap));
 +              cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN;
 +              hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp);
  
 -int hci_cancel_le_scan(struct hci_dev *hdev)
 -{
 -      BT_DBG("%s", hdev->name);
 +              hci_dev_lock(hdev);
  
 -      if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags))
 -              return -EALREADY;
 +              hci_inquiry_cache_flush(hdev);
  
 -      if (cancel_delayed_work(&hdev->le_scan_disable)) {
 -              struct hci_cp_le_set_scan_enable cp;
 +              err = hci_req_run(&req, inquiry_complete);
 +              if (err) {
 +                      BT_ERR("Inquiry request failed: err %d", err);
 +                      hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
 +              }
  
 -              /* Send HCI command to disable LE Scan */
 -              memset(&cp, 0, sizeof(cp));
 -              hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
 +              hci_dev_unlock(hdev);
 +              break;
        }
 -
 -      return 0;
  }
  
  static void le_scan_disable_work(struct work_struct *work)
        struct hci_dev *hdev = container_of(work, struct hci_dev,
                                            le_scan_disable.work);
        struct hci_cp_le_set_scan_enable cp;
 +      struct hci_request req;
 +      int err;
  
        BT_DBG("%s", hdev->name);
  
 -      memset(&cp, 0, sizeof(cp));
 -
 -      hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
 -}
 -
 -static void le_scan_work(struct work_struct *work)
 -{
 -      struct hci_dev *hdev = container_of(work, struct hci_dev, le_scan);
 -      struct le_scan_params *param = &hdev->le_scan_params;
 +      hci_req_init(&req, hdev);
  
 -      BT_DBG("%s", hdev->name);
 +      memset(&cp, 0, sizeof(cp));
 +      cp.enable = LE_SCAN_DISABLE;
 +      hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
  
 -      hci_do_le_scan(hdev, param->type, param->interval, param->window,
 -                     param->timeout);
 -}
 -
 -int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window,
 -              int timeout)
 -{
 -      struct le_scan_params *param = &hdev->le_scan_params;
 -
 -      BT_DBG("%s", hdev->name);
 -
 -      if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags))
 -              return -ENOTSUPP;
 -
 -      if (work_busy(&hdev->le_scan))
 -              return -EINPROGRESS;
 -
 -      param->type = type;
 -      param->interval = interval;
 -      param->window = window;
 -      param->timeout = timeout;
 -
 -      queue_work(system_long_wq, &hdev->le_scan);
 -
 -      return 0;
 +      err = hci_req_run(&req, le_scan_disable_work_complete);
 +      if (err)
 +              BT_ERR("Disable LE scanning request failed: err %d", err);
  }
  
  /* Alloc HCI device */
@@@ -2107,6 -2151,7 +2110,6 @@@ struct hci_dev *hci_alloc_dev(void
        INIT_WORK(&hdev->cmd_work, hci_cmd_work);
        INIT_WORK(&hdev->tx_work, hci_tx_work);
        INIT_WORK(&hdev->power_on, hci_power_on);
 -      INIT_WORK(&hdev->le_scan, le_scan_work);
  
        INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
        INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
@@@ -2165,19 -2210,16 +2168,15 @@@ int hci_register_dev(struct hci_dev *hd
  
        BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
  
-       write_lock(&hci_dev_list_lock);
-       list_add(&hdev->list, &hci_dev_list);
-       write_unlock(&hci_dev_list_lock);
 -      hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND |
 -                                        WQ_MEM_RECLAIM, 1);
 +      hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
 +                                        WQ_MEM_RECLAIM, 1, hdev->name);
        if (!hdev->workqueue) {
                error = -ENOMEM;
                goto err;
        }
  
 -      hdev->req_workqueue = alloc_workqueue(hdev->name,
 -                                            WQ_HIGHPRI | WQ_UNBOUND |
 -                                            WQ_MEM_RECLAIM, 1);
 +      hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
 +                                            WQ_MEM_RECLAIM, 1, hdev->name);
        if (!hdev->req_workqueue) {
                destroy_workqueue(hdev->workqueue);
                error = -ENOMEM;
        if (hdev->dev_type != HCI_AMP)
                set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
  
+       write_lock(&hci_dev_list_lock);
+       list_add(&hdev->list, &hci_dev_list);
+       write_unlock(&hci_dev_list_lock);
        hci_notify(hdev, HCI_DEV_REG);
        hci_dev_hold(hdev);
  
@@@ -2215,9 -2261,6 +2218,6 @@@ err_wqueue
        destroy_workqueue(hdev->req_workqueue);
  err:
        ida_simple_remove(&hci_index_ida, hdev->id);
-       write_lock(&hci_dev_list_lock);
-       list_del(&hdev->list);
-       write_unlock(&hci_dev_list_lock);
  
        return error;
  }
@@@ -3399,8 -3442,16 +3399,16 @@@ void hci_req_cmd_complete(struct hci_de
         */
        if (hdev->sent_cmd) {
                req_complete = bt_cb(hdev->sent_cmd)->req.complete;
-               if (req_complete)
+               if (req_complete) {
+                       /* We must set the complete callback to NULL to
+                        * avoid calling the callback more than once if
+                        * this function gets called again.
+                        */
+                       bt_cb(hdev->sent_cmd)->req.complete = NULL;
                        goto call_complete;
+               }
        }
  
        /* Remove all pending commands belonging to this request */
@@@ -3508,6 -3559,36 +3516,6 @@@ static void hci_cmd_work(struct work_st
        }
  }
  
 -int hci_do_inquiry(struct hci_dev *hdev, u8 length)
 -{
 -      /* General inquiry access code (GIAC) */
 -      u8 lap[3] = { 0x33, 0x8b, 0x9e };
 -      struct hci_cp_inquiry cp;
 -
 -      BT_DBG("%s", hdev->name);
 -
 -      if (test_bit(HCI_INQUIRY, &hdev->flags))
 -              return -EINPROGRESS;
 -
 -      inquiry_cache_flush(hdev);
 -
 -      memset(&cp, 0, sizeof(cp));
 -      memcpy(&cp.lap, lap, sizeof(cp.lap));
 -      cp.length  = length;
 -
 -      return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
 -}
 -
 -int hci_cancel_inquiry(struct hci_dev *hdev)
 -{
 -      BT_DBG("%s", hdev->name);
 -
 -      if (!test_bit(HCI_INQUIRY, &hdev->flags))
 -              return -EALREADY;
 -
 -      return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL);
 -}
 -
  u8 bdaddr_to_le(u8 bdaddr_type)
  {
        switch (bdaddr_type) {