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
20extern device_manager_info *gDeviceManager;
21
22
23//	#pragma mark - Device module interface
24
25
26static status_t
27virtio_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
46static void
47virtio_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
59static float
60virtio_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
83static status_t
84virtio_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
97static status_t
98virtio_balloon_init_driver(device_node *node, void **_cookie)
99{
100	CALLED();
101	*_cookie = node;
102	return B_OK;
103}
104
105
106static status_t
107virtio_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
123static status_t
124std_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
137driver_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
153driver_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