qdev.c 22.8 KB
Newer Older
P
Paul Brook 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/*
 *  Dynamic device configuration and creation.
 *
 *  Copyright (c) 2009 CodeSourcery
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * 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/>.
P
Paul Brook 已提交
18 19 20 21 22 23 24 25 26 27
 */

/* The theory here is that it should be possible to create a machine without
   knowledge of specific devices.  Historically board init routines have
   passed a bunch of arguments to each device, requiring the board know
   exactly which device it is dealing with.  This file provides an abstract
   API for device configuration and initialization.  Devices will generally
   inherit from a particular bus (e.g. PCI or I2C) rather than
   this API directly.  */

28
#include "hw/qdev.h"
29
#include "sysemu/sysemu.h"
30
#include "qapi/error.h"
31
#include "qapi/qmp/qerror.h"
32
#include "qapi/visitor.h"
M
Michael S. Tsirkin 已提交
33 34
#include "qapi/qmp/qjson.h"
#include "monitor/monitor.h"
P
Paul Brook 已提交
35

36
int qdev_hotplug = 0;
37 38
static bool qdev_hot_added = false;
static bool qdev_hot_removed = false;
39

A
Anthony Liguori 已提交
40 41
const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
{
A
Anthony Liguori 已提交
42 43
    DeviceClass *dc = DEVICE_GET_CLASS(dev);
    return dc->vmsd;
A
Anthony Liguori 已提交
44 45 46 47
}

const char *qdev_fw_name(DeviceState *dev)
{
A
Anthony Liguori 已提交
48
    DeviceClass *dc = DEVICE_GET_CLASS(dev);
A
Anthony Liguori 已提交
49

A
Anthony Liguori 已提交
50 51
    if (dc->fw_name) {
        return dc->fw_name;
A
Anthony Liguori 已提交
52 53 54 55 56
    }

    return object_get_typename(OBJECT(dev));
}

57 58 59
static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
                                     Error **errp);

A
Anthony Liguori 已提交
60
static void bus_remove_child(BusState *bus, DeviceState *child)
61
{
A
Anthony Liguori 已提交
62 63 64 65 66 67 68 69
    BusChild *kid;

    QTAILQ_FOREACH(kid, &bus->children, sibling) {
        if (kid->child == child) {
            char name[32];

            snprintf(name, sizeof(name), "child[%d]", kid->index);
            QTAILQ_REMOVE(&bus->children, kid, sibling);
70 71

            /* This gives back ownership of kid->child back to us.  */
A
Anthony Liguori 已提交
72
            object_property_del(OBJECT(bus), name, NULL);
73
            object_unref(OBJECT(kid->child));
A
Anthony Liguori 已提交
74 75 76 77 78 79 80 81 82 83
            g_free(kid);
            return;
        }
    }
}

static void bus_add_child(BusState *bus, DeviceState *child)
{
    char name[32];
    BusChild *kid = g_malloc0(sizeof(*kid));
84 85 86 87

    if (qdev_hotplug) {
        assert(bus->allow_hotplug);
    }
88

A
Anthony Liguori 已提交
89 90
    kid->index = bus->max_index++;
    kid->child = child;
91
    object_ref(OBJECT(kid->child));
92

A
Anthony Liguori 已提交
93 94
    QTAILQ_INSERT_HEAD(&bus->children, kid, sibling);

95
    /* This transfers ownership of kid->child to the property.  */
A
Anthony Liguori 已提交
96 97 98 99 100 101 102 103 104
    snprintf(name, sizeof(name), "child[%d]", kid->index);
    object_property_add_link(OBJECT(bus), name,
                             object_get_typename(OBJECT(child)),
                             (Object **)&kid->child,
                             NULL);
}

void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
{
105
    dev->parent_bus = bus;
106
    object_ref(OBJECT(bus));
A
Anthony Liguori 已提交
107
    bus_add_child(bus, dev);
108 109
}

P
Paul Brook 已提交
110 111 112
/* Create a new device.  This only initializes the device state structure
   and allows properties to be set.  qdev_init should be called to
   initialize the actual device emulation.  */
