qdev.c 32.4 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.  */

P
Peter Maydell 已提交
28
#include "qemu/osdep.h"
29
#include "hw/qdev.h"
30
#include "sysemu/sysemu.h"
31
#include "qapi/error.h"
32
#include "qapi/qapi-events-misc.h"
33
#include "qapi/qmp/qerror.h"
34
#include "qapi/visitor.h"
35
#include "qemu/error-report.h"
36
#include "qemu/option.h"
37
#include "hw/hotplug.h"
38
#include "hw/boards.h"
39
#include "hw/sysbus.h"
P
Paul Brook 已提交
40

41
bool qdev_hotplug = false;
42
static bool qdev_hot_added = false;
J
Juan Quintela 已提交
43
bool qdev_hot_removed = false;
44

A
Anthony Liguori 已提交
45 46
const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
{
A
Anthony Liguori 已提交
47 48
    DeviceClass *dc = DEVICE_GET_CLASS(dev);
    return dc->vmsd;
A
Anthony Liguori 已提交
49 50
}

A
Anthony Liguori 已提交
51
static void bus_remove_child(BusState *bus, DeviceState *child)
52
{
A
Anthony Liguori 已提交
53 54 55 56 57 58 59 60
    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);
61 62

            /* This gives back ownership of kid->child back to us.  */
A
Anthony Liguori 已提交
63
            object_property_del(OBJECT(bus), name, NULL);
64
            object_unref(OBJECT(kid->child));
A
Anthony Liguori 已提交
65 66 67 68 69 70 71 72 73 74
            g_free(kid);
            return;
        }
    }
}

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

A
Anthony Liguori 已提交
76 77
    kid->index = bus->max_index++;
    kid->child = child;
78
    object_ref(OBJECT(kid->child));
79

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

82
    /* This transfers ownership of kid->child to the property.  */
A
Anthony Liguori 已提交
83 84 85
    snprintf(name, sizeof(name), "child[%d]", kid->index);
    object_property_add_link(OBJECT(bus), name,
                             object_get_typename(OBJECT(child)),
86 87 88 89
                             (Object **)&kid->child,
                             NULL, /* read-only property */
                             0, /* return ownership on prop deletion */
                             NULL);
A
Anthony Liguori 已提交
90 91 92 93
}

void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
{
94 95 96 97 98 99 100 101 102 103 104
    bool replugging = dev->parent_bus != NULL;

    if (replugging) {
        /* Keep a reference to the device while it's not plugged into
         * any bus, to avoid it potentially evaporating when it is
         * dereffed in bus_remove_child().
         */
        object_ref(OBJECT(dev));
        bus_remove_child(dev->parent_bus, dev);
        object_unref(OBJECT(dev->parent_bus));
    }
105
    dev->parent_bus = bus;
106
    object_ref(OBJECT(bus));
A
Anthony Liguori 已提交
107
    bus_add_child(bus, dev);
108 109 110
    if (replugging) {
        object_unref(OBJECT(dev));
    }
111 112
}

113 114 115
/* Create a new device.  This only initializes the device state
   structure and allows properties to be set.  The device still needs
   to be realized.  See qdev-core.h.  */
P
Paul Brook 已提交
116
DeviceState *qdev_create(BusState *bus, const char *name)
117 118 119 120 121
{
    DeviceState *dev;

    dev = qdev_try_create(bus, name);
    if (!dev) {
122
        if (bus) {
123
            error_report("Unknown device '%s' for bus '%s'", name,
124
                         object_get_typename(OBJECT(bus)));
125
        } else {
126
            error_report("Unknown device '%s' for default sysbus", name);
127
        }
L
liguang 已提交
128
        abort();
129 130 131 132 133
    }

    return dev;
}

134
DeviceState *qdev_try_create(BusState *bus, const char *type)
P
Paul Brook 已提交
135
{
136 137
    DeviceState *dev;

138
    if (object_class_by_name(type) == NULL) {
139 140
        return NULL;
    }
141
    dev = DEVICE(object_new(type));
142 143 144 145
    if (!dev) {
        return NULL;
    }

146
    if (!bus) {
147 148 149 150 151 152
        /* Assert that the device really is a SysBusDevice before
         * we put it onto the sysbus. Non-sysbus devices which aren't
         * being put onto a bus should be created with object_new(TYPE_FOO),
         * not qdev_create(NULL, TYPE_FOO).
         */
        g_assert(object_dynamic_cast(OBJECT(dev), TYPE_SYS_BUS_DEVICE));
153
        bus = sysbus_get_default();
154 155
    }

156
    qdev_set_parent_bus(dev, bus);
157
    object_unref(OBJECT(dev));
158
    return dev;
P
Paul Brook 已提交
159 160
}

