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