P
Paul Brook 已提交
113
DeviceState *qdev_create(BusState *bus, const char *name)
114 115 116 117 118
{
    DeviceState *dev;

    dev = qdev_try_create(bus, name);
    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
        }
L
liguang 已提交
125
        abort();
126 127 128 129 130
    }

    return dev;
}

131
DeviceState *qdev_try_create(BusState *bus, const char *type)
P
Paul Brook 已提交
132
{
133 134
    DeviceState *dev;

135
    if (object_class_by_name(type) == NULL) {
136 137
        return NULL;
    }
138
    dev = DEVICE(object_new(type));
139 140 141 142
    if (!dev) {
        return NULL;
    }

143
    if (!bus) {
144
        bus = sysbus_get_default();
145 146
    }

147
    qdev_set_parent_bus(dev, bus);
148
    object_unref(OBJECT(dev));
149
    return dev;
P
Paul Brook 已提交
150 151 152 153
}

/* Initialize a device.  Device properties should be set before calling
   this function.  IRQs and MMIO regions should be connected/mapped after
154 155 156
   calling this function.
   On failure, destroy the device and return negative value.
   Return 0 on success.  */
157
int qdev_init(DeviceState *dev)
P
Paul Brook 已提交
158
{
159
    Error *local_err = NULL;
G
Gerd Hoffmann 已提交
160

161
    assert(!dev->realized);
A
Anthony Liguori 已提交
162

163 164
    object_property_set_bool(OBJECT(dev), true, "realized", &local_err);
    if (local_err != NULL) {
165
        qerror_report_err(local_err);
166
        error_free(local_err);
167
        object_unparent(OBJECT(dev));
168
        return -1;
169
    }
170 171
    return 0;
}
172

173 174 175
static void device_realize(DeviceState *dev, Error **err)
{
    DeviceClass *dc = DEVICE_GET_CLASS(dev);
176

177 178 179 180 181 182
    if (dc->init) {
        int rc = dc->init(dev);
        if (rc < 0) {
            error_setg(err, "Device initialization failed.");
            return;
        }
J
Jan Kiszka 已提交
183
    }
P
Paul Brook 已提交
184 185
}

186 187 188 189 190 191 192 193 194 195 196 197 198
static void device_unrealize(DeviceState *dev, Error **errp)
{
    DeviceClass *dc = DEVICE_GET_CLASS(dev);

    if (dc->exit) {
        int rc = dc->exit(dev);
        if (rc < 0) {
            error_setg(errp, "Device exit failed.");
            return;
        }
    }
}

J
Jan Kiszka 已提交
199 200 201
void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
                                 int required_for_version)
{
202
    assert(!dev->realized);
J
Jan Kiszka 已提交
203 204 205 206
    dev->instance_id_alias = alias_id;
    dev->alias_required_for_version = required_for_version;
}

