[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH 11/12] plat/drivers: Handle responses from backend for virtio block
This patch introduces the function responsible of processing responses from the queue. Responses are popped out from queue until there is nothing to process. Signed-off-by: Roxana Nicolescu <nicolescu.roxana1996@xxxxxxxxx> --- plat/drivers/include/virtio/virtio_blk.h | 4 ++ plat/drivers/virtio/virtio_blk.c | 82 ++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/plat/drivers/include/virtio/virtio_blk.h b/plat/drivers/include/virtio/virtio_blk.h index e2d28928..1b8dffd3 100644 --- a/plat/drivers/include/virtio/virtio_blk.h +++ b/plat/drivers/include/virtio/virtio_blk.h @@ -39,6 +39,10 @@ /* Device supports multi-queues */ #define VIRTIO_BLK_F_MQ 12 +/* Response status */ +#define VIRTIO_BLK_S_OK 0 +#define VIRTIO_BLK_S_IOERR 1 +#define VIRTIO_BLK_S_UNSUPP 2 struct virtio_blk_config { /* Dimension in sectors number */ diff --git a/plat/drivers/virtio/virtio_blk.c b/plat/drivers/virtio/virtio_blk.c index 5b8972cf..a1d2bd68 100644 --- a/plat/drivers/virtio/virtio_blk.c +++ b/plat/drivers/virtio/virtio_blk.c @@ -324,6 +324,87 @@ err: return rc; } +static int virtio_blkdev_queue_dequeue(struct uk_blkdev_queue *queue, + struct uk_blkdev_request **req) +{ + int ret = 0; + __u32 len; + struct uk_blkdev_request *response_req = NULL; + + UK_ASSERT(req); + ret = virtqueue_buffer_dequeue(queue->vq, (void **) &response_req, + &len); + if (ret < 0) { + uk_pr_info("No data available in the queue\n"); + ret = 0; + goto out; + } + + /* We need at least one byte for the result status */ + if (unlikely(len < 1)) { + uk_pr_err("Received invalid response size: %u\n", len); + return -EINVAL; + } + +out: + *req = response_req; + return ret; +} + +static int virtio_blkdev_complete_reqs(struct uk_blkdev *dev, + uint16_t queue_id) +{ + struct virtio_blk_device *vbdev; + struct uk_blkdev_queue *queue; + struct uk_blkdev_request *req; + int rc = 0; + + UK_ASSERT(dev); + + vbdev = to_virtioblkdev(dev); + if (unlikely(queue_id >= vbdev->nb_queues)) { + uk_pr_err("Invalid queue_id %"__PRIu16"\n", queue_id); + return -EINVAL; + } + + queue = &vbdev->qs[queue_id]; + + /* Queue interrupts have to be off when calling receive */ + UK_ASSERT(!(queue->intr_enabled & VTBLK_INTR_EN)); + +moretodo: + for (;;) { + rc = virtio_blkdev_queue_dequeue(queue, &req); + if (unlikely(rc < 0)) { + uk_pr_err("Failed to dequeue the request: %d\n", rc); + goto err_exit; + } + + if (!req) + break; + + uk_refcount_release(&req->state); + if (req->cb) { + rc = req->cb(req, req->cookie_callback); + if (rc) { + uk_pr_err("Callback failed %d\n", rc); + goto err_exit; + } + } + } + + /* Enable interrupt only when user had previously enabled it */ + if (queue->intr_enabled & VTBLK_INTR_USR_EN_MASK) { + rc = virtqueue_intr_enable(queue->vq); + if (rc == 1) + goto moretodo; + } + + return 0; + +err_exit: + return rc; +} static int virtio_blkdev_recv_done(struct virtqueue *vq, void *priv) { @@ -814,6 +895,7 @@ static int virtio_blk_add_dev(struct virtio_dev *vdev) return -ENOMEM; vbdev->vdev = vdev; + vbdev->blkdev.finish_reqs = virtio_blkdev_complete_reqs; vbdev->blkdev.submit_one = virtio_blkdev_submit_request; vbdev->blkdev.dev_ops = &virtio_blkdev_ops; -- 2.11.0 _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |