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