207
void qdev_unplug(DeviceState *dev, Error **errp)
208
{
A
Anthony Liguori 已提交
209 210
    DeviceClass *dc = DEVICE_GET_CLASS(dev);

211
    if (dev->parent_bus && !dev->parent_bus->allow_hotplug) {
212 213
        error_set(errp, QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
        return;
214
    }
A
Anthony Liguori 已提交
215
    assert(dc->unplug != NULL);
216

217 218
    qdev_hot_removed = true;

219 220 221 222
    if (dc->unplug(dev) < 0) {
        error_set(errp, QERR_UNDEFINED_ERROR);
        return;
    }
223 224
}

225 226
static int qdev_reset_one(DeviceState *dev, void *opaque)
{
227
    device_reset(dev);
228 229 230 231

    return 0;
}

232 233
static int qbus_reset_one(BusState *bus, void *opaque)
{
234 235
    BusClass *bc = BUS_GET_CLASS(bus);
    if (bc->reset) {
P
Paolo Bonzini 已提交
236
        bc->reset(bus);
237 238 239 240
    }
    return 0;
}

241 242
void qdev_reset_all(DeviceState *dev)
{
P
Paolo Bonzini 已提交
243
    qdev_walk_children(dev, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
244 245
}

P
Paolo Bonzini 已提交
246 247
void qbus_reset_all(BusState *bus)
{
P
Paolo Bonzini 已提交
248
    qbus_walk_children(bus, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
P
Paolo Bonzini 已提交
249 250
}

251 252 253
void qbus_reset_all_fn(void *opaque)
{
    BusState *bus = opaque;
P
Paolo Bonzini 已提交
254
    qbus_reset_all(bus);
255 256
}

257 258 259 260
/* can be used as ->unplug() callback for the simple cases */
int qdev_simple_unplug_cb(DeviceState *dev)
{
    /* just zap it */
261
    object_unparent(OBJECT(dev));
262 263 264
    return 0;
}

265 266

/* Like qdev_init(), but terminate program via error_report() instead of
M
Markus Armbruster 已提交
267 268 269 270 271 272 273 274
   returning an error value.  This is okay during machine creation.
   Don't use for hotplug, because there callers need to recover from
   failure.  Exception: if you know the device's init() callback can't
   fail, then qdev_init_nofail() can't fail either, and is therefore
   usable even then.  But relying on the device implementation that
   way is somewhat unclean, and best avoided.  */
void qdev_init_nofail(DeviceState *dev)
{
275 276
    const char *typename = object_get_typename(OBJECT(dev));

277
    if (qdev_init(dev) < 0) {
278
        error_report("Initialization of device %s failed", typename);
279 280
        exit(1);
    }
M
Markus Armbruster 已提交
281 282
}

283 284 285 286 287 288 289 290 291
void qdev_machine_creation_done(void)
{
    /*
     * ok, initial machine setup is done, starting from now we can
     * only create hotpluggable devices
     */
    qdev_hotplug = 1;
}

292 293 294 295 296
bool qdev_machine_modified(void)
{
    return qdev_hot_added || qdev_hot_removed;
}

P
Paul Brook 已提交
297
BusState *qdev_get_parent_bus(DeviceState *dev)
P
Paul Brook 已提交
298
{
P
Paul Brook 已提交
299
    return dev->parent_bus;
P
Paul Brook 已提交
300 301 302 303
}

void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
{
304 305 306
    dev->gpio_in = qemu_extend_irqs(dev->gpio_in, dev->num_gpio_in, handler,
                                        dev, n);
    dev->num_gpio_in += n;
P
Paul Brook 已提交
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327
}

void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
{
    assert(dev->num_gpio_out == 0);
    dev->num_gpio_out = n;
    dev->gpio_out = pins;
}

qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
{
    assert(n >= 0 && n < dev->num_gpio_in);
    return dev->gpio_in[n];
}

void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
{
    assert(n >= 0 && n < dev->num_gpio_out);
    dev->gpio_out[n] = pin;
}

P
Paul Brook 已提交
328
BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
P
Paul Brook 已提交
329
{
P
Paul Brook 已提交
330
    BusState *bus;
P
Paul Brook 已提交
331

B
Blue Swirl 已提交
332
    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
P
Paul Brook 已提交
333
        if (strcmp(name, bus->name) == 0) {
P
Paul Brook 已提交
334
            return bus;
P
Paul Brook 已提交
335 336 337 338 339
        }
    }
    return NULL;
}

340 341 342 343
int qbus_walk_children(BusState *bus,
                       qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
                       qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
                       void *opaque)
344
{
A
Anthony Liguori 已提交
345
    BusChild *kid;
346 347
    int err;

348 349
    if (pre_busfn) {
        err = pre_busfn(bus, opaque);
350 351 352 353 354
        if (err) {
            return err;
        }
    }

A
Anthony Liguori 已提交
355
    QTAILQ_FOREACH(kid, &bus->children, sibling) {
356 357 358
        err = qdev_walk_children(kid->child,
                                 pre_devfn, pre_busfn,
                                 post_devfn, post_busfn, opaque);
359 360 361 362 363
        if (err < 0) {
            return err;
        }
    }

364 365 366 367 368 369 370
    if (post_busfn) {
        err = post_busfn(bus, opaque);
        if (err) {
            return err;
        }
    }

371 372 373
    return 0;
}

374 375 376 377
int qdev_walk_children(DeviceState *dev,
                       qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
                       qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
                       void *opaque)
378 379 380 381
{
    BusState *bus;
    int err;

382 383
    if (pre_devfn) {
        err = pre_devfn(dev, opaque);
384 385 386 387 388 389
        if (err) {
            return err;
        }
    }

    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
390 391
        err = qbus_walk_children(bus, pre_devfn, pre_busfn,
                                 post_devfn, post_busfn, opaque);
392 393 394 395 396
        if (err < 0) {
            return err;
        }
    }

397 398 399 400 401 402 403
    if (post_devfn) {
        err = post_devfn(dev, opaque);
        if (err) {
            return err;
        }
    }

404 405 406
    return 0;
}

407
DeviceState *qdev_find_recursive(BusState *bus, const char *id)
408
{
A
Anthony Liguori 已提交
409 410
    BusChild *kid;
    DeviceState *ret;
411 412
    BusState *child;

A
Anthony Liguori 已提交
413 414 415 416
    QTAILQ_FOREACH(kid, &bus->children, sibling) {
        DeviceState *dev = kid->child;

        if (dev->id && strcmp(dev->id, id) == 0) {
417
            return dev;
A
Anthony Liguori 已提交
418 419
        }

420 421 422 423 424 425 426 427 428 429
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
            ret = qdev_find_recursive(child, id);
            if (ret) {
                return ret;
            }
        }
    }
    return NULL;
}

