NTSTATUS virtio_find_queue(VirtIODevice *vdev, unsigned index,
                           struct virtqueue **vq)
{
    u16 msix_vec = vdev_get_msix_vector(vdev, index);
    return vp_setup_vq(
        vq,
        vdev,
        index,
        msix_vec);
}
NTSTATUS virtio_find_queues(VirtIODevice *vdev,
                            unsigned nvqs,
                            struct virtqueue *vqs[])
{
    unsigned i;
    NTSTATUS status;
    u16 msix_vec;

    status = virtio_reserve_queue_memory(vdev, nvqs);
    if (!NT_SUCCESS(status)) {
        return status;
    }

    /* set up the device config interrupt */
    msix_vec = vdev_get_msix_vector(vdev, -1);

    if (msix_vec != VIRTIO_MSI_NO_VECTOR) {
        msix_vec = vdev->device->set_config_vector(vdev, msix_vec);
        /* Verify we had enough resources to assign the vector */
        if (msix_vec == VIRTIO_MSI_NO_VECTOR) {
            status = STATUS_DEVICE_BUSY;
            goto error_find;
        }
    }

    /* set up queue interrupts */
    for (i = 0; i < nvqs; i++) {
        msix_vec = vdev_get_msix_vector(vdev, i);
        status = vp_setup_vq(
            &vqs[i],
            vdev,
            i,
            msix_vec);
        if (!NT_SUCCESS(status)) {
            goto error_find;
        }
    }
    return STATUS_SUCCESS;

error_find:
    virtio_delete_queues(vdev);
    return status;
}