41 |
41 |
DeviceProperty *next;
|
42 |
42 |
};
|
43 |
43 |
|
44 |
|
struct DeviceType {
|
45 |
|
DeviceInfo *info;
|
46 |
|
DeviceType *next;
|
47 |
|
};
|
48 |
|
|
49 |
44 |
/* This is a nasty hack to allow passing a NULL bus to qdev_create. */
|
50 |
45 |
static BusState *main_system_bus;
|
51 |
46 |
extern struct BusInfo system_bus_info;
|
52 |
47 |
|
53 |
|
static DeviceType *device_type_list;
|
|
48 |
static DeviceInfo *device_info_list;
|
54 |
49 |
|
55 |
50 |
/* Register a new device type. */
|
56 |
51 |
void qdev_register(DeviceInfo *info)
|
57 |
52 |
{
|
58 |
|
DeviceType *t;
|
59 |
|
|
60 |
53 |
assert(info->size >= sizeof(DeviceState));
|
|
54 |
assert(!info->next);
|
61 |
55 |
|
62 |
|
t = qemu_mallocz(sizeof(DeviceType));
|
63 |
|
t->next = device_type_list;
|
64 |
|
device_type_list = t;
|
65 |
|
t->info = info;
|
|
56 |
info->next = device_info_list;
|
|
57 |
device_info_list = info;
|
66 |
58 |
}
|
67 |
59 |
|
68 |
60 |
/* Create a new device. This only initializes the device state structure
|
... | ... | |
70 |
62 |
initialize the actual device emulation. */
|
71 |
63 |
DeviceState *qdev_create(BusState *bus, const char *name)
|
72 |
64 |
{
|
73 |
|
DeviceType *t;
|
|
65 |
DeviceInfo *info;
|
74 |
66 |
DeviceState *dev;
|
75 |
67 |
|
76 |
68 |
if (!bus) {
|
... | ... | |
80 |
72 |
bus = main_system_bus;
|
81 |
73 |
}
|
82 |
74 |
|
83 |
|
for (t = device_type_list; t; t = t->next) {
|
84 |
|
if (t->info->bus_info != bus->info)
|
|
75 |
for (info = device_info_list; info != NULL; info = info->next) {
|
|
76 |
if (info->bus_info != bus->info)
|
85 |
77 |
continue;
|
86 |
|
if (strcmp(t->info->name, name) != 0)
|
|
78 |
if (strcmp(info->name, name) != 0)
|
87 |
79 |
continue;
|
88 |
80 |
break;
|
89 |
81 |
}
|
90 |
|
if (!t) {
|
|
82 |
if (!info) {
|
91 |
83 |
hw_error("Unknown device '%s' for bus '%s'\n", name, bus->info->name);
|
92 |
84 |
}
|
93 |
85 |
|
94 |
|
dev = qemu_mallocz(t->info->size);
|
95 |
|
dev->type = t;
|
|
86 |
dev = qemu_mallocz(info->size);
|
|
87 |
dev->info = info;
|
96 |
88 |
dev->parent_bus = bus;
|
97 |
89 |
LIST_INSERT_HEAD(&bus->children, dev, sibling);
|
98 |
90 |
return dev;
|
... | ... | |
103 |
95 |
calling this function. */
|
104 |
96 |
void qdev_init(DeviceState *dev)
|
105 |
97 |
{
|
106 |
|
dev->type->info->init(dev, dev->type->info);
|
|
98 |
dev->info->init(dev, dev->info);
|
107 |
99 |
}
|
108 |
100 |
|
109 |
101 |
/* Unlink device from bus and free the structure. */
|
... | ... | |
165 |
157 |
static int next_serial;
|
166 |
158 |
static int next_virtconsole;
|
167 |
159 |
/* FIXME: This is a nasty hack that needs to go away. */
|
168 |
|
if (strncmp(dev->type->info->name, "virtio", 6) == 0) {
|
|
160 |
if (strncmp(dev->info->name, "virtio", 6) == 0) {
|
169 |
161 |
return virtcon_hds[next_virtconsole++];
|
170 |
162 |
} else {
|
171 |
163 |
return serial_hds[next_serial++];
|
... | ... | |
338 |
330 |
{
|
339 |
331 |
DeviceProperty *prop;
|
340 |
332 |
BusState *child;
|
341 |
|
qdev_printf("dev: %s\n", dev->type->info->name);
|
|
333 |
qdev_printf("dev: %s\n", dev->info->name);
|
342 |
334 |
indent += 2;
|
343 |
335 |
if (dev->num_gpio_in) {
|
344 |
336 |
qdev_printf("gpio-in %d\n", dev->num_gpio_in);
|
... | ... | |
357 |
349 |
break;
|
358 |
350 |
case PROP_TYPE_DEV:
|
359 |
351 |
qdev_printf("prop-dev %s %s\n", prop->name,
|
360 |
|
((DeviceState *)prop->value.ptr)->type->info->name);
|
|
352 |
((DeviceState *)prop->value.ptr)->info->name);
|
361 |
353 |
break;
|
362 |
354 |
default:
|
363 |
355 |
qdev_printf("prop-unknown%d %s\n", prop->type, prop->name);
|