430
static void qbus_realize(BusState *bus, DeviceState *parent, const char *name)
P
Paul Brook 已提交
431
{
432
    const char *typename = object_get_typename(OBJECT(bus));
G
Gerd Hoffmann 已提交
433 434
    char *buf;
    int i,len;
P
Paul Brook 已提交
435

436 437 438 439
    bus->parent = parent;

    if (name) {
        bus->name = g_strdup(name);
440
    } else if (bus->parent && bus->parent->id) {
G
Gerd Hoffmann 已提交
441
        /* parent device has id -> use it for bus name */
442
        len = strlen(bus->parent->id) + 16;
443
        buf = g_malloc(len);
444
        snprintf(buf, len, "%s.%d", bus->parent->id, bus->parent->num_child_bus);
G
Gerd Hoffmann 已提交
445 446 447
        bus->name = buf;
    } else {
        /* no id -> use lowercase bus type for bus name */
448
        len = strlen(typename) + 16;
449
        buf = g_malloc(len);
450
        len = snprintf(buf, len, "%s.%d", typename,
451
                       bus->parent ? bus->parent->num_child_bus : 0);
G
Gerd Hoffmann 已提交
452
        for (i = 0; i < len; i++)
C
Christoph Egger 已提交
453
            buf[i] = qemu_tolower(buf[i]);
G
Gerd Hoffmann 已提交
454 455 456
        bus->name = buf;
    }

457 458 459 460
    if (bus->parent) {
        QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
        bus->parent->num_child_bus++;
        object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL);
461
        object_unref(OBJECT(bus));
462
    } else if (bus != sysbus_get_default()) {
463 464 465
        /* TODO: once all bus devices are qdevified,
           only reset handler for main_system_bus should be registered here. */
        qemu_register_reset(qbus_reset_all_fn, bus);
P
Paul Brook 已提交
466
    }
467 468
}

469 470 471 472 473 474 475
static void bus_unparent(Object *obj)
{
    BusState *bus = BUS(obj);
    BusChild *kid;

    while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) {
        DeviceState *dev = kid->child;
476
        object_unparent(OBJECT(dev));
477 478 479 480 481 482 483 484 485 486 487
    }
    if (bus->parent) {
        QLIST_REMOVE(bus, sibling);
        bus->parent->num_child_bus--;
        bus->parent = NULL;
    } else {
        assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
        qemu_unregister_reset(qbus_reset_all_fn, bus);
    }
}

488
void qbus_create_inplace(void *bus, size_t size, const char *typename,
489
                         DeviceState *parent, const char *name)
490
{
491
    object_initialize(bus, size, typename);
492
    qbus_realize(bus, parent, name);
P
Paul Brook 已提交
493
}
494