P
Paul Durrant 已提交
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
static QTAILQ_HEAD(device_listeners, DeviceListener) device_listeners
    = QTAILQ_HEAD_INITIALIZER(device_listeners);

enum ListenerDirection { Forward, Reverse };

#define DEVICE_LISTENER_CALL(_callback, _direction, _args...)     \
    do {                                                          \
        DeviceListener *_listener;                                \
                                                                  \
        switch (_direction) {                                     \
        case Forward:                                             \
            QTAILQ_FOREACH(_listener, &device_listeners, link) {  \
                if (_listener->_callback) {                       \
                    _listener->_callback(_listener, ##_args);     \
                }                                                 \
            }                                                     \
            break;                                                \
        case Reverse:                                             \
            QTAILQ_FOREACH_REVERSE(_listener, &device_listeners,  \
                                   device_listeners, link) {      \
                if (_listener->_callback) {                       \
                    _listener->_callback(_listener, ##_args);     \
                }                                                 \
            }                                                     \
            break;                                                \
        default:                                                  \
            abort();                                              \
        }                                                         \
    } while (0)

static int device_listener_add(DeviceState *dev, void *opaque)
{
    DEVICE_LISTENER_CALL(realize, Forward, dev);

    return 0;
}

void device_listener_register(DeviceListener *listener)
{
    QTAILQ_INSERT_TAIL(&device_listeners, listener, link);

    qbus_walk_children(sysbus_get_default(), NULL, NULL, device_listener_add,
                       NULL, NULL);
}

void device_listener_unregister(DeviceListener *listener)
{
    QTAILQ_REMOVE(&device_listeners, listener, link);
}

J
Jan Kiszka 已提交
211 212 213
void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
                                 int required_for_version)
{
214
    assert(!dev->realized);
J
Jan Kiszka 已提交
215 216 217 218
    dev->instance_id_alias = alias_id;
    dev->alias_required_for_version = required_for_version;
}

219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev)
{
    MachineState *machine;
    MachineClass *mc;
    Object *m_obj = qdev_get_machine();

    if (object_dynamic_cast(m_obj, TYPE_MACHINE)) {
        machine = MACHINE(m_obj);
        mc = MACHINE_GET_CLASS(machine);
        if (mc->get_hotplug_handler) {
            return mc->get_hotplug_handler(machine, dev);
        }
    }

    return NULL;
}

236
HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev)
237
{
238
    HotplugHandler *hotplug_ctrl;
239 240 241

    if (dev->parent_bus && dev->parent_bus->hotplug_handler) {
        hotplug_ctrl = dev->parent_bus->hotplug_handler;
242 243
    } else {
        hotplug_ctrl = qdev_get_machine_hotplug_handler(dev);
244 245 246 247
    }
    return hotplug_ctrl;
}

248 249
static int qdev_reset_one(DeviceState *dev, void *opaque)
{
250
    device_reset(dev);
251 252 253 254

    return 0;
}

255 256
static int qbus_reset_one(BusState *bus, void *opaque)
{
257 258
    BusClass *bc = BUS_GET_CLASS(bus);
    if (bc->reset) {
P
Paolo Bonzini 已提交
259
        bc->reset(bus);
260 261 262 263
    }
    return 0;
}

