static int virtio_mem_probe()

in virtio_mem.c [2758:2807]


static int virtio_mem_probe(struct virtio_device *vdev)
{
	struct virtio_mem *vm;
	int rc;

	BUILD_BUG_ON(sizeof(struct virtio_mem_req) != 24);
	BUILD_BUG_ON(sizeof(struct virtio_mem_resp) != 10);

	vdev->priv = vm = kzalloc(sizeof(*vm), GFP_KERNEL);
	if (!vm)
		return -ENOMEM;

	init_waitqueue_head(&vm->host_resp);
	vm->vdev = vdev;
	INIT_WORK(&vm->wq, virtio_mem_run_wq);
	mutex_init(&vm->hotplug_mutex);
	INIT_LIST_HEAD(&vm->next);
	spin_lock_init(&vm->removal_lock);
	hrtimer_init(&vm->retry_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	vm->retry_timer.function = virtio_mem_timer_expired;
	vm->retry_timer_ms = VIRTIO_MEM_RETRY_TIMER_MIN_MS;
	vm->in_kdump = is_kdump_kernel();

	/* register the virtqueue */
	rc = virtio_mem_init_vq(vm);
	if (rc)
		goto out_free_vm;

	/* initialize the device by querying the config */
	rc = virtio_mem_init(vm);
	if (rc)
		goto out_del_vq;

	virtio_device_ready(vdev);

	/* trigger a config update to start processing the requested_size */
	if (!vm->in_kdump) {
		atomic_set(&vm->config_changed, 1);
		queue_work(system_freezable_wq, &vm->wq);
	}

	return 0;
out_del_vq:
	vdev->config->del_vqs(vdev);
out_free_vm:
	kfree(vm);
	vdev->priv = NULL;

	return rc;
}