495
BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
I
Isaku Yamahata 已提交
496
{
497 498
    BusState *bus;

499
    bus = BUS(object_new(typename));
500
    qbus_realize(bus, parent, name);
501

P
Paul Brook 已提交
502
    return bus;
I
Isaku Yamahata 已提交
503 504
}

505 506 507 508 509 510
static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev)
{
    BusClass *bc = BUS_GET_CLASS(bus);

    if (bc->get_fw_dev_path) {
        return bc->get_fw_dev_path(dev);
G
Gerd Hoffmann 已提交
511
    }
512 513

    return NULL;
G
Gerd Hoffmann 已提交
514 515
}

516 517 518 519 520 521 522
static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
{
    int l = 0;

    if (dev && dev->parent_bus) {
        char *d;
        l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
523 524
        d = bus_get_fw_dev_path(dev->parent_bus, dev);
        if (d) {
525
            l += snprintf(p + l, size - l, "%s", d);
526
            g_free(d);
527
        } else {
528
            return l;
529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544
        }
    }
    l += snprintf(p + l , size - l, "/");

    return l;
}

char* qdev_get_fw_dev_path(DeviceState *dev)
{
    char path[128];
    int l;

    l = qdev_get_fw_dev_path_helper(dev, path, 128);

    path[l-1] = '\0';

545
    return g_strdup(path);
546
}
547

548
char *qdev_get_dev_path(DeviceState *dev)
549
{
550
    BusClass *bc;
551 552 553 554 555

    if (!dev || !dev->parent_bus) {
        return NULL;
    }

556 557 558
    bc = BUS_GET_CLASS(dev->parent_bus);
    if (bc->get_dev_path) {
        return bc->get_dev_path(dev);
559 560 561
    }

    return NULL;
562
}
563 564 565 566 567

/**
 * Legacy property handling
 */

568
static void qdev_get_legacy_property(Object *obj, Visitor *v, void *opaque,
569 570
                                     const char *name, Error **errp)
{
571
    DeviceState *dev = DEVICE(obj);
572 573
    Property *prop = opaque;

574 575
    char buffer[1024];
    char *ptr = buffer;
576

577 578
    prop->info->print(dev, prop, buffer, sizeof(buffer));
    visit_type_str(v, &ptr, name, errp);
579 580 581 582 583 584
}

/**
 * @qdev_add_legacy_property - adds a legacy property
 *
 * Do not use this is new code!  Properties added through this interface will
585
 * be given names and types in the "legacy" namespace.
586
 *
587 588
 * Legacy properties are string versions of other OOM properties.  The format
 * of the string depends on the property type.
589 590 591 592
 */
void qdev_property_add_legacy(DeviceState *dev, Property *prop,
                              Error **errp)
{
593
    gchar *name, *type;
594

595
    /* Register pointer properties as legacy properties */
596
    if (!prop->info->print && prop->info->get) {
597 598
        return;
    }
599

600
    name = g_strdup_printf("legacy-%s", prop->name);
601 602
    type = g_strdup_printf("legacy<%s>",
                           prop->info->legacy_name ?: prop->info->name);
603

604
    object_property_add(OBJECT(dev), name, type,
605
                        prop->info->print ? qdev_get_legacy_property : prop->info->get,
606
                        NULL,
607 608
                        NULL,
                        prop, errp);
609 610

    g_free(type);
611 612 613 614 615 616 617 618 619 620 621 622
    g_free(name);
}

/**
 * @qdev_property_add_static - add a @Property to a device.
 *
 * Static properties access data in a struct.  The actual type of the
 * property and the field depends on the property type.
 */