264 265
void qdev_reset_all(DeviceState *dev)
{
P
Paolo Bonzini 已提交
266
    qdev_walk_children(dev, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
267 268
}

269 270 271 272 273
void qdev_reset_all_fn(void *opaque)
{
    qdev_reset_all(DEVICE(opaque));
}

P
Paolo Bonzini 已提交
274 275
void qbus_reset_all(BusState *bus)
{
P
Paolo Bonzini 已提交
276
    qbus_walk_children(bus, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
P
Paolo Bonzini 已提交
277 278
}

279 280 281
void qbus_reset_all_fn(void *opaque)
{
    BusState *bus = opaque;
P
Paolo Bonzini 已提交
282
    qbus_reset_all(bus);
283 284
}

285
/* can be used as ->unplug() callback for the simple cases */
286 287 288
void qdev_simple_device_unplug_cb(HotplugHandler *hotplug_dev,
                                  DeviceState *dev, Error **errp)
{
289 290
    /* just zap it */
    object_unparent(OBJECT(dev));
291
}
292

293 294 295 296 297 298 299 300 301 302 303 304 305
/*
 * Realize @dev.
 * Device properties should be set before calling this function.  IRQs
 * and MMIO regions should be connected/mapped after calling this
 * function.
 * On failure, report an error with error_report() and terminate the
 * program.  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.
 */
M
Markus Armbruster 已提交
306 307
void qdev_init_nofail(DeviceState *dev)
{
308
    Error *err = NULL;
309

310 311
    assert(!dev->realized);

312
    object_ref(OBJECT(dev));
313 314
    object_property_set_bool(OBJECT(dev), true, "realized", &err);
    if (err) {
315 316
        error_reportf_err(err, "Initialization of device %s failed: ",
                          object_get_typename(OBJECT(dev)));
317 318
        exit(1);
    }
319
    object_unref(OBJECT(dev));
M
Markus Armbruster 已提交
320 321
}

322 323 324 325 326 327
void qdev_machine_creation_done(void)
{
    /*
     * ok, initial machine setup is done, starting from now we can
     * only create hotpluggable devices
     */
328
    qdev_hotplug = true;
329 330
}

331 332 333 334 335
bool qdev_machine_modified(void)
{
    return qdev_hot_added || qdev_hot_removed;
}

P
Paul Brook 已提交
336
BusState *qdev_get_parent_bus(DeviceState *dev)
P
Paul Brook 已提交
337
{
P
Paul Brook 已提交
338
    return dev->parent_bus;
P
Paul Brook 已提交
339 340
}

P
Peter Crosthwaite 已提交
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361
static NamedGPIOList *qdev_get_named_gpio_list(DeviceState *dev,
                                               const char *name)
{
    NamedGPIOList *ngl;

    QLIST_FOREACH(ngl, &dev->gpios, node) {
        /* NULL is a valid and matchable name, otherwise do a normal
         * strcmp match.
         */
        if ((!ngl->name && !name) ||
                (name && ngl->name && strcmp(name, ngl->name) == 0)) {
            return ngl;
        }
    }

    ngl = g_malloc0(sizeof(*ngl));
    ngl->name = g_strdup(name);
    QLIST_INSERT_HEAD(&dev->gpios, ngl, node);
    return ngl;
}

362 363 364 365
void qdev_init_gpio_in_named_with_opaque(DeviceState *dev,
                                         qemu_irq_handler handler,
                                         void *opaque,
                                         const char *name, int n)
P
Peter Crosthwaite 已提交
366
{
367
    int i;
P
Peter Crosthwaite 已提交
368 369
    NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);

370
    assert(gpio_list->num_out == 0 || !name);
P
Peter Crosthwaite 已提交
371
    gpio_list->in = qemu_extend_irqs(gpio_list->in, gpio_list->num_in, handler,
372
                                     opaque, n);
373

374 375 376
    if (!name) {
        name = "unnamed-gpio-in";
    }
377
    for (i = gpio_list->num_in; i < gpio_list->num_in + n; i++) {
378 379
        gchar *propname = g_strdup_printf("%s[%u]", name, i);

380 381
        object_property_add_child(OBJECT(dev), propname,
                                  OBJECT(gpio_list->in[i]), &error_abort);
382
        g_free(propname);
383 384
    }

P
Peter Crosthwaite 已提交
385 386 387
    gpio_list->num_in += n;
}

P
Paul Brook 已提交
388 389
void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
{
P
Peter Crosthwaite 已提交
390 391 392 393 394 395
    qdev_init_gpio_in_named(dev, handler, NULL, n);
}

void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins,
                              const char *name, int n)
{
396
    int i;
P
Peter Crosthwaite 已提交
397 398
    NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);

399
    assert(gpio_list->num_in == 0 || !name);
400

401 402 403 404
    if (!name) {
        name = "unnamed-gpio-out";
    }
    memset(pins, 0, sizeof(*pins) * n);
405
    for (i = 0; i < n; ++i) {
406 407 408
        gchar *propname = g_strdup_printf("%s[%u]", name,
                                          gpio_list->num_out + i);

409 410 411
        object_property_add_link(OBJECT(dev), propname, TYPE_IRQ,
                                 (Object **)&pins[i],
                                 object_property_allow_set_link,
412
                                 OBJ_PROP_LINK_STRONG,
413
                                 &error_abort);
414
        g_free(propname);
415
    }
416
    gpio_list->num_out += n;
P
Paul Brook 已提交
417 418 419 420
}

void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
{
P
Peter Crosthwaite 已提交
421 422 423 424 425 426 427 428 429
    qdev_init_gpio_out_named(dev, pins, NULL, n);
}

