xref: /haiku/src/add-ons/kernel/bus_managers/virtio/virtio_balloon.cpp (revision c237c4ce593ee823d9867fd997e51e4c447f5623)
1 /*
2  * Copyright 2018, Jérôme Duval, jerome.duval@gmail.com.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include "VirtioBalloonPrivate.h"
8 
9 #include <new>
10 #include <stdlib.h>
11 #include <string.h>
12 
13 
14 #define VIRTIO_BALLOON_CONTROLLER_PRETTY_NAME "Virtio Balloon Device"
15 
16 #define VIRTIO_BALLOON_DRIVER_MODULE_NAME "drivers/misc/virtio_balloon/driver_v1"
17 #define VIRTIO_BALLOON_DEVICE_MODULE_NAME "drivers/misc/virtio_balloon/device_v1"
18 
19 
20 extern device_manager_info *gDeviceManager;
21 
22 
23 //	#pragma mark - Device module interface
24 
25 
26 static status_t
27 virtio_balloon_init_device(device_node *node, void **_cookie)
28 {
29 	CALLED();
30 
31 	VirtioBalloonDevice *device =  new(std::nothrow)
32 		VirtioBalloonDevice(node);
33 	if (device == NULL)
34 		return B_NO_MEMORY;
35 	status_t status = device->InitCheck();
36 	if (status < B_OK) {
37 		delete device;
38 		return status;
39 	}
40 
41 	*_cookie = device;
42 	return B_OK;
43 }
44 
45 
46 static void
47 virtio_balloon_uninit_device(void *cookie)
48 {
49 	CALLED();
50 	VirtioBalloonDevice *device = (VirtioBalloonDevice*)cookie;
51 
52 	delete device;
53 }
54 
55 
56 //	#pragma mark -	Driver module interface
57 
58 
59 static float
60 virtio_balloon_supports_device(device_node *parent)
61 {
62 	const char *bus;
63 	uint16 deviceType;
64 
65 	// make sure parent is really the Virtio bus manager
66 	if (gDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false))
67 		return -1;
68 
69 	if (strcmp(bus, "virtio"))
70 		return 0.0;
71 
72 	// check whether it's really a Virtio Entropy Device
73 	if (gDeviceManager->get_attr_uint16(parent, VIRTIO_DEVICE_TYPE_ITEM,
74 			&deviceType, true) != B_OK || deviceType != VIRTIO_DEVICE_ID_BALLOON)
75 		return 0.0;
76 
77 	TRACE("Virtio Balloon device found!\n");
78 
79 	return 0.6f;
80 }
81 
82 
83 static status_t
84 virtio_balloon_register_device(device_node *parent)
85 {
86 	CALLED();
87 
88 	device_attr attrs[] = {
89 		{ NULL }
90 	};
91 
92 	return gDeviceManager->register_node(parent, VIRTIO_BALLOON_DRIVER_MODULE_NAME,
93 		attrs, NULL, NULL);
94 }
95 
96 
97 static status_t
98 virtio_balloon_init_driver(device_node *node, void **_cookie)
99 {
100 	CALLED();
101 	*_cookie = node;
102 	return B_OK;
103 }
104 
105 
106 static status_t
107 virtio_balloon_register_child_devices(void *cookie)
108 {
109 	CALLED();
110 	device_node *node = (device_node *)cookie;
111 
112 	device_attr attrs[] = {
113 		{ B_DEVICE_PRETTY_NAME, B_STRING_TYPE,
114 			{ .string = VIRTIO_BALLOON_CONTROLLER_PRETTY_NAME }},
115 		{ NULL }
116 	};
117 
118 	return gDeviceManager->register_node(node,
119 		VIRTIO_BALLOON_DEVICE_MODULE_NAME, attrs, NULL, NULL);
120 }
121 
122 
123 static status_t
124 std_ops(int32 op, ...)
125 {
126 	switch (op) {
127 		case B_MODULE_INIT:
128 		case B_MODULE_UNINIT:
129 			return B_OK;
130 
131 		default:
132 			return B_ERROR;
133 	}
134 }
135 
136 
137 driver_module_info sVirtioBalloonDeviceInterface = {
138 	{
139 		VIRTIO_BALLOON_DEVICE_MODULE_NAME,
140 		0,
141 		std_ops
142 	},
143 	NULL,	// supported devices
144 	NULL,	// register node
145 	virtio_balloon_init_device,
146 	virtio_balloon_uninit_device,
147 	NULL,	// register child devices
148 	NULL,	// rescan
149 	NULL	// bus_removed
150 };
151 
152 
153 driver_module_info sVirtioBalloonDriver = {
154 	{
155 		VIRTIO_BALLOON_DRIVER_MODULE_NAME,
156 		0,
157 		std_ops
158 	},
159 	virtio_balloon_supports_device,
160 	virtio_balloon_register_device,
161 	virtio_balloon_init_driver,
162 	NULL,	// uninit_driver,
163 	virtio_balloon_register_child_devices,
164 	NULL,	// rescan
165 	NULL,	// device_removed
166 };
167 
168