void qdev_property_add_static(DeviceState *dev, Property *prop,
                              Error **errp)
{
623 624 625
    Error *local_err = NULL;
    Object *obj = OBJECT(dev);

626 627 628 629 630 631 632 633 634
    /*
     * TODO qdev_prop_ptr does not have getters or setters.  It must
     * go now that it can be replaced with links.  The test should be
     * removed along with it: all static properties are read/write.
     */
    if (!prop->info->get && !prop->info->set) {
        return;
    }

635
    object_property_add(obj, prop->name, prop->info->name,
636
                        prop->info->get, prop->info->set,
P
Paolo Bonzini 已提交
637
                        prop->info->release,
638 639 640 641 642 643 644 645 646 647 648
                        prop, &local_err);

    if (local_err) {
        error_propagate(errp, local_err);
        return;
    }
    if (prop->qtype == QTYPE_NONE) {
        return;
    }

    if (prop->qtype == QTYPE_QBOOL) {
649
        object_property_set_bool(obj, prop->defval, prop->name, &error_abort);
650 651
    } else if (prop->info->enum_table) {
        object_property_set_str(obj, prop->info->enum_table[prop->defval],
652
                                prop->name, &error_abort);
653
    } else if (prop->qtype == QTYPE_QINT) {
654
        object_property_set_int(obj, prop->defval, prop->name, &error_abort);
655
    }
A
Anthony Liguori 已提交
656
}
657

658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680
static bool device_get_realized(Object *obj, Error **err)
{
    DeviceState *dev = DEVICE(obj);
    return dev->realized;
}

static void device_set_realized(Object *obj, bool value, Error **err)
{
    DeviceState *dev = DEVICE(obj);
    DeviceClass *dc = DEVICE_GET_CLASS(dev);
    Error *local_err = NULL;

    if (value && !dev->realized) {
        if (!obj->parent && local_err == NULL) {
            static int unattached_count;
            gchar *name = g_strdup_printf("device[%d]", unattached_count++);

            object_property_add_child(container_get(qdev_get_machine(),
                                                    "/unattached"),
                                      name, obj, &local_err);
            g_free(name);
        }

681 682 683 684
        if (dc->realize) {
            dc->realize(dev, &local_err);
        }

685 686 687 688 689 690 691 692 693
        if (qdev_get_vmsd(dev) && local_err == NULL) {
            vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
                                           dev->instance_id_alias,
                                           dev->alias_required_for_version);
        }
        if (dev->hotplugged && local_err == NULL) {
            device_reset(dev);
        }
    } else if (!value && dev->realized) {
694 695 696
        if (qdev_get_vmsd(dev)) {
            vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
        }
697 698 699 700 701 702 703 704 705 706 707 708 709
        if (dc->unrealize) {
            dc->unrealize(dev, &local_err);
        }
    }

    if (local_err != NULL) {
        error_propagate(err, local_err);
        return;
    }

    dev->realized = value;
}

710 711 712
static void device_initfn(Object *obj)
{
    DeviceState *dev = DEVICE(obj);
713
    ObjectClass *class;
714 715 716 717 718 719 720 721
    Property *prop;

    if (qdev_hotplug) {
        dev->hotplugged = 1;
        qdev_hot_added = true;
    }

    dev->instance_id_alias = -1;
722
    dev->realized = false;
723

724 725 726
    object_property_add_bool(obj, "realized",
                             device_get_realized, device_set_realized, NULL);

727 728 729
    class = object_get_class(OBJECT(dev));
    do {
        for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
730 731
            qdev_property_add_legacy(dev, prop, &error_abort);
            qdev_property_add_static(dev, prop, &error_abort);
732 733 734
        }
        class = object_class_get_parent(class);
    } while (class != object_class_by_name(TYPE_DEVICE));
735

736
    object_property_add_link(OBJECT(dev), "parent_bus", TYPE_BUS,
737
                             (Object **)&dev->parent_bus, &error_abort);
738 739
}

740 741
static void device_post_init(Object *obj)
{
742
    qdev_prop_set_globals(DEVICE(obj), &error_abort);
743 744
}

745 746 747 748
/* Unlink device from bus and free the structure.  */
static void device_finalize(Object *obj)
{
    DeviceState *dev = DEVICE(obj);
749 750
    if (dev->opts) {
        qemu_opts_del(dev->opts);
751 752 753
    }
}

754 755 756 757 758 759 760 761
static void device_class_base_init(ObjectClass *class, void *data)
{
    DeviceClass *klass = DEVICE_CLASS(class);

    /* We explicitly look up properties in the superclasses,
     * so do not propagate them to the subclasses.
     */
    klass->props = NULL;
762 763
}

