]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - drivers/bluetooth/bpa10x.c
Bluetooth: bpa10x: Add support for set_diag driver callback
[mirror_ubuntu-bionic-kernel.git] / drivers / bluetooth / bpa10x.c
index 8a319913c9a96fd60c6d021c5edd055b83ef0aad..a1a0f80212b30f858cc8c54caf953eb0b32bf9dd 100644 (file)
@@ -304,9 +304,6 @@ static int bpa10x_open(struct hci_dev *hdev)
 
        BT_DBG("%s", hdev->name);
 
-       if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
-               return 0;
-
        err = bpa10x_submit_intr_urb(hdev);
        if (err < 0)
                goto error;
@@ -320,8 +317,6 @@ static int bpa10x_open(struct hci_dev *hdev)
 error:
        usb_kill_anchored_urbs(&data->rx_anchor);
 
-       clear_bit(HCI_RUNNING, &hdev->flags);
-
        return err;
 }
 
@@ -331,9 +326,6 @@ static int bpa10x_close(struct hci_dev *hdev)
 
        BT_DBG("%s", hdev->name);
 
-       if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
-               return 0;
-
        usb_kill_anchored_urbs(&data->rx_anchor);
 
        return 0;
@@ -350,6 +342,24 @@ static int bpa10x_flush(struct hci_dev *hdev)
        return 0;
 }
 
+static int bpa10x_setup(struct hci_dev *hdev)
+{
+       const u8 req[] = { 0x07 };
+       struct sk_buff *skb;
+
+       BT_DBG("%s", hdev->name);
+
+       /* Read revision string */
+       skb = __hci_cmd_sync(hdev, 0xfc0e, sizeof(req), req, HCI_INIT_TIMEOUT);
+       if (IS_ERR(skb))
+               return PTR_ERR(skb);
+
+       BT_INFO("%s: %s", hdev->name, (char *)(skb->data + 1));
+
+       kfree_skb(skb);
+       return 0;
+}
+
 static int bpa10x_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
        struct bpa10x_data *data = hci_get_drvdata(hdev);
@@ -360,9 +370,6 @@ static int bpa10x_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 
        BT_DBG("%s", hdev->name);
 
-       if (!test_bit(HCI_RUNNING, &hdev->flags))
-               return -EBUSY;
-
        skb->dev = (void *) hdev;
 
        urb = usb_alloc_urb(0, GFP_ATOMIC);
@@ -431,6 +438,25 @@ static int bpa10x_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
        return 0;
 }
 
+static int bpa10x_set_diag(struct hci_dev *hdev, bool enable)
+{
+       const u8 req[] = { 0x00, enable };
+       struct sk_buff *skb;
+
+       BT_DBG("%s", hdev->name);
+
+       if (!test_bit(HCI_RUNNING, &hdev->flags))
+               return -ENETDOWN;
+
+       /* Enable sniffer operation */
+       skb = __hci_cmd_sync(hdev, 0xfc0e, sizeof(req), req, HCI_INIT_TIMEOUT);
+       if (IS_ERR(skb))
+               return PTR_ERR(skb);
+
+       kfree_skb(skb);
+       return 0;
+}
+
 static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
        struct bpa10x_data *data;
@@ -465,7 +491,9 @@ static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *
        hdev->open     = bpa10x_open;
        hdev->close    = bpa10x_close;
        hdev->flush    = bpa10x_flush;
+       hdev->setup    = bpa10x_setup;
        hdev->send     = bpa10x_send_frame;
+       hdev->set_diag = bpa10x_set_diag;
 
        set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);