]> Git Repo - qemu.git/blob - hw/qdev.c
qdev: add a qdev_get_type() function and expose as a 'type' property
[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     Property *prop;
87
88     assert(bus->info == info->bus_info);
89     dev = g_malloc0(info->size);
90     dev->info = info;
91     dev->parent_bus = bus;
92     qdev_prop_set_defaults(dev, dev->info->props);
93     qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
94     qdev_prop_set_globals(dev);
95     QTAILQ_INSERT_HEAD(&bus->children, dev, sibling);
96     if (qdev_hotplug) {
97         assert(bus->allow_hotplug);
98         dev->hotplugged = 1;
99         qdev_hot_added = true;
100     }
101     dev->instance_id_alias = -1;
102     QTAILQ_INIT(&dev->properties);
103     dev->state = DEV_STATE_CREATED;
104
105     for (prop = dev->info->props; prop && prop->name; prop++) {
106         qdev_property_add_legacy(dev, prop, NULL);
107     }
108
109     for (prop = dev->info->bus_info->props; prop && prop->name; prop++) {
110         qdev_property_add_legacy(dev, prop, NULL);
111     }
112
113     qdev_property_add_str(dev, "type", qdev_get_type, NULL, NULL);
114
115     return dev;
116 }
117
118 /* Create a new device.  This only initializes the device state structure
119    and allows properties to be set.  qdev_init should be called to
120    initialize the actual device emulation.  */
121 DeviceState *qdev_create(BusState *bus, const char *name)
122 {
123     DeviceState *dev;
124
125     dev = qdev_try_create(bus, name);
126     if (!dev) {
127         if (bus) {
128             hw_error("Unknown device '%s' for bus '%s'\n", name,
129                      bus->info->name);
130         } else {
131             hw_error("Unknown device '%s' for default sysbus\n", name);
132         }
133     }
134
135     return dev;
136 }
137
138 DeviceState *qdev_try_create(BusState *bus, const char *name)
139 {
140     DeviceInfo *info;
141
142     if (!bus) {
143         bus = sysbus_get_default();
144     }
145
146     info = qdev_find_info(bus->info, name);
147     if (!info) {
148         return NULL;
149     }
150
151     return qdev_create_from_info(bus, info);
152 }
153
154 static void qdev_print_devinfo(DeviceInfo *info)
155 {
156     error_printf("name \"%s\", bus %s",
157                  info->name, info->bus_info->name);
158     if (info->alias) {
159         error_printf(", alias \"%s\"", info->alias);
160     }
161     if (info->desc) {
162         error_printf(", desc \"%s\"", info->desc);
163     }
164     if (info->no_user) {
165         error_printf(", no-user");
166     }
167     error_printf("\n");
168 }
169
170 static int set_property(const char *name, const char *value, void *opaque)
171 {
172     DeviceState *dev = opaque;
173
174     if (strcmp(name, "driver") == 0)
175         return 0;
176     if (strcmp(name, "bus") == 0)
177         return 0;
178
179     if (qdev_prop_parse(dev, name, value) == -1) {
180         return -1;
181     }
182     return 0;
183 }
184
185 int qdev_device_help(QemuOpts *opts)
186 {
187     const char *driver;
188     DeviceInfo *info;
189     Property *prop;
190
191     driver = qemu_opt_get(opts, "driver");
192     if (driver && !strcmp(driver, "?")) {
193         for (info = device_info_list; info != NULL; info = info->next) {
194             if (info->no_user) {
195                 continue;       /* not available, don't show */
196             }
197             qdev_print_devinfo(info);
198         }
199         return 1;
200     }
201
202     if (!driver || !qemu_opt_get(opts, "?")) {
203         return 0;
204     }
205
206     info = qdev_find_info(NULL, driver);
207     if (!info) {
208         return 0;
209     }
210
211     for (prop = info->props; prop && prop->name; prop++) {
212         /*
213          * TODO Properties without a parser are just for dirty hacks.
214          * qdev_prop_ptr is the only such PropertyInfo.  It's marked
215          * for removal.  This conditional should be removed along with
216          * it.
217          */
218         if (!prop->info->parse) {
219             continue;           /* no way to set it, don't show */
220         }
221         error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name);
222     }
223     for (prop = info->bus_info->props; prop && prop->name; prop++) {
224         if (!prop->info->parse) {
225             continue;           /* no way to set it, don't show */
226         }
227         error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name);
228     }
229     return 1;
230 }
231
232 static DeviceState *qdev_get_peripheral(void)
233 {
234     static DeviceState *dev;
235
236     if (dev == NULL) {
237         dev = qdev_create(NULL, "container");
238         qdev_property_add_child(qdev_get_root(), "peripheral", dev, NULL);
239         qdev_init_nofail(dev);
240     }
241
242     return dev;
243 }
244
245 static DeviceState *qdev_get_peripheral_anon(void)
246 {
247     static DeviceState *dev;
248
249     if (dev == NULL) {
250         dev = qdev_create(NULL, "container");
251         qdev_property_add_child(qdev_get_root(), "peripheral-anon", dev, NULL);
252         qdev_init_nofail(dev);
253     }
254
255     return dev;
256 }
257
258 DeviceState *qdev_device_add(QemuOpts *opts)
259 {
260     const char *driver, *path, *id;
261     DeviceInfo *info;
262     DeviceState *qdev;
263     BusState *bus;
264
265     driver = qemu_opt_get(opts, "driver");
266     if (!driver) {
267         qerror_report(QERR_MISSING_PARAMETER, "driver");
268         return NULL;
269     }
270
271     /* find driver */
272     info = qdev_find_info(NULL, driver);
273     if (!info || info->no_user) {
274         qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", "a driver name");
275         error_printf_unless_qmp("Try with argument '?' for a list.\n");
276         return NULL;
277     }
278
279     /* find bus */
280     path = qemu_opt_get(opts, "bus");
281     if (path != NULL) {
282         bus = qbus_find(path);
283         if (!bus) {
284             return NULL;
285         }
286         if (bus->info != info->bus_info) {
287             qerror_report(QERR_BAD_BUS_FOR_DEVICE,
288                            driver, bus->info->name);
289             return NULL;
290         }
291     } else {
292         bus = qbus_find_recursive(main_system_bus, NULL, info->bus_info);
293         if (!bus) {
294             qerror_report(QERR_NO_BUS_FOR_DEVICE,
295                            info->name, info->bus_info->name);
296             return NULL;
297         }
298     }
299     if (qdev_hotplug && !bus->allow_hotplug) {
300         qerror_report(QERR_BUS_NO_HOTPLUG, bus->name);
301         return NULL;
302     }
303
304     /* create device, set properties */
305     qdev = qdev_create_from_info(bus, info);
306     id = qemu_opts_id(opts);
307     if (id) {
308         qdev->id = id;
309         qdev_property_add_child(qdev_get_peripheral(), qdev->id, qdev, NULL);
310     } else {
311         static int anon_count;
312         gchar *name = g_strdup_printf("device[%d]", anon_count++);
313         qdev_property_add_child(qdev_get_peripheral_anon(), name,
314                                 qdev, NULL);
315         g_free(name);
316     }        
317     if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
318         qdev_free(qdev);
319         return NULL;
320     }
321     if (qdev_init(qdev) < 0) {
322         qerror_report(QERR_DEVICE_INIT_FAILED, driver);
323         return NULL;
324     }
325     qdev->opts = opts;
326     return qdev;
327 }
328
329 /* Initialize a device.  Device properties should be set before calling
330    this function.  IRQs and MMIO regions should be connected/mapped after
331    calling this function.
332    On failure, destroy the device and return negative value.
333    Return 0 on success.  */
334 int qdev_init(DeviceState *dev)
335 {
336     int rc;
337
338     assert(dev->state == DEV_STATE_CREATED);
339     rc = dev->info->init(dev, dev->info);
340     if (rc < 0) {
341         qdev_free(dev);
342         return rc;
343     }
344     if (dev->info->vmsd) {
345         vmstate_register_with_alias_id(dev, -1, dev->info->vmsd, dev,
346                                        dev->instance_id_alias,
347                                        dev->alias_required_for_version);
348     }
349     dev->state = DEV_STATE_INITIALIZED;
350     if (dev->hotplugged && dev->info->reset) {
351         dev->info->reset(dev);
352     }
353     return 0;
354 }
355
356 void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
357                                  int required_for_version)
358 {
359     assert(dev->state == DEV_STATE_CREATED);
360     dev->instance_id_alias = alias_id;
361     dev->alias_required_for_version = required_for_version;
362 }
363
364 int qdev_unplug(DeviceState *dev)
365 {
366     if (!dev->parent_bus->allow_hotplug) {
367         qerror_report(QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
368         return -1;
369     }
370     assert(dev->info->unplug != NULL);
371
372     if (dev->ref != 0) {
373         qerror_report(QERR_DEVICE_IN_USE, dev->id?:"");
374         return -1;
375     }
376
377     qdev_hot_removed = true;
378
379     return dev->info->unplug(dev);
380 }
381
382 static int qdev_reset_one(DeviceState *dev, void *opaque)
383 {
384     if (dev->info->reset) {
385         dev->info->reset(dev);
386     }
387
388     return 0;
389 }
390
391 BusState *sysbus_get_default(void)
392 {
393     if (!main_system_bus) {
394         main_system_bus_create();
395     }
396     return main_system_bus;
397 }
398
399 static int qbus_reset_one(BusState *bus, void *opaque)
400 {
401     if (bus->info->reset) {
402         return bus->info->reset(bus);
403     }
404     return 0;
405 }
406
407 void qdev_reset_all(DeviceState *dev)
408 {
409     qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
410 }
411
412 void qbus_reset_all_fn(void *opaque)
413 {
414     BusState *bus = opaque;
415     qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
416 }
417
418 /* can be used as ->unplug() callback for the simple cases */
419 int qdev_simple_unplug_cb(DeviceState *dev)
420 {
421     /* just zap it */
422     qdev_free(dev);
423     return 0;
424 }
425
426
427 /* Like qdev_init(), but terminate program via error_report() instead of
428    returning an error value.  This is okay during machine creation.
429    Don't use for hotplug, because there callers need to recover from
430    failure.  Exception: if you know the device's init() callback can't
431    fail, then qdev_init_nofail() can't fail either, and is therefore
432    usable even then.  But relying on the device implementation that
433    way is somewhat unclean, and best avoided.  */
434 void qdev_init_nofail(DeviceState *dev)
435 {
436     DeviceInfo *info = dev->info;
437
438     if (qdev_init(dev) < 0) {
439         error_report("Initialization of device %s failed", info->name);
440         exit(1);
441     }
442 }
443
444 static void qdev_property_del_all(DeviceState *dev)
445 {
446     while (!QTAILQ_EMPTY(&dev->properties)) {
447         DeviceProperty *prop = QTAILQ_FIRST(&dev->properties);
448
449         QTAILQ_REMOVE(&dev->properties, prop, node);
450
451         if (prop->release) {
452             prop->release(dev, prop->name, prop->opaque);
453         }
454
455         g_free(prop->name);
456         g_free(prop->type);
457         g_free(prop);
458     }
459 }
460
461 /* Unlink device from bus and free the structure.  */
462 void qdev_free(DeviceState *dev)
463 {
464     BusState *bus;
465     Property *prop;
466
467     qdev_property_del_all(dev);
468
469     if (dev->state == DEV_STATE_INITIALIZED) {
470         while (dev->num_child_bus) {
471             bus = QLIST_FIRST(&dev->child_bus);
472             qbus_free(bus);
473         }
474         if (dev->info->vmsd)
475             vmstate_unregister(dev, dev->info->vmsd, dev);
476         if (dev->info->exit)
477             dev->info->exit(dev);
478         if (dev->opts)
479             qemu_opts_del(dev->opts);
480     }
481     QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling);
482     for (prop = dev->info->props; prop && prop->name; prop++) {
483         if (prop->info->free) {
484             prop->info->free(dev, prop);
485         }
486     }
487     g_free(dev);
488 }
489
490 void qdev_machine_creation_done(void)
491 {
492     /*
493      * ok, initial machine setup is done, starting from now we can
494      * only create hotpluggable devices
495      */
496     qdev_hotplug = 1;
497 }
498
499 bool qdev_machine_modified(void)
500 {
501     return qdev_hot_added || qdev_hot_removed;
502 }
503
504 /* Get a character (serial) device interface.  */
505 CharDriverState *qdev_init_chardev(DeviceState *dev)
506 {
507     static int next_serial;
508
509     /* FIXME: This function needs to go away: use chardev properties!  */
510     return serial_hds[next_serial++];
511 }
512
513 BusState *qdev_get_parent_bus(DeviceState *dev)
514 {
515     return dev->parent_bus;
516 }
517
518 void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
519 {
520     assert(dev->num_gpio_in == 0);
521     dev->num_gpio_in = n;
522     dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
523 }
524
525 void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
526 {
527     assert(dev->num_gpio_out == 0);
528     dev->num_gpio_out = n;
529     dev->gpio_out = pins;
530 }
531
532 qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
533 {
534     assert(n >= 0 && n < dev->num_gpio_in);
535     return dev->gpio_in[n];
536 }
537
538 void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
539 {
540     assert(n >= 0 && n < dev->num_gpio_out);
541     dev->gpio_out[n] = pin;
542 }
543
544 void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
545 {
546     qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a);
547     if (nd->vlan)
548         qdev_prop_set_vlan(dev, "vlan", nd->vlan);
549     if (nd->netdev)
550         qdev_prop_set_netdev(dev, "netdev", nd->netdev);
551     if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
552         qdev_prop_exists(dev, "vectors")) {
553         qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
554     }
555     nd->instantiated = 1;
556 }
557
558 BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
559 {
560     BusState *bus;
561
562     QLIST_FOREACH(bus, &dev->child_bus, sibling) {
563         if (strcmp(name, bus->name) == 0) {
564             return bus;
565         }
566     }
567     return NULL;
568 }
569
570 int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
571                        qbus_walkerfn *busfn, void *opaque)
572 {
573     DeviceState *dev;
574     int err;
575
576     if (busfn) {
577         err = busfn(bus, opaque);
578         if (err) {
579             return err;
580         }
581     }
582
583     QTAILQ_FOREACH(dev, &bus->children, sibling) {
584         err = qdev_walk_children(dev, devfn, busfn, opaque);
585         if (err < 0) {
586             return err;
587         }
588     }
589
590     return 0;
591 }
592
593 int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
594                        qbus_walkerfn *busfn, void *opaque)
595 {
596     BusState *bus;
597     int err;
598
599     if (devfn) {
600         err = devfn(dev, opaque);
601         if (err) {
602             return err;
603         }
604     }
605
606     QLIST_FOREACH(bus, &dev->child_bus, sibling) {
607         err = qbus_walk_children(bus, devfn, busfn, opaque);
608         if (err < 0) {
609             return err;
610         }
611     }
612
613     return 0;
614 }
615
616 static BusState *qbus_find_recursive(BusState *bus, const char *name,
617                                      const BusInfo *info)
618 {
619     DeviceState *dev;
620     BusState *child, *ret;
621     int match = 1;
622
623     if (name && (strcmp(bus->name, name) != 0)) {
624         match = 0;
625     }
626     if (info && (bus->info != info)) {
627         match = 0;
628     }
629     if (match) {
630         return bus;
631     }
632
633     QTAILQ_FOREACH(dev, &bus->children, sibling) {
634         QLIST_FOREACH(child, &dev->child_bus, sibling) {
635             ret = qbus_find_recursive(child, name, info);
636             if (ret) {
637                 return ret;
638             }
639         }
640     }
641     return NULL;
642 }
643
644 DeviceState *qdev_find_recursive(BusState *bus, const char *id)
645 {
646     DeviceState *dev, *ret;
647     BusState *child;
648
649     QTAILQ_FOREACH(dev, &bus->children, sibling) {
650         if (dev->id && strcmp(dev->id, id) == 0)
651             return dev;
652         QLIST_FOREACH(child, &dev->child_bus, sibling) {
653             ret = qdev_find_recursive(child, id);
654             if (ret) {
655                 return ret;
656             }
657         }
658     }
659     return NULL;
660 }
661
662 static void qbus_list_bus(DeviceState *dev)
663 {
664     BusState *child;
665     const char *sep = " ";
666
667     error_printf("child busses at \"%s\":",
668                  dev->id ? dev->id : dev->info->name);
669     QLIST_FOREACH(child, &dev->child_bus, sibling) {
670         error_printf("%s\"%s\"", sep, child->name);
671         sep = ", ";
672     }
673     error_printf("\n");
674 }
675
676 static void qbus_list_dev(BusState *bus)
677 {
678     DeviceState *dev;
679     const char *sep = " ";
680
681     error_printf("devices at \"%s\":", bus->name);
682     QTAILQ_FOREACH(dev, &bus->children, sibling) {
683         error_printf("%s\"%s\"", sep, dev->info->name);
684         if (dev->id)
685             error_printf("/\"%s\"", dev->id);
686         sep = ", ";
687     }
688     error_printf("\n");
689 }
690
691 static BusState *qbus_find_bus(DeviceState *dev, char *elem)
692 {
693     BusState *child;
694
695     QLIST_FOREACH(child, &dev->child_bus, sibling) {
696         if (strcmp(child->name, elem) == 0) {
697             return child;
698         }
699     }
700     return NULL;
701 }
702
703 static DeviceState *qbus_find_dev(BusState *bus, char *elem)
704 {
705     DeviceState *dev;
706
707     /*
708      * try to match in order:
709      *   (1) instance id, if present
710      *   (2) driver name
711      *   (3) driver alias, if present
712      */
713     QTAILQ_FOREACH(dev, &bus->children, sibling) {
714         if (dev->id  &&  strcmp(dev->id, elem) == 0) {
715             return dev;
716         }
717     }
718     QTAILQ_FOREACH(dev, &bus->children, sibling) {
719         if (strcmp(dev->info->name, elem) == 0) {
720             return dev;
721         }
722     }
723     QTAILQ_FOREACH(dev, &bus->children, sibling) {
724         if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) {
725             return dev;
726         }
727     }
728     return NULL;
729 }
730
731 static BusState *qbus_find(const char *path)
732 {
733     DeviceState *dev;
734     BusState *bus;
735     char elem[128];
736     int pos, len;
737
738     /* find start element */
739     if (path[0] == '/') {
740         bus = main_system_bus;
741         pos = 0;
742     } else {
743         if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
744             assert(!path[0]);
745             elem[0] = len = 0;
746         }
747         bus = qbus_find_recursive(main_system_bus, elem, NULL);
748         if (!bus) {
749             qerror_report(QERR_BUS_NOT_FOUND, elem);
750             return NULL;
751         }
752         pos = len;
753     }
754
755     for (;;) {
756         assert(path[pos] == '/' || !path[pos]);
757         while (path[pos] == '/') {
758             pos++;
759         }
760         if (path[pos] == '\0') {
761             return bus;
762         }
763
764         /* find device */
765         if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
766             assert(0);
767             elem[0] = len = 0;
768         }
769         pos += len;
770         dev = qbus_find_dev(bus, elem);
771         if (!dev) {
772             qerror_report(QERR_DEVICE_NOT_FOUND, elem);
773             if (!monitor_cur_is_qmp()) {
774                 qbus_list_dev(bus);
775             }
776             return NULL;
777         }
778
779         assert(path[pos] == '/' || !path[pos]);
780         while (path[pos] == '/') {
781             pos++;
782         }
783         if (path[pos] == '\0') {
784             /* last specified element is a device.  If it has exactly
785              * one child bus accept it nevertheless */
786             switch (dev->num_child_bus) {
787             case 0:
788                 qerror_report(QERR_DEVICE_NO_BUS, elem);
789                 return NULL;
790             case 1:
791                 return QLIST_FIRST(&dev->child_bus);
792             default:
793                 qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
794                 if (!monitor_cur_is_qmp()) {
795                     qbus_list_bus(dev);
796                 }
797                 return NULL;
798             }
799         }
800
801         /* find bus */
802         if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
803             assert(0);
804             elem[0] = len = 0;
805         }
806         pos += len;
807         bus = qbus_find_bus(dev, elem);
808         if (!bus) {
809             qerror_report(QERR_BUS_NOT_FOUND, elem);
810             if (!monitor_cur_is_qmp()) {
811                 qbus_list_bus(dev);
812             }
813             return NULL;
814         }
815     }
816 }
817
818 void qbus_create_inplace(BusState *bus, BusInfo *info,
819                          DeviceState *parent, const char *name)
820 {
821     char *buf;
822     int i,len;
823
824     bus->info = info;
825     bus->parent = parent;
826
827     if (name) {
828         /* use supplied name */
829         bus->name = g_strdup(name);
830     } else if (parent && parent->id) {
831         /* parent device has id -> use it for bus name */
832         len = strlen(parent->id) + 16;
833         buf = g_malloc(len);
834         snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
835         bus->name = buf;
836     } else {
837         /* no id -> use lowercase bus type for bus name */
838         len = strlen(info->name) + 16;
839         buf = g_malloc(len);
840         len = snprintf(buf, len, "%s.%d", info->name,
841                        parent ? parent->num_child_bus : 0);
842         for (i = 0; i < len; i++)
843             buf[i] = qemu_tolower(buf[i]);
844         bus->name = buf;
845     }
846
847     QTAILQ_INIT(&bus->children);
848     if (parent) {
849         QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
850         parent->num_child_bus++;
851     } else if (bus != main_system_bus) {
852         /* TODO: once all bus devices are qdevified,
853            only reset handler for main_system_bus should be registered here. */
854         qemu_register_reset(qbus_reset_all_fn, bus);
855     }
856 }
857
858 BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
859 {
860     BusState *bus;
861
862     bus = g_malloc0(info->size);
863     bus->qdev_allocated = 1;
864     qbus_create_inplace(bus, info, parent, name);
865     return bus;
866 }
867
868 static void main_system_bus_create(void)
869 {
870     /* assign main_system_bus before qbus_create_inplace()
871      * in order to make "if (bus != main_system_bus)" work */
872     main_system_bus = g_malloc0(system_bus_info.size);
873     main_system_bus->qdev_allocated = 1;
874     qbus_create_inplace(main_system_bus, &system_bus_info, NULL,
875                         "main-system-bus");
876 }
877
878 void qbus_free(BusState *bus)
879 {
880     DeviceState *dev;
881
882     while ((dev = QTAILQ_FIRST(&bus->children)) != NULL) {
883         qdev_free(dev);
884     }
885     if (bus->parent) {
886         QLIST_REMOVE(bus, sibling);
887         bus->parent->num_child_bus--;
888     } else {
889         assert(bus != main_system_bus); /* main_system_bus is never freed */
890         qemu_unregister_reset(qbus_reset_all_fn, bus);
891     }
892     g_free((void*)bus->name);
893     if (bus->qdev_allocated) {
894         g_free(bus);
895     }
896 }
897
898 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
899 static void qbus_print(Monitor *mon, BusState *bus, int indent);
900
901 static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
902                              const char *prefix, int indent)
903 {
904     char buf[64];
905
906     if (!props)
907         return;
908     while (props->name) {
909         /*
910          * TODO Properties without a print method are just for dirty
911          * hacks.  qdev_prop_ptr is the only such PropertyInfo.  It's
912          * marked for removal.  The test props->info->print should be
913          * removed along with it.
914          */
915         if (props->info->print) {
916             props->info->print(dev, props, buf, sizeof(buf));
917             qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
918         }
919         props++;
920     }
921 }
922
923 static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
924 {
925     BusState *child;
926     qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
927                 dev->id ? dev->id : "");
928     indent += 2;
929     if (dev->num_gpio_in) {
930         qdev_printf("gpio-in %d\n", dev->num_gpio_in);
931     }
932     if (dev->num_gpio_out) {
933         qdev_printf("gpio-out %d\n", dev->num_gpio_out);
934     }
935     qdev_print_props(mon, dev, dev->info->props, "dev", indent);
936     qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
937     if (dev->parent_bus->info->print_dev)
938         dev->parent_bus->info->print_dev(mon, dev, indent);
939     QLIST_FOREACH(child, &dev->child_bus, sibling) {
940         qbus_print(mon, child, indent);
941     }
942 }
943
944 static void qbus_print(Monitor *mon, BusState *bus, int indent)
945 {
946     struct DeviceState *dev;
947
948     qdev_printf("bus: %s\n", bus->name);
949     indent += 2;
950     qdev_printf("type %s\n", bus->info->name);
951     QTAILQ_FOREACH(dev, &bus->children, sibling) {
952         qdev_print(mon, dev, indent);
953     }
954 }
955 #undef qdev_printf
956
957 void do_info_qtree(Monitor *mon)
958 {
959     if (main_system_bus)
960         qbus_print(mon, main_system_bus, 0);
961 }
962
963 void do_info_qdm(Monitor *mon)
964 {
965     DeviceInfo *info;
966
967     for (info = device_info_list; info != NULL; info = info->next) {
968         qdev_print_devinfo(info);
969     }
970 }
971
972 int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
973 {
974     QemuOpts *opts;
975
976     opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict);
977     if (!opts) {
978         return -1;
979     }
980     if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
981         qemu_opts_del(opts);
982         return 0;
983     }
984     if (!qdev_device_add(opts)) {
985         qemu_opts_del(opts);
986         return -1;
987     }
988     return 0;
989 }
990
991 int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
992 {
993     const char *id = qdict_get_str(qdict, "id");
994     DeviceState *dev;
995
996     dev = qdev_find_recursive(main_system_bus, id);
997     if (NULL == dev) {
998         qerror_report(QERR_DEVICE_NOT_FOUND, id);
999         return -1;
1000     }
1001     return qdev_unplug(dev);
1002 }
1003
1004 static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
1005 {
1006     int l = 0;
1007
1008     if (dev && dev->parent_bus) {
1009         char *d;
1010         l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
1011         if (dev->parent_bus->info->get_fw_dev_path) {
1012             d = dev->parent_bus->info->get_fw_dev_path(dev);
1013             l += snprintf(p + l, size - l, "%s", d);
1014             g_free(d);
1015         } else {
1016             l += snprintf(p + l, size - l, "%s", dev->info->name);
1017         }
1018     }
1019     l += snprintf(p + l , size - l, "/");
1020
1021     return l;
1022 }
1023
1024 char* qdev_get_fw_dev_path(DeviceState *dev)
1025 {
1026     char path[128];
1027     int l;
1028
1029     l = qdev_get_fw_dev_path_helper(dev, path, 128);
1030
1031     path[l-1] = '\0';
1032
1033     return strdup(path);
1034 }
1035
1036 char *qdev_get_type(DeviceState *dev, Error **errp)
1037 {
1038     return g_strdup(dev->info->name);
1039 }
1040
1041 void qdev_ref(DeviceState *dev)
1042 {
1043     dev->ref++;
1044 }
1045
1046 void qdev_unref(DeviceState *dev)
1047 {
1048     g_assert(dev->ref > 0);
1049     dev->ref--;
1050 }
1051
1052 void qdev_property_add(DeviceState *dev, const char *name, const char *type,
1053                        DevicePropertyAccessor *get, DevicePropertyAccessor *set,
1054                        DevicePropertyRelease *release,
1055                        void *opaque, Error **errp)
1056 {
1057     DeviceProperty *prop = g_malloc0(sizeof(*prop));
1058
1059     prop->name = g_strdup(name);
1060     prop->type = g_strdup(type);
1061
1062     prop->get = get;
1063     prop->set = set;
1064     prop->release = release;
1065     prop->opaque = opaque;
1066
1067     QTAILQ_INSERT_TAIL(&dev->properties, prop, node);
1068 }
1069
1070 static DeviceProperty *qdev_property_find(DeviceState *dev, const char *name)
1071 {
1072     DeviceProperty *prop;
1073
1074     QTAILQ_FOREACH(prop, &dev->properties, node) {
1075         if (strcmp(prop->name, name) == 0) {
1076             return prop;
1077         }
1078     }
1079
1080     return NULL;
1081 }
1082
1083 void qdev_property_get(DeviceState *dev, Visitor *v, const char *name,
1084                        Error **errp)
1085 {
1086     DeviceProperty *prop = qdev_property_find(dev, name);
1087
1088     if (prop == NULL) {
1089         error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
1090         return;
1091     }
1092
1093     if (!prop->get) {
1094         error_set(errp, QERR_PERMISSION_DENIED);
1095     } else {
1096         prop->get(dev, v, prop->opaque, name, errp);
1097     }
1098 }
1099
1100 void qdev_property_set(DeviceState *dev, Visitor *v, const char *name,
1101                        Error **errp)
1102 {
1103     DeviceProperty *prop = qdev_property_find(dev, name);
1104
1105     if (prop == NULL) {
1106         error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
1107         return;
1108     }
1109
1110     if (!prop->set) {
1111         error_set(errp, QERR_PERMISSION_DENIED);
1112     } else {
1113         prop->set(dev, prop->opaque, v, name, errp);
1114     }
1115 }
1116
1117 const char *qdev_property_get_type(DeviceState *dev, const char *name, Error **errp)
1118 {
1119     DeviceProperty *prop = qdev_property_find(dev, name);
1120
1121     if (prop == NULL) {
1122         error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
1123         return NULL;
1124     }
1125
1126     return prop->type;
1127 }
1128
1129 /**
1130  * Legacy property handling
1131  */
1132
1133 static void qdev_get_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
1134                                      const char *name, Error **errp)
1135 {
1136     Property *prop = opaque;
1137
1138     if (prop->info->print) {
1139         char buffer[1024];
1140         char *ptr = buffer;
1141
1142         prop->info->print(dev, prop, buffer, sizeof(buffer));
1143         visit_type_str(v, &ptr, name, errp);
1144     } else {
1145         error_set(errp, QERR_PERMISSION_DENIED);
1146     }
1147 }
1148
1149 static void qdev_set_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
1150                                      const char *name, Error **errp)
1151 {
1152     Property *prop = opaque;
1153
1154     if (dev->state != DEV_STATE_CREATED) {
1155         error_set(errp, QERR_PERMISSION_DENIED);
1156         return;
1157     }
1158
1159     if (prop->info->parse) {
1160         Error *local_err = NULL;
1161         char *ptr = NULL;
1162
1163         visit_type_str(v, &ptr, name, &local_err);
1164         if (!local_err) {
1165             int ret;
1166             ret = prop->info->parse(dev, prop, ptr);
1167             if (ret != 0) {
1168                 error_set(errp, QERR_INVALID_PARAMETER_VALUE,
1169                           name, prop->info->name);
1170             }
1171             g_free(ptr);
1172         } else {
1173             error_propagate(errp, local_err);
1174         }
1175     } else {
1176         error_set(errp, QERR_PERMISSION_DENIED);
1177     }
1178 }
1179
1180 /**
1181  * @qdev_add_legacy_property - adds a legacy property
1182  *
1183  * Do not use this is new code!  Properties added through this interface will
1184  * be given types in the "legacy<>" type namespace.
1185  *
1186  * Legacy properties are always processed as strings.  The format of the string
1187  * depends on the property type.
1188  */
1189 void qdev_property_add_legacy(DeviceState *dev, Property *prop,
1190                               Error **errp)
1191 {
1192     gchar *type;
1193
1194     type = g_strdup_printf("legacy<%s>", prop->info->name);
1195
1196     qdev_property_add(dev, prop->name, type,
1197                       qdev_get_legacy_property,
1198                       qdev_set_legacy_property,
1199                       NULL,
1200                       prop, errp);
1201
1202     g_free(type);
1203 }
1204
1205 DeviceState *qdev_get_root(void)
1206 {
1207     static DeviceState *qdev_root;
1208
1209     if (!qdev_root) {
1210         qdev_root = qdev_create(NULL, "container");
1211         qdev_init_nofail(qdev_root);
1212     }
1213
1214     return qdev_root;
1215 }
1216
1217 static void qdev_get_child_property(DeviceState *dev, Visitor *v, void *opaque,
1218                                     const char *name, Error **errp)
1219 {
1220     DeviceState *child = opaque;
1221     gchar *path;
1222
1223     path = qdev_get_canonical_path(child);
1224     visit_type_str(v, &path, name, errp);
1225     g_free(path);
1226 }
1227
1228 void qdev_property_add_child(DeviceState *dev, const char *name,
1229                              DeviceState *child, Error **errp)
1230 {
1231     gchar *type;
1232
1233     type = g_strdup_printf("child<%s>", child->info->name);
1234
1235     qdev_property_add(dev, name, type, qdev_get_child_property,
1236                       NULL, NULL, child, errp);
1237
1238     qdev_ref(child);
1239     g_assert(child->parent == NULL);
1240     child->parent = dev;
1241
1242     g_free(type);
1243 }
1244
1245 static void qdev_get_link_property(DeviceState *dev, Visitor *v, void *opaque,
1246                                    const char *name, Error **errp)
1247 {
1248     DeviceState **child = opaque;
1249     gchar *path;
1250
1251     if (*child) {
1252         path = qdev_get_canonical_path(*child);
1253         visit_type_str(v, &path, name, errp);
1254         g_free(path);
1255     } else {
1256         path = (gchar *)"";
1257         visit_type_str(v, &path, name, errp);
1258     }
1259 }
1260
1261 static void qdev_set_link_property(DeviceState *dev, Visitor *v, void *opaque,
1262                                    const char *name, Error **errp)
1263 {
1264     DeviceState **child = opaque;
1265     bool ambiguous = false;
1266     const char *type;
1267     char *path;
1268
1269     type = qdev_property_get_type(dev, name, NULL);
1270
1271     visit_type_str(v, &path, name, errp);
1272
1273     if (*child) {
1274         qdev_unref(*child);
1275     }
1276
1277     if (strcmp(path, "") != 0) {
1278         DeviceState *target;
1279
1280         target = qdev_resolve_path(path, &ambiguous);
1281         if (target) {
1282             gchar *target_type;
1283
1284             target_type = g_strdup_printf("link<%s>", target->info->name);
1285             if (strcmp(target_type, type) == 0) {
1286                 *child = target;
1287                 qdev_ref(target);
1288             } else {
1289                 error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, type);
1290             }
1291
1292             g_free(target_type);
1293         } else {
1294             error_set(errp, QERR_DEVICE_NOT_FOUND, path);
1295         }
1296     } else {
1297         *child = NULL;
1298     }
1299
1300     g_free(path);
1301 }
1302
1303 void qdev_property_add_link(DeviceState *dev, const char *name,
1304                             const char *type, DeviceState **child,
1305                             Error **errp)
1306 {
1307     gchar *full_type;
1308
1309     full_type = g_strdup_printf("link<%s>", type);
1310
1311     qdev_property_add(dev, name, full_type,
1312                       qdev_get_link_property,
1313                       qdev_set_link_property,
1314                       NULL, child, errp);
1315
1316     g_free(full_type);
1317 }
1318
1319 gchar *qdev_get_canonical_path(DeviceState *dev)
1320 {
1321     DeviceState *root = qdev_get_root();
1322     char *newpath = NULL, *path = NULL;
1323
1324     while (dev != root) {
1325         DeviceProperty *prop = NULL;
1326
1327         g_assert(dev->parent != NULL);
1328
1329         QTAILQ_FOREACH(prop, &dev->parent->properties, node) {
1330             if (!strstart(prop->type, "child<", NULL)) {
1331                 continue;
1332             }
1333
1334             if (prop->opaque == dev) {
1335                 if (path) {
1336                     newpath = g_strdup_printf("%s/%s", prop->name, path);
1337                     g_free(path);
1338                     path = newpath;
1339                 } else {
1340                     path = g_strdup(prop->name);
1341                 }
1342                 break;
1343             }
1344         }
1345
1346         g_assert(prop != NULL);
1347
1348         dev = dev->parent;
1349     }
1350
1351     newpath = g_strdup_printf("/%s", path);
1352     g_free(path);
1353
1354     return newpath;
1355 }
1356
1357 static DeviceState *qdev_resolve_abs_path(DeviceState *parent,
1358                                           gchar **parts,
1359                                           int index)
1360 {
1361     DeviceProperty *prop;
1362     DeviceState *child;
1363
1364     if (parts[index] == NULL) {
1365         return parent;
1366     }
1367
1368     if (strcmp(parts[index], "") == 0) {
1369         return qdev_resolve_abs_path(parent, parts, index + 1);
1370     }
1371
1372     prop = qdev_property_find(parent, parts[index]);
1373     if (prop == NULL) {
1374         return NULL;
1375     }
1376
1377     child = NULL;
1378     if (strstart(prop->type, "link<", NULL)) {
1379         DeviceState **pchild = prop->opaque;
1380         if (*pchild) {
1381             child = *pchild;
1382         }
1383     } else if (strstart(prop->type, "child<", NULL)) {
1384         child = prop->opaque;
1385     }
1386
1387     if (!child) {
1388         return NULL;
1389     }
1390
1391     return qdev_resolve_abs_path(child, parts, index + 1);
1392 }
1393
1394 static DeviceState *qdev_resolve_partial_path(DeviceState *parent,
1395                                               gchar **parts,
1396                                               bool *ambiguous)
1397 {
1398     DeviceState *dev;
1399     DeviceProperty *prop;
1400
1401     dev = qdev_resolve_abs_path(parent, parts, 0);
1402
1403     QTAILQ_FOREACH(prop, &parent->properties, node) {
1404         DeviceState *found;
1405
1406         if (!strstart(prop->type, "child<", NULL)) {
1407             continue;
1408         }
1409
1410         found = qdev_resolve_partial_path(prop->opaque, parts, ambiguous);
1411         if (found) {
1412             if (dev) {
1413                 if (ambiguous) {
1414                     *ambiguous = true;
1415                 }
1416                 return NULL;
1417             }
1418             dev = found;
1419         }
1420
1421         if (ambiguous && *ambiguous) {
1422             return NULL;
1423         }
1424     }
1425
1426     return dev;
1427 }
1428
1429 DeviceState *qdev_resolve_path(const char *path, bool *ambiguous)
1430 {
1431     bool partial_path = true;
1432     DeviceState *dev;
1433     gchar **parts;
1434
1435     parts = g_strsplit(path, "/", 0);
1436     if (parts == NULL || parts[0] == NULL) {
1437         g_strfreev(parts);
1438         return qdev_get_root();
1439     }
1440
1441     if (strcmp(parts[0], "") == 0) {
1442         partial_path = false;
1443     }
1444
1445     if (partial_path) {
1446         if (ambiguous) {
1447             *ambiguous = false;
1448         }
1449         dev = qdev_resolve_partial_path(qdev_get_root(), parts, ambiguous);
1450     } else {
1451         dev = qdev_resolve_abs_path(qdev_get_root(), parts, 1);
1452     }
1453
1454     g_strfreev(parts);
1455
1456     return dev;
1457 }
1458
1459 typedef struct StringProperty
1460 {
1461     char *(*get)(DeviceState *, Error **);
1462     void (*set)(DeviceState *, const char *, Error **);
1463 } StringProperty;
1464
1465 static void qdev_property_get_str(DeviceState *dev, Visitor *v, void *opaque,
1466                                   const char *name, Error **errp)
1467 {
1468     StringProperty *prop = opaque;
1469     char *value;
1470
1471     value = prop->get(dev, errp);
1472     if (value) {
1473         visit_type_str(v, &value, name, errp);
1474         g_free(value);
1475     }
1476 }
1477
1478 static void qdev_property_set_str(DeviceState *dev, Visitor *v, void *opaque,
1479                                   const char *name, Error **errp)
1480 {
1481     StringProperty *prop = opaque;
1482     char *value;
1483     Error *local_err = NULL;
1484
1485     visit_type_str(v, &value, name, &local_err);
1486     if (local_err) {
1487         error_propagate(errp, local_err);
1488         return;
1489     }
1490
1491     prop->set(dev, value, errp);
1492     g_free(value);
1493 }
1494
1495 static void qdev_property_release_str(DeviceState *dev, const char *name,
1496                                       void *opaque)
1497 {
1498     StringProperty *prop = opaque;
1499     g_free(prop);
1500 }
1501
1502 void qdev_property_add_str(DeviceState *dev, const char *name,
1503                            char *(*get)(DeviceState *, Error **),
1504                            void (*set)(DeviceState *, const char *, Error **),
1505                            Error **errp)
1506 {
1507     StringProperty *prop = g_malloc0(sizeof(*prop));
1508
1509     prop->get = get;
1510     prop->set = set;
1511
1512     qdev_property_add(dev, name, "string",
1513                       get ? qdev_property_get_str : NULL,
1514                       set ? qdev_property_set_str : NULL,
1515                       qdev_property_release_str,
1516                       prop, errp);
1517 }
This page took 0.11098 seconds and 4 git commands to generate.