764
static void device_unparent(Object *obj)
765 766
{
    DeviceState *dev = DEVICE(obj);
767
    BusState *bus;
M
Michael S. Tsirkin 已提交
768
    QObject *event_data;
769
    bool have_realized = dev->realized;
770

771 772
    while (dev->num_child_bus) {
        bus = QLIST_FIRST(&dev->child_bus);
773
        object_unparent(OBJECT(bus));
774 775
    }
    if (dev->realized) {
776
        object_property_set_bool(obj, false, "realized", NULL);
777 778
    }
    if (dev->parent_bus) {
779
        bus_remove_child(dev->parent_bus, dev);
780 781
        object_unref(OBJECT(dev->parent_bus));
        dev->parent_bus = NULL;
782
    }
M
Michael S. Tsirkin 已提交
783

784 785 786 787 788 789 790 791 792 793 794 795 796
    /* Only send event if the device had been completely realized */
    if (have_realized) {
        gchar *path = object_get_canonical_path(OBJECT(dev));

        if (dev->id) {
            event_data = qobject_from_jsonf("{ 'device': %s, 'path': %s }",
                                            dev->id, path);
        } else {
            event_data = qobject_from_jsonf("{ 'path': %s }", path);
        }
        monitor_protocol_event(QEVENT_DEVICE_DELETED, event_data);
        qobject_decref(event_data);
        g_free(path);
M
Michael S. Tsirkin 已提交
797
    }
798 799 800 801
}

static void device_class_init(ObjectClass *class, void *data)
{
802 803
    DeviceClass *dc = DEVICE_CLASS(class);

804
    class->unparent = device_unparent;
805
    dc->realize = device_realize;
806
    dc->unrealize = device_unrealize;
807 808
}

809 810 811 812 813 814 815 816 817
void device_reset(DeviceState *dev)
{
    DeviceClass *klass = DEVICE_GET_CLASS(dev);

    if (klass->reset) {
        klass->reset(dev);
    }
}

818 819 820 821 822
Object *qdev_get_machine(void)
{
    static Object *dev;

    if (dev == NULL) {
823
        dev = container_get(object_get_root(), "/machine");
824 825 826 827 828
    }

    return dev;
}

829
static const TypeInfo device_type_info = {
830 831 832
    .name = TYPE_DEVICE,
    .parent = TYPE_OBJECT,
    .instance_size = sizeof(DeviceState),
833
    .instance_init = device_initfn,
834
    .instance_post_init = device_post_init,
835
    .instance_finalize = device_finalize,
836
    .class_base_init = device_class_base_init,
837
    .class_init = device_class_init,
838 839 840 841
    .abstract = true,
    .class_size = sizeof(DeviceClass),
};

842 843 844 845 846 847 848
static void qbus_initfn(Object *obj)
{
    BusState *bus = BUS(obj);

    QTAILQ_INIT(&bus->children);
}

849 850 851 852 853
static char *default_bus_get_fw_dev_path(DeviceState *dev)
{
    return g_strdup(object_get_typename(OBJECT(dev)));
}

854 855
static void bus_class_init(ObjectClass *class, void *data)
{
856 857
    BusClass *bc = BUS_CLASS(class);

858
    class->unparent = bus_unparent;
859
    bc->get_fw_dev_path = default_bus_get_fw_dev_path;
860 861
}

862 863 864 865 866 867 868
static void qbus_finalize(Object *obj)
{
    BusState *bus = BUS(obj);

    g_free((char *)bus->name);
}

869 870 871 872 873 874
static const TypeInfo bus_info = {
    .name = TYPE_BUS,
    .parent = TYPE_OBJECT,
    .instance_size = sizeof(BusState),
    .abstract = true,
    .class_size = sizeof(BusClass),
875 876
    .instance_init = qbus_initfn,
    .instance_finalize = qbus_finalize,
877
    .class_init = bus_class_init,
878 879
};

A
Andreas Färber 已提交
880
static void qdev_register_types(void)
881
{
882
    type_register_static(&bus_info);
883 884 885
    type_register_static(&device_type_info);
}

A
Andreas Färber 已提交
886
type_init(qdev_register_types)