qdev: device free fixups.
[qemu.git] / hw / qdev.c
blob7b204f9517a9fce7c8a3faca96e5b11a6d5435c1
1 /*
2 * Dynamic device configuration and creation.
4 * Copyright (c) 2009 CodeSourcery
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 /* The theory here is that it should be possible to create a machine without
21 knowledge of specific devices. Historically board init routines have
22 passed a bunch of arguments to each device, requiring the board know
23 exactly which device it is dealing with. This file provides an abstract
24 API for device configuration and initialization. Devices will generally
25 inherit from a particular bus (e.g. PCI or I2C) rather than
26 this API directly. */
28 #include "net.h"
29 #include "qdev.h"
30 #include "sysemu.h"
31 #include "monitor.h"
33 /* This is a nasty hack to allow passing a NULL bus to qdev_create. */
34 static BusState *main_system_bus;
36 static DeviceInfo *device_info_list;
38 static BusState *qbus_find_recursive(BusState *bus, const char *name,
39 const BusInfo *info);
40 static BusState *qbus_find(const char *path);
42 /* Register a new device type. */
43 void qdev_register(DeviceInfo *info)
45 assert(info->size >= sizeof(DeviceState));
46 assert(!info->next);
48 info->next = device_info_list;
49 device_info_list = info;
52 static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name)
54 DeviceInfo *info;
56 /* first check device names */
57 for (info = device_info_list; info != NULL; info = info->next) {
58 if (bus_info && info->bus_info != bus_info)
59 continue;
60 if (strcmp(info->name, name) != 0)
61 continue;
62 return info;
65 /* failing that check the aliases */
66 for (info = device_info_list; info != NULL; info = info->next) {
67 if (bus_info && info->bus_info != bus_info)
68 continue;
69 if (!info->alias)
70 continue;
71 if (strcmp(info->alias, name) != 0)
72 continue;
73 return info;
75 return NULL;
78 /* Create a new device. This only initializes the device state structure
79 and allows properties to be set. qdev_init should be called to
80 initialize the actual device emulation. */
81 DeviceState *qdev_create(BusState *bus, const char *name)
83 DeviceInfo *info;
84 DeviceState *dev;
86 if (!bus) {
87 if (!main_system_bus) {
88 main_system_bus = qbus_create(&system_bus_info, NULL, "main-system-bus");
90 bus = main_system_bus;
93 info = qdev_find_info(bus->info, name);
94 if (!info) {
95 hw_error("Unknown device '%s' for bus '%s'\n", name, bus->info->name);
98 dev = qemu_mallocz(info->size);
99 dev->info = info;
100 dev->parent_bus = bus;
101 qdev_prop_set_defaults(dev, dev->info->props);
102 qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
103 qdev_prop_set_compat(dev);
104 QLIST_INSERT_HEAD(&bus->children, dev, sibling);
105 dev->state = DEV_STATE_CREATED;
106 return dev;
109 static int qdev_print_devinfo(DeviceInfo *info, char *dest, int len)
111 int pos = 0;
112 int ret;
114 ret = snprintf(dest+pos, len-pos, "name \"%s\", bus %s",
115 info->name, info->bus_info->name);
116 pos += MIN(len-pos,ret);
117 if (info->alias) {
118 ret = snprintf(dest+pos, len-pos, ", alias \"%s\"", info->alias);
119 pos += MIN(len-pos,ret);
121 if (info->desc) {
122 ret = snprintf(dest+pos, len-pos, ", desc \"%s\"", info->desc);
123 pos += MIN(len-pos,ret);
125 if (info->no_user) {
126 ret = snprintf(dest+pos, len-pos, ", no-user");
127 pos += MIN(len-pos,ret);
129 return pos;
132 static int set_property(const char *name, const char *value, void *opaque)
134 DeviceState *dev = opaque;
136 if (strcmp(name, "driver") == 0)
137 return 0;
138 if (strcmp(name, "bus") == 0)
139 return 0;
141 if (qdev_prop_parse(dev, name, value) == -1) {
142 qemu_error("can't set property \"%s\" to \"%s\" for \"%s\"\n",
143 name, value, dev->info->name);
144 return -1;
146 return 0;
149 DeviceState *qdev_device_add(QemuOpts *opts)
151 const char *driver, *path, *id;
152 DeviceInfo *info;
153 DeviceState *qdev;
154 BusState *bus;
156 driver = qemu_opt_get(opts, "driver");
157 if (!driver) {
158 qemu_error("-device: no driver specified\n");
159 return NULL;
161 if (strcmp(driver, "?") == 0) {
162 char msg[256];
163 for (info = device_info_list; info != NULL; info = info->next) {
164 qdev_print_devinfo(info, msg, sizeof(msg));
165 qemu_error("%s\n", msg);
167 return NULL;
170 /* find driver */
171 info = qdev_find_info(NULL, driver);
172 if (!info) {
173 qemu_error("Device \"%s\" not found. Try -device '?' for a list.\n",
174 driver);
175 return NULL;
177 if (info->no_user) {
178 qemu_error("device \"%s\" can't be added via command line\n",
179 info->name);
180 return NULL;
183 /* find bus */
184 path = qemu_opt_get(opts, "bus");
185 if (path != NULL) {
186 bus = qbus_find(path);
187 } else {
188 bus = qbus_find_recursive(main_system_bus, NULL, info->bus_info);
190 if (!bus) {
191 qemu_error("Did not find %s bus for %s\n",
192 path ? path : info->bus_info->name, info->name);
193 return NULL;
196 /* create device, set properties */
197 qdev = qdev_create(bus, driver);
198 id = qemu_opts_id(opts);
199 if (id) {
200 qdev->id = id;
202 if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
203 qdev_free(qdev);
204 return NULL;
206 if (qdev_init(qdev) != 0) {
207 qdev_free(qdev);
208 return NULL;
210 return qdev;
213 /* Initialize a device. Device properties should be set before calling
214 this function. IRQs and MMIO regions should be connected/mapped after
215 calling this function. */
216 int qdev_init(DeviceState *dev)
218 int rc;
220 assert(dev->state == DEV_STATE_CREATED);
221 rc = dev->info->init(dev, dev->info);
222 if (rc < 0)
223 return rc;
224 if (dev->info->reset)
225 qemu_register_reset(dev->info->reset, dev);
226 if (dev->info->vmsd)
227 vmstate_register(-1, dev->info->vmsd, dev);
228 dev->state = DEV_STATE_INITIALIZED;
229 return 0;
232 /* Unlink device from bus and free the structure. */
233 void qdev_free(DeviceState *dev)
235 BusState *bus;
237 if (dev->state == DEV_STATE_INITIALIZED) {
238 while (dev->num_child_bus) {
239 bus = QLIST_FIRST(&dev->child_bus);
240 qbus_free(bus);
242 #if 0 /* FIXME: need sane vmstate_unregister function */
243 if (dev->info->vmsd)
244 vmstate_unregister(dev->info->vmsd, dev);
245 #endif
246 if (dev->info->reset)
247 qemu_unregister_reset(dev->info->reset, dev);
249 QLIST_REMOVE(dev, sibling);
250 qemu_free(dev);
253 /* Get a character (serial) device interface. */
254 CharDriverState *qdev_init_chardev(DeviceState *dev)
256 static int next_serial;
257 static int next_virtconsole;
258 /* FIXME: This is a nasty hack that needs to go away. */
259 if (strncmp(dev->info->name, "virtio", 6) == 0) {
260 return virtcon_hds[next_virtconsole++];
261 } else {
262 return serial_hds[next_serial++];
266 BusState *qdev_get_parent_bus(DeviceState *dev)
268 return dev->parent_bus;
271 void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
273 assert(dev->num_gpio_in == 0);
274 dev->num_gpio_in = n;
275 dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
278 void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
280 assert(dev->num_gpio_out == 0);
281 dev->num_gpio_out = n;
282 dev->gpio_out = pins;
285 qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
287 assert(n >= 0 && n < dev->num_gpio_in);
288 return dev->gpio_in[n];
291 void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
293 assert(n >= 0 && n < dev->num_gpio_out);
294 dev->gpio_out[n] = pin;
297 VLANClientState *qdev_get_vlan_client(DeviceState *dev,
298 NetCanReceive *can_receive,
299 NetReceive *receive,
300 NetReceiveIOV *receive_iov,
301 NetCleanup *cleanup,
302 void *opaque)
304 NICInfo *nd = dev->nd;
305 assert(nd);
306 nd->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name, can_receive,
307 receive, receive_iov, cleanup, opaque);
308 return nd->vc;
312 void qdev_get_macaddr(DeviceState *dev, uint8_t *macaddr)
314 memcpy(macaddr, dev->nd->macaddr, 6);
317 static int next_block_unit[IF_COUNT];
319 /* Get a block device. This should only be used for single-drive devices
320 (e.g. SD/Floppy/MTD). Multi-disk devices (scsi/ide) should use the
321 appropriate bus. */
322 BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type)
324 int unit = next_block_unit[type]++;
325 DriveInfo *dinfo;
327 dinfo = drive_get(type, 0, unit);
328 return dinfo ? dinfo->bdrv : NULL;
331 BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
333 BusState *bus;
335 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
336 if (strcmp(name, bus->name) == 0) {
337 return bus;
340 return NULL;
343 static BusState *qbus_find_recursive(BusState *bus, const char *name,
344 const BusInfo *info)
346 DeviceState *dev;
347 BusState *child, *ret;
348 int match = 1;
350 if (name && (strcmp(bus->name, name) != 0)) {
351 match = 0;
353 if (info && (bus->info != info)) {
354 match = 0;
356 if (match) {
357 return bus;
360 QLIST_FOREACH(dev, &bus->children, sibling) {
361 QLIST_FOREACH(child, &dev->child_bus, sibling) {
362 ret = qbus_find_recursive(child, name, info);
363 if (ret) {
364 return ret;
368 return NULL;
371 static void qbus_list_bus(DeviceState *dev, char *dest, int len)
373 BusState *child;
374 const char *sep = " ";
375 int pos = 0;
377 pos += snprintf(dest+pos, len-pos,"child busses at \"%s\":",
378 dev->id ? dev->id : dev->info->name);
379 QLIST_FOREACH(child, &dev->child_bus, sibling) {
380 pos += snprintf(dest+pos, len-pos, "%s\"%s\"", sep, child->name);
381 sep = ", ";
385 static void qbus_list_dev(BusState *bus, char *dest, int len)
387 DeviceState *dev;
388 const char *sep = " ";
389 int pos = 0;
391 pos += snprintf(dest+pos, len-pos, "devices at \"%s\":",
392 bus->name);
393 QLIST_FOREACH(dev, &bus->children, sibling) {
394 pos += snprintf(dest+pos, len-pos, "%s\"%s\"",
395 sep, dev->info->name);
396 if (dev->id)
397 pos += snprintf(dest+pos, len-pos, "/\"%s\"", dev->id);
398 sep = ", ";
402 static BusState *qbus_find_bus(DeviceState *dev, char *elem)
404 BusState *child;
406 QLIST_FOREACH(child, &dev->child_bus, sibling) {
407 if (strcmp(child->name, elem) == 0) {
408 return child;
411 return NULL;
414 static DeviceState *qbus_find_dev(BusState *bus, char *elem)
416 DeviceState *dev;
419 * try to match in order:
420 * (1) instance id, if present
421 * (2) driver name
422 * (3) driver alias, if present
424 QLIST_FOREACH(dev, &bus->children, sibling) {
425 if (dev->id && strcmp(dev->id, elem) == 0) {
426 return dev;
429 QLIST_FOREACH(dev, &bus->children, sibling) {
430 if (strcmp(dev->info->name, elem) == 0) {
431 return dev;
434 QLIST_FOREACH(dev, &bus->children, sibling) {
435 if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) {
436 return dev;
439 return NULL;
442 static BusState *qbus_find(const char *path)
444 DeviceState *dev;
445 BusState *bus;
446 char elem[128], msg[256];
447 int pos, len;
449 /* find start element */
450 if (path[0] == '/') {
451 bus = main_system_bus;
452 pos = 0;
453 } else {
454 if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
455 qemu_error("path parse error (\"%s\")\n", path);
456 return NULL;
458 bus = qbus_find_recursive(main_system_bus, elem, NULL);
459 if (!bus) {
460 qemu_error("bus \"%s\" not found\n", elem);
461 return NULL;
463 pos = len;
466 for (;;) {
467 if (path[pos] == '\0') {
468 /* we are done */
469 return bus;
472 /* find device */
473 if (sscanf(path+pos, "/%127[^/]%n", elem, &len) != 1) {
474 qemu_error("path parse error (\"%s\" pos %d)\n", path, pos);
475 return NULL;
477 pos += len;
478 dev = qbus_find_dev(bus, elem);
479 if (!dev) {
480 qbus_list_dev(bus, msg, sizeof(msg));
481 qemu_error("device \"%s\" not found\n%s\n", elem, msg);
482 return NULL;
484 if (path[pos] == '\0') {
485 /* last specified element is a device. If it has exactly
486 * one child bus accept it nevertheless */
487 switch (dev->num_child_bus) {
488 case 0:
489 qemu_error("device has no child bus (%s)\n", path);
490 return NULL;
491 case 1:
492 return QLIST_FIRST(&dev->child_bus);
493 default:
494 qbus_list_bus(dev, msg, sizeof(msg));
495 qemu_error("device has multiple child busses (%s)\n%s\n",
496 path, msg);
497 return NULL;
501 /* find bus */
502 if (sscanf(path+pos, "/%127[^/]%n", elem, &len) != 1) {
503 qemu_error("path parse error (\"%s\" pos %d)\n", path, pos);
504 return NULL;
506 pos += len;
507 bus = qbus_find_bus(dev, elem);
508 if (!bus) {
509 qbus_list_bus(dev, msg, sizeof(msg));
510 qemu_error("child bus \"%s\" not found\n%s\n", elem, msg);
511 return NULL;
516 void qbus_create_inplace(BusState *bus, BusInfo *info,
517 DeviceState *parent, const char *name)
519 char *buf;
520 int i,len;
522 bus->info = info;
523 bus->parent = parent;
525 if (name) {
526 /* use supplied name */
527 bus->name = qemu_strdup(name);
528 } else if (parent && parent->id) {
529 /* parent device has id -> use it for bus name */
530 len = strlen(parent->id) + 16;
531 buf = qemu_malloc(len);
532 snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
533 bus->name = buf;
534 } else {
535 /* no id -> use lowercase bus type for bus name */
536 len = strlen(info->name) + 16;
537 buf = qemu_malloc(len);
538 len = snprintf(buf, len, "%s.%d", info->name,
539 parent ? parent->num_child_bus : 0);
540 for (i = 0; i < len; i++)
541 buf[i] = qemu_tolower(buf[i]);
542 bus->name = buf;
545 QLIST_INIT(&bus->children);
546 if (parent) {
547 QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
548 parent->num_child_bus++;
553 BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
555 BusState *bus;
557 bus = qemu_mallocz(info->size);
558 bus->qdev_allocated = 1;
559 qbus_create_inplace(bus, info, parent, name);
560 return bus;
563 void qbus_free(BusState *bus)
565 DeviceState *dev;
567 while ((dev = QLIST_FIRST(&bus->children)) != NULL) {
568 qdev_free(dev);
570 if (bus->parent) {
571 QLIST_REMOVE(bus, sibling);
572 bus->parent->num_child_bus--;
574 if (bus->qdev_allocated) {
575 qemu_free(bus);
579 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
580 static void qbus_print(Monitor *mon, BusState *bus, int indent);
582 static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
583 const char *prefix, int indent)
585 char buf[64];
587 if (!props)
588 return;
589 while (props->name) {
590 if (props->info->print) {
591 props->info->print(dev, props, buf, sizeof(buf));
592 qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
594 props++;
598 static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
600 BusState *child;
601 qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
602 dev->id ? dev->id : "");
603 indent += 2;
604 if (dev->num_gpio_in) {
605 qdev_printf("gpio-in %d\n", dev->num_gpio_in);
607 if (dev->num_gpio_out) {
608 qdev_printf("gpio-out %d\n", dev->num_gpio_out);
610 qdev_print_props(mon, dev, dev->info->props, "dev", indent);
611 qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
612 if (dev->parent_bus->info->print_dev)
613 dev->parent_bus->info->print_dev(mon, dev, indent);
614 QLIST_FOREACH(child, &dev->child_bus, sibling) {
615 qbus_print(mon, child, indent);
619 static void qbus_print(Monitor *mon, BusState *bus, int indent)
621 struct DeviceState *dev;
623 qdev_printf("bus: %s\n", bus->name);
624 indent += 2;
625 qdev_printf("type %s\n", bus->info->name);
626 QLIST_FOREACH(dev, &bus->children, sibling) {
627 qdev_print(mon, dev, indent);
630 #undef qdev_printf
632 void do_info_qtree(Monitor *mon)
634 if (main_system_bus)
635 qbus_print(mon, main_system_bus, 0);
638 void do_info_qdm(Monitor *mon)
640 DeviceInfo *info;
641 char msg[256];
643 for (info = device_info_list; info != NULL; info = info->next) {
644 qdev_print_devinfo(info, msg, sizeof(msg));
645 monitor_printf(mon, "%s\n", msg);