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