]> Git Repo - qemu.git/blob - hw/qdev.c
blockdev: New drive_get_next(), replacing qdev_init_bdrv()
[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 static bool qdev_hot_added = false;
36 static bool qdev_hot_removed = false;
37
38 /* This is a nasty hack to allow passing a NULL bus to qdev_create.  */
39 static BusState *main_system_bus;
40
41 DeviceInfo *device_info_list;
42
43 static BusState *qbus_find_recursive(BusState *bus, const char *name,
44                                      const BusInfo *info);
45 static BusState *qbus_find(const char *path);
46
47 /* Register a new device type.  */
48 void qdev_register(DeviceInfo *info)
49 {
50     assert(info->size >= sizeof(DeviceState));
51     assert(!info->next);
52
53     info->next = device_info_list;
54     device_info_list = info;
55 }
56
57 static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name)
58 {
59     DeviceInfo *info;
60
61     /* first check device names */
62     for (info = device_info_list; info != NULL; info = info->next) {
63         if (bus_info && info->bus_info != bus_info)
64             continue;
65         if (strcmp(info->name, name) != 0)
66             continue;
67         return info;
68     }
69
70     /* failing that check the aliases */
71     for (info = device_info_list; info != NULL; info = info->next) {
72         if (bus_info && info->bus_info != bus_info)
73             continue;
74         if (!info->alias)
75             continue;
76         if (strcmp(info->alias, name) != 0)
77             continue;
78         return info;
79     }
80     return NULL;
81 }
82
83 static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
84 {
85     DeviceState *dev;
86
87     assert(bus->info == info->bus_info);
88     dev = qemu_mallocz(info->size);
89     dev->info = info;
90     dev->parent_bus = bus;
91     qdev_prop_set_defaults(dev, dev->info->props);
92     qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
93     qdev_prop_set_globals(dev);
94     QLIST_INSERT_HEAD(&bus->children, dev, sibling);
95     if (qdev_hotplug) {
96         assert(bus->allow_hotplug);
97         dev->hotplugged = 1;
98         qdev_hot_added = true;
99     }
100     dev->instance_id_alias = -1;
101     dev->state = DEV_STATE_CREATED;
102     return dev;
103 }
104
105 /* Create a new device.  This only initializes the device state structure
106    and allows properties to be set.  qdev_init should be called to
107    initialize the actual device emulation.  */
108 DeviceState *qdev_create(BusState *bus, const char *name)
109 {
110     DeviceInfo *info;
111
112     if (!bus) {
113         bus = sysbus_get_default();
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     qdev_hot_removed = true;
301
302     return dev->info->unplug(dev);
303 }
304
305 static int qdev_reset_one(DeviceState *dev, void *opaque)
306 {
307     if (dev->info->reset) {
308         dev->info->reset(dev);
309     }
310
311     return 0;
312 }
313
314 BusState *sysbus_get_default(void)
315 {
316     if (!main_system_bus) {
317         main_system_bus = qbus_create(&system_bus_info, NULL,
318                                       "main-system-bus");
319     }
320     return main_system_bus;
321 }
322
323 static int qbus_reset_one(BusState *bus, void *opaque)
324 {
325     if (bus->info->reset) {
326         return bus->info->reset(bus);
327     }
328     return 0;
329 }
330
331 void qdev_reset_all(DeviceState *dev)
332 {
333     qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
334 }
335
336 void qbus_reset_all_fn(void *opaque)
337 {
338     BusState *bus = opaque;
339     qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
340 }
341
342 /* can be used as ->unplug() callback for the simple cases */
343 int qdev_simple_unplug_cb(DeviceState *dev)
344 {
345     /* just zap it */
346     qdev_free(dev);
347     return 0;
348 }
349
350 /* Like qdev_init(), but terminate program via hw_error() instead of
351    returning an error value.  This is okay during machine creation.
352    Don't use for hotplug, because there callers need to recover from
353    failure.  Exception: if you know the device's init() callback can't
354    fail, then qdev_init_nofail() can't fail either, and is therefore
355    usable even then.  But relying on the device implementation that
356    way is somewhat unclean, and best avoided.  */
357 void qdev_init_nofail(DeviceState *dev)
358 {
359     DeviceInfo *info = dev->info;
360
361     if (qdev_init(dev) < 0) {
362         error_report("Initialization of device %s failed\n", info->name);
363         exit(1);
364     }
365 }
366
367 /* Unlink device from bus and free the structure.  */
368 void qdev_free(DeviceState *dev)
369 {
370     BusState *bus;
371     Property *prop;
372
373     if (dev->state == DEV_STATE_INITIALIZED) {
374         while (dev->num_child_bus) {
375             bus = QLIST_FIRST(&dev->child_bus);
376             qbus_free(bus);
377         }
378         if (dev->info->vmsd)
379             vmstate_unregister(dev, dev->info->vmsd, dev);
380         if (dev->info->exit)
381             dev->info->exit(dev);
382         if (dev->opts)
383             qemu_opts_del(dev->opts);
384     }
385     QLIST_REMOVE(dev, sibling);
386     for (prop = dev->info->props; prop && prop->name; prop++) {
387         if (prop->info->free) {
388             prop->info->free(dev, prop);
389         }
390     }
391     qemu_free(dev);
392 }
393
394 void qdev_machine_creation_done(void)
395 {
396     /*
397      * ok, initial machine setup is done, starting from now we can
398      * only create hotpluggable devices
399      */
400     qdev_hotplug = 1;
401 }
402
403 bool qdev_machine_modified(void)
404 {
405     return qdev_hot_added || qdev_hot_removed;
406 }
407
408 /* Get a character (serial) device interface.  */
409 CharDriverState *qdev_init_chardev(DeviceState *dev)
410 {
411     static int next_serial;
412
413     /* FIXME: This function needs to go away: use chardev properties!  */
414     return serial_hds[next_serial++];
415 }
416
417 BusState *qdev_get_parent_bus(DeviceState *dev)
418 {
419     return dev->parent_bus;
420 }
421
422 void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
423 {
424     assert(dev->num_gpio_in == 0);
425     dev->num_gpio_in = n;
426     dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
427 }
428
429 void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
430 {
431     assert(dev->num_gpio_out == 0);
432     dev->num_gpio_out = n;
433     dev->gpio_out = pins;
434 }
435
436 qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
437 {
438     assert(n >= 0 && n < dev->num_gpio_in);
439     return dev->gpio_in[n];
440 }
441
442 void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
443 {
444     assert(n >= 0 && n < dev->num_gpio_out);
445     dev->gpio_out[n] = pin;
446 }
447
448 void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
449 {
450     qdev_prop_set_macaddr(dev, "mac", nd->macaddr);
451     if (nd->vlan)
452         qdev_prop_set_vlan(dev, "vlan", nd->vlan);
453     if (nd->netdev)
454         qdev_prop_set_netdev(dev, "netdev", nd->netdev);
455     if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
456         qdev_prop_exists(dev, "vectors")) {
457         qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
458     }
459 }
460
461 BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
462 {
463     BusState *bus;
464
465     QLIST_FOREACH(bus, &dev->child_bus, sibling) {
466         if (strcmp(name, bus->name) == 0) {
467             return bus;
468         }
469     }
470     return NULL;
471 }
472
473 int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
474                        qbus_walkerfn *busfn, void *opaque)
475 {
476     DeviceState *dev;
477     int err;
478
479     if (busfn) {
480         err = busfn(bus, opaque);
481         if (err) {
482             return err;
483         }
484     }
485
486     QLIST_FOREACH(dev, &bus->children, sibling) {
487         err = qdev_walk_children(dev, devfn, busfn, opaque);
488         if (err < 0) {
489             return err;
490         }
491     }
492
493     return 0;
494 }
495
496 int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
497                        qbus_walkerfn *busfn, void *opaque)
498 {
499     BusState *bus;
500     int err;
501
502     if (devfn) {
503         err = devfn(dev, opaque);
504         if (err) {
505             return err;
506         }
507     }
508
509     QLIST_FOREACH(bus, &dev->child_bus, sibling) {
510         err = qbus_walk_children(bus, devfn, busfn, opaque);
511         if (err < 0) {
512             return err;
513         }
514     }
515
516     return 0;
517 }
518
519 static BusState *qbus_find_recursive(BusState *bus, const char *name,
520                                      const BusInfo *info)
521 {
522     DeviceState *dev;
523     BusState *child, *ret;
524     int match = 1;
525
526     if (name && (strcmp(bus->name, name) != 0)) {
527         match = 0;
528     }
529     if (info && (bus->info != info)) {
530         match = 0;
531     }
532     if (match) {
533         return bus;
534     }
535
536     QLIST_FOREACH(dev, &bus->children, sibling) {
537         QLIST_FOREACH(child, &dev->child_bus, sibling) {
538             ret = qbus_find_recursive(child, name, info);
539             if (ret) {
540                 return ret;
541             }
542         }
543     }
544     return NULL;
545 }
546
547 DeviceState *qdev_find_recursive(BusState *bus, const char *id)
548 {
549     DeviceState *dev, *ret;
550     BusState *child;
551
552     QLIST_FOREACH(dev, &bus->children, sibling) {
553         if (dev->id && strcmp(dev->id, id) == 0)
554             return dev;
555         QLIST_FOREACH(child, &dev->child_bus, sibling) {
556             ret = qdev_find_recursive(child, id);
557             if (ret) {
558                 return ret;
559             }
560         }
561     }
562     return NULL;
563 }
564
565 static void qbus_list_bus(DeviceState *dev)
566 {
567     BusState *child;
568     const char *sep = " ";
569
570     error_printf("child busses at \"%s\":",
571                  dev->id ? dev->id : dev->info->name);
572     QLIST_FOREACH(child, &dev->child_bus, sibling) {
573         error_printf("%s\"%s\"", sep, child->name);
574         sep = ", ";
575     }
576     error_printf("\n");
577 }
578
579 static void qbus_list_dev(BusState *bus)
580 {
581     DeviceState *dev;
582     const char *sep = " ";
583
584     error_printf("devices at \"%s\":", bus->name);
585     QLIST_FOREACH(dev, &bus->children, sibling) {
586         error_printf("%s\"%s\"", sep, dev->info->name);
587         if (dev->id)
588             error_printf("/\"%s\"", dev->id);
589         sep = ", ";
590     }
591     error_printf("\n");
592 }
593
594 static BusState *qbus_find_bus(DeviceState *dev, char *elem)
595 {
596     BusState *child;
597
598     QLIST_FOREACH(child, &dev->child_bus, sibling) {
599         if (strcmp(child->name, elem) == 0) {
600             return child;
601         }
602     }
603     return NULL;
604 }
605
606 static DeviceState *qbus_find_dev(BusState *bus, char *elem)
607 {
608     DeviceState *dev;
609
610     /*
611      * try to match in order:
612      *   (1) instance id, if present
613      *   (2) driver name
614      *   (3) driver alias, if present
615      */
616     QLIST_FOREACH(dev, &bus->children, sibling) {
617         if (dev->id  &&  strcmp(dev->id, elem) == 0) {
618             return dev;
619         }
620     }
621     QLIST_FOREACH(dev, &bus->children, sibling) {
622         if (strcmp(dev->info->name, elem) == 0) {
623             return dev;
624         }
625     }
626     QLIST_FOREACH(dev, &bus->children, sibling) {
627         if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) {
628             return dev;
629         }
630     }
631     return NULL;
632 }
633
634 static BusState *qbus_find(const char *path)
635 {
636     DeviceState *dev;
637     BusState *bus;
638     char elem[128];
639     int pos, len;
640
641     /* find start element */
642     if (path[0] == '/') {
643         bus = main_system_bus;
644         pos = 0;
645     } else {
646         if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
647             assert(!path[0]);
648             elem[0] = len = 0;
649         }
650         bus = qbus_find_recursive(main_system_bus, elem, NULL);
651         if (!bus) {
652             qerror_report(QERR_BUS_NOT_FOUND, elem);
653             return NULL;
654         }
655         pos = len;
656     }
657
658     for (;;) {
659         assert(path[pos] == '/' || !path[pos]);
660         while (path[pos] == '/') {
661             pos++;
662         }
663         if (path[pos] == '\0') {
664             return bus;
665         }
666
667         /* find device */
668         if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
669             assert(0);
670             elem[0] = len = 0;
671         }
672         pos += len;
673         dev = qbus_find_dev(bus, elem);
674         if (!dev) {
675             qerror_report(QERR_DEVICE_NOT_FOUND, elem);
676             if (!monitor_cur_is_qmp()) {
677                 qbus_list_dev(bus);
678             }
679             return NULL;
680         }
681
682         assert(path[pos] == '/' || !path[pos]);
683         while (path[pos] == '/') {
684             pos++;
685         }
686         if (path[pos] == '\0') {
687             /* last specified element is a device.  If it has exactly
688              * one child bus accept it nevertheless */
689             switch (dev->num_child_bus) {
690             case 0:
691                 qerror_report(QERR_DEVICE_NO_BUS, elem);
692                 return NULL;
693             case 1:
694                 return QLIST_FIRST(&dev->child_bus);
695             default:
696                 qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
697                 if (!monitor_cur_is_qmp()) {
698                     qbus_list_bus(dev);
699                 }
700                 return NULL;
701             }
702         }
703
704         /* find bus */
705         if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
706             assert(0);
707             elem[0] = len = 0;
708         }
709         pos += len;
710         bus = qbus_find_bus(dev, elem);
711         if (!bus) {
712             qerror_report(QERR_BUS_NOT_FOUND, elem);
713             if (!monitor_cur_is_qmp()) {
714                 qbus_list_bus(dev);
715             }
716             return NULL;
717         }
718     }
719 }
720
721 void qbus_create_inplace(BusState *bus, BusInfo *info,
722                          DeviceState *parent, const char *name)
723 {
724     char *buf;
725     int i,len;
726
727     bus->info = info;
728     bus->parent = parent;
729
730     if (name) {
731         /* use supplied name */
732         bus->name = qemu_strdup(name);
733     } else if (parent && parent->id) {
734         /* parent device has id -> use it for bus name */
735         len = strlen(parent->id) + 16;
736         buf = qemu_malloc(len);
737         snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
738         bus->name = buf;
739     } else {
740         /* no id -> use lowercase bus type for bus name */
741         len = strlen(info->name) + 16;
742         buf = qemu_malloc(len);
743         len = snprintf(buf, len, "%s.%d", info->name,
744                        parent ? parent->num_child_bus : 0);
745         for (i = 0; i < len; i++)
746             buf[i] = qemu_tolower(buf[i]);
747         bus->name = buf;
748     }
749
750     QLIST_INIT(&bus->children);
751     if (parent) {
752         QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
753         parent->num_child_bus++;
754     } else if (bus != main_system_bus) {
755         /* TODO: once all bus devices are qdevified,
756            only reset handler for main_system_bus should be registered here. */
757         qemu_register_reset(qbus_reset_all_fn, bus);
758     }
759 }
760
761 BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
762 {
763     BusState *bus;
764
765     bus = qemu_mallocz(info->size);
766     bus->qdev_allocated = 1;
767     qbus_create_inplace(bus, info, parent, name);
768     return bus;
769 }
770
771 void qbus_free(BusState *bus)
772 {
773     DeviceState *dev;
774
775     while ((dev = QLIST_FIRST(&bus->children)) != NULL) {
776         qdev_free(dev);
777     }
778     if (bus->parent) {
779         QLIST_REMOVE(bus, sibling);
780         bus->parent->num_child_bus--;
781     } else {
782         assert(bus != main_system_bus); /* main_system_bus is never freed */
783         qemu_unregister_reset(qbus_reset_all_fn, bus);
784     }
785     qemu_free((void*)bus->name);
786     if (bus->qdev_allocated) {
787         qemu_free(bus);
788     }
789 }
790
791 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
792 static void qbus_print(Monitor *mon, BusState *bus, int indent);
793
794 static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
795                              const char *prefix, int indent)
796 {
797     char buf[64];
798
799     if (!props)
800         return;
801     while (props->name) {
802         /*
803          * TODO Properties without a print method are just for dirty
804          * hacks.  qdev_prop_ptr is the only such PropertyInfo.  It's
805          * marked for removal.  The test props->info->print should be
806          * removed along with it.
807          */
808         if (props->info->print) {
809             props->info->print(dev, props, buf, sizeof(buf));
810             qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
811         }
812         props++;
813     }
814 }
815
816 static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
817 {
818     BusState *child;
819     qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
820                 dev->id ? dev->id : "");
821     indent += 2;
822     if (dev->num_gpio_in) {
823         qdev_printf("gpio-in %d\n", dev->num_gpio_in);
824     }
825     if (dev->num_gpio_out) {
826         qdev_printf("gpio-out %d\n", dev->num_gpio_out);
827     }
828     qdev_print_props(mon, dev, dev->info->props, "dev", indent);
829     qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
830     if (dev->parent_bus->info->print_dev)
831         dev->parent_bus->info->print_dev(mon, dev, indent);
832     QLIST_FOREACH(child, &dev->child_bus, sibling) {
833         qbus_print(mon, child, indent);
834     }
835 }
836
837 static void qbus_print(Monitor *mon, BusState *bus, int indent)
838 {
839     struct DeviceState *dev;
840
841     qdev_printf("bus: %s\n", bus->name);
842     indent += 2;
843     qdev_printf("type %s\n", bus->info->name);
844     QLIST_FOREACH(dev, &bus->children, sibling) {
845         qdev_print(mon, dev, indent);
846     }
847 }
848 #undef qdev_printf
849
850 void do_info_qtree(Monitor *mon)
851 {
852     if (main_system_bus)
853         qbus_print(mon, main_system_bus, 0);
854 }
855
856 void do_info_qdm(Monitor *mon)
857 {
858     DeviceInfo *info;
859
860     for (info = device_info_list; info != NULL; info = info->next) {
861         qdev_print_devinfo(info);
862     }
863 }
864
865 int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
866 {
867     QemuOpts *opts;
868
869     opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict);
870     if (!opts) {
871         return -1;
872     }
873     if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
874         qemu_opts_del(opts);
875         return 0;
876     }
877     if (!qdev_device_add(opts)) {
878         qemu_opts_del(opts);
879         return -1;
880     }
881     return 0;
882 }
883
884 int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
885 {
886     const char *id = qdict_get_str(qdict, "id");
887     DeviceState *dev;
888
889     dev = qdev_find_recursive(main_system_bus, id);
890     if (NULL == dev) {
891         qerror_report(QERR_DEVICE_NOT_FOUND, id);
892         return -1;
893     }
894     return qdev_unplug(dev);
895 }
896
897 static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
898 {
899     int l = 0;
900
901     if (dev && dev->parent_bus) {
902         char *d;
903         l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
904         if (dev->parent_bus->info->get_fw_dev_path) {
905             d = dev->parent_bus->info->get_fw_dev_path(dev);
906             l += snprintf(p + l, size - l, "%s", d);
907             qemu_free(d);
908         } else {
909             l += snprintf(p + l, size - l, "%s", dev->info->name);
910         }
911     }
912     l += snprintf(p + l , size - l, "/");
913
914     return l;
915 }
916
917 char* qdev_get_fw_dev_path(DeviceState *dev)
918 {
919     char path[128];
920     int l;
921
922     l = qdev_get_fw_dev_path_helper(dev, path, 128);
923
924     path[l-1] = '\0';
925
926     return strdup(path);
927 }
This page took 0.072542 seconds and 4 git commands to generate.