]> Git Repo - qemu.git/blob - hw/qdev.c
qcow2: Simplify image creation
[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 static void qdev_reset(void *opaque)
261 {
262     DeviceState *dev = opaque;
263     if (dev->info->reset)
264         dev->info->reset(dev);
265 }
266
267 /* Initialize a device.  Device properties should be set before calling
268    this function.  IRQs and MMIO regions should be connected/mapped after
269    calling this function.
270    On failure, destroy the device and return negative value.
271    Return 0 on success.  */
272 int qdev_init(DeviceState *dev)
273 {
274     int rc;
275
276     assert(dev->state == DEV_STATE_CREATED);
277     rc = dev->info->init(dev, dev->info);
278     if (rc < 0) {
279         qdev_free(dev);
280         return rc;
281     }
282     qemu_register_reset(qdev_reset, dev);
283     if (dev->info->vmsd) {
284         vmstate_register_with_alias_id(dev, -1, dev->info->vmsd, dev,
285                                        dev->instance_id_alias,
286                                        dev->alias_required_for_version);
287     }
288     dev->state = DEV_STATE_INITIALIZED;
289     return 0;
290 }
291
292 void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
293                                  int required_for_version)
294 {
295     assert(dev->state == DEV_STATE_CREATED);
296     dev->instance_id_alias = alias_id;
297     dev->alias_required_for_version = required_for_version;
298 }
299
300 int qdev_unplug(DeviceState *dev)
301 {
302     if (!dev->parent_bus->allow_hotplug) {
303         qerror_report(QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
304         return -1;
305     }
306     assert(dev->info->unplug != NULL);
307
308     return dev->info->unplug(dev);
309 }
310
311 /* can be used as ->unplug() callback for the simple cases */
312 int qdev_simple_unplug_cb(DeviceState *dev)
313 {
314     /* just zap it */
315     qdev_free(dev);
316     return 0;
317 }
318
319 /* Like qdev_init(), but terminate program via hw_error() instead of
320    returning an error value.  This is okay during machine creation.
321    Don't use for hotplug, because there callers need to recover from
322    failure.  Exception: if you know the device's init() callback can't
323    fail, then qdev_init_nofail() can't fail either, and is therefore
324    usable even then.  But relying on the device implementation that
325    way is somewhat unclean, and best avoided.  */
326 void qdev_init_nofail(DeviceState *dev)
327 {
328     DeviceInfo *info = dev->info;
329
330     if (qdev_init(dev) < 0) {
331         error_report("Initialization of device %s failed\n", info->name);
332         exit(1);
333     }
334 }
335
336 /* Unlink device from bus and free the structure.  */
337 void qdev_free(DeviceState *dev)
338 {
339     BusState *bus;
340     Property *prop;
341
342     if (dev->state == DEV_STATE_INITIALIZED) {
343         while (dev->num_child_bus) {
344             bus = QLIST_FIRST(&dev->child_bus);
345             qbus_free(bus);
346         }
347         if (dev->info->vmsd)
348             vmstate_unregister(dev, dev->info->vmsd, dev);
349         if (dev->info->exit)
350             dev->info->exit(dev);
351         if (dev->opts)
352             qemu_opts_del(dev->opts);
353     }
354     qemu_unregister_reset(qdev_reset, dev);
355     QLIST_REMOVE(dev, sibling);
356     for (prop = dev->info->props; prop && prop->name; prop++) {
357         if (prop->info->free) {
358             prop->info->free(dev, prop);
359         }
360     }
361     qemu_free(dev);
362 }
363
364 void qdev_machine_creation_done(void)
365 {
366     /*
367      * ok, initial machine setup is done, starting from now we can
368      * only create hotpluggable devices
369      */
370     qdev_hotplug = 1;
371 }
372
373 /* Get a character (serial) device interface.  */
374 CharDriverState *qdev_init_chardev(DeviceState *dev)
375 {
376     static int next_serial;
377
378     /* FIXME: This function needs to go away: use chardev properties!  */
379     return serial_hds[next_serial++];
380 }
381
382 BusState *qdev_get_parent_bus(DeviceState *dev)
383 {
384     return dev->parent_bus;
385 }
386
387 void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
388 {
389     assert(dev->num_gpio_in == 0);
390     dev->num_gpio_in = n;
391     dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
392 }
393
394 void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
395 {
396     assert(dev->num_gpio_out == 0);
397     dev->num_gpio_out = n;
398     dev->gpio_out = pins;
399 }
400
401 qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
402 {
403     assert(n >= 0 && n < dev->num_gpio_in);
404     return dev->gpio_in[n];
405 }
406
407 void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
408 {
409     assert(n >= 0 && n < dev->num_gpio_out);
410     dev->gpio_out[n] = pin;
411 }
412
413 void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
414 {
415     qdev_prop_set_macaddr(dev, "mac", nd->macaddr);
416     if (nd->vlan)
417         qdev_prop_set_vlan(dev, "vlan", nd->vlan);
418     if (nd->netdev)
419         qdev_prop_set_netdev(dev, "netdev", nd->netdev);
420     if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
421         qdev_prop_exists(dev, "vectors")) {
422         qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
423     }
424 }
425
426 static int next_block_unit[IF_COUNT];
427
428 /* Get a block device.  This should only be used for single-drive devices
429    (e.g. SD/Floppy/MTD).  Multi-disk devices (scsi/ide) should use the
430    appropriate bus.  */
431 BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type)
432 {
433     int unit = next_block_unit[type]++;
434     DriveInfo *dinfo;
435
436     dinfo = drive_get(type, 0, unit);
437     return dinfo ? dinfo->bdrv : NULL;
438 }
439
440 BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
441 {
442     BusState *bus;
443
444     QLIST_FOREACH(bus, &dev->child_bus, sibling) {
445         if (strcmp(name, bus->name) == 0) {
446             return bus;
447         }
448     }
449     return NULL;
450 }
451
452 static BusState *qbus_find_recursive(BusState *bus, const char *name,
453                                      const BusInfo *info)
454 {
455     DeviceState *dev;
456     BusState *child, *ret;
457     int match = 1;
458
459     if (name && (strcmp(bus->name, name) != 0)) {
460         match = 0;
461     }
462     if (info && (bus->info != info)) {
463         match = 0;
464     }
465     if (match) {
466         return bus;
467     }
468
469     QLIST_FOREACH(dev, &bus->children, sibling) {
470         QLIST_FOREACH(child, &dev->child_bus, sibling) {
471             ret = qbus_find_recursive(child, name, info);
472             if (ret) {
473                 return ret;
474             }
475         }
476     }
477     return NULL;
478 }
479
480 static DeviceState *qdev_find_recursive(BusState *bus, const char *id)
481 {
482     DeviceState *dev, *ret;
483     BusState *child;
484
485     QLIST_FOREACH(dev, &bus->children, sibling) {
486         if (dev->id && strcmp(dev->id, id) == 0)
487             return dev;
488         QLIST_FOREACH(child, &dev->child_bus, sibling) {
489             ret = qdev_find_recursive(child, id);
490             if (ret) {
491                 return ret;
492             }
493         }
494     }
495     return NULL;
496 }
497
498 static void qbus_list_bus(DeviceState *dev)
499 {
500     BusState *child;
501     const char *sep = " ";
502
503     error_printf("child busses at \"%s\":",
504                  dev->id ? dev->id : dev->info->name);
505     QLIST_FOREACH(child, &dev->child_bus, sibling) {
506         error_printf("%s\"%s\"", sep, child->name);
507         sep = ", ";
508     }
509     error_printf("\n");
510 }
511
512 static void qbus_list_dev(BusState *bus)
513 {
514     DeviceState *dev;
515     const char *sep = " ";
516
517     error_printf("devices at \"%s\":", bus->name);
518     QLIST_FOREACH(dev, &bus->children, sibling) {
519         error_printf("%s\"%s\"", sep, dev->info->name);
520         if (dev->id)
521             error_printf("/\"%s\"", dev->id);
522         sep = ", ";
523     }
524     error_printf("\n");
525 }
526
527 static BusState *qbus_find_bus(DeviceState *dev, char *elem)
528 {
529     BusState *child;
530
531     QLIST_FOREACH(child, &dev->child_bus, sibling) {
532         if (strcmp(child->name, elem) == 0) {
533             return child;
534         }
535     }
536     return NULL;
537 }
538
539 static DeviceState *qbus_find_dev(BusState *bus, char *elem)
540 {
541     DeviceState *dev;
542
543     /*
544      * try to match in order:
545      *   (1) instance id, if present
546      *   (2) driver name
547      *   (3) driver alias, if present
548      */
549     QLIST_FOREACH(dev, &bus->children, sibling) {
550         if (dev->id  &&  strcmp(dev->id, elem) == 0) {
551             return dev;
552         }
553     }
554     QLIST_FOREACH(dev, &bus->children, sibling) {
555         if (strcmp(dev->info->name, elem) == 0) {
556             return dev;
557         }
558     }
559     QLIST_FOREACH(dev, &bus->children, sibling) {
560         if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) {
561             return dev;
562         }
563     }
564     return NULL;
565 }
566
567 static BusState *qbus_find(const char *path)
568 {
569     DeviceState *dev;
570     BusState *bus;
571     char elem[128];
572     int pos, len;
573
574     /* find start element */
575     if (path[0] == '/') {
576         bus = main_system_bus;
577         pos = 0;
578     } else {
579         if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
580             assert(!path[0]);
581             elem[0] = len = 0;
582         }
583         bus = qbus_find_recursive(main_system_bus, elem, NULL);
584         if (!bus) {
585             qerror_report(QERR_BUS_NOT_FOUND, elem);
586             return NULL;
587         }
588         pos = len;
589     }
590
591     for (;;) {
592         assert(path[pos] == '/' || !path[pos]);
593         while (path[pos] == '/') {
594             pos++;
595         }
596         if (path[pos] == '\0') {
597             return bus;
598         }
599
600         /* find device */
601         if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
602             assert(0);
603             elem[0] = len = 0;
604         }
605         pos += len;
606         dev = qbus_find_dev(bus, elem);
607         if (!dev) {
608             qerror_report(QERR_DEVICE_NOT_FOUND, elem);
609             if (!monitor_cur_is_qmp()) {
610                 qbus_list_dev(bus);
611             }
612             return NULL;
613         }
614
615         assert(path[pos] == '/' || !path[pos]);
616         while (path[pos] == '/') {
617             pos++;
618         }
619         if (path[pos] == '\0') {
620             /* last specified element is a device.  If it has exactly
621              * one child bus accept it nevertheless */
622             switch (dev->num_child_bus) {
623             case 0:
624                 qerror_report(QERR_DEVICE_NO_BUS, elem);
625                 return NULL;
626             case 1:
627                 return QLIST_FIRST(&dev->child_bus);
628             default:
629                 qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
630                 if (!monitor_cur_is_qmp()) {
631                     qbus_list_bus(dev);
632                 }
633                 return NULL;
634             }
635         }
636
637         /* find bus */
638         if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
639             assert(0);
640             elem[0] = len = 0;
641         }
642         pos += len;
643         bus = qbus_find_bus(dev, elem);
644         if (!bus) {
645             qerror_report(QERR_BUS_NOT_FOUND, elem);
646             if (!monitor_cur_is_qmp()) {
647                 qbus_list_bus(dev);
648             }
649             return NULL;
650         }
651     }
652 }
653
654 void qbus_create_inplace(BusState *bus, BusInfo *info,
655                          DeviceState *parent, const char *name)
656 {
657     char *buf;
658     int i,len;
659
660     bus->info = info;
661     bus->parent = parent;
662
663     if (name) {
664         /* use supplied name */
665         bus->name = qemu_strdup(name);
666     } else if (parent && parent->id) {
667         /* parent device has id -> use it for bus name */
668         len = strlen(parent->id) + 16;
669         buf = qemu_malloc(len);
670         snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
671         bus->name = buf;
672     } else {
673         /* no id -> use lowercase bus type for bus name */
674         len = strlen(info->name) + 16;
675         buf = qemu_malloc(len);
676         len = snprintf(buf, len, "%s.%d", info->name,
677                        parent ? parent->num_child_bus : 0);
678         for (i = 0; i < len; i++)
679             buf[i] = qemu_tolower(buf[i]);
680         bus->name = buf;
681     }
682
683     QLIST_INIT(&bus->children);
684     if (parent) {
685         QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
686         parent->num_child_bus++;
687     }
688
689 }
690
691 BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
692 {
693     BusState *bus;
694
695     bus = qemu_mallocz(info->size);
696     bus->qdev_allocated = 1;
697     qbus_create_inplace(bus, info, parent, name);
698     return bus;
699 }
700
701 void qbus_free(BusState *bus)
702 {
703     DeviceState *dev;
704
705     while ((dev = QLIST_FIRST(&bus->children)) != NULL) {
706         qdev_free(dev);
707     }
708     if (bus->parent) {
709         QLIST_REMOVE(bus, sibling);
710         bus->parent->num_child_bus--;
711     }
712     qemu_free((void*)bus->name);
713     if (bus->qdev_allocated) {
714         qemu_free(bus);
715     }
716 }
717
718 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
719 static void qbus_print(Monitor *mon, BusState *bus, int indent);
720
721 static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
722                              const char *prefix, int indent)
723 {
724     char buf[64];
725
726     if (!props)
727         return;
728     while (props->name) {
729         /*
730          * TODO Properties without a print method are just for dirty
731          * hacks.  qdev_prop_ptr is the only such PropertyInfo.  It's
732          * marked for removal.  The test props->info->print should be
733          * removed along with it.
734          */
735         if (props->info->print) {
736             props->info->print(dev, props, buf, sizeof(buf));
737             qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
738         }
739         props++;
740     }
741 }
742
743 static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
744 {
745     BusState *child;
746     qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
747                 dev->id ? dev->id : "");
748     indent += 2;
749     if (dev->num_gpio_in) {
750         qdev_printf("gpio-in %d\n", dev->num_gpio_in);
751     }
752     if (dev->num_gpio_out) {
753         qdev_printf("gpio-out %d\n", dev->num_gpio_out);
754     }
755     qdev_print_props(mon, dev, dev->info->props, "dev", indent);
756     qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
757     if (dev->parent_bus->info->print_dev)
758         dev->parent_bus->info->print_dev(mon, dev, indent);
759     QLIST_FOREACH(child, &dev->child_bus, sibling) {
760         qbus_print(mon, child, indent);
761     }
762 }
763
764 static void qbus_print(Monitor *mon, BusState *bus, int indent)
765 {
766     struct DeviceState *dev;
767
768     qdev_printf("bus: %s\n", bus->name);
769     indent += 2;
770     qdev_printf("type %s\n", bus->info->name);
771     QLIST_FOREACH(dev, &bus->children, sibling) {
772         qdev_print(mon, dev, indent);
773     }
774 }
775 #undef qdev_printf
776
777 void do_info_qtree(Monitor *mon)
778 {
779     if (main_system_bus)
780         qbus_print(mon, main_system_bus, 0);
781 }
782
783 void do_info_qdm(Monitor *mon)
784 {
785     DeviceInfo *info;
786
787     for (info = device_info_list; info != NULL; info = info->next) {
788         qdev_print_devinfo(info);
789     }
790 }
791
792 int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
793 {
794     QemuOpts *opts;
795
796     opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict);
797     if (!opts) {
798         return -1;
799     }
800     if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
801         qemu_opts_del(opts);
802         return 0;
803     }
804     if (!qdev_device_add(opts)) {
805         qemu_opts_del(opts);
806         return -1;
807     }
808     return 0;
809 }
810
811 int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
812 {
813     const char *id = qdict_get_str(qdict, "id");
814     DeviceState *dev;
815
816     dev = qdev_find_recursive(main_system_bus, id);
817     if (NULL == dev) {
818         qerror_report(QERR_DEVICE_NOT_FOUND, id);
819         return -1;
820     }
821     return qdev_unplug(dev);
822 }
This page took 0.069459 seconds and 4 git commands to generate.