qemu_irq qdev_get_gpio_in_named(DeviceState *dev, const char *name, int n)
{
    NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);

    assert(n >= 0 && n < gpio_list->num_in);
    return gpio_list->in[n];
P
Paul Brook 已提交
430 431 432 433
}

qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
{
P
Peter Crosthwaite 已提交
434 435 436 437 438 439
    return qdev_get_gpio_in_named(dev, NULL, n);
}

void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n,
                                 qemu_irq pin)
{
440 441 442 443 444 445 446 447
    char *propname = g_strdup_printf("%s[%d]",
                                     name ? name : "unnamed-gpio-out", n);
    if (pin) {
        /* We need a name for object_property_set_link to work.  If the
         * object has a parent, object_property_add_child will come back
         * with an error without doing anything.  If it has none, it will
         * never fail.  So we can just call it with a NULL Error pointer.
         */
448 449 450
        object_property_add_child(container_get(qdev_get_machine(),
                                                "/unattached"),
                                  "non-qdev-gpio[*]", OBJECT(pin), NULL);
451 452 453
    }
    object_property_set_link(OBJECT(dev), OBJECT(pin), propname, &error_abort);
    g_free(propname);
P
Paul Brook 已提交
454 455
}

456 457 458 459 460 461 462 463 464 465 466
qemu_irq qdev_get_gpio_out_connector(DeviceState *dev, const char *name, int n)
{
    char *propname = g_strdup_printf("%s[%d]",
                                     name ? name : "unnamed-gpio-out", n);

    qemu_irq ret = (qemu_irq)object_property_get_link(OBJECT(dev), propname,
                                                      NULL);

    return ret;
}

V
Veres Lajos 已提交
467
/* disconnect a GPIO output, returning the disconnected input (if any) */
468 469 470 471 472 473 474 475 476 477 478 479 480 481 482

static qemu_irq qdev_disconnect_gpio_out_named(DeviceState *dev,
                                               const char *name, int n)
{
    char *propname = g_strdup_printf("%s[%d]",
                                     name ? name : "unnamed-gpio-out", n);

    qemu_irq ret = (qemu_irq)object_property_get_link(OBJECT(dev), propname,
                                                      NULL);
    if (ret) {
        object_property_set_link(OBJECT(dev), NULL, propname, NULL);
    }
    g_free(propname);
    return ret;
}
P
Peter Crosthwaite 已提交
483

484 485 486 487 488 489
qemu_irq qdev_intercept_gpio_out(DeviceState *dev, qemu_irq icpt,
                                 const char *name, int n)
{
    qemu_irq disconnected = qdev_disconnect_gpio_out_named(dev, name, n);
    qdev_connect_gpio_out_named(dev, name, n, icpt);
    return disconnected;
P
Paul Brook 已提交
490 491 492 493
}

void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
{
P
Peter Crosthwaite 已提交
494
    qdev_connect_gpio_out_named(dev, NULL, n, pin);
P
Paul Brook 已提交
495 496
}

497 498 499 500 501 502 503 504 505 506 507 508 509
void qdev_pass_gpios(DeviceState *dev, DeviceState *container,
                     const char *name)
{
    int i;
    NamedGPIOList *ngl = qdev_get_named_gpio_list(dev, name);

    for (i = 0; i < ngl->num_in; i++) {
        const char *nm = ngl->name ? ngl->name : "unnamed-gpio-in";
        char *propname = g_strdup_printf("%s[%d]", nm, i);

        object_property_add_alias(OBJECT(container), propname,
                                  OBJECT(dev), propname,
                                  &error_abort);
510
        g_free(propname);
511 512 513 514 515 516 517 518
    }
    for (i = 0; i < ngl->num_out; i++) {
        const char *nm = ngl->name ? ngl->name : "unnamed-gpio-out";
        char *propname = g_strdup_printf("%s[%d]", nm, i);

        object_property_add_alias(OBJECT(container), propname,
                                  OBJECT(dev), propname,
                                  &error_abort);
519
        g_free(propname);
520 521 522 523 524
    }
    QLIST_REMOVE(ngl, node);
    QLIST_INSERT_HEAD(&container->gpios, ngl, node);
}

P
Paul Brook 已提交
525
BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
P
Paul Brook 已提交
526
{
P
Paul Brook 已提交
527
    BusState *bus;
528 529 530 531 532 533
    Object *child = object_resolve_path_component(OBJECT(dev), name);

    bus = (BusState *)object_dynamic_cast(child, TYPE_BUS);
    if (bus) {
        return bus;
    }
P
Paul Brook 已提交
534

B
Blue Swirl 已提交
535
    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
P
Paul Brook 已提交
536
        if (strcmp(name, bus->name) == 0) {
P
Paul Brook 已提交
537
            return bus;
P
Paul Brook 已提交
538 539 540 541 542
        }
    }
    return NULL;
}

