xref: /haiku/src/add-ons/kernel/busses/random/virtio/virtio_rng.cpp (revision dd2a1e350b303b855a50fd64e6cb55618be1ae6a)
1 /*
2  * Copyright 2013, Jérôme Duval, korli@users.berlios.de.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include "VirtioRNGPrivate.h"
8 
9 #include <new>
10 #include <stdlib.h>
11 #include <string.h>
12 
13 
14 #define VIRTIO_RNG_CONTROLLER_PRETTY_NAME "Virtio RNG Device"
15 
16 #define VIRTIO_RNG_DRIVER_MODULE_NAME "busses/random/virtio_rng/driver_v1"
17 #define VIRTIO_RNG_DEVICE_MODULE_NAME "busses/random/virtio_rng/device_v1"
18 
19 
20 device_manager_info *gDeviceManager;
21 random_for_controller_interface *gRandom;
22 dpc_module_info *gDPC;
23 
24 
25 //	#pragma mark -	Driver module interface
26 
27 
28 static float
29 virtio_rng_supports_device(device_node *parent)
30 {
31 	const char *bus;
32 	uint16 deviceType;
33 
34 	// make sure parent is really the Virtio bus manager
35 	if (gDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false))
36 		return -1;
37 
38 	if (strcmp(bus, "virtio"))
39 		return 0.0;
40 
41 	// check whether it's really a Virtio Entropy Device
42 	if (gDeviceManager->get_attr_uint16(parent, VIRTIO_DEVICE_TYPE_ITEM,
43 			&deviceType, true) != B_OK || deviceType != VIRTIO_DEVICE_ID_ENTROPY)
44 		return 0.0;
45 
46 	TRACE("Virtio RNG device found!\n");
47 
48 	return 0.6f;
49 }
50 
51 
52 static status_t
53 virtio_rng_register_device(device_node *parent)
54 {
55 	CALLED();
56 
57 	device_attr attrs[] = {
58 		{ NULL }
59 	};
60 
61 	return gDeviceManager->register_node(parent, VIRTIO_RNG_DRIVER_MODULE_NAME,
62 		attrs, NULL, NULL);
63 }
64 
65 
66 static status_t
67 virtio_rng_init_driver(device_node *node, void **_cookie)
68 {
69 	CALLED();
70 	VirtioRNGDevice *device =  new(std::nothrow) VirtioRNGDevice(node);
71 	if (device == NULL)
72 		return B_NO_MEMORY;
73 	status_t status = device->InitCheck();
74 	if (status < B_OK) {
75 		delete device;
76 		return status;
77 	}
78 	*_cookie = device;
79 
80 	return B_OK;
81 }
82 
83 
84 static void
85 virtio_rng_uninit_driver(void *cookie)
86 {
87 	VirtioRNGDevice *device = (VirtioRNGDevice*)cookie;
88 	delete device;
89 }
90 
91 
92 static driver_module_info sVirtioRNGDriver = {
93 	{
94 		VIRTIO_RNG_DRIVER_MODULE_NAME,
95 		0,
96 		NULL
97 	},
98 	virtio_rng_supports_device,
99 	virtio_rng_register_device,
100 	virtio_rng_init_driver,
101 	virtio_rng_uninit_driver,
102 	NULL,
103 	NULL,	// rescan
104 	NULL,	// device_removed
105 };
106 
107 
108 module_dependency module_dependencies[] = {
109 	{ B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager },
110 	{ RANDOM_FOR_CONTROLLER_MODULE_NAME, (module_info **)&gRandom },
111 	{ B_DPC_MODULE_NAME, (module_info **)&gDPC },
112 	{}
113 };
114 
115 
116 module_info *modules[] = {
117 	(module_info *)&sVirtioRNGDriver,
118 	NULL
119 };
120