virtio-loopback-adapter: Update adapter recipe for sound and GPIO Yocto builds
[AGL/meta-agl-devel.git] / meta-egvirt / recipes-kernel / linux / linux-yocto-5.18 / 0002-Bluetooth-virtio_bt-fix-device-removal.patch
1 From b26cba86bfa2f29841279d7d3950cf1d4db0e6af Mon Sep 17 00:00:00 2001
2 From: "Michael S. Tsirkin" <mst@redhat.com>
3 Date: Thu, 25 Nov 2021 12:44:48 -0500
4 Subject: [PATCH] Bluetooth: virtio_bt: fix device removal
5
6 Device removal is clearly out of virtio spec: it attempts to remove
7 unused buffers from a VQ before invoking device reset. To fix, make
8 open/close NOPs and do all cleanup/setup in probe/remove.
9
10 The cost here is a single skb wasted on an unused bt device - which
11 seems modest.
12
13 NB: with this fix in place driver still suffers from a race condition if
14 an interrupt triggers while device is being reset. Work on a fix for
15 that issue is in progress.
16
17 Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
18 Upstream-Status: Submitted [https://lore.kernel.org/all/20211125174200.133230-1-mst@redhat.com/]
19 ---
20  drivers/bluetooth/virtio_bt.c | 18 ++++++++++++++++--
21  1 file changed, 16 insertions(+), 2 deletions(-)
22
23 diff --git a/drivers/bluetooth/virtio_bt.c b/drivers/bluetooth/virtio_bt.c
24 index 67c21263f9e0..1dd734aef87b 100644
25 --- a/drivers/bluetooth/virtio_bt.c
26 +++ b/drivers/bluetooth/virtio_bt.c
27 @@ -50,8 +50,11 @@ static int virtbt_add_inbuf(struct virtio_bluetooth *vbt)
28  
29  static int virtbt_open(struct hci_dev *hdev)
30  {
31 -       struct virtio_bluetooth *vbt = hci_get_drvdata(hdev);
32 +       return 0;
33 +}
34  
35 +static int virtbt_open_vdev(struct virtio_bluetooth *vbt)
36 +{
37         if (virtbt_add_inbuf(vbt) < 0)
38                 return -EIO;
39  
40 @@ -61,7 +64,11 @@ static int virtbt_open(struct hci_dev *hdev)
41  
42  static int virtbt_close(struct hci_dev *hdev)
43  {
44 -       struct virtio_bluetooth *vbt = hci_get_drvdata(hdev);
45 +       return 0;
46 +}
47 +
48 +static int virtbt_close_vdev(struct virtio_bluetooth *vbt)
49 +{
50         int i;
51  
52         cancel_work_sync(&vbt->rx);
53 @@ -354,8 +361,14 @@ static int virtbt_probe(struct virtio_device *vdev)
54                 goto failed;
55         }
56  
57 +       virtio_device_ready(vdev);
58 +       if (virtbt_open_vdev(vbt))
59 +               goto open_failed;
60 +
61         return 0;
62  
63 +open_failed:
64 +       hci_free_dev(hdev);
65  failed:
66         vdev->config->del_vqs(vdev);
67         return err;
68 @@ -368,6 +381,7 @@ static void virtbt_remove(struct virtio_device *vdev)
69  
70         hci_unregister_dev(hdev);
71         virtio_reset_device(vdev);
72 +       virtbt_close_vdev(vbt);
73  
74         hci_free_dev(hdev);
75         vbt->hdev = NULL;
76 -- 
77 2.37.1
78