543 544 545 546
int qdev_walk_children(DeviceState *dev,
                       qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
                       qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
                       void *opaque)
547 548 549 550
{
    BusState *bus;
    int err;

551 552
    if (pre_devfn) {
        err = pre_devfn(dev, opaque);
553 554 555 556 557 558
        if (err) {
            return err;
        }
    }

    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
559 560
        err = qbus_walk_children(bus, pre_devfn, pre_busfn,
                                 post_devfn, post_busfn, opaque);
561 562 563 564 565
        if (err < 0) {
            return err;
        }
    }

566 567 568 569 570 571 572
    if (post_devfn) {
        err = post_devfn(dev, opaque);
        if (err) {
            return err;
        }
    }

573 574 575
    return 0;
}

576
DeviceState *qdev_find_recursive(BusState *bus, const char *id)
577
{
A
Anthony Liguori 已提交
578 579
    BusChild *kid;
    DeviceState *ret;
580 581
    BusState *child;

A
Anthony Liguori 已提交
582 583 584 585
    QTAILQ_FOREACH(kid, &bus->children, sibling) {
        DeviceState *dev = kid->child;

        if (dev->id && strcmp(dev->id, id) == 0) {
586
            return dev;
A
Anthony Liguori 已提交
587 588
        }

589 590 591 592 593 594 595 596 597 598
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
            ret = qdev_find_recursive(child, id);
            if (ret) {
                return ret;
            }
        }
    }
    return NULL;
}

599
char *qdev_get_dev_path(DeviceState *dev)
600
{
601
    BusClass *bc;
602 603 604 605 606

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

607 608 609
    bc = BUS_GET_CLASS(dev->parent_bus);
    if (bc->get_dev_path) {
        return bc->get_dev_path(dev);
610 611 612
    }

    return NULL;
613
}
614 615 616 617 618

/**
 * Legacy property handling
 */

619 620 621
static void qdev_get_legacy_property(Object *obj, Visitor *v,
                                     const char *name, void *opaque,
                                     Error **errp)
622
{
623
    DeviceState *dev = DEVICE(obj);
624 625
    Property *prop = opaque;

626 627
    char buffer[1024];
    char *ptr = buffer;
628

629
    prop->info->print(dev, prop, buffer, sizeof(buffer));
630
    visit_type_str(v, name, &ptr, errp);
631 632 633
}

/**
C
Cao jin 已提交
634 635 636 637 638 639 640
 * qdev_property_add_legacy:
 * @dev: Device to add the property to.
 * @prop: The qdev property definition.
 * @errp: location to store error information.
 *
 * Add a legacy QOM property to @dev for qdev property @prop.
 * On error, store error in @errp.
641
 *
C
Cao jin 已提交
642 643 644
 * Legacy properties are string versions of QOM properties.  The format of
 * the string depends on the property type.  Legacy properties are only
 * needed for "info qtree".
645
 *
C
Cao jin 已提交
646 647
 * Do not use this is new code!  QOM Properties added through this interface
 * will be given names in the "legacy" namespace.
648
 */
649 650
static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
                                     Error **errp)
651
{
652
    gchar *name;
653

654
    /* Register pointer properties as legacy properties */
655
    if (!prop->info->print && prop->info->get) {
656 657
        return;
    }
658

F
Fam Zheng 已提交
659 660 661 662
    if (prop->info->create) {
        return;
    }

663
    name = g_strdup_printf("legacy-%s", prop->name);
664
    object_property_add(OBJECT(dev), name, "str",
665
                        prop->info->print ? qdev_get_legacy_property : prop->info->get,
666
                        NULL,
667 668
                        NULL,
                        prop, errp);
669

670 671 672 673
    g_free(name);
}

/**
C
Cao jin 已提交
674 675 676 677
 * qdev_property_add_static:
 * @dev: Device to add the property to.
 * @prop: The qdev property definition.
 * @errp: location to store error information.
678
 *
C
Cao jin 已提交
679 680 681
 * Add a static QOM property to @dev for qdev property @prop.
 * On error, store error in @errp.  Static properties access data in a struct.
 * The type of the QOM property is derived from prop->info.
682 683 684 685
 */
