The rng, net, blk and scsi drivers all use virtio_reset() as their remove() method.
virtio_reset() only uses the transport's reset() operation, leaving the virtual queues still allocated (12 KB per virtqueue). Every probe/remove cycle of a virtio device therefore fails to free its queues. Add a remove() method to delete the queues before resetting. Update the four drivers to use it. Signed-off-by: Simon Glass <[email protected]> --- drivers/virtio/virtio-uclass.c | 7 +++++++ drivers/virtio/virtio_blk.c | 2 +- drivers/virtio/virtio_net.c | 2 +- drivers/virtio/virtio_rng.c | 2 +- include/virtio.h | 8 ++++++++ 5 files changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/virtio/virtio-uclass.c b/drivers/virtio/virtio-uclass.c index 7003f30cb85..532d50ea088 100644 --- a/drivers/virtio/virtio-uclass.c +++ b/drivers/virtio/virtio-uclass.c @@ -90,6 +90,13 @@ int virtio_reset(struct udevice *vdev) return ops->reset(vdev->parent); } +int virtio_remove(struct udevice *vdev) +{ + virtio_del_vqs(vdev); + + return virtio_reset(vdev); +} + int virtio_get_features(struct udevice *vdev, u64 *features) { struct dm_virtio_ops *ops; diff --git a/drivers/virtio/virtio_blk.c b/drivers/virtio/virtio_blk.c index 404d9140cb2..fe06135a7ac 100644 --- a/drivers/virtio/virtio_blk.c +++ b/drivers/virtio/virtio_blk.c @@ -296,7 +296,7 @@ U_BOOT_DRIVER(virtio_blk) = { .ops = &virtio_blk_ops, .bind = virtio_blk_bind, .probe = virtio_blk_probe, - .remove = virtio_reset, + .remove = virtio_remove, .priv_auto = sizeof(struct virtio_blk_priv), .flags = DM_FLAG_ACTIVE_DMA, }; diff --git a/drivers/virtio/virtio_net.c b/drivers/virtio/virtio_net.c index 7a94c8a528f..d49dab3a6ed 100644 --- a/drivers/virtio/virtio_net.c +++ b/drivers/virtio/virtio_net.c @@ -233,7 +233,7 @@ U_BOOT_DRIVER(virtio_net) = { .id = UCLASS_ETH, .bind = virtio_net_bind, .probe = virtio_net_probe, - .remove = virtio_reset, + .remove = virtio_remove, .ops = &virtio_net_ops, .priv_auto = sizeof(struct virtio_net_priv), .plat_auto = sizeof(struct eth_pdata), diff --git a/drivers/virtio/virtio_rng.c b/drivers/virtio/virtio_rng.c index c6de62142bb..9a5db5f3930 100644 --- a/drivers/virtio/virtio_rng.c +++ b/drivers/virtio/virtio_rng.c @@ -89,7 +89,7 @@ U_BOOT_DRIVER(virtio_rng) = { .id = UCLASS_RNG, .bind = virtio_rng_bind, .probe = virtio_rng_probe, - .remove = virtio_reset, + .remove = virtio_remove, .ops = &virtio_rng_ops, .priv_auto = sizeof(struct virtio_rng_priv), .flags = DM_FLAG_ACTIVE_DMA, diff --git a/include/virtio.h b/include/virtio.h index 3edf023463d..5c580e59779 100644 --- a/include/virtio.h +++ b/include/virtio.h @@ -285,6 +285,14 @@ int virtio_set_status(struct udevice *vdev, u8 status); */ int virtio_reset(struct udevice *vdev); +/** + * virtio_remove() - remove a virtio device by deleting its vqs and resetting it + * + * @vdev: the real virtio device + * Return: 0 if OK, -ve on error + */ +int virtio_remove(struct udevice *vdev); + /** * virtio_get_features() - get the array of feature bits for this device * -- 2.43.0

