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