void qdev_property_add_static(DeviceState *dev, Property *prop,
                              Error **errp)
{
686 687 688
    Error *local_err = NULL;
    Object *obj = OBJECT(dev);

F
Fam Zheng 已提交
689 690 691 692 693 694 695 696 697 698 699 700 701 702 703
    if (prop->info->create) {
        prop->info->create(obj, prop, &local_err);
    } else {
        /*
         * 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;
        }
        object_property_add(obj, prop->name, prop->info->name,
                            prop->info->get, prop->info->set,
                            prop->info->release,
                            prop, &local_err);
704 705
    }

706 707 708 709
    if (local_err) {
        error_propagate(errp, local_err);
        return;
    }
710 711 712 713 714

    object_property_set_description(obj, prop->name,
                                    prop->info->description,
                                    &error_abort);

715
    if (prop->set_default) {
716
        prop->info->set_default_value(obj, prop);
717
    }
A
Anthony Liguori 已提交
718
}
719

720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740
/* @qdev_alias_all_properties - Add alias properties to the source object for
 * all qdev properties on the target DeviceState.
 */
void qdev_alias_all_properties(DeviceState *target, Object *source)
{
    ObjectClass *class;
    Property *prop;

    class = object_get_class(OBJECT(target));
    do {
        DeviceClass *dc = DEVICE_CLASS(class);

        for (prop = dc->props; prop && prop->name; prop++) {
            object_property_add_alias(source, prop->name,
                                      OBJECT(target), prop->name,
                                      &error_abort);
        }
        class = object_class_get_parent(class);
    } while (class != object_class_by_name(TYPE_DEVICE));
}

741
static int qdev_add_hotpluggable_device(Object *obj, void *opaque)
742 743
{
    GSList **list = opaque;
744 745 746 747 748 749
    DeviceState *dev = (DeviceState *)object_dynamic_cast(OBJECT(obj),
                                                          TYPE_DEVICE);

    if (dev == NULL) {
        return 0;
    }
750 751 752 753 754 755 756 757

    if (dev->realized && object_property_get_bool(obj, "hotpluggable", NULL)) {
        *list = g_slist_append(*list, dev);
    }

    return 0;
}

758 759 760 761 762 763 764 765 766
GSList *qdev_build_hotpluggable_device_list(Object *peripheral)
{
    GSList *list = NULL;

    object_child_foreach(peripheral, qdev_add_hotpluggable_device, &list);

    return list;
}

767
static bool device_get_realized(Object *obj, Error **errp)
768 769 770 771 772
{
    DeviceState *dev = DEVICE(obj);
    return dev->realized;
}

773 774 775 776 777 778 779 780 781 782 783 784 785 786
static bool check_only_migratable(Object *obj, Error **err)
{
    DeviceClass *dc = DEVICE_GET_CLASS(obj);

    if (!vmstate_check_only_migratable(dc->vmsd)) {
        error_setg(err, "Device %s is not migratable, but "
                   "--only-migratable was specified",
                   object_get_typename(obj));
        return false;
    }

    return true;
}

787
static void device_set_realized(Object *obj, bool value, Error **errp)
788 789 790
{
    DeviceState *dev = DEVICE(obj);
    DeviceClass *dc = DEVICE_GET_CLASS(dev);
791
    HotplugHandler *hotplug_ctrl;
792
    BusState *bus;
793
    Error *local_err = NULL;
794 795
    bool unattached_parent = false;
    static int unattached_count;
796

797
    if (dev->hotplugged && !dc->hotpluggable) {
798
        error_setg(errp, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj));
799 800 801
        return;
    }

802
    if (value && !dev->realized) {
803
        if (!check_only_migratable(obj, &local_err)) {
804 805 806
            goto fail;
        }

807
        if (!obj->parent) {
808 809 810 811
            gchar *name = g_strdup_printf("device[%d]", unattached_count++);

            object_property_add_child(container_get(qdev_get_machine(),
                                                    "/unattached"),
812
                                      name, obj, &error_abort);
813
            unattached_parent = true;
814 815 816
            g_free(name);
        }

817 818 819 820 821 822 823 824
        hotplug_ctrl = qdev_get_hotplug_handler(dev);
        if (hotplug_ctrl) {
            hotplug_handler_pre_plug(hotplug_ctrl, dev, &local_err);
            if (local_err != NULL) {
                goto fail;
            }
        }

825 826 827 828
        if (dc->realize) {
            dc->realize(dev, &local_err);
        }

829 830 831 832
        if (local_err != NULL) {
            goto fail;
        }

P
Paul Durrant 已提交
833 834
        DEVICE_LISTENER_CALL(realize, Forward, dev);

835 836
        if (hotplug_ctrl) {
            hotplug_handler_plug(hotplug_ctrl, dev, &local_err);
837 838
        }

839 840 841 842
        if (local_err != NULL) {
            goto post_realize_fail;
        }

843 844 845 846 847 848 849
        /*
         * always free/re-initialize here since the value cannot be cleaned up
         * in device_unrealize due to its usage later on in the unplug path
         */
        g_free(dev->canonical_path);
        dev->canonical_path = object_get_canonical_path(OBJECT(dev));

850
        if (qdev_get_vmsd(dev)) {
851 852 853 854 855 856
            if (vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
                                               dev->instance_id_alias,
                                               dev->alias_required_for_version,
                                               &local_err) < 0) {
                goto post_realize_fail;
            }
857
        }
858 859 860

        QLIST_FOREACH(bus, &dev->child_bus, sibling) {
            object_property_set_bool(OBJECT(bus), true, "realized",
861
                                         &local_err);
862 863
            if (local_err != NULL) {
                goto child_realize_fail;
864 865
            }
        }
866
        if (dev->hotplugged) {
867 868
            device_reset(dev);
        }
869
        dev->pending_deleted_event = false;
870 871 872 873

        if (hotplug_ctrl) {
            hotplug_handler_post_plug(hotplug_ctrl, dev);
        }
874
    } else if (!value && dev->realized) {
875
        Error **local_errp = NULL;
876
        QLIST_FOREACH(bus, &dev->child_bus, sibling) {
877
            local_errp = local_err ? NULL : &local_err;
878
            object_property_set_bool(OBJECT(bus), false, "realized",
879
                                     local_errp);
880
        }
881
        if (qdev_get_vmsd(dev)) {
882 883
            vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
        }
884 885 886
        if (dc->unrealize) {
            local_errp = local_err ? NULL : &local_err;
            dc->unrealize(dev, local_errp);
887
        }
888
        dev->pending_deleted_event = true;
P
Paul Durrant 已提交
889
        DEVICE_LISTENER_CALL(unrealize, Reverse, dev);
890
    }
891

892 893
    if (local_err != NULL) {
        goto fail;
894 895
    }

896
    dev->realized = value;
897 898 899 900 901 902 903 904 905 906 907 908 909
    return;

child_realize_fail:
    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
        object_property_set_bool(OBJECT(bus), false, "realized",
                                 NULL);
    }

    if (qdev_get_vmsd(dev)) {
        vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
    }

