]> Git Repo - qemu.git/blob - hw/core/qdev.c
qdev: hotplug: Introduce HotplugHandler.pre_plug() callback
[qemu.git] / hw / core / 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 "qemu/osdep.h"
29 #include "hw/qdev.h"
30 #include "hw/fw-path-provider.h"
31 #include "sysemu/sysemu.h"
32 #include "qapi/qmp/qerror.h"
33 #include "qapi/visitor.h"
34 #include "qapi/qmp/qjson.h"
35 #include "qemu/error-report.h"
36 #include "hw/hotplug.h"
37 #include "hw/boards.h"
38 #include "hw/sysbus.h"
39 #include "qapi-event.h"
40
41 int qdev_hotplug = 0;
42 static bool qdev_hot_added = false;
43 static bool qdev_hot_removed = false;
44
45 const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
46 {
47     DeviceClass *dc = DEVICE_GET_CLASS(dev);
48     return dc->vmsd;
49 }
50
51 const char *qdev_fw_name(DeviceState *dev)
52 {
53     DeviceClass *dc = DEVICE_GET_CLASS(dev);
54
55     if (dc->fw_name) {
56         return dc->fw_name;
57     }
58
59     return object_get_typename(OBJECT(dev));
60 }
61
62 static void bus_remove_child(BusState *bus, DeviceState *child)
63 {
64     BusChild *kid;
65
66     QTAILQ_FOREACH(kid, &bus->children, sibling) {
67         if (kid->child == child) {
68             char name[32];
69
70             snprintf(name, sizeof(name), "child[%d]", kid->index);
71             QTAILQ_REMOVE(&bus->children, kid, sibling);
72
73             /* This gives back ownership of kid->child back to us.  */
74             object_property_del(OBJECT(bus), name, NULL);
75             object_unref(OBJECT(kid->child));
76             g_free(kid);
77             return;
78         }
79     }
80 }
81
82 static void bus_add_child(BusState *bus, DeviceState *child)
83 {
84     char name[32];
85     BusChild *kid = g_malloc0(sizeof(*kid));
86
87     kid->index = bus->max_index++;
88     kid->child = child;
89     object_ref(OBJECT(kid->child));
90
91     QTAILQ_INSERT_HEAD(&bus->children, kid, sibling);
92
93     /* This transfers ownership of kid->child to the property.  */
94     snprintf(name, sizeof(name), "child[%d]", kid->index);
95     object_property_add_link(OBJECT(bus), name,
96                              object_get_typename(OBJECT(child)),
97                              (Object **)&kid->child,
98                              NULL, /* read-only property */
99                              0, /* return ownership on prop deletion */
100                              NULL);
101 }
102
103 void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
104 {
105     dev->parent_bus = bus;
106     object_ref(OBJECT(bus));
107     bus_add_child(bus, dev);
108 }
109
110 /* Create a new device.  This only initializes the device state
111    structure and allows properties to be set.  The device still needs
112    to be realized.  See qdev-core.h.  */
113 DeviceState *qdev_create(BusState *bus, const char *name)
114 {
115     DeviceState *dev;
116
117     dev = qdev_try_create(bus, name);
118     if (!dev) {
119         if (bus) {
120             error_report("Unknown device '%s' for bus '%s'", name,
121                          object_get_typename(OBJECT(bus)));
122         } else {
123             error_report("Unknown device '%s' for default sysbus", name);
124         }
125         abort();
126     }
127
128     return dev;
129 }
130
131 DeviceState *qdev_try_create(BusState *bus, const char *type)
132 {
133     DeviceState *dev;
134
135     if (object_class_by_name(type) == NULL) {
136         return NULL;
137     }
138     dev = DEVICE(object_new(type));
139     if (!dev) {
140         return NULL;
141     }
142
143     if (!bus) {
144         /* Assert that the device really is a SysBusDevice before
145          * we put it onto the sysbus. Non-sysbus devices which aren't
146          * being put onto a bus should be created with object_new(TYPE_FOO),
147          * not qdev_create(NULL, TYPE_FOO).
148          */
149         g_assert(object_dynamic_cast(OBJECT(dev), TYPE_SYS_BUS_DEVICE));
150         bus = sysbus_get_default();
151     }
152
153     qdev_set_parent_bus(dev, bus);
154     object_unref(OBJECT(dev));
155     return dev;
156 }
157
158 static QTAILQ_HEAD(device_listeners, DeviceListener) device_listeners
159     = QTAILQ_HEAD_INITIALIZER(device_listeners);
160
161 enum ListenerDirection { Forward, Reverse };
162
163 #define DEVICE_LISTENER_CALL(_callback, _direction, _args...)     \
164     do {                                                          \
165         DeviceListener *_listener;                                \
166                                                                   \
167         switch (_direction) {                                     \
168         case Forward:                                             \
169             QTAILQ_FOREACH(_listener, &device_listeners, link) {  \
170                 if (_listener->_callback) {                       \
171                     _listener->_callback(_listener, ##_args);     \
172                 }                                                 \
173             }                                                     \
174             break;                                                \
175         case Reverse:                                             \
176             QTAILQ_FOREACH_REVERSE(_listener, &device_listeners,  \
177                                    device_listeners, link) {      \
178                 if (_listener->_callback) {                       \
179                     _listener->_callback(_listener, ##_args);     \
180                 }                                                 \
181             }                                                     \
182             break;                                                \
183         default:                                                  \
184             abort();                                              \
185         }                                                         \
186     } while (0)
187
188 static int device_listener_add(DeviceState *dev, void *opaque)
189 {
190     DEVICE_LISTENER_CALL(realize, Forward, dev);
191
192     return 0;
193 }
194
195 void device_listener_register(DeviceListener *listener)
196 {
197     QTAILQ_INSERT_TAIL(&device_listeners, listener, link);
198
199     qbus_walk_children(sysbus_get_default(), NULL, NULL, device_listener_add,
200                        NULL, NULL);
201 }
202
203 void device_listener_unregister(DeviceListener *listener)
204 {
205     QTAILQ_REMOVE(&device_listeners, listener, link);
206 }
207
208 static void device_realize(DeviceState *dev, Error **errp)
209 {
210     DeviceClass *dc = DEVICE_GET_CLASS(dev);
211
212     if (dc->init) {
213         int rc = dc->init(dev);
214         if (rc < 0) {
215             error_setg(errp, "Device initialization failed.");
216             return;
217         }
218     }
219 }
220
221 static void device_unrealize(DeviceState *dev, Error **errp)
222 {
223     DeviceClass *dc = DEVICE_GET_CLASS(dev);
224
225     if (dc->exit) {
226         int rc = dc->exit(dev);
227         if (rc < 0) {
228             error_setg(errp, "Device exit failed.");
229             return;
230         }
231     }
232 }
233
234 void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
235                                  int required_for_version)
236 {
237     assert(!dev->realized);
238     dev->instance_id_alias = alias_id;
239     dev->alias_required_for_version = required_for_version;
240 }
241
242 HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev)
243 {
244     HotplugHandler *hotplug_ctrl = NULL;
245
246     if (dev->parent_bus && dev->parent_bus->hotplug_handler) {
247         hotplug_ctrl = dev->parent_bus->hotplug_handler;
248     } else if (object_dynamic_cast(qdev_get_machine(), TYPE_MACHINE)) {
249         MachineState *machine = MACHINE(qdev_get_machine());
250         MachineClass *mc = MACHINE_GET_CLASS(machine);
251
252         if (mc->get_hotplug_handler) {
253             hotplug_ctrl = mc->get_hotplug_handler(machine, dev);
254         }
255     }
256     return hotplug_ctrl;
257 }
258
259 void qdev_unplug(DeviceState *dev, Error **errp)
260 {
261     DeviceClass *dc = DEVICE_GET_CLASS(dev);
262     HotplugHandler *hotplug_ctrl;
263     HotplugHandlerClass *hdc;
264
265     if (dev->parent_bus && !qbus_is_hotpluggable(dev->parent_bus)) {
266         error_setg(errp, QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
267         return;
268     }
269
270     if (!dc->hotpluggable) {
271         error_setg(errp, QERR_DEVICE_NO_HOTPLUG,
272                    object_get_typename(OBJECT(dev)));
273         return;
274     }
275
276     qdev_hot_removed = true;
277
278     hotplug_ctrl = qdev_get_hotplug_handler(dev);
279     /* hotpluggable device MUST have HotplugHandler, if it doesn't
280      * then something is very wrong with it */
281     g_assert(hotplug_ctrl);
282
283     /* If device supports async unplug just request it to be done,
284      * otherwise just remove it synchronously */
285     hdc = HOTPLUG_HANDLER_GET_CLASS(hotplug_ctrl);
286     if (hdc->unplug_request) {
287         hotplug_handler_unplug_request(hotplug_ctrl, dev, errp);
288     } else {
289         hotplug_handler_unplug(hotplug_ctrl, dev, errp);
290     }
291 }
292
293 static int qdev_reset_one(DeviceState *dev, void *opaque)
294 {
295     device_reset(dev);
296
297     return 0;
298 }
299
300 static int qbus_reset_one(BusState *bus, void *opaque)
301 {
302     BusClass *bc = BUS_GET_CLASS(bus);
303     if (bc->reset) {
304         bc->reset(bus);
305     }
306     return 0;
307 }
308
309 void qdev_reset_all(DeviceState *dev)
310 {
311     qdev_walk_children(dev, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
312 }
313
314 void qdev_reset_all_fn(void *opaque)
315 {
316     qdev_reset_all(DEVICE(opaque));
317 }
318
319 void qbus_reset_all(BusState *bus)
320 {
321     qbus_walk_children(bus, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
322 }
323
324 void qbus_reset_all_fn(void *opaque)
325 {
326     BusState *bus = opaque;
327     qbus_reset_all(bus);
328 }
329
330 /* can be used as ->unplug() callback for the simple cases */
331 void qdev_simple_device_unplug_cb(HotplugHandler *hotplug_dev,
332                                   DeviceState *dev, Error **errp)
333 {
334     /* just zap it */
335     object_unparent(OBJECT(dev));
336 }
337
338 /*
339  * Realize @dev.
340  * Device properties should be set before calling this function.  IRQs
341  * and MMIO regions should be connected/mapped after calling this
342  * function.
343  * On failure, report an error with error_report() and terminate the
344  * program.  This is okay during machine creation.  Don't use for
345  * hotplug, because there callers need to recover from failure.
346  * Exception: if you know the device's init() callback can't fail,
347  * then qdev_init_nofail() can't fail either, and is therefore usable
348  * even then.  But relying on the device implementation that way is
349  * somewhat unclean, and best avoided.
350  */
351 void qdev_init_nofail(DeviceState *dev)
352 {
353     Error *err = NULL;
354
355     assert(!dev->realized);
356
357     object_property_set_bool(OBJECT(dev), true, "realized", &err);
358     if (err) {
359         error_reportf_err(err, "Initialization of device %s failed: ",
360                           object_get_typename(OBJECT(dev)));
361         exit(1);
362     }
363 }
364
365 void qdev_machine_creation_done(void)
366 {
367     /*
368      * ok, initial machine setup is done, starting from now we can
369      * only create hotpluggable devices
370      */
371     qdev_hotplug = 1;
372 }
373
374 bool qdev_machine_modified(void)
375 {
376     return qdev_hot_added || qdev_hot_removed;
377 }
378
379 BusState *qdev_get_parent_bus(DeviceState *dev)
380 {
381     return dev->parent_bus;
382 }
383
384 static NamedGPIOList *qdev_get_named_gpio_list(DeviceState *dev,
385                                                const char *name)
386 {
387     NamedGPIOList *ngl;
388
389     QLIST_FOREACH(ngl, &dev->gpios, node) {
390         /* NULL is a valid and matchable name, otherwise do a normal
391          * strcmp match.
392          */
393         if ((!ngl->name && !name) ||
394                 (name && ngl->name && strcmp(name, ngl->name) == 0)) {
395             return ngl;
396         }
397     }
398
399     ngl = g_malloc0(sizeof(*ngl));
400     ngl->name = g_strdup(name);
401     QLIST_INSERT_HEAD(&dev->gpios, ngl, node);
402     return ngl;
403 }
404
405 void qdev_init_gpio_in_named(DeviceState *dev, qemu_irq_handler handler,
406                              const char *name, int n)
407 {
408     int i;
409     NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
410
411     assert(gpio_list->num_out == 0 || !name);
412     gpio_list->in = qemu_extend_irqs(gpio_list->in, gpio_list->num_in, handler,
413                                      dev, n);
414
415     if (!name) {
416         name = "unnamed-gpio-in";
417     }
418     for (i = gpio_list->num_in; i < gpio_list->num_in + n; i++) {
419         gchar *propname = g_strdup_printf("%s[%u]", name, i);
420
421         object_property_add_child(OBJECT(dev), propname,
422                                   OBJECT(gpio_list->in[i]), &error_abort);
423         g_free(propname);
424     }
425
426     gpio_list->num_in += n;
427 }
428
429 void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
430 {
431     qdev_init_gpio_in_named(dev, handler, NULL, n);
432 }
433
434 void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins,
435                               const char *name, int n)
436 {
437     int i;
438     NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
439
440     assert(gpio_list->num_in == 0 || !name);
441
442     if (!name) {
443         name = "unnamed-gpio-out";
444     }
445     memset(pins, 0, sizeof(*pins) * n);
446     for (i = 0; i < n; ++i) {
447         gchar *propname = g_strdup_printf("%s[%u]", name,
448                                           gpio_list->num_out + i);
449
450         object_property_add_link(OBJECT(dev), propname, TYPE_IRQ,
451                                  (Object **)&pins[i],
452                                  object_property_allow_set_link,
453                                  OBJ_PROP_LINK_UNREF_ON_RELEASE,
454                                  &error_abort);
455         g_free(propname);
456     }
457     gpio_list->num_out += n;
458 }
459
460 void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
461 {
462     qdev_init_gpio_out_named(dev, pins, NULL, n);
463 }
464
465 qemu_irq qdev_get_gpio_in_named(DeviceState *dev, const char *name, int n)
466 {
467     NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
468
469     assert(n >= 0 && n < gpio_list->num_in);
470     return gpio_list->in[n];
471 }
472
473 qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
474 {
475     return qdev_get_gpio_in_named(dev, NULL, n);
476 }
477
478 void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n,
479                                  qemu_irq pin)
480 {
481     char *propname = g_strdup_printf("%s[%d]",
482                                      name ? name : "unnamed-gpio-out", n);
483     if (pin) {
484         /* We need a name for object_property_set_link to work.  If the
485          * object has a parent, object_property_add_child will come back
486          * with an error without doing anything.  If it has none, it will
487          * never fail.  So we can just call it with a NULL Error pointer.
488          */
489         object_property_add_child(container_get(qdev_get_machine(),
490                                                 "/unattached"),
491                                   "non-qdev-gpio[*]", OBJECT(pin), NULL);
492     }
493     object_property_set_link(OBJECT(dev), OBJECT(pin), propname, &error_abort);
494     g_free(propname);
495 }
496
497 qemu_irq qdev_get_gpio_out_connector(DeviceState *dev, const char *name, int n)
498 {
499     char *propname = g_strdup_printf("%s[%d]",
500                                      name ? name : "unnamed-gpio-out", n);
501
502     qemu_irq ret = (qemu_irq)object_property_get_link(OBJECT(dev), propname,
503                                                       NULL);
504
505     return ret;
506 }
507
508 /* disconnect a GPIO output, returning the disconnected input (if any) */
509
510 static qemu_irq qdev_disconnect_gpio_out_named(DeviceState *dev,
511                                                const char *name, int n)
512 {
513     char *propname = g_strdup_printf("%s[%d]",
514                                      name ? name : "unnamed-gpio-out", n);
515
516     qemu_irq ret = (qemu_irq)object_property_get_link(OBJECT(dev), propname,
517                                                       NULL);
518     if (ret) {
519         object_property_set_link(OBJECT(dev), NULL, propname, NULL);
520     }
521     g_free(propname);
522     return ret;
523 }
524
525 qemu_irq qdev_intercept_gpio_out(DeviceState *dev, qemu_irq icpt,
526                                  const char *name, int n)
527 {
528     qemu_irq disconnected = qdev_disconnect_gpio_out_named(dev, name, n);
529     qdev_connect_gpio_out_named(dev, name, n, icpt);
530     return disconnected;
531 }
532
533 void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
534 {
535     qdev_connect_gpio_out_named(dev, NULL, n, pin);
536 }
537
538 void qdev_pass_gpios(DeviceState *dev, DeviceState *container,
539                      const char *name)
540 {
541     int i;
542     NamedGPIOList *ngl = qdev_get_named_gpio_list(dev, name);
543
544     for (i = 0; i < ngl->num_in; i++) {
545         const char *nm = ngl->name ? ngl->name : "unnamed-gpio-in";
546         char *propname = g_strdup_printf("%s[%d]", nm, i);
547
548         object_property_add_alias(OBJECT(container), propname,
549                                   OBJECT(dev), propname,
550                                   &error_abort);
551         g_free(propname);
552     }
553     for (i = 0; i < ngl->num_out; i++) {
554         const char *nm = ngl->name ? ngl->name : "unnamed-gpio-out";
555         char *propname = g_strdup_printf("%s[%d]", nm, i);
556
557         object_property_add_alias(OBJECT(container), propname,
558                                   OBJECT(dev), propname,
559                                   &error_abort);
560         g_free(propname);
561     }
562     QLIST_REMOVE(ngl, node);
563     QLIST_INSERT_HEAD(&container->gpios, ngl, node);
564 }
565
566 BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
567 {
568     BusState *bus;
569     Object *child = object_resolve_path_component(OBJECT(dev), name);
570
571     bus = (BusState *)object_dynamic_cast(child, TYPE_BUS);
572     if (bus) {
573         return bus;
574     }
575
576     QLIST_FOREACH(bus, &dev->child_bus, sibling) {
577         if (strcmp(name, bus->name) == 0) {
578             return bus;
579         }
580     }
581     return NULL;
582 }
583
584 int qdev_walk_children(DeviceState *dev,
585                        qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
586                        qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
587                        void *opaque)
588 {
589     BusState *bus;
590     int err;
591
592     if (pre_devfn) {
593         err = pre_devfn(dev, opaque);
594         if (err) {
595             return err;
596         }
597     }
598
599     QLIST_FOREACH(bus, &dev->child_bus, sibling) {
600         err = qbus_walk_children(bus, pre_devfn, pre_busfn,
601                                  post_devfn, post_busfn, opaque);
602         if (err < 0) {
603             return err;
604         }
605     }
606
607     if (post_devfn) {
608         err = post_devfn(dev, opaque);
609         if (err) {
610             return err;
611         }
612     }
613
614     return 0;
615 }
616
617 DeviceState *qdev_find_recursive(BusState *bus, const char *id)
618 {
619     BusChild *kid;
620     DeviceState *ret;
621     BusState *child;
622
623     QTAILQ_FOREACH(kid, &bus->children, sibling) {
624         DeviceState *dev = kid->child;
625
626         if (dev->id && strcmp(dev->id, id) == 0) {
627             return dev;
628         }
629
630         QLIST_FOREACH(child, &dev->child_bus, sibling) {
631             ret = qdev_find_recursive(child, id);
632             if (ret) {
633                 return ret;
634             }
635         }
636     }
637     return NULL;
638 }
639
640 static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev)
641 {
642     BusClass *bc = BUS_GET_CLASS(bus);
643
644     if (bc->get_fw_dev_path) {
645         return bc->get_fw_dev_path(dev);
646     }
647
648     return NULL;
649 }
650
651 static char *qdev_get_fw_dev_path_from_handler(BusState *bus, DeviceState *dev)
652 {
653     Object *obj = OBJECT(dev);
654     char *d = NULL;
655
656     while (!d && obj->parent) {
657         obj = obj->parent;
658         d = fw_path_provider_try_get_dev_path(obj, bus, dev);
659     }
660     return d;
661 }
662
663 char *qdev_get_own_fw_dev_path_from_handler(BusState *bus, DeviceState *dev)
664 {
665     Object *obj = OBJECT(dev);
666
667     return fw_path_provider_try_get_dev_path(obj, bus, dev);
668 }
669
670 static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
671 {
672     int l = 0;
673
674     if (dev && dev->parent_bus) {
675         char *d;
676         l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
677         d = qdev_get_fw_dev_path_from_handler(dev->parent_bus, dev);
678         if (!d) {
679             d = bus_get_fw_dev_path(dev->parent_bus, dev);
680         }
681         if (d) {
682             l += snprintf(p + l, size - l, "%s", d);
683             g_free(d);
684         } else {
685             return l;
686         }
687     }
688     l += snprintf(p + l , size - l, "/");
689
690     return l;
691 }
692
693 char* qdev_get_fw_dev_path(DeviceState *dev)
694 {
695     char path[128];
696     int l;
697
698     l = qdev_get_fw_dev_path_helper(dev, path, 128);
699
700     path[l-1] = '\0';
701
702     return g_strdup(path);
703 }
704
705 char *qdev_get_dev_path(DeviceState *dev)
706 {
707     BusClass *bc;
708
709     if (!dev || !dev->parent_bus) {
710         return NULL;
711     }
712
713     bc = BUS_GET_CLASS(dev->parent_bus);
714     if (bc->get_dev_path) {
715         return bc->get_dev_path(dev);
716     }
717
718     return NULL;
719 }
720
721 /**
722  * Legacy property handling
723  */
724
725 static void qdev_get_legacy_property(Object *obj, Visitor *v,
726                                      const char *name, void *opaque,
727                                      Error **errp)
728 {
729     DeviceState *dev = DEVICE(obj);
730     Property *prop = opaque;
731
732     char buffer[1024];
733     char *ptr = buffer;
734
735     prop->info->print(dev, prop, buffer, sizeof(buffer));
736     visit_type_str(v, name, &ptr, errp);
737 }
738
739 /**
740  * qdev_property_add_legacy:
741  * @dev: Device to add the property to.
742  * @prop: The qdev property definition.
743  * @errp: location to store error information.
744  *
745  * Add a legacy QOM property to @dev for qdev property @prop.
746  * On error, store error in @errp.
747  *
748  * Legacy properties are string versions of QOM properties.  The format of
749  * the string depends on the property type.  Legacy properties are only
750  * needed for "info qtree".
751  *
752  * Do not use this is new code!  QOM Properties added through this interface
753  * will be given names in the "legacy" namespace.
754  */
755 static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
756                                      Error **errp)
757 {
758     gchar *name;
759
760     /* Register pointer properties as legacy properties */
761     if (!prop->info->print && prop->info->get) {
762         return;
763     }
764
765     name = g_strdup_printf("legacy-%s", prop->name);
766     object_property_add(OBJECT(dev), name, "str",
767                         prop->info->print ? qdev_get_legacy_property : prop->info->get,
768                         NULL,
769                         NULL,
770                         prop, errp);
771
772     g_free(name);
773 }
774
775 /**
776  * qdev_property_add_static:
777  * @dev: Device to add the property to.
778  * @prop: The qdev property definition.
779  * @errp: location to store error information.
780  *
781  * Add a static QOM property to @dev for qdev property @prop.
782  * On error, store error in @errp.  Static properties access data in a struct.
783  * The type of the QOM property is derived from prop->info.
784  */
785 void qdev_property_add_static(DeviceState *dev, Property *prop,
786                               Error **errp)
787 {
788     Error *local_err = NULL;
789     Object *obj = OBJECT(dev);
790
791     /*
792      * TODO qdev_prop_ptr does not have getters or setters.  It must
793      * go now that it can be replaced with links.  The test should be
794      * removed along with it: all static properties are read/write.
795      */
796     if (!prop->info->get && !prop->info->set) {
797         return;
798     }
799
800     object_property_add(obj, prop->name, prop->info->name,
801                         prop->info->get, prop->info->set,
802                         prop->info->release,
803                         prop, &local_err);
804
805     if (local_err) {
806         error_propagate(errp, local_err);
807         return;
808     }
809
810     object_property_set_description(obj, prop->name,
811                                     prop->info->description,
812                                     &error_abort);
813
814     if (prop->qtype == QTYPE_NONE) {
815         return;
816     }
817
818     if (prop->qtype == QTYPE_QBOOL) {
819         object_property_set_bool(obj, prop->defval, prop->name, &error_abort);
820     } else if (prop->info->enum_table) {
821         object_property_set_str(obj, prop->info->enum_table[prop->defval],
822                                 prop->name, &error_abort);
823     } else if (prop->qtype == QTYPE_QINT) {
824         object_property_set_int(obj, prop->defval, prop->name, &error_abort);
825     }
826 }
827
828 /* @qdev_alias_all_properties - Add alias properties to the source object for
829  * all qdev properties on the target DeviceState.
830  */
831 void qdev_alias_all_properties(DeviceState *target, Object *source)
832 {
833     ObjectClass *class;
834     Property *prop;
835
836     class = object_get_class(OBJECT(target));
837     do {
838         DeviceClass *dc = DEVICE_CLASS(class);
839
840         for (prop = dc->props; prop && prop->name; prop++) {
841             object_property_add_alias(source, prop->name,
842                                       OBJECT(target), prop->name,
843                                       &error_abort);
844         }
845         class = object_class_get_parent(class);
846     } while (class != object_class_by_name(TYPE_DEVICE));
847 }
848
849 static int qdev_add_hotpluggable_device(Object *obj, void *opaque)
850 {
851     GSList **list = opaque;
852     DeviceState *dev = (DeviceState *)object_dynamic_cast(OBJECT(obj),
853                                                           TYPE_DEVICE);
854
855     if (dev == NULL) {
856         return 0;
857     }
858
859     if (dev->realized && object_property_get_bool(obj, "hotpluggable", NULL)) {
860         *list = g_slist_append(*list, dev);
861     }
862
863     return 0;
864 }
865
866 GSList *qdev_build_hotpluggable_device_list(Object *peripheral)
867 {
868     GSList *list = NULL;
869
870     object_child_foreach(peripheral, qdev_add_hotpluggable_device, &list);
871
872     return list;
873 }
874
875 static bool device_get_realized(Object *obj, Error **errp)
876 {
877     DeviceState *dev = DEVICE(obj);
878     return dev->realized;
879 }
880
881 static void device_set_realized(Object *obj, bool value, Error **errp)
882 {
883     DeviceState *dev = DEVICE(obj);
884     DeviceClass *dc = DEVICE_GET_CLASS(dev);
885     HotplugHandler *hotplug_ctrl;
886     BusState *bus;
887     Error *local_err = NULL;
888
889     if (dev->hotplugged && !dc->hotpluggable) {
890         error_setg(errp, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj));
891         return;
892     }
893
894     if (value && !dev->realized) {
895         if (!obj->parent) {
896             static int unattached_count;
897             gchar *name = g_strdup_printf("device[%d]", unattached_count++);
898
899             object_property_add_child(container_get(qdev_get_machine(),
900                                                     "/unattached"),
901                                       name, obj, &error_abort);
902             g_free(name);
903         }
904
905         hotplug_ctrl = qdev_get_hotplug_handler(dev);
906         if (hotplug_ctrl) {
907             hotplug_handler_pre_plug(hotplug_ctrl, dev, &local_err);
908             if (local_err != NULL) {
909                 goto fail;
910             }
911         }
912
913         if (dc->realize) {
914             dc->realize(dev, &local_err);
915         }
916
917         if (local_err != NULL) {
918             goto fail;
919         }
920
921         DEVICE_LISTENER_CALL(realize, Forward, dev);
922
923         if (hotplug_ctrl) {
924             hotplug_handler_plug(hotplug_ctrl, dev, &local_err);
925         }
926
927         if (local_err != NULL) {
928             goto post_realize_fail;
929         }
930
931         if (qdev_get_vmsd(dev)) {
932             vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
933                                            dev->instance_id_alias,
934                                            dev->alias_required_for_version);
935         }
936
937         QLIST_FOREACH(bus, &dev->child_bus, sibling) {
938             object_property_set_bool(OBJECT(bus), true, "realized",
939                                          &local_err);
940             if (local_err != NULL) {
941                 goto child_realize_fail;
942             }
943         }
944         if (dev->hotplugged) {
945             device_reset(dev);
946         }
947         dev->pending_deleted_event = false;
948     } else if (!value && dev->realized) {
949         Error **local_errp = NULL;
950         QLIST_FOREACH(bus, &dev->child_bus, sibling) {
951             local_errp = local_err ? NULL : &local_err;
952             object_property_set_bool(OBJECT(bus), false, "realized",
953                                      local_errp);
954         }
955         if (qdev_get_vmsd(dev)) {
956             vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
957         }
958         if (dc->unrealize) {
959             local_errp = local_err ? NULL : &local_err;
960             dc->unrealize(dev, local_errp);
961         }
962         dev->pending_deleted_event = true;
963         DEVICE_LISTENER_CALL(unrealize, Reverse, dev);
964     }
965
966     if (local_err != NULL) {
967         goto fail;
968     }
969
970     dev->realized = value;
971     return;
972
973 child_realize_fail:
974     QLIST_FOREACH(bus, &dev->child_bus, sibling) {
975         object_property_set_bool(OBJECT(bus), false, "realized",
976                                  NULL);
977     }
978
979     if (qdev_get_vmsd(dev)) {
980         vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
981     }
982
983 post_realize_fail:
984     if (dc->unrealize) {
985         dc->unrealize(dev, NULL);
986     }
987
988 fail:
989     error_propagate(errp, local_err);
990 }
991
992 static bool device_get_hotpluggable(Object *obj, Error **errp)
993 {
994     DeviceClass *dc = DEVICE_GET_CLASS(obj);
995     DeviceState *dev = DEVICE(obj);
996
997     return dc->hotpluggable && (dev->parent_bus == NULL ||
998                                 qbus_is_hotpluggable(dev->parent_bus));
999 }
1000
1001 static bool device_get_hotplugged(Object *obj, Error **err)
1002 {
1003     DeviceState *dev = DEVICE(obj);
1004
1005     return dev->hotplugged;
1006 }
1007
1008 static void device_set_hotplugged(Object *obj, bool value, Error **err)
1009 {
1010     DeviceState *dev = DEVICE(obj);
1011
1012     dev->hotplugged = value;
1013 }
1014
1015 static void device_initfn(Object *obj)
1016 {
1017     DeviceState *dev = DEVICE(obj);
1018     ObjectClass *class;
1019     Property *prop;
1020
1021     if (qdev_hotplug) {
1022         dev->hotplugged = 1;
1023         qdev_hot_added = true;
1024     }
1025
1026     dev->instance_id_alias = -1;
1027     dev->realized = false;
1028
1029     object_property_add_bool(obj, "realized",
1030                              device_get_realized, device_set_realized, NULL);
1031     object_property_add_bool(obj, "hotpluggable",
1032                              device_get_hotpluggable, NULL, NULL);
1033     object_property_add_bool(obj, "hotplugged",
1034                              device_get_hotplugged, device_set_hotplugged,
1035                              &error_abort);
1036
1037     class = object_get_class(OBJECT(dev));
1038     do {
1039         for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
1040             qdev_property_add_legacy(dev, prop, &error_abort);
1041             qdev_property_add_static(dev, prop, &error_abort);
1042         }
1043         class = object_class_get_parent(class);
1044     } while (class != object_class_by_name(TYPE_DEVICE));
1045
1046     object_property_add_link(OBJECT(dev), "parent_bus", TYPE_BUS,
1047                              (Object **)&dev->parent_bus, NULL, 0,
1048                              &error_abort);
1049     QLIST_INIT(&dev->gpios);
1050 }
1051
1052 static void device_post_init(Object *obj)
1053 {
1054     qdev_prop_set_globals(DEVICE(obj));
1055 }
1056
1057 /* Unlink device from bus and free the structure.  */
1058 static void device_finalize(Object *obj)
1059 {
1060     NamedGPIOList *ngl, *next;
1061
1062     DeviceState *dev = DEVICE(obj);
1063
1064     QLIST_FOREACH_SAFE(ngl, &dev->gpios, node, next) {
1065         QLIST_REMOVE(ngl, node);
1066         qemu_free_irqs(ngl->in, ngl->num_in);
1067         g_free(ngl->name);
1068         g_free(ngl);
1069         /* ngl->out irqs are owned by the other end and should not be freed
1070          * here
1071          */
1072     }
1073 }
1074
1075 static void device_class_base_init(ObjectClass *class, void *data)
1076 {
1077     DeviceClass *klass = DEVICE_CLASS(class);
1078
1079     /* We explicitly look up properties in the superclasses,
1080      * so do not propagate them to the subclasses.
1081      */
1082     klass->props = NULL;
1083 }
1084
1085 static void device_unparent(Object *obj)
1086 {
1087     DeviceState *dev = DEVICE(obj);
1088     BusState *bus;
1089
1090     if (dev->realized) {
1091         object_property_set_bool(obj, false, "realized", NULL);
1092     }
1093     while (dev->num_child_bus) {
1094         bus = QLIST_FIRST(&dev->child_bus);
1095         object_unparent(OBJECT(bus));
1096     }
1097     if (dev->parent_bus) {
1098         bus_remove_child(dev->parent_bus, dev);
1099         object_unref(OBJECT(dev->parent_bus));
1100         dev->parent_bus = NULL;
1101     }
1102
1103     /* Only send event if the device had been completely realized */
1104     if (dev->pending_deleted_event) {
1105         gchar *path = object_get_canonical_path(OBJECT(dev));
1106
1107         qapi_event_send_device_deleted(!!dev->id, dev->id, path, &error_abort);
1108         g_free(path);
1109     }
1110
1111     qemu_opts_del(dev->opts);
1112     dev->opts = NULL;
1113 }
1114
1115 static void device_class_init(ObjectClass *class, void *data)
1116 {
1117     DeviceClass *dc = DEVICE_CLASS(class);
1118
1119     class->unparent = device_unparent;
1120     dc->realize = device_realize;
1121     dc->unrealize = device_unrealize;
1122
1123     /* by default all devices were considered as hotpluggable,
1124      * so with intent to check it in generic qdev_unplug() /
1125      * device_set_realized() functions make every device
1126      * hotpluggable. Devices that shouldn't be hotpluggable,
1127      * should override it in their class_init()
1128      */
1129     dc->hotpluggable = true;
1130 }
1131
1132 void device_reset(DeviceState *dev)
1133 {
1134     DeviceClass *klass = DEVICE_GET_CLASS(dev);
1135
1136     if (klass->reset) {
1137         klass->reset(dev);
1138     }
1139 }
1140
1141 Object *qdev_get_machine(void)
1142 {
1143     static Object *dev;
1144
1145     if (dev == NULL) {
1146         dev = container_get(object_get_root(), "/machine");
1147     }
1148
1149     return dev;
1150 }
1151
1152 static const TypeInfo device_type_info = {
1153     .name = TYPE_DEVICE,
1154     .parent = TYPE_OBJECT,
1155     .instance_size = sizeof(DeviceState),
1156     .instance_init = device_initfn,
1157     .instance_post_init = device_post_init,
1158     .instance_finalize = device_finalize,
1159     .class_base_init = device_class_base_init,
1160     .class_init = device_class_init,
1161     .abstract = true,
1162     .class_size = sizeof(DeviceClass),
1163 };
1164
1165 static void qdev_register_types(void)
1166 {
1167     type_register_static(&device_type_info);
1168 }
1169
1170 type_init(qdev_register_types)
This page took 0.090684 seconds and 4 git commands to generate.