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; }
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; }
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; }
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; }
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); }
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; }