post_realize_fail:
910 911
    g_free(dev->canonical_path);
    dev->canonical_path = NULL;
912 913 914 915 916 917
    if (dc->unrealize) {
        dc->unrealize(dev, NULL);
    }

fail:
    error_propagate(errp, local_err);
918 919 920 921
    if (unattached_parent) {
        object_unparent(OBJECT(dev));
        unattached_count--;
    }
922 923
}

924
static bool device_get_hotpluggable(Object *obj, Error **errp)
925 926 927 928
{
    DeviceClass *dc = DEVICE_GET_CLASS(obj);
    DeviceState *dev = DEVICE(obj);

929
    return dc->hotpluggable && (dev->parent_bus == NULL ||
930
                                qbus_is_hotpluggable(dev->parent_bus));
931 932
}

933 934 935 936 937 938 939
static bool device_get_hotplugged(Object *obj, Error **err)
{
    DeviceState *dev = DEVICE(obj);

    return dev->hotplugged;
}

940 941 942
static void device_initfn(Object *obj)
{
    DeviceState *dev = DEVICE(obj);
943
    ObjectClass *class;
944 945 946 947 948 949 950 951
    Property *prop;

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

    dev->instance_id_alias = -1;
952
    dev->realized = false;
953

954 955
    object_property_add_bool(obj, "realized",
                             device_get_realized, device_set_realized, NULL);
956 957
    object_property_add_bool(obj, "hotpluggable",
                             device_get_hotpluggable, NULL, NULL);
958
    object_property_add_bool(obj, "hotplugged",
959
                             device_get_hotplugged, NULL,
960
                             &error_abort);
961

962 963 964
    class = object_get_class(OBJECT(dev));
    do {
        for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
965 966
            qdev_property_add_legacy(dev, prop, &error_abort);
            qdev_property_add_static(dev, prop, &error_abort);
967 968 969
        }
        class = object_class_get_parent(class);
    } while (class != object_class_by_name(TYPE_DEVICE));
970

971
    object_property_add_link(OBJECT(dev), "parent_bus", TYPE_BUS,
972
                             (Object **)&dev->parent_bus, NULL, 0,
973
                             &error_abort);
