diff options
Diffstat (limited to 'drivers/bluetooth/virtio_bt.c')
| -rw-r--r-- | drivers/bluetooth/virtio_bt.c | 62 |
1 files changed, 40 insertions, 22 deletions
diff --git a/drivers/bluetooth/virtio_bt.c b/drivers/bluetooth/virtio_bt.c index fd281d439505..6f1a37e85c6a 100644 --- a/drivers/bluetooth/virtio_bt.c +++ b/drivers/bluetooth/virtio_bt.c @@ -50,8 +50,11 @@ static int virtbt_add_inbuf(struct virtio_bluetooth *vbt) static int virtbt_open(struct hci_dev *hdev) { - struct virtio_bluetooth *vbt = hci_get_drvdata(hdev); + return 0; +} +static int virtbt_open_vdev(struct virtio_bluetooth *vbt) +{ if (virtbt_add_inbuf(vbt) < 0) return -EIO; @@ -61,7 +64,11 @@ static int virtbt_open(struct hci_dev *hdev) static int virtbt_close(struct hci_dev *hdev) { - struct virtio_bluetooth *vbt = hci_get_drvdata(hdev); + return 0; +} + +static int virtbt_close_vdev(struct virtio_bluetooth *vbt) +{ int i; cancel_work_sync(&vbt->rx); @@ -72,6 +79,7 @@ static int virtbt_close(struct hci_dev *hdev) while ((skb = virtqueue_detach_unused_buf(vq))) kfree_skb(skb); + cond_resched(); } return 0; @@ -246,13 +254,9 @@ static void virtbt_rx_done(struct virtqueue *vq) static int virtbt_probe(struct virtio_device *vdev) { - vq_callback_t *callbacks[VIRTBT_NUM_VQS] = { - [VIRTBT_VQ_TX] = virtbt_tx_done, - [VIRTBT_VQ_RX] = virtbt_rx_done, - }; - const char *names[VIRTBT_NUM_VQS] = { - [VIRTBT_VQ_TX] = "tx", - [VIRTBT_VQ_RX] = "rx", + struct virtqueue_info vqs_info[VIRTBT_NUM_VQS] = { + [VIRTBT_VQ_TX] = { "tx", virtbt_tx_done }, + [VIRTBT_VQ_RX] = { "rx", virtbt_rx_done }, }; struct virtio_bluetooth *vbt; struct hci_dev *hdev; @@ -266,7 +270,6 @@ static int virtbt_probe(struct virtio_device *vdev) switch (type) { case VIRTIO_BT_CONFIG_TYPE_PRIMARY: - case VIRTIO_BT_CONFIG_TYPE_AMP: break; default: return -EINVAL; @@ -281,8 +284,7 @@ static int virtbt_probe(struct virtio_device *vdev) INIT_WORK(&vbt->rx, virtbt_rx_work); - err = virtio_find_vqs(vdev, VIRTBT_NUM_VQS, vbt->vqs, callbacks, - names, NULL); + err = virtio_find_vqs(vdev, VIRTBT_NUM_VQS, vbt->vqs, vqs_info, NULL); if (err) return err; @@ -295,7 +297,6 @@ static int virtbt_probe(struct virtio_device *vdev) vbt->hdev = hdev; hdev->bus = HCI_VIRTIO; - hdev->dev_type = type; hci_set_drvdata(hdev, vbt); hdev->open = virtbt_open; @@ -306,7 +307,12 @@ static int virtbt_probe(struct virtio_device *vdev) if (virtio_has_feature(vdev, VIRTIO_BT_F_VND_HCI)) { __u16 vendor; - virtio_cread(vdev, struct virtio_bt_config, vendor, &vendor); + if (virtio_has_feature(vdev, VIRTIO_BT_F_CONFIG_V2)) + virtio_cread(vdev, struct virtio_bt_config_v2, + vendor, &vendor); + else + virtio_cread(vdev, struct virtio_bt_config, + vendor, &vendor); switch (vendor) { case VIRTIO_BT_CONFIG_VENDOR_ZEPHYR: @@ -321,17 +327,17 @@ static int virtbt_probe(struct virtio_device *vdev) hdev->setup = virtbt_setup_intel; hdev->shutdown = virtbt_shutdown_generic; hdev->set_bdaddr = virtbt_set_bdaddr_intel; - set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks); - set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks); - set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks); + hci_set_quirk(hdev, HCI_QUIRK_STRICT_DUPLICATE_FILTER); + hci_set_quirk(hdev, HCI_QUIRK_SIMULTANEOUS_DISCOVERY); + hci_set_quirk(hdev, HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED); break; case VIRTIO_BT_CONFIG_VENDOR_REALTEK: hdev->manufacturer = 93; hdev->setup = virtbt_setup_realtek; hdev->shutdown = virtbt_shutdown_generic; - set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks); - set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks); + hci_set_quirk(hdev, HCI_QUIRK_SIMULTANEOUS_DISCOVERY); + hci_set_quirk(hdev, HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED); break; } } @@ -339,8 +345,12 @@ static int virtbt_probe(struct virtio_device *vdev) if (virtio_has_feature(vdev, VIRTIO_BT_F_MSFT_EXT)) { __u16 msft_opcode; - virtio_cread(vdev, struct virtio_bt_config, - msft_opcode, &msft_opcode); + if (virtio_has_feature(vdev, VIRTIO_BT_F_CONFIG_V2)) + virtio_cread(vdev, struct virtio_bt_config_v2, + msft_opcode, &msft_opcode); + else + virtio_cread(vdev, struct virtio_bt_config, + msft_opcode, &msft_opcode); hci_set_msft_opcode(hdev, msft_opcode); } @@ -354,8 +364,15 @@ static int virtbt_probe(struct virtio_device *vdev) goto failed; } + virtio_device_ready(vdev); + err = virtbt_open_vdev(vbt); + if (err) + goto open_failed; + return 0; +open_failed: + hci_free_dev(hdev); failed: vdev->config->del_vqs(vdev); return err; @@ -368,6 +385,7 @@ static void virtbt_remove(struct virtio_device *vdev) hci_unregister_dev(hdev); virtio_reset_device(vdev); + virtbt_close_vdev(vbt); hci_free_dev(hdev); vbt->hdev = NULL; @@ -387,11 +405,11 @@ static const unsigned int virtbt_features[] = { VIRTIO_BT_F_VND_HCI, VIRTIO_BT_F_MSFT_EXT, VIRTIO_BT_F_AOSP_EXT, + VIRTIO_BT_F_CONFIG_V2, }; static struct virtio_driver virtbt_driver = { .driver.name = KBUILD_MODNAME, - .driver.owner = THIS_MODULE, .feature_table = virtbt_features, .feature_table_size = ARRAY_SIZE(virtbt_features), .id_table = virtbt_table, |
