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