]> git.proxmox.com Git - mirror_qemu.git/blame - hw/qdev.c
pcnet APROMWE bit location (retry)
[mirror_qemu.git] / hw / qdev.c
CommitLineData
aae9460e
PB
1/*
2 * Dynamic device configuration and creation.
3 *
4 * Copyright (c) 2009 CodeSourcery
5 *
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.
10 *
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.
15 *
16 * You should have received a copy of the GNU Lesser General Public
8167ee88 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
aae9460e
PB
18 */
19
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. */
27
9d07d757 28#include "net.h"
aae9460e
PB
29#include "qdev.h"
30#include "sysemu.h"
cae4956e 31#include "monitor.h"
3ced9f7a 32#include "qerror.h"
aae9460e 33
3418bd25
GH
34static int qdev_hotplug = 0;
35
cdaed7c7 36/* This is a nasty hack to allow passing a NULL bus to qdev_create. */
b9aaf7f8 37static BusState *main_system_bus;
4d6ae674 38
0958b4cc 39DeviceInfo *device_info_list;
aae9460e 40
8ffb1bcf
GH
41static BusState *qbus_find_recursive(BusState *bus, const char *name,
42 const BusInfo *info);
43static BusState *qbus_find(const char *path);
44
aae9460e 45/* Register a new device type. */
074f2fff 46void qdev_register(DeviceInfo *info)
aae9460e 47{
074f2fff 48 assert(info->size >= sizeof(DeviceState));
042f84d0 49 assert(!info->next);
aae9460e 50
042f84d0
GH
51 info->next = device_info_list;
52 device_info_list = info;
aae9460e
PB
53}
54
81ebb98b
GH
55static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name)
56{
57 DeviceInfo *info;
58
3320e56e 59 /* first check device names */
81ebb98b
GH
60 for (info = device_info_list; info != NULL; info = info->next) {
61 if (bus_info && info->bus_info != bus_info)
62 continue;
63 if (strcmp(info->name, name) != 0)
64 continue;
65 return info;
66 }
3320e56e
GH
67
68 /* failing that check the aliases */
69 for (info = device_info_list; info != NULL; info = info->next) {
70 if (bus_info && info->bus_info != bus_info)
71 continue;
72 if (!info->alias)
73 continue;
74 if (strcmp(info->alias, name) != 0)
75 continue;
76 return info;
77 }
81ebb98b
GH
78 return NULL;
79}
80
aae9460e
PB
81/* Create a new device. This only initializes the device state structure
82 and allows properties to be set. qdev_init should be called to
83 initialize the actual device emulation. */
02e2da45 84DeviceState *qdev_create(BusState *bus, const char *name)
aae9460e 85{
042f84d0 86 DeviceInfo *info;
aae9460e
PB
87 DeviceState *dev;
88
10c4c98a
GH
89 if (!bus) {
90 if (!main_system_bus) {
91 main_system_bus = qbus_create(&system_bus_info, NULL, "main-system-bus");
aae9460e 92 }
10c4c98a
GH
93 bus = main_system_bus;
94 }
95
81ebb98b 96 info = qdev_find_info(bus->info, name);
042f84d0 97 if (!info) {
10c4c98a 98 hw_error("Unknown device '%s' for bus '%s'\n", name, bus->info->name);
aae9460e
PB
99 }
100
042f84d0
GH
101 dev = qemu_mallocz(info->size);
102 dev->info = info;
02e2da45 103 dev->parent_bus = bus;
ee6847d1
GH
104 qdev_prop_set_defaults(dev, dev->info->props);
105 qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
458fb679 106 qdev_prop_set_globals(dev);
72cf2d4f 107 QLIST_INSERT_HEAD(&bus->children, dev, sibling);
3418bd25
GH
108 if (qdev_hotplug) {
109 assert(bus->allow_hotplug);
110 dev->hotplugged = 1;
111 }
131ec1bd 112 dev->state = DEV_STATE_CREATED;
aae9460e
PB
113 return dev;
114}
115
1b524b04
GH
116static int qdev_print_devinfo(DeviceInfo *info, char *dest, int len)
117{
118 int pos = 0;
22f2e344
GH
119 int ret;
120
121 ret = snprintf(dest+pos, len-pos, "name \"%s\", bus %s",
122 info->name, info->bus_info->name);
123 pos += MIN(len-pos,ret);
124 if (info->alias) {
125 ret = snprintf(dest+pos, len-pos, ", alias \"%s\"", info->alias);
126 pos += MIN(len-pos,ret);
127 }
128 if (info->desc) {
129 ret = snprintf(dest+pos, len-pos, ", desc \"%s\"", info->desc);
130 pos += MIN(len-pos,ret);
131 }
132 if (info->no_user) {
133 ret = snprintf(dest+pos, len-pos, ", no-user");
134 pos += MIN(len-pos,ret);
135 }
1b524b04
GH
136 return pos;
137}
138
f31d07d1 139static int set_property(const char *name, const char *value, void *opaque)
8ffb1bcf 140{
f31d07d1
GH
141 DeviceState *dev = opaque;
142
143 if (strcmp(name, "driver") == 0)
144 return 0;
145 if (strcmp(name, "bus") == 0)
146 return 0;
147
3df04ac3 148 if (qdev_prop_parse(dev, name, value) == -1) {
286c2321
GH
149 qemu_error("can't set property \"%s\" to \"%s\" for \"%s\"\n",
150 name, value, dev->info->name);
f31d07d1
GH
151 return -1;
152 }
153 return 0;
154}
155
ff952ba2
MA
156int qdev_device_help(QemuOpts *opts)
157{
158 const char *driver;
159 DeviceInfo *info;
160 char msg[256];
08350cf0 161 Property *prop;
ff952ba2
MA
162
163 driver = qemu_opt_get(opts, "driver");
164 if (driver && !strcmp(driver, "?")) {
165 for (info = device_info_list; info != NULL; info = info->next) {
166 qdev_print_devinfo(info, msg, sizeof(msg));
167 qemu_error("%s\n", msg);
168 }
169 return 1;
170 }
171
08350cf0
MA
172 if (!qemu_opt_get(opts, "?")) {
173 return 0;
174 }
175
176 info = qdev_find_info(NULL, driver);
177 if (!info) {
178 return 0;
179 }
180
181 for (prop = info->props; prop && prop->name; prop++) {
117f8eb8 182 qemu_error("%s.%s=%s\n", info->name, prop->name, prop->info->name);
08350cf0
MA
183 }
184 return 1;
ff952ba2
MA
185}
186
f31d07d1
GH
187DeviceState *qdev_device_add(QemuOpts *opts)
188{
189 const char *driver, *path, *id;
8ffb1bcf
GH
190 DeviceInfo *info;
191 DeviceState *qdev;
192 BusState *bus;
8ffb1bcf 193
f31d07d1
GH
194 driver = qemu_opt_get(opts, "driver");
195 if (!driver) {
286c2321 196 qemu_error("-device: no driver specified\n");
8ffb1bcf
GH
197 return NULL;
198 }
f31d07d1
GH
199
200 /* find driver */
8ffb1bcf
GH
201 info = qdev_find_info(NULL, driver);
202 if (!info) {
3ced9f7a 203 qemu_error_new(QERR_DEVICE_NOT_FOUND, driver);
8ffb1bcf
GH
204 return NULL;
205 }
206 if (info->no_user) {
286c2321
GH
207 qemu_error("device \"%s\" can't be added via command line\n",
208 info->name);
8ffb1bcf
GH
209 return NULL;
210 }
211
f31d07d1
GH
212 /* find bus */
213 path = qemu_opt_get(opts, "bus");
214 if (path != NULL) {
8ffb1bcf 215 bus = qbus_find(path);
8ffb1bcf
GH
216 } else {
217 bus = qbus_find_recursive(main_system_bus, NULL, info->bus_info);
8ffb1bcf 218 }
75570088
GH
219 if (!bus) {
220 qemu_error("Did not find %s bus for %s\n",
221 path ? path : info->bus_info->name, info->name);
f31d07d1 222 return NULL;
75570088 223 }
3418bd25
GH
224 if (qdev_hotplug && !bus->allow_hotplug) {
225 qemu_error("Bus %s does not support hotplugging\n",
226 bus->name);
227 return NULL;
228 }
8ffb1bcf 229
f31d07d1
GH
230 /* create device, set properties */
231 qdev = qdev_create(bus, driver);
232 id = qemu_opts_id(opts);
233 if (id) {
234 qdev->id = id;
235 }
236 if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
237 qdev_free(qdev);
238 return NULL;
8ffb1bcf 239 }
5c17ca25 240 if (qdev_init(qdev) < 0) {
c8cd1fcd 241 qemu_error("Error initializing device %s\n", driver);
81a322d4
GH
242 return NULL;
243 }
ef80b466 244 qdev->opts = opts;
8ffb1bcf
GH
245 return qdev;
246}
247
7f23f812
MT
248static void qdev_reset(void *opaque)
249{
250 DeviceState *dev = opaque;
251 if (dev->info->reset)
252 dev->info->reset(dev);
253}
254
aae9460e
PB
255/* Initialize a device. Device properties should be set before calling
256 this function. IRQs and MMIO regions should be connected/mapped after
18cfeb52
MA
257 calling this function.
258 On failure, destroy the device and return negative value.
259 Return 0 on success. */
81a322d4 260int qdev_init(DeviceState *dev)
aae9460e 261{
959f733a
GH
262 int rc;
263
131ec1bd 264 assert(dev->state == DEV_STATE_CREATED);
959f733a 265 rc = dev->info->init(dev, dev->info);
18cfeb52
MA
266 if (rc < 0) {
267 qdev_free(dev);
959f733a 268 return rc;
18cfeb52 269 }
7f23f812 270 qemu_register_reset(qdev_reset, dev);
391a079e
GH
271 if (dev->info->vmsd)
272 vmstate_register(-1, dev->info->vmsd, dev);
131ec1bd 273 dev->state = DEV_STATE_INITIALIZED;
959f733a 274 return 0;
02e2da45
PB
275}
276
3418bd25
GH
277int qdev_unplug(DeviceState *dev)
278{
279 if (!dev->parent_bus->allow_hotplug) {
280 qemu_error("Bus %s does not support hotplugging\n",
281 dev->parent_bus->name);
282 return -1;
283 }
593831de
AS
284 assert(dev->info->unplug != NULL);
285
3418bd25
GH
286 return dev->info->unplug(dev);
287}
288
289/* can be used as ->unplug() callback for the simple cases */
290int qdev_simple_unplug_cb(DeviceState *dev)
291{
292 /* just zap it */
293 qdev_free(dev);
294 return 0;
295}
296
e23a1b33
MA
297/* Like qdev_init(), but terminate program via hw_error() instead of
298 returning an error value. This is okay during machine creation.
299 Don't use for hotplug, because there callers need to recover from
300 failure. Exception: if you know the device's init() callback can't
301 fail, then qdev_init_nofail() can't fail either, and is therefore
302 usable even then. But relying on the device implementation that
303 way is somewhat unclean, and best avoided. */
304void qdev_init_nofail(DeviceState *dev)
305{
306 DeviceInfo *info = dev->info;
307
308 if (qdev_init(dev) < 0)
309 hw_error("Initialization of device %s failed\n", info->name);
310}
311
02e2da45
PB
312/* Unlink device from bus and free the structure. */
313void qdev_free(DeviceState *dev)
314{
131ec1bd
GH
315 BusState *bus;
316
317 if (dev->state == DEV_STATE_INITIALIZED) {
318 while (dev->num_child_bus) {
319 bus = QLIST_FIRST(&dev->child_bus);
320 qbus_free(bus);
321 }
131ec1bd
GH
322 if (dev->info->vmsd)
323 vmstate_unregister(dev->info->vmsd, dev);
d29275f1
GH
324 if (dev->info->exit)
325 dev->info->exit(dev);
ef80b466
GH
326 if (dev->opts)
327 qemu_opts_del(dev->opts);
131ec1bd 328 }
7f23f812 329 qemu_unregister_reset(qdev_reset, dev);
72cf2d4f 330 QLIST_REMOVE(dev, sibling);
ccb63de3 331 qemu_free(dev);
aae9460e
PB
332}
333
3418bd25
GH
334void qdev_machine_creation_done(void)
335{
336 /*
337 * ok, initial machine setup is done, starting from now we can
338 * only create hotpluggable devices
339 */
340 qdev_hotplug = 1;
341}
342
aae9460e
PB
343/* Get a character (serial) device interface. */
344CharDriverState *qdev_init_chardev(DeviceState *dev)
345{
346 static int next_serial;
98b19252
AS
347
348 /* FIXME: This function needs to go away: use chardev properties! */
349 return serial_hds[next_serial++];
aae9460e
PB
350}
351
02e2da45 352BusState *qdev_get_parent_bus(DeviceState *dev)
aae9460e 353{
02e2da45 354 return dev->parent_bus;
aae9460e
PB
355}
356
aae9460e
PB
357void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
358{
359 assert(dev->num_gpio_in == 0);
360 dev->num_gpio_in = n;
361 dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
362}
363
364void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
365{
366 assert(dev->num_gpio_out == 0);
367 dev->num_gpio_out = n;
368 dev->gpio_out = pins;
369}
370
371qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
372{
373 assert(n >= 0 && n < dev->num_gpio_in);
374 return dev->gpio_in[n];
375}
376
377void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
378{
379 assert(n >= 0 && n < dev->num_gpio_out);
380 dev->gpio_out[n] = pin;
381}
382
ed16ab5a
GH
383void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
384{
385 qdev_prop_set_macaddr(dev, "mac", nd->macaddr);
386 if (nd->vlan)
387 qdev_prop_set_vlan(dev, "vlan", nd->vlan);
388 if (nd->netdev)
389 qdev_prop_set_netdev(dev, "netdev", nd->netdev);
97b15621
GH
390 if (nd->nvectors != NIC_NVECTORS_UNSPECIFIED &&
391 qdev_prop_exists(dev, "vectors")) {
392 qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
393 }
ed16ab5a
GH
394}
395
aae9460e
PB
396static int next_block_unit[IF_COUNT];
397
398/* Get a block device. This should only be used for single-drive devices
399 (e.g. SD/Floppy/MTD). Multi-disk devices (scsi/ide) should use the
400 appropriate bus. */
401BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type)
402{
403 int unit = next_block_unit[type]++;
751c6a17 404 DriveInfo *dinfo;
aae9460e 405
751c6a17
GH
406 dinfo = drive_get(type, 0, unit);
407 return dinfo ? dinfo->bdrv : NULL;
aae9460e 408}
4d6ae674 409
02e2da45 410BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
4d6ae674 411{
02e2da45 412 BusState *bus;
4d6ae674 413
72cf2d4f 414 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
4d6ae674 415 if (strcmp(name, bus->name) == 0) {
02e2da45 416 return bus;
4d6ae674
PB
417 }
418 }
419 return NULL;
420}
421
8ffb1bcf
GH
422static BusState *qbus_find_recursive(BusState *bus, const char *name,
423 const BusInfo *info)
424{
425 DeviceState *dev;
426 BusState *child, *ret;
427 int match = 1;
428
429 if (name && (strcmp(bus->name, name) != 0)) {
430 match = 0;
431 }
432 if (info && (bus->info != info)) {
433 match = 0;
434 }
435 if (match) {
436 return bus;
437 }
438
72cf2d4f
BS
439 QLIST_FOREACH(dev, &bus->children, sibling) {
440 QLIST_FOREACH(child, &dev->child_bus, sibling) {
8ffb1bcf
GH
441 ret = qbus_find_recursive(child, name, info);
442 if (ret) {
443 return ret;
444 }
445 }
446 }
447 return NULL;
448}
449
3418bd25
GH
450static DeviceState *qdev_find_recursive(BusState *bus, const char *id)
451{
452 DeviceState *dev, *ret;
453 BusState *child;
454
455 QLIST_FOREACH(dev, &bus->children, sibling) {
456 if (dev->id && strcmp(dev->id, id) == 0)
457 return dev;
458 QLIST_FOREACH(child, &dev->child_bus, sibling) {
459 ret = qdev_find_recursive(child, id);
460 if (ret) {
461 return ret;
462 }
463 }
464 }
465 return NULL;
466}
467
8ffb1bcf
GH
468static void qbus_list_bus(DeviceState *dev, char *dest, int len)
469{
470 BusState *child;
471 const char *sep = " ";
472 int pos = 0;
473
474 pos += snprintf(dest+pos, len-pos,"child busses at \"%s\":",
475 dev->id ? dev->id : dev->info->name);
72cf2d4f 476 QLIST_FOREACH(child, &dev->child_bus, sibling) {
8ffb1bcf
GH
477 pos += snprintf(dest+pos, len-pos, "%s\"%s\"", sep, child->name);
478 sep = ", ";
479 }
480}
481
482static void qbus_list_dev(BusState *bus, char *dest, int len)
483{
484 DeviceState *dev;
485 const char *sep = " ";
486 int pos = 0;
487
488 pos += snprintf(dest+pos, len-pos, "devices at \"%s\":",
489 bus->name);
72cf2d4f 490 QLIST_FOREACH(dev, &bus->children, sibling) {
8ffb1bcf
GH
491 pos += snprintf(dest+pos, len-pos, "%s\"%s\"",
492 sep, dev->info->name);
493 if (dev->id)
494 pos += snprintf(dest+pos, len-pos, "/\"%s\"", dev->id);
495 sep = ", ";
496 }
497}
498
499static BusState *qbus_find_bus(DeviceState *dev, char *elem)
500{
501 BusState *child;
502
72cf2d4f 503 QLIST_FOREACH(child, &dev->child_bus, sibling) {
8ffb1bcf
GH
504 if (strcmp(child->name, elem) == 0) {
505 return child;
506 }
507 }
508 return NULL;
509}
510
511static DeviceState *qbus_find_dev(BusState *bus, char *elem)
512{
513 DeviceState *dev;
514
515 /*
516 * try to match in order:
517 * (1) instance id, if present
518 * (2) driver name
519 * (3) driver alias, if present
520 */
72cf2d4f 521 QLIST_FOREACH(dev, &bus->children, sibling) {
8ffb1bcf
GH
522 if (dev->id && strcmp(dev->id, elem) == 0) {
523 return dev;
524 }
525 }
72cf2d4f 526 QLIST_FOREACH(dev, &bus->children, sibling) {
8ffb1bcf
GH
527 if (strcmp(dev->info->name, elem) == 0) {
528 return dev;
529 }
530 }
72cf2d4f 531 QLIST_FOREACH(dev, &bus->children, sibling) {
8ffb1bcf
GH
532 if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) {
533 return dev;
534 }
535 }
536 return NULL;
537}
538
539static BusState *qbus_find(const char *path)
540{
541 DeviceState *dev;
542 BusState *bus;
543 char elem[128], msg[256];
544 int pos, len;
545
546 /* find start element */
547 if (path[0] == '/') {
548 bus = main_system_bus;
549 pos = 0;
550 } else {
551 if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
286c2321 552 qemu_error("path parse error (\"%s\")\n", path);
8ffb1bcf
GH
553 return NULL;
554 }
555 bus = qbus_find_recursive(main_system_bus, elem, NULL);
556 if (!bus) {
286c2321 557 qemu_error("bus \"%s\" not found\n", elem);
8ffb1bcf
GH
558 return NULL;
559 }
560 pos = len;
561 }
562
563 for (;;) {
564 if (path[pos] == '\0') {
565 /* we are done */
566 return bus;
567 }
568
569 /* find device */
570 if (sscanf(path+pos, "/%127[^/]%n", elem, &len) != 1) {
286c2321 571 qemu_error("path parse error (\"%s\" pos %d)\n", path, pos);
8ffb1bcf
GH
572 return NULL;
573 }
574 pos += len;
575 dev = qbus_find_dev(bus, elem);
576 if (!dev) {
577 qbus_list_dev(bus, msg, sizeof(msg));
286c2321 578 qemu_error("device \"%s\" not found\n%s\n", elem, msg);
8ffb1bcf
GH
579 return NULL;
580 }
581 if (path[pos] == '\0') {
582 /* last specified element is a device. If it has exactly
583 * one child bus accept it nevertheless */
584 switch (dev->num_child_bus) {
585 case 0:
286c2321 586 qemu_error("device has no child bus (%s)\n", path);
8ffb1bcf
GH
587 return NULL;
588 case 1:
72cf2d4f 589 return QLIST_FIRST(&dev->child_bus);
8ffb1bcf
GH
590 default:
591 qbus_list_bus(dev, msg, sizeof(msg));
286c2321
GH
592 qemu_error("device has multiple child busses (%s)\n%s\n",
593 path, msg);
8ffb1bcf
GH
594 return NULL;
595 }
596 }
597
598 /* find bus */
599 if (sscanf(path+pos, "/%127[^/]%n", elem, &len) != 1) {
286c2321 600 qemu_error("path parse error (\"%s\" pos %d)\n", path, pos);
8ffb1bcf
GH
601 return NULL;
602 }
603 pos += len;
604 bus = qbus_find_bus(dev, elem);
605 if (!bus) {
606 qbus_list_bus(dev, msg, sizeof(msg));
286c2321 607 qemu_error("child bus \"%s\" not found\n%s\n", elem, msg);
8ffb1bcf
GH
608 return NULL;
609 }
610 }
611}
612
cd739fb6
GH
613void qbus_create_inplace(BusState *bus, BusInfo *info,
614 DeviceState *parent, const char *name)
02e2da45 615{
d271de9f
GH
616 char *buf;
617 int i,len;
02e2da45 618
10c4c98a 619 bus->info = info;
02e2da45 620 bus->parent = parent;
d271de9f
GH
621
622 if (name) {
623 /* use supplied name */
624 bus->name = qemu_strdup(name);
625 } else if (parent && parent->id) {
626 /* parent device has id -> use it for bus name */
627 len = strlen(parent->id) + 16;
628 buf = qemu_malloc(len);
629 snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
630 bus->name = buf;
631 } else {
632 /* no id -> use lowercase bus type for bus name */
633 len = strlen(info->name) + 16;
634 buf = qemu_malloc(len);
635 len = snprintf(buf, len, "%s.%d", info->name,
636 parent ? parent->num_child_bus : 0);
637 for (i = 0; i < len; i++)
bb87ece5 638 buf[i] = qemu_tolower(buf[i]);
d271de9f
GH
639 bus->name = buf;
640 }
641
72cf2d4f 642 QLIST_INIT(&bus->children);
02e2da45 643 if (parent) {
72cf2d4f 644 QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
d271de9f 645 parent->num_child_bus++;
02e2da45 646 }
cd739fb6
GH
647
648}
649
650BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
651{
652 BusState *bus;
653
654 bus = qemu_mallocz(info->size);
655 bus->qdev_allocated = 1;
656 qbus_create_inplace(bus, info, parent, name);
02e2da45
PB
657 return bus;
658}
cae4956e 659
131ec1bd
GH
660void qbus_free(BusState *bus)
661{
662 DeviceState *dev;
663
664 while ((dev = QLIST_FIRST(&bus->children)) != NULL) {
665 qdev_free(dev);
666 }
667 if (bus->parent) {
668 QLIST_REMOVE(bus, sibling);
669 bus->parent->num_child_bus--;
670 }
671 if (bus->qdev_allocated) {
672 qemu_free(bus);
673 }
674}
675
cae4956e
GH
676#define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
677static void qbus_print(Monitor *mon, BusState *bus, int indent);
678
ee6847d1
GH
679static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
680 const char *prefix, int indent)
681{
682 char buf[64];
683
684 if (!props)
685 return;
686 while (props->name) {
687 if (props->info->print) {
688 props->info->print(dev, props, buf, sizeof(buf));
689 qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
690 }
691 props++;
692 }
693}
694
cae4956e
GH
695static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
696{
cae4956e 697 BusState *child;
ccb63de3
GH
698 qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
699 dev->id ? dev->id : "");
cae4956e
GH
700 indent += 2;
701 if (dev->num_gpio_in) {
702 qdev_printf("gpio-in %d\n", dev->num_gpio_in);
703 }
704 if (dev->num_gpio_out) {
705 qdev_printf("gpio-out %d\n", dev->num_gpio_out);
706 }
ee6847d1
GH
707 qdev_print_props(mon, dev, dev->info->props, "dev", indent);
708 qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
10c4c98a
GH
709 if (dev->parent_bus->info->print_dev)
710 dev->parent_bus->info->print_dev(mon, dev, indent);
72cf2d4f 711 QLIST_FOREACH(child, &dev->child_bus, sibling) {
cae4956e
GH
712 qbus_print(mon, child, indent);
713 }
714}
715
716static void qbus_print(Monitor *mon, BusState *bus, int indent)
717{
718 struct DeviceState *dev;
719
720 qdev_printf("bus: %s\n", bus->name);
721 indent += 2;
10c4c98a 722 qdev_printf("type %s\n", bus->info->name);
72cf2d4f 723 QLIST_FOREACH(dev, &bus->children, sibling) {
cae4956e
GH
724 qdev_print(mon, dev, indent);
725 }
726}
727#undef qdev_printf
728
729void do_info_qtree(Monitor *mon)
730{
731 if (main_system_bus)
732 qbus_print(mon, main_system_bus, 0);
733}
9316d30f 734
f6c64e0e 735void do_info_qdm(Monitor *mon)
9316d30f
GH
736{
737 DeviceInfo *info;
738 char msg[256];
739
740 for (info = device_info_list; info != NULL; info = info->next) {
741 qdev_print_devinfo(info, msg, sizeof(msg));
742 monitor_printf(mon, "%s\n", msg);
743 }
744}
3418bd25
GH
745
746void do_device_add(Monitor *mon, const QDict *qdict)
747{
748 QemuOpts *opts;
749
750 opts = qemu_opts_parse(&qemu_device_opts,
751 qdict_get_str(qdict, "config"), "driver");
0f853a38
KW
752 if (opts) {
753 if (qdev_device_help(opts) || qdev_device_add(opts) == NULL) {
754 qemu_opts_del(opts);
755 }
756 }
3418bd25
GH
757}
758
759void do_device_del(Monitor *mon, const QDict *qdict)
760{
761 const char *id = qdict_get_str(qdict, "id");
762 DeviceState *dev;
763
764 dev = qdev_find_recursive(main_system_bus, id);
765 if (NULL == dev) {
766 qemu_error("Device '%s' not found\n", id);
767 return;
768 }
769 qdev_unplug(dev);
770}