The sandbox virtio transport ignores notifications, so a driver that waits for the device to answer a request cannot be tested beyond its probe. The virtio-rng test works around this by writing to the used ring of the driver's virtqueue before reading.
Add sandbox_virtio_set_notify() so that a test can install a handler which is called when the driver kicks a virtqueue. The handler can then process the available ring and fill in the used ring, as a real device would. Without a handler, notifications are still ignored. Signed-off-by: Hung-Chun Tseng <[email protected]> --- Changes in v3: - New patch, needed by the next one arch/sandbox/include/asm/test.h | 25 +++++++++++++++++++++++++ drivers/virtio/virtio_sandbox.c | 15 +++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h index 043879002..d95de1095 100644 --- a/arch/sandbox/include/asm/test.h +++ b/arch/sandbox/include/asm/test.h @@ -11,6 +11,8 @@ #include <pci_ids.h> struct unit_test_state; +struct udevice; +struct virtqueue; /* The sandbox driver always permits an I2C device with this address */ #define SANDBOX_I2C_TEST_ADDR 0x59 @@ -369,4 +371,27 @@ bool sandbox_sf_bootdev_enabled(void); */ void sandbox_sf_set_enable_bootdevs(bool enable); +/** + * typedef sandbox_virtio_notify_t - Emulate the device side of a virtqueue + * + * @dev: sandbox virtio transport device + * @vq: virtqueue that was kicked + * Returns: 0 on success, or -ve error code + */ +typedef int (*sandbox_virtio_notify_t)(struct udevice *dev, + struct virtqueue *vq); + +/** + * sandbox_virtio_set_notify() - Set a handler for virtqueue notifications + * + * The sandbox virtio transport ignores notifications by default. A test can + * set a handler here to process the buffers the driver adds, like a real + * device would. + * + * @dev: sandbox virtio transport device + * @notify: handler to call, or NULL to ignore notifications again + */ +void sandbox_virtio_set_notify(struct udevice *dev, + sandbox_virtio_notify_t notify); + #endif diff --git a/drivers/virtio/virtio_sandbox.c b/drivers/virtio/virtio_sandbox.c index 0f1ebef22..3b8a4d5a6 100644 --- a/drivers/virtio/virtio_sandbox.c +++ b/drivers/virtio/virtio_sandbox.c @@ -13,6 +13,7 @@ #include <linux/compat.h> #include <linux/err.h> #include <linux/io.h> +#include <asm/test.h> struct virtio_sandbox_priv { u8 id; @@ -22,6 +23,7 @@ struct virtio_sandbox_priv { ulong queue_desc; ulong queue_available; ulong queue_used; + sandbox_virtio_notify_t notify; }; static int virtio_sandbox_get_config(struct udevice *udev, unsigned int offset, @@ -150,9 +152,22 @@ static int virtio_sandbox_find_vqs(struct udevice *udev, unsigned int nvqs, static int virtio_sandbox_notify(struct udevice *udev, struct virtqueue *vq) { + struct virtio_sandbox_priv *priv = dev_get_priv(udev); + + if (priv->notify) + return priv->notify(udev, vq); + return 0; } +void sandbox_virtio_set_notify(struct udevice *udev, + sandbox_virtio_notify_t notify) +{ + struct virtio_sandbox_priv *priv = dev_get_priv(udev); + + priv->notify = notify; +} + static int virtio_sandbox_probe(struct udevice *udev) { struct virtio_sandbox_priv *priv = dev_get_priv(udev); -- 2.43.0
