]> Git Repo - qemu.git/blame - hw/qdev.c
Merge remote branch 'mst/for_anthony' into staging
[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"
2446333c 32#include "blockdev.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
0c17542d
MA
81static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
82{
83 DeviceState *dev;
84
85 assert(bus->info == info->bus_info);
86 dev = qemu_mallocz(info->size);
87 dev->info = info;
88 dev->parent_bus = bus;
89 qdev_prop_set_defaults(dev, dev->info->props);
90 qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
91 qdev_prop_set_globals(dev);
92 QLIST_INSERT_HEAD(&bus->children, dev, sibling);
93 if (qdev_hotplug) {
94 assert(bus->allow_hotplug);
95 dev->hotplugged = 1;
96 }
4d2ffa08 97 dev->instance_id_alias = -1;
0c17542d
MA
98 dev->state = DEV_STATE_CREATED;
99 return dev;
100}
101
aae9460e
PB
102/* Create a new device. This only initializes the device state structure
103 and allows properties to be set. qdev_init should be called to
104 initialize the actual device emulation. */
02e2da45 105DeviceState *qdev_create(BusState *bus, const char *name)
aae9460e 106{
042f84d0 107 DeviceInfo *info;
aae9460e 108
10c4c98a 109 if (!bus) {
68694897 110 bus = sysbus_get_default();
10c4c98a
GH
111 }
112
81ebb98b 113 info = qdev_find_info(bus->info, name);
042f84d0 114 if (!info) {
10c4c98a 115 hw_error("Unknown device '%s' for bus '%s'\n", name, bus->info->name);
aae9460e
PB
116 }
117
0c17542d 118 return qdev_create_from_info(bus, info);
aae9460e
PB
119}
120
8a9662ca 121static void qdev_print_devinfo(DeviceInfo *info)
1b524b04 122{
8a9662ca
MA
123 error_printf("name \"%s\", bus %s",
124 info->name, info->bus_info->name);
22f2e344 125 if (info->alias) {
8a9662ca 126 error_printf(", alias \"%s\"", info->alias);
22f2e344
GH
127 }
128 if (info->desc) {
8a9662ca 129 error_printf(", desc \"%s\"", info->desc);
22f2e344
GH
130 }
131 if (info->no_user) {
8a9662ca 132 error_printf(", no-user");
22f2e344 133 }
8a9662ca 134 error_printf("\n");
1b524b04
GH
135}
136
f31d07d1 137static int set_property(const char *name, const char *value, void *opaque)
8ffb1bcf 138{
f31d07d1
GH
139 DeviceState *dev = opaque;
140
141 if (strcmp(name, "driver") == 0)
142 return 0;
143 if (strcmp(name, "bus") == 0)
144 return 0;
145
3df04ac3 146 if (qdev_prop_parse(dev, name, value) == -1) {
f31d07d1
GH
147 return -1;
148 }
149 return 0;
150}
151
ff952ba2
MA
152int qdev_device_help(QemuOpts *opts)
153{
154 const char *driver;
155 DeviceInfo *info;
08350cf0 156 Property *prop;
ff952ba2
MA
157
158 driver = qemu_opt_get(opts, "driver");
159 if (driver && !strcmp(driver, "?")) {
160 for (info = device_info_list; info != NULL; info = info->next) {
c64eafaf
MA
161 if (info->no_user) {
162 continue; /* not available, don't show */
163 }
8a9662ca 164 qdev_print_devinfo(info);
ff952ba2
MA
165 }
166 return 1;
167 }
168
08350cf0
MA
169 if (!qemu_opt_get(opts, "?")) {
170 return 0;
171 }
172
173 info = qdev_find_info(NULL, driver);
174 if (!info) {
175 return 0;
176 }
177
178 for (prop = info->props; prop && prop->name; prop++) {
036f7166
MA
179 /*
180 * TODO Properties without a parser are just for dirty hacks.
181 * qdev_prop_ptr is the only such PropertyInfo. It's marked
182 * for removal. This conditional should be removed along with
183 * it.
184 */
185 if (!prop->info->parse) {
186 continue; /* no way to set it, don't show */
187 }
8a9662ca 188 error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name);
08350cf0
MA
189 }
190 return 1;
ff952ba2
MA
191}
192
f31d07d1
GH
193DeviceState *qdev_device_add(QemuOpts *opts)
194{
195 const char *driver, *path, *id;
8ffb1bcf
GH
196 DeviceInfo *info;
197 DeviceState *qdev;
198 BusState *bus;
8ffb1bcf 199
f31d07d1
GH
200 driver = qemu_opt_get(opts, "driver");
201 if (!driver) {
0204276b 202 qerror_report(QERR_MISSING_PARAMETER, "driver");
8ffb1bcf
GH
203 return NULL;
204 }
f31d07d1
GH
205
206 /* find driver */
8ffb1bcf 207 info = qdev_find_info(NULL, driver);
c64eafaf 208 if (!info || info->no_user) {
e17ba87c 209 qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", "a driver name");
0204276b 210 error_printf_unless_qmp("Try with argument '?' for a list.\n");
8ffb1bcf
GH
211 return NULL;
212 }
8ffb1bcf 213
f31d07d1
GH
214 /* find bus */
215 path = qemu_opt_get(opts, "bus");
216 if (path != NULL) {
8ffb1bcf 217 bus = qbus_find(path);
ac8dae67
MA
218 if (!bus) {
219 return NULL;
220 }
221 if (bus->info != info->bus_info) {
0204276b
MA
222 qerror_report(QERR_BAD_BUS_FOR_DEVICE,
223 driver, bus->info->name);
327867b6
MA
224 return NULL;
225 }
8ffb1bcf
GH
226 } else {
227 bus = qbus_find_recursive(main_system_bus, NULL, info->bus_info);
ac8dae67 228 if (!bus) {
0204276b
MA
229 qerror_report(QERR_NO_BUS_FOR_DEVICE,
230 info->name, info->bus_info->name);
ac8dae67
MA
231 return NULL;
232 }
75570088 233 }
3418bd25 234 if (qdev_hotplug && !bus->allow_hotplug) {
0204276b 235 qerror_report(QERR_BUS_NO_HOTPLUG, bus->name);
3418bd25
GH
236 return NULL;
237 }
8ffb1bcf 238
f31d07d1 239 /* create device, set properties */
0c17542d 240 qdev = qdev_create_from_info(bus, info);
f31d07d1
GH
241 id = qemu_opts_id(opts);
242 if (id) {
243 qdev->id = id;
244 }
245 if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
246 qdev_free(qdev);
247 return NULL;
8ffb1bcf 248 }
5c17ca25 249 if (qdev_init(qdev) < 0) {
0204276b 250 qerror_report(QERR_DEVICE_INIT_FAILED, driver);
81a322d4
GH
251 return NULL;
252 }
ef80b466 253 qdev->opts = opts;
8ffb1bcf
GH
254 return qdev;
255}
256
aae9460e
PB
257/* Initialize a device. Device properties should be set before calling
258 this function. IRQs and MMIO regions should be connected/mapped after
18cfeb52
MA
259 calling this function.
260 On failure, destroy the device and return negative value.
261 Return 0 on success. */
81a322d4 262int qdev_init(DeviceState *dev)
aae9460e 263{
959f733a
GH
264 int rc;
265
131ec1bd 266 assert(dev->state == DEV_STATE_CREATED);
959f733a 267 rc = dev->info->init(dev, dev->info);
18cfeb52
MA
268 if (rc < 0) {
269 qdev_free(dev);
959f733a 270 return rc;
18cfeb52 271 }
4d2ffa08 272 if (dev->info->vmsd) {
0be71e32 273 vmstate_register_with_alias_id(dev, -1, dev->info->vmsd, dev,
4d2ffa08
JK
274 dev->instance_id_alias,
275 dev->alias_required_for_version);
276 }
131ec1bd 277 dev->state = DEV_STATE_INITIALIZED;
959f733a 278 return 0;
02e2da45
PB
279}
280
4d2ffa08
JK
281void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
282 int required_for_version)
283{
284 assert(dev->state == DEV_STATE_CREATED);
285 dev->instance_id_alias = alias_id;
286 dev->alias_required_for_version = required_for_version;
287}
288
3418bd25
GH
289int qdev_unplug(DeviceState *dev)
290{
291 if (!dev->parent_bus->allow_hotplug) {
cc601cb7 292 qerror_report(QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
3418bd25
GH
293 return -1;
294 }
593831de
AS
295 assert(dev->info->unplug != NULL);
296
3418bd25
GH
297 return dev->info->unplug(dev);
298}
299
ec990eb6
AL
300static int qdev_reset_one(DeviceState *dev, void *opaque)
301{
302 if (dev->info->reset) {
303 dev->info->reset(dev);
304 }
305
306 return 0;
307}
308
309BusState *sysbus_get_default(void)
310{
68694897
SW
311 if (!main_system_bus) {
312 main_system_bus = qbus_create(&system_bus_info, NULL,
313 "main-system-bus");
314 }
ec990eb6
AL
315 return main_system_bus;
316}
317
b4694b7c
IY
318static int qbus_reset_one(BusState *bus, void *opaque)
319{
320 if (bus->info->reset) {
321 return bus->info->reset(bus);
322 }
323 return 0;
324}
325
5af0a04b
IY
326void qdev_reset_all(DeviceState *dev)
327{
328 qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
329}
330
80376c3f
IY
331void qbus_reset_all_fn(void *opaque)
332{
333 BusState *bus = opaque;
f530cce3 334 qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
80376c3f
IY
335}
336
3418bd25
GH
337/* can be used as ->unplug() callback for the simple cases */
338int qdev_simple_unplug_cb(DeviceState *dev)
339{
340 /* just zap it */
341 qdev_free(dev);
342 return 0;
343}
344
e23a1b33
MA
345/* Like qdev_init(), but terminate program via hw_error() instead of
346 returning an error value. This is okay during machine creation.
347 Don't use for hotplug, because there callers need to recover from
348 failure. Exception: if you know the device's init() callback can't
349 fail, then qdev_init_nofail() can't fail either, and is therefore
350 usable even then. But relying on the device implementation that
351 way is somewhat unclean, and best avoided. */
352void qdev_init_nofail(DeviceState *dev)
353{
354 DeviceInfo *info = dev->info;
355
bd6c9a61
MA
356 if (qdev_init(dev) < 0) {
357 error_report("Initialization of device %s failed\n", info->name);
358 exit(1);
359 }
e23a1b33
MA
360}
361
02e2da45
PB
362/* Unlink device from bus and free the structure. */
363void qdev_free(DeviceState *dev)
364{
131ec1bd 365 BusState *bus;
d21357df 366 Property *prop;
131ec1bd
GH
367
368 if (dev->state == DEV_STATE_INITIALIZED) {
369 while (dev->num_child_bus) {
370 bus = QLIST_FIRST(&dev->child_bus);
371 qbus_free(bus);
372 }
131ec1bd 373 if (dev->info->vmsd)
0be71e32 374 vmstate_unregister(dev, dev->info->vmsd, dev);
d29275f1
GH
375 if (dev->info->exit)
376 dev->info->exit(dev);
ef80b466
GH
377 if (dev->opts)
378 qemu_opts_del(dev->opts);
131ec1bd 379 }
72cf2d4f 380 QLIST_REMOVE(dev, sibling);
d21357df
MA
381 for (prop = dev->info->props; prop && prop->name; prop++) {
382 if (prop->info->free) {
383 prop->info->free(dev, prop);
384 }
385 }
ccb63de3 386 qemu_free(dev);
aae9460e
PB
387}
388
3418bd25
GH
389void qdev_machine_creation_done(void)
390{
391 /*
392 * ok, initial machine setup is done, starting from now we can
393 * only create hotpluggable devices
394 */
395 qdev_hotplug = 1;
396}
397
aae9460e
PB
398/* Get a character (serial) device interface. */
399CharDriverState *qdev_init_chardev(DeviceState *dev)
400{
401 static int next_serial;
98b19252
AS
402
403 /* FIXME: This function needs to go away: use chardev properties! */
404 return serial_hds[next_serial++];
aae9460e
PB
405}
406
02e2da45 407BusState *qdev_get_parent_bus(DeviceState *dev)
aae9460e 408{
02e2da45 409 return dev->parent_bus;
aae9460e
PB
410}
411
aae9460e
PB
412void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
413{
414 assert(dev->num_gpio_in == 0);
415 dev->num_gpio_in = n;
416 dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
417}
418
419void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
420{
421 assert(dev->num_gpio_out == 0);
422 dev->num_gpio_out = n;
423 dev->gpio_out = pins;
424}
425
426qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
427{
428 assert(n >= 0 && n < dev->num_gpio_in);
429 return dev->gpio_in[n];
430}
431
432void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
433{
434 assert(n >= 0 && n < dev->num_gpio_out);
435 dev->gpio_out[n] = pin;
436}
437
ed16ab5a
GH
438void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
439{
440 qdev_prop_set_macaddr(dev, "mac", nd->macaddr);
441 if (nd->vlan)
442 qdev_prop_set_vlan(dev, "vlan", nd->vlan);
443 if (nd->netdev)
444 qdev_prop_set_netdev(dev, "netdev", nd->netdev);
75422b0d 445 if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
97b15621
GH
446 qdev_prop_exists(dev, "vectors")) {
447 qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
448 }
ed16ab5a
GH
449}
450
aae9460e
PB
451static int next_block_unit[IF_COUNT];
452
453/* Get a block device. This should only be used for single-drive devices
454 (e.g. SD/Floppy/MTD). Multi-disk devices (scsi/ide) should use the
455 appropriate bus. */
456BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type)
457{
458 int unit = next_block_unit[type]++;
751c6a17 459 DriveInfo *dinfo;
aae9460e 460
751c6a17
GH
461 dinfo = drive_get(type, 0, unit);
462 return dinfo ? dinfo->bdrv : NULL;
aae9460e 463}
4d6ae674 464
02e2da45 465BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
4d6ae674 466{
02e2da45 467 BusState *bus;
4d6ae674 468
72cf2d4f 469 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
4d6ae674 470 if (strcmp(name, bus->name) == 0) {
02e2da45 471 return bus;
4d6ae674
PB
472 }
473 }
474 return NULL;
475}
476
81699d8a
AL
477int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
478 qbus_walkerfn *busfn, void *opaque)
479{
480 DeviceState *dev;
481 int err;
482
483 if (busfn) {
484 err = busfn(bus, opaque);
485 if (err) {
486 return err;
487 }
488 }
489
490 QLIST_FOREACH(dev, &bus->children, sibling) {
491 err = qdev_walk_children(dev, devfn, busfn, opaque);
492 if (err < 0) {
493 return err;
494 }
495 }
496
497 return 0;
498}
499
500int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
501 qbus_walkerfn *busfn, void *opaque)
502{
503 BusState *bus;
504 int err;
505
506 if (devfn) {
507 err = devfn(dev, opaque);
508 if (err) {
509 return err;
510 }
511 }
512
513 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
514 err = qbus_walk_children(bus, devfn, busfn, opaque);
515 if (err < 0) {
516 return err;
517 }
518 }
519
520 return 0;
521}
522
8ffb1bcf
GH
523static BusState *qbus_find_recursive(BusState *bus, const char *name,
524 const BusInfo *info)
525{
526 DeviceState *dev;
527 BusState *child, *ret;
528 int match = 1;
529
530 if (name && (strcmp(bus->name, name) != 0)) {
531 match = 0;
532 }
533 if (info && (bus->info != info)) {
534 match = 0;
535 }
536 if (match) {
537 return bus;
538 }
539
72cf2d4f
BS
540 QLIST_FOREACH(dev, &bus->children, sibling) {
541 QLIST_FOREACH(child, &dev->child_bus, sibling) {
8ffb1bcf
GH
542 ret = qbus_find_recursive(child, name, info);
543 if (ret) {
544 return ret;
545 }
546 }
547 }
548 return NULL;
549}
550
a2ee6b4f 551DeviceState *qdev_find_recursive(BusState *bus, const char *id)
3418bd25
GH
552{
553 DeviceState *dev, *ret;
554 BusState *child;
555
556 QLIST_FOREACH(dev, &bus->children, sibling) {
557 if (dev->id && strcmp(dev->id, id) == 0)
558 return dev;
559 QLIST_FOREACH(child, &dev->child_bus, sibling) {
560 ret = qdev_find_recursive(child, id);
561 if (ret) {
562 return ret;
563 }
564 }
565 }
566 return NULL;
567}
568
53db16b5 569static void qbus_list_bus(DeviceState *dev)
8ffb1bcf
GH
570{
571 BusState *child;
572 const char *sep = " ";
8ffb1bcf 573
53db16b5
MA
574 error_printf("child busses at \"%s\":",
575 dev->id ? dev->id : dev->info->name);
72cf2d4f 576 QLIST_FOREACH(child, &dev->child_bus, sibling) {
53db16b5 577 error_printf("%s\"%s\"", sep, child->name);
8ffb1bcf
GH
578 sep = ", ";
579 }
53db16b5 580 error_printf("\n");
8ffb1bcf
GH
581}
582
53db16b5 583static void qbus_list_dev(BusState *bus)
8ffb1bcf
GH
584{
585 DeviceState *dev;
586 const char *sep = " ";
8ffb1bcf 587
53db16b5 588 error_printf("devices at \"%s\":", bus->name);
72cf2d4f 589 QLIST_FOREACH(dev, &bus->children, sibling) {
53db16b5 590 error_printf("%s\"%s\"", sep, dev->info->name);
8ffb1bcf 591 if (dev->id)
53db16b5 592 error_printf("/\"%s\"", dev->id);
8ffb1bcf
GH
593 sep = ", ";
594 }
53db16b5 595 error_printf("\n");
8ffb1bcf
GH
596}
597
598static BusState *qbus_find_bus(DeviceState *dev, char *elem)
599{
600 BusState *child;
601
72cf2d4f 602 QLIST_FOREACH(child, &dev->child_bus, sibling) {
8ffb1bcf
GH
603 if (strcmp(child->name, elem) == 0) {
604 return child;
605 }
606 }
607 return NULL;
608}
609
610static DeviceState *qbus_find_dev(BusState *bus, char *elem)
611{
612 DeviceState *dev;
613
614 /*
615 * try to match in order:
616 * (1) instance id, if present
617 * (2) driver name
618 * (3) driver alias, if present
619 */
72cf2d4f 620 QLIST_FOREACH(dev, &bus->children, sibling) {
8ffb1bcf
GH
621 if (dev->id && strcmp(dev->id, elem) == 0) {
622 return dev;
623 }
624 }
72cf2d4f 625 QLIST_FOREACH(dev, &bus->children, sibling) {
8ffb1bcf
GH
626 if (strcmp(dev->info->name, elem) == 0) {
627 return dev;
628 }
629 }
72cf2d4f 630 QLIST_FOREACH(dev, &bus->children, sibling) {
8ffb1bcf
GH
631 if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) {
632 return dev;
633 }
634 }
635 return NULL;
636}
637
638static BusState *qbus_find(const char *path)
639{
640 DeviceState *dev;
641 BusState *bus;
53db16b5 642 char elem[128];
8ffb1bcf
GH
643 int pos, len;
644
645 /* find start element */
646 if (path[0] == '/') {
647 bus = main_system_bus;
648 pos = 0;
649 } else {
650 if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
fc98eb43
MA
651 assert(!path[0]);
652 elem[0] = len = 0;
8ffb1bcf
GH
653 }
654 bus = qbus_find_recursive(main_system_bus, elem, NULL);
655 if (!bus) {
ac8dae67 656 qerror_report(QERR_BUS_NOT_FOUND, elem);
8ffb1bcf
GH
657 return NULL;
658 }
659 pos = len;
660 }
661
662 for (;;) {
fc98eb43
MA
663 assert(path[pos] == '/' || !path[pos]);
664 while (path[pos] == '/') {
665 pos++;
666 }
8ffb1bcf 667 if (path[pos] == '\0') {
8ffb1bcf
GH
668 return bus;
669 }
670
671 /* find device */
fc98eb43
MA
672 if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
673 assert(0);
674 elem[0] = len = 0;
8ffb1bcf
GH
675 }
676 pos += len;
677 dev = qbus_find_dev(bus, elem);
678 if (!dev) {
ac8dae67 679 qerror_report(QERR_DEVICE_NOT_FOUND, elem);
8bc27249
MA
680 if (!monitor_cur_is_qmp()) {
681 qbus_list_dev(bus);
682 }
8ffb1bcf
GH
683 return NULL;
684 }
fc98eb43
MA
685
686 assert(path[pos] == '/' || !path[pos]);
687 while (path[pos] == '/') {
688 pos++;
689 }
8ffb1bcf
GH
690 if (path[pos] == '\0') {
691 /* last specified element is a device. If it has exactly
692 * one child bus accept it nevertheless */
693 switch (dev->num_child_bus) {
694 case 0:
ac8dae67 695 qerror_report(QERR_DEVICE_NO_BUS, elem);
8ffb1bcf
GH
696 return NULL;
697 case 1:
72cf2d4f 698 return QLIST_FIRST(&dev->child_bus);
8ffb1bcf 699 default:
ac8dae67 700 qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
8bc27249
MA
701 if (!monitor_cur_is_qmp()) {
702 qbus_list_bus(dev);
703 }
8ffb1bcf
GH
704 return NULL;
705 }
706 }
707
708 /* find bus */
fc98eb43
MA
709 if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
710 assert(0);
711 elem[0] = len = 0;
8ffb1bcf
GH
712 }
713 pos += len;
714 bus = qbus_find_bus(dev, elem);
715 if (!bus) {
ac8dae67 716 qerror_report(QERR_BUS_NOT_FOUND, elem);
8bc27249
MA
717 if (!monitor_cur_is_qmp()) {
718 qbus_list_bus(dev);
719 }
8ffb1bcf
GH
720 return NULL;
721 }
722 }
723}
724
cd739fb6
GH
725void qbus_create_inplace(BusState *bus, BusInfo *info,
726 DeviceState *parent, const char *name)
02e2da45 727{
d271de9f
GH
728 char *buf;
729 int i,len;
02e2da45 730
10c4c98a 731 bus->info = info;
02e2da45 732 bus->parent = parent;
d271de9f
GH
733
734 if (name) {
735 /* use supplied name */
736 bus->name = qemu_strdup(name);
737 } else if (parent && parent->id) {
738 /* parent device has id -> use it for bus name */
739 len = strlen(parent->id) + 16;
740 buf = qemu_malloc(len);
741 snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
742 bus->name = buf;
743 } else {
744 /* no id -> use lowercase bus type for bus name */
745 len = strlen(info->name) + 16;
746 buf = qemu_malloc(len);
747 len = snprintf(buf, len, "%s.%d", info->name,
748 parent ? parent->num_child_bus : 0);
749 for (i = 0; i < len; i++)
bb87ece5 750 buf[i] = qemu_tolower(buf[i]);
d271de9f
GH
751 bus->name = buf;
752 }
753
72cf2d4f 754 QLIST_INIT(&bus->children);
02e2da45 755 if (parent) {
72cf2d4f 756 QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
d271de9f 757 parent->num_child_bus++;
80376c3f
IY
758 } else if (bus != main_system_bus) {
759 /* TODO: once all bus devices are qdevified,
760 only reset handler for main_system_bus should be registered here. */
761 qemu_register_reset(qbus_reset_all_fn, bus);
02e2da45 762 }
cd739fb6
GH
763}
764
765BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
766{
767 BusState *bus;
768
769 bus = qemu_mallocz(info->size);
770 bus->qdev_allocated = 1;
771 qbus_create_inplace(bus, info, parent, name);
02e2da45
PB
772 return bus;
773}
cae4956e 774
131ec1bd
GH
775void qbus_free(BusState *bus)
776{
777 DeviceState *dev;
778
779 while ((dev = QLIST_FIRST(&bus->children)) != NULL) {
780 qdev_free(dev);
781 }
782 if (bus->parent) {
783 QLIST_REMOVE(bus, sibling);
784 bus->parent->num_child_bus--;
80376c3f
IY
785 } else {
786 assert(bus != main_system_bus); /* main_system_bus is never freed */
787 qemu_unregister_reset(qbus_reset_all_fn, bus);
131ec1bd 788 }
e163ae7b 789 qemu_free((void*)bus->name);
131ec1bd
GH
790 if (bus->qdev_allocated) {
791 qemu_free(bus);
792 }
793}
794
cae4956e
GH
795#define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
796static void qbus_print(Monitor *mon, BusState *bus, int indent);
797
ee6847d1
GH
798static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
799 const char *prefix, int indent)
800{
801 char buf[64];
802
803 if (!props)
804 return;
805 while (props->name) {
036f7166
MA
806 /*
807 * TODO Properties without a print method are just for dirty
808 * hacks. qdev_prop_ptr is the only such PropertyInfo. It's
809 * marked for removal. The test props->info->print should be
810 * removed along with it.
811 */
ee6847d1
GH
812 if (props->info->print) {
813 props->info->print(dev, props, buf, sizeof(buf));
814 qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
815 }
816 props++;
817 }
818}
819
cae4956e
GH
820static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
821{
cae4956e 822 BusState *child;
ccb63de3
GH
823 qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
824 dev->id ? dev->id : "");
cae4956e
GH
825 indent += 2;
826 if (dev->num_gpio_in) {
827 qdev_printf("gpio-in %d\n", dev->num_gpio_in);
828 }
829 if (dev->num_gpio_out) {
830 qdev_printf("gpio-out %d\n", dev->num_gpio_out);
831 }
ee6847d1
GH
832 qdev_print_props(mon, dev, dev->info->props, "dev", indent);
833 qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
10c4c98a
GH
834 if (dev->parent_bus->info->print_dev)
835 dev->parent_bus->info->print_dev(mon, dev, indent);
72cf2d4f 836 QLIST_FOREACH(child, &dev->child_bus, sibling) {
cae4956e
GH
837 qbus_print(mon, child, indent);
838 }
839}
840
841static void qbus_print(Monitor *mon, BusState *bus, int indent)
842{
843 struct DeviceState *dev;
844
845 qdev_printf("bus: %s\n", bus->name);
846 indent += 2;
10c4c98a 847 qdev_printf("type %s\n", bus->info->name);
72cf2d4f 848 QLIST_FOREACH(dev, &bus->children, sibling) {
cae4956e
GH
849 qdev_print(mon, dev, indent);
850 }
851}
852#undef qdev_printf
853
854void do_info_qtree(Monitor *mon)
855{
856 if (main_system_bus)
857 qbus_print(mon, main_system_bus, 0);
858}
9316d30f 859
f6c64e0e 860void do_info_qdm(Monitor *mon)
9316d30f
GH
861{
862 DeviceInfo *info;
9316d30f
GH
863
864 for (info = device_info_list; info != NULL; info = info->next) {
8a9662ca 865 qdev_print_devinfo(info);
9316d30f
GH
866 }
867}
3418bd25 868
8bc27249 869int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
3418bd25
GH
870{
871 QemuOpts *opts;
872
3329f07b 873 opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict);
8bc27249
MA
874 if (!opts) {
875 return -1;
876 }
877 if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
878 qemu_opts_del(opts);
879 return 0;
0f853a38 880 }
8bc27249
MA
881 if (!qdev_device_add(opts)) {
882 qemu_opts_del(opts);
883 return -1;
884 }
885 return 0;
3418bd25
GH
886}
887
17a38eaa 888int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
3418bd25
GH
889{
890 const char *id = qdict_get_str(qdict, "id");
891 DeviceState *dev;
892
893 dev = qdev_find_recursive(main_system_bus, id);
894 if (NULL == dev) {
17a38eaa
MA
895 qerror_report(QERR_DEVICE_NOT_FOUND, id);
896 return -1;
3418bd25 897 }
17a38eaa 898 return qdev_unplug(dev);
3418bd25 899}
1ca4d09a
GN
900
901static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
902{
903 int l = 0;
904
905 if (dev && dev->parent_bus) {
906 char *d;
907 l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
908 if (dev->parent_bus->info->get_fw_dev_path) {
909 d = dev->parent_bus->info->get_fw_dev_path(dev);
910 l += snprintf(p + l, size - l, "%s", d);
911 qemu_free(d);
912 } else {
913 l += snprintf(p + l, size - l, "%s", dev->info->name);
914 }
915 }
916 l += snprintf(p + l , size - l, "/");
917
918 return l;
919}
920
921char* qdev_get_fw_dev_path(DeviceState *dev)
922{
923 char path[128];
924 int l;
925
926 l = qdev_get_fw_dev_path_helper(dev, path, 128);
927
928 path[l-1] = '\0';
929
930 return strdup(path);
931}
This page took 0.453463 seconds and 4 git commands to generate.