static int p9_virtio_probe(struct virtio_device *vdev)
{
	__u16 tag_len;
	char *tag;
	int err;
	struct virtio_chan *chan;

	chan = kmalloc(sizeof(struct virtio_chan), GFP_KERNEL);
	if (!chan) {
		pr_err("Failed to allocate virtio 9P channel\n");
		err = -ENOMEM;
		goto fail;
	}

	chan->vdev = vdev;

	/* We expect one virtqueue, for requests. */
	chan->vq = virtio_find_single_vq(vdev, req_done, "requests");
	if (IS_ERR(chan->vq)) {
		err = PTR_ERR(chan->vq);
		goto out_free_vq;
	}
	chan->vq->vdev->priv = chan;
	spin_lock_init(&chan->lock);

	sg_init_table(chan->sg, VIRTQUEUE_NUM);

	chan->inuse = false;
	if (virtio_has_feature(vdev, VIRTIO_9P_MOUNT_TAG)) {
		virtio_cread(vdev, struct virtio_9p_config, tag_len, &tag_len);
	} else {
static int virtrng_probe(struct virtio_device *vdev)
{
	int err;

	if (vq) {
		/* We only support one device for now */
		return -EBUSY;
	}
	/* We expect a single virtqueue. */
	vq = virtio_find_single_vq(vdev, random_recv_done, "input");
	if (IS_ERR(vq)) {
		err = PTR_ERR(vq);
		vq = NULL;
		return err;
	}

	err = hwrng_register(&virtio_hwrng);
	if (err) {
		vdev->config->del_vqs(vdev);
		vq = NULL;
		return err;
	}

	return 0;
}
Exemplo n.º 3
0
static struct virtqueue *find_vq(struct virtio_device *vdev)
{
	int err;
	struct virtqueue *vq;

	vq = virtio_find_single_vq(vdev, vq_has_data, "cuda-vq");
	if (IS_ERR(vq)) {
		printk("virtio-cuda: Could not find vq");
		vq = NULL;
	}

	return vq;
}
Exemplo n.º 4
0
static int virtrng_probe(struct virtio_device *vdev)
{
	int err;

	/* We expect a single virtqueue. */
	vq = virtio_find_single_vq(vdev, random_recv_done, "input");
	if (IS_ERR(vq))
		return PTR_ERR(vq);

	err = hwrng_register(&virtio_hwrng);
	if (err) {
		vdev->config->del_vqs(vdev);
		return err;
	}

	return 0;
}
Exemplo n.º 5
0
static int p9_virtio_probe(struct virtio_device *vdev)
{
	int err;
	struct virtio_chan *chan;
	int index;

	mutex_lock(&virtio_9p_lock);
	index = chan_index++;
	chan = &channels[index];
	mutex_unlock(&virtio_9p_lock);

	if (chan_index > MAX_9P_CHAN) {
		printk(KERN_ERR "9p: virtio: Maximum channels exceeded\n");
		BUG();
		err = -ENOMEM;
		goto fail;
	}

	chan->vdev = vdev;

	
	chan->vq = virtio_find_single_vq(vdev, req_done, "requests");
	if (IS_ERR(chan->vq)) {
		err = PTR_ERR(chan->vq);
		goto out_free_vq;
	}
	chan->vq->vdev->priv = chan;
	spin_lock_init(&chan->lock);

	sg_init_table(chan->sg, VIRTQUEUE_NUM);

	chan->inuse = false;
	chan->initialized = true;
	return 0;

out_free_vq:
	vdev->config->del_vqs(vdev);
fail:
	mutex_lock(&virtio_9p_lock);
	chan_index--;
	mutex_unlock(&virtio_9p_lock);
	return err;
}
Exemplo n.º 6
0
static int probe_common(struct virtio_device *vdev)
{
	int err, index;
	struct virtrng_info *vi = NULL;

	vi = kzalloc(sizeof(struct virtrng_info), GFP_KERNEL);
	if (!vi)
		return -ENOMEM;

	vi->index = index = ida_simple_get(&rng_index_ida, 0, 0, GFP_KERNEL);
	if (index < 0) {
		err = index;
		goto err_ida;
	}
	sprintf(vi->name, "virtio_rng.%d", index);
	init_completion(&vi->have_data);

	vi->hwrng = (struct hwrng) {
		.read = virtio_read,
		.cleanup = virtio_cleanup,
		.priv = (unsigned long)vi,
		.name = vi->name,
		.quality = 1000,
	};
	vdev->priv = vi;

	/* We expect a single virtqueue. */
	vi->vq = virtio_find_single_vq(vdev, random_recv_done, "input");
	if (IS_ERR(vi->vq)) {
		err = PTR_ERR(vi->vq);
		goto err_find;
	}

	return 0;

err_find:
	ida_simple_remove(&rng_index_ida, index);
err_ida:
	kfree(vi);
	return err;
}

static void remove_common(struct virtio_device *vdev)
{
	struct virtrng_info *vi = vdev->priv;

	vi->hwrng_removed = true;
	vi->data_avail = 0;
	complete(&vi->have_data);
	vdev->config->reset(vdev);
	vi->busy = false;
	if (vi->hwrng_register_done)
		hwrng_unregister(&vi->hwrng);
	vdev->config->del_vqs(vdev);
	ida_simple_remove(&rng_index_ida, vi->index);
	kfree(vi);
}

static int virtrng_probe(struct virtio_device *vdev)
{
	return probe_common(vdev);
}

static void virtrng_remove(struct virtio_device *vdev)
{
	remove_common(vdev);
}
Exemplo n.º 7
0
static int virtio_hwkey_probe(struct virtio_device *vdev)
{
    int ret = 0;
    vqidx = 0;

    printk(KERN_INFO "virtio hwkey driver is probed\n");

    /* init virtio */
    vdev->priv = vh = kmalloc(sizeof(*vh), GFP_KERNEL);
    if (!vh) {
        return -ENOMEM;
    }
    memset(&vh->vbuf, 0x00, sizeof(vh->vbuf));

    vh->vdev = vdev;

    vh->vq = virtio_find_single_vq(vh->vdev, vq_hwkey_callback, "virtio-hwkey-vq");
    if (IS_ERR(vh->vq)) {
        ret = PTR_ERR(vh->vq);

        kfree(vh);
        vdev->priv = NULL;
        return ret;
    }

    /* enable callback */
    virtqueue_enable_cb(vh->vq);

    sg_init_table(vh->sg, MAX_BUF_COUNT);

    /* prepare the buffers */
    for (index = 0; index < MAX_BUF_COUNT; index++) {
        sg_set_buf(&vh->sg[index], &vh->vbuf[index], sizeof(EmulHwkeyEvent));

        if (err < 0) {
            printk(KERN_ERR "failed to add buffer\n");

            kfree(vh);
            vdev->priv = NULL;
            return ret;
        }
    }

    err = virtqueue_add_buf(vh->vq, vh->sg, 0,
            MAX_BUF_COUNT, (void *)MAX_BUF_COUNT, GFP_ATOMIC);

    /* register for input device */
    vh->idev = input_allocate_device();
    if (!vh->idev) {
        printk(KERN_ERR "failed to allocate a input hwkey device\n");
        ret = -1;

        kfree(vh);
        vdev->priv = NULL;
        return ret;
    }

    vh->idev->name = "Maru Virtio Hwkey";
    vh->idev->dev.parent = &(vdev->dev);

    input_set_drvdata(vh->idev, vh);
    vh->idev->open = input_hwkey_open;
    vh->idev->close = input_hwkey_close;

    vh->idev->evbit[0] = BIT_MASK(EV_KEY);
    /* to support any keycode */
    memset(vh->idev->keybit, 0xffffffff, sizeof(unsigned long) * BITS_TO_LONGS(KEY_CNT));

    ret = input_register_device(vh->idev);
    if (ret) {
        printk(KERN_ERR "input hwkey driver cannot registered\n");
        ret = -1;

        input_free_device(vh->idev);
        kfree(vh);
        vdev->priv = NULL;
        return ret;
    }

    virtqueue_kick(vh->vq);
    index = 0;

    return 0;
}