P
Peter Crosthwaite 已提交
974
    QLIST_INIT(&dev->gpios);
975 976
}

977 978
static void device_post_init(Object *obj)
{
979
    qdev_prop_set_globals(DEVICE(obj));
980 981
}

982 983 984
/* Unlink device from bus and free the structure.  */
static void device_finalize(Object *obj)
{
P
Peter Crosthwaite 已提交
985 986
    NamedGPIOList *ngl, *next;

987
    DeviceState *dev = DEVICE(obj);
P
Peter Crosthwaite 已提交
988 989 990

    QLIST_FOREACH_SAFE(ngl, &dev->gpios, node, next) {
        QLIST_REMOVE(ngl, node);
991
        qemu_free_irqs(ngl->in, ngl->num_in);
P
Peter Crosthwaite 已提交
992 993 994 995 996 997
        g_free(ngl->name);
        g_free(ngl);
        /* ngl->out irqs are owned by the other end and should not be freed
         * here
         */
    }
998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009

    /* Only send event if the device had been completely realized */
    if (dev->pending_deleted_event) {
        g_assert(dev->canonical_path);

        qapi_event_send_device_deleted(!!dev->id, dev->id, dev->canonical_path,
                                       &error_abort);
        g_free(dev->canonical_path);
        dev->canonical_path = NULL;
    }

    qemu_opts_del(dev->opts);
1010 1011
}

1012 1013 1014 1015 1016 1017 1018 1019
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;
1020 1021
}

1022
static void device_unparent(Object *obj)
1023 1024
{
    DeviceState *dev = DEVICE(obj);
1025
    BusState *bus;
1026

1027 1028 1029
    if (dev->realized) {
        object_property_set_bool(obj, false, "realized", NULL);
    }
1030 1031
    while (dev->num_child_bus) {
        bus = QLIST_FIRST(&dev->child_bus);
1032
        object_unparent(OBJECT(bus));
1033 1034
    }
    if (dev->parent_bus) {
1035
        bus_remove_child(dev->parent_bus, dev);
1036 1037
        object_unref(OBJECT(dev->parent_bus));
        dev->parent_bus = NULL;
1038
    }
1039 1040 1041 1042
}

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

1045
    class->unparent = device_unparent;
1046 1047 1048 1049 1050 1051 1052 1053

    /* by default all devices were considered as hotpluggable,
     * so with intent to check it in generic qdev_unplug() /
     * device_set_realized() functions make every device
     * hotpluggable. Devices that shouldn't be hotpluggable,
     * should override it in their class_init()
     */
    dc->hotpluggable = true;
1054
    dc->user_creatable = true;
1055 1056
}

1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080
void device_class_set_parent_reset(DeviceClass *dc,
                                   DeviceReset dev_reset,
                                   DeviceReset *parent_reset)
{
    *parent_reset = dc->reset;
    dc->reset = dev_reset;
}

void device_class_set_parent_realize(DeviceClass *dc,
                                     DeviceRealize dev_realize,
                                     DeviceRealize *parent_realize)
{
    *parent_realize = dc->realize;
    dc->realize = dev_realize;
}

void device_class_set_parent_unrealize(DeviceClass *dc,
                                       DeviceUnrealize dev_unrealize,
                                       DeviceUnrealize *parent_unrealize)
{
    *parent_unrealize = dc->unrealize;
    dc->unrealize = dev_unrealize;
}

1081 1082 1083 1084 1085 1086 1087 1088 1089
void device_reset(DeviceState *dev)
{
    DeviceClass *klass = DEVICE_GET_CLASS(dev);

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

1090 1091 1092 1093 1094
Object *qdev_get_machine(void)
{
    static Object *dev;

    if (dev == NULL) {
1095
        dev = container_get(object_get_root(), "/machine");
1096 1097 1098 1099 1100
    }

    return dev;
}

1101
static const TypeInfo device_type_info = {
1102 1103 1104
    .name = TYPE_DEVICE,
    .parent = TYPE_OBJECT,
    .instance_size = sizeof(DeviceState),
1105
    .instance_init = device_initfn,
1106
    .instance_post_init = device_post_init,
1107
    .instance_finalize = device_finalize,
1108
    .class_base_init = device_class_base_init,
1109
    .class_init = device_class_init,
1110 1111 1112 1113
    .abstract = true,
    .class_size = sizeof(DeviceClass),
};

A
Andreas Färber 已提交
1114
static void qdev_register_types(void)
1115 1116 1117 1118
{
    type_register_static(&device_type_info);
}

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