qdev.c 33.0 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/qmp/qerror.h"
33
#include "qapi/visitor.h"
34
#include "qemu/error-report.h"
35
#include "qemu/option.h"
36
#include "hw/hotplug.h"
37
#include "hw/boards.h"
38
#include "hw/sysbus.h"
W
Wenchao Xia 已提交
39
#include "qapi-event.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);
}

211
static void device_realize(DeviceState *dev, Error **errp)
212 213
{
    DeviceClass *dc = DEVICE_GET_CLASS(dev);
214

215 216 217
    if (dc->init) {
        int rc = dc->init(dev);
        if (rc < 0) {
218
            error_setg(errp, "Device initialization failed.");
219 220
            return;
        }
J
Jan Kiszka 已提交
221
    }
P
Paul Brook 已提交
222 223
}

224 225 226 227 228 229 230 231 232 233 234 235 236
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 已提交
237 238 239
void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
                                 int required_for_version)
{
240
    assert(!dev->realized);
J
Jan Kiszka 已提交
241 242 243 244
    dev->instance_id_alias = alias_id;
    dev->alias_required_for_version = required_for_version;
}

245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261
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;
}

262
HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev)
263
{
264
    HotplugHandler *hotplug_ctrl;
265 266 267

    if (dev->parent_bus && dev->parent_bus->hotplug_handler) {
        hotplug_ctrl = dev->parent_bus->hotplug_handler;
268 269
    } else {
        hotplug_ctrl = qdev_get_machine_hotplug_handler(dev);
270 271 272 273
    }
    return hotplug_ctrl;
}

274 275
static int qdev_reset_one(DeviceState *dev, void *opaque)
{
276
    device_reset(dev);
277 278 279 280

    return 0;
}

281 282
static int qbus_reset_one(BusState *bus, void *opaque)
{
283 284
    BusClass *bc = BUS_GET_CLASS(bus);
    if (bc->reset) {
P
Paolo Bonzini 已提交
285
        bc->reset(bus);
286 287 288 289
    }
    return 0;
}

290 291
void qdev_reset_all(DeviceState *dev)
{
P
Paolo Bonzini 已提交
292
    qdev_walk_children(dev, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
293 294
}

295 296 297 298 299
void qdev_reset_all_fn(void *opaque)
{
    qdev_reset_all(DEVICE(opaque));
}

P
Paolo Bonzini 已提交
300 301
void qbus_reset_all(BusState *bus)
{
P
Paolo Bonzini 已提交
302
    qbus_walk_children(bus, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
P
Paolo Bonzini 已提交
303 304
}

305 306 307
void qbus_reset_all_fn(void *opaque)
{
    BusState *bus = opaque;
P
Paolo Bonzini 已提交
308
    qbus_reset_all(bus);
309 310
}

311
/* can be used as ->unplug() callback for the simple cases */
312 313 314
void qdev_simple_device_unplug_cb(HotplugHandler *hotplug_dev,
                                  DeviceState *dev, Error **errp)
{
315 316
    /* just zap it */
    object_unparent(OBJECT(dev));
317
}
318

319 320 321 322 323 324 325 326 327 328 329 330 331
/*
 * 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 已提交
332 333
void qdev_init_nofail(DeviceState *dev)
{
334
    Error *err = NULL;
335

336 337
    assert(!dev->realized);

338
    object_ref(OBJECT(dev));
339 340
    object_property_set_bool(OBJECT(dev), true, "realized", &err);
    if (err) {
341 342
        error_reportf_err(err, "Initialization of device %s failed: ",
                          object_get_typename(OBJECT(dev)));
343 344
        exit(1);
    }
345
    object_unref(OBJECT(dev));
M
Markus Armbruster 已提交
346 347
}

348 349 350 351 352 353
void qdev_machine_creation_done(void)
{
    /*
     * ok, initial machine setup is done, starting from now we can
     * only create hotpluggable devices
     */
354
    qdev_hotplug = true;
355 356
}

357 358 359 360 361
bool qdev_machine_modified(void)
{
    return qdev_hot_added || qdev_hot_removed;
}

P
Paul Brook 已提交
362
BusState *qdev_get_parent_bus(DeviceState *dev)
P
Paul Brook 已提交
363
{
P
Paul Brook 已提交
364
    return dev->parent_bus;
P
Paul Brook 已提交
365 366
}

P
Peter Crosthwaite 已提交
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387
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;
}

388 389 390 391
void qdev_init_gpio_in_named_with_opaque(DeviceState *dev,
                                         qemu_irq_handler handler,
                                         void *opaque,
                                         const char *name, int n)
P
Peter Crosthwaite 已提交
392
{
393
    int i;
P
Peter Crosthwaite 已提交
394 395
    NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);

396
    assert(gpio_list->num_out == 0 || !name);
P
Peter Crosthwaite 已提交
397
    gpio_list->in = qemu_extend_irqs(gpio_list->in, gpio_list->num_in, handler,
398
                                     opaque, n);
399

400 401 402
    if (!name) {
        name = "unnamed-gpio-in";
    }
403
    for (i = gpio_list->num_in; i < gpio_list->num_in + n; i++) {
404 405
        gchar *propname = g_strdup_printf("%s[%u]", name, i);

406 407
        object_property_add_child(OBJECT(dev), propname,
                                  OBJECT(gpio_list->in[i]), &error_abort);
408
        g_free(propname);
409 410
    }

P
Peter Crosthwaite 已提交
411 412 413
    gpio_list->num_in += n;
}

P
Paul Brook 已提交
414 415
void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
{
P
Peter Crosthwaite 已提交
416 417 418 419 420 421
    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)
{
422
    int i;
P
Peter Crosthwaite 已提交
423 424
    NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);

425
    assert(gpio_list->num_in == 0 || !name);
426

427 428 429 430
    if (!name) {
        name = "unnamed-gpio-out";
    }
    memset(pins, 0, sizeof(*pins) * n);
431
    for (i = 0; i < n; ++i) {
432 433 434
        gchar *propname = g_strdup_printf("%s[%u]", name,
                                          gpio_list->num_out + i);

435 436 437 438 439
        object_property_add_link(OBJECT(dev), propname, TYPE_IRQ,
                                 (Object **)&pins[i],
                                 object_property_allow_set_link,
                                 OBJ_PROP_LINK_UNREF_ON_RELEASE,
                                 &error_abort);
440
        g_free(propname);
441
    }
442
    gpio_list->num_out += n;
P
Paul Brook 已提交
443 444 445 446
}

void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
{
P
Peter Crosthwaite 已提交
447 448 449 450 451 452 453 454 455
    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 已提交
456 457 458 459
}

qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
{
P
Peter Crosthwaite 已提交
460 461 462 463 464 465
    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)
{
466 467 468 469 470 471 472 473
    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.
         */
474 475 476
        object_property_add_child(container_get(qdev_get_machine(),
                                                "/unattached"),
                                  "non-qdev-gpio[*]", OBJECT(pin), NULL);
477 478 479
    }
    object_property_set_link(OBJECT(dev), OBJECT(pin), propname, &error_abort);
    g_free(propname);
P
Paul Brook 已提交
480 481
}

482 483 484 485 486 487 488 489 490 491 492
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 已提交
493
/* disconnect a GPIO output, returning the disconnected input (if any) */
494 495 496 497 498 499 500 501 502 503 504 505 506 507 508

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 已提交
509

510 511 512 513 514 515
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 已提交
516 517 518 519
}

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

523 524 525 526 527 528 529 530 531 532 533 534 535
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);
536
        g_free(propname);
537 538 539 540 541 542 543 544
    }
    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);
545
        g_free(propname);
546 547 548 549 550
    }
    QLIST_REMOVE(ngl, node);
    QLIST_INSERT_HEAD(&container->gpios, ngl, node);
}

P
Paul Brook 已提交
551
BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
P
Paul Brook 已提交
552
{
P
Paul Brook 已提交
553
    BusState *bus;
554 555 556 557 558 559
    Object *child = object_resolve_path_component(OBJECT(dev), name);

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

B
Blue Swirl 已提交
561
    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
P
Paul Brook 已提交
562
        if (strcmp(name, bus->name) == 0) {
P
Paul Brook 已提交
563
            return bus;
P
Paul Brook 已提交
564 565 566 567 568
        }
    }
    return NULL;
}

569 570 571 572
int qdev_walk_children(DeviceState *dev,
                       qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
                       qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
                       void *opaque)
573 574 575 576
{
    BusState *bus;
    int err;

577 578
    if (pre_devfn) {
        err = pre_devfn(dev, opaque);
579 580 581 582 583 584
        if (err) {
            return err;
        }
    }

    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
585 586
        err = qbus_walk_children(bus, pre_devfn, pre_busfn,
                                 post_devfn, post_busfn, opaque);
587 588 589 590 591
        if (err < 0) {
            return err;
        }
    }

592 593 594 595 596 597 598
    if (post_devfn) {
        err = post_devfn(dev, opaque);
        if (err) {
            return err;
        }
    }

599 600 601
    return 0;
}

602
DeviceState *qdev_find_recursive(BusState *bus, const char *id)
603
{
A
Anthony Liguori 已提交
604 605
    BusChild *kid;
    DeviceState *ret;
606 607
    BusState *child;

A
Anthony Liguori 已提交
608 609 610 611
    QTAILQ_FOREACH(kid, &bus->children, sibling) {
        DeviceState *dev = kid->child;

        if (dev->id && strcmp(dev->id, id) == 0) {
612
            return dev;
A
Anthony Liguori 已提交
613 614
        }

615 616 617 618 619 620 621 622 623 624
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
            ret = qdev_find_recursive(child, id);
            if (ret) {
                return ret;
            }
        }
    }
    return NULL;
}

625
char *qdev_get_dev_path(DeviceState *dev)
626
{
627
    BusClass *bc;
628 629 630 631 632

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

633 634 635
    bc = BUS_GET_CLASS(dev->parent_bus);
    if (bc->get_dev_path) {
        return bc->get_dev_path(dev);
636 637 638
    }

    return NULL;
639
}
640 641 642 643 644

/**
 * Legacy property handling
 */

645 646 647
static void qdev_get_legacy_property(Object *obj, Visitor *v,
                                     const char *name, void *opaque,
                                     Error **errp)
648
{
649
    DeviceState *dev = DEVICE(obj);
650 651
    Property *prop = opaque;

652 653
    char buffer[1024];
    char *ptr = buffer;
654

655
    prop->info->print(dev, prop, buffer, sizeof(buffer));
656
    visit_type_str(v, name, &ptr, errp);
657 658 659
}

/**
C
Cao jin 已提交
660 661 662 663 664 665 666
 * 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.
667
 *
C
Cao jin 已提交
668 669 670
 * 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".
671
 *
C
Cao jin 已提交
672 673
 * Do not use this is new code!  QOM Properties added through this interface
 * will be given names in the "legacy" namespace.
674
 */
675 676
static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
                                     Error **errp)
677
{
678
    gchar *name;
679

680
    /* Register pointer properties as legacy properties */
681
    if (!prop->info->print && prop->info->get) {
682 683
        return;
    }
684

F
Fam Zheng 已提交
685 686 687 688
    if (prop->info->create) {
        return;
    }

689
    name = g_strdup_printf("legacy-%s", prop->name);
690
    object_property_add(OBJECT(dev), name, "str",
691
                        prop->info->print ? qdev_get_legacy_property : prop->info->get,
692
                        NULL,
693 694
                        NULL,
                        prop, errp);
695

696 697 698 699
    g_free(name);
}

/**
C
Cao jin 已提交
700 701 702 703
 * qdev_property_add_static:
 * @dev: Device to add the property to.
 * @prop: The qdev property definition.
 * @errp: location to store error information.
704
 *
C
Cao jin 已提交
705 706 707
 * 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.
708 709 710 711
 */
void qdev_property_add_static(DeviceState *dev, Property *prop,
                              Error **errp)
{
712 713 714
    Error *local_err = NULL;
    Object *obj = OBJECT(dev);

F
Fam Zheng 已提交
715 716 717 718 719 720 721 722 723 724 725 726 727 728 729
    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);
730 731
    }

732 733 734 735
    if (local_err) {
        error_propagate(errp, local_err);
        return;
    }
736 737 738 739 740

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

741
    if (prop->set_default) {
742
        prop->info->set_default_value(obj, prop);
743
    }
A
Anthony Liguori 已提交
744
}
745

746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766
/* @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));
}

767
static int qdev_add_hotpluggable_device(Object *obj, void *opaque)
768 769
{
    GSList **list = opaque;
770 771 772 773 774 775
    DeviceState *dev = (DeviceState *)object_dynamic_cast(OBJECT(obj),
                                                          TYPE_DEVICE);

    if (dev == NULL) {
        return 0;
    }
776 777 778 779 780 781 782 783

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

    return 0;
}

784 785 786 787 788 789 790 791 792
GSList *qdev_build_hotpluggable_device_list(Object *peripheral)
{
    GSList *list = NULL;

    object_child_foreach(peripheral, qdev_add_hotpluggable_device, &list);

    return list;
}

793
static bool device_get_realized(Object *obj, Error **errp)
794 795 796 797 798
{
    DeviceState *dev = DEVICE(obj);
    return dev->realized;
}

799 800 801 802 803 804 805 806 807 808 809 810 811 812
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;
}

813
static void device_set_realized(Object *obj, bool value, Error **errp)
814 815 816
{
    DeviceState *dev = DEVICE(obj);
    DeviceClass *dc = DEVICE_GET_CLASS(dev);
817
    HotplugHandler *hotplug_ctrl;
818
    BusState *bus;
819
    Error *local_err = NULL;
820 821
    bool unattached_parent = false;
    static int unattached_count;
822

823
    if (dev->hotplugged && !dc->hotpluggable) {
824
        error_setg(errp, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj));
825 826 827
        return;
    }

828
    if (value && !dev->realized) {
829
        if (!check_only_migratable(obj, &local_err)) {
830 831 832
            goto fail;
        }

833
        if (!obj->parent) {
834 835 836 837
            gchar *name = g_strdup_printf("device[%d]", unattached_count++);

            object_property_add_child(container_get(qdev_get_machine(),
                                                    "/unattached"),
838
                                      name, obj, &error_abort);
839
            unattached_parent = true;
840 841 842
            g_free(name);
        }

843 844 845 846 847 848 849 850
        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;
            }
        }

851 852 853 854
        if (dc->realize) {
            dc->realize(dev, &local_err);
        }

855 856 857 858
        if (local_err != NULL) {
            goto fail;
        }

P
Paul Durrant 已提交
859 860
        DEVICE_LISTENER_CALL(realize, Forward, dev);

861 862
        if (hotplug_ctrl) {
            hotplug_handler_plug(hotplug_ctrl, dev, &local_err);
863 864
        }

865 866 867 868
        if (local_err != NULL) {
            goto post_realize_fail;
        }

869 870 871 872 873 874 875
        /*
         * 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));

876
        if (qdev_get_vmsd(dev)) {
877 878 879 880 881 882
            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;
            }
883
        }
884 885 886

        QLIST_FOREACH(bus, &dev->child_bus, sibling) {
            object_property_set_bool(OBJECT(bus), true, "realized",
887
                                         &local_err);
888 889
            if (local_err != NULL) {
                goto child_realize_fail;
890 891
            }
        }
892
        if (dev->hotplugged) {
893 894
            device_reset(dev);
        }
895
        dev->pending_deleted_event = false;
896
    } else if (!value && dev->realized) {
897
        Error **local_errp = NULL;
898
        QLIST_FOREACH(bus, &dev->child_bus, sibling) {
899
            local_errp = local_err ? NULL : &local_err;
900
            object_property_set_bool(OBJECT(bus), false, "realized",
901
                                     local_errp);
902
        }
903
        if (qdev_get_vmsd(dev)) {
904 905
            vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
        }
906 907 908
        if (dc->unrealize) {
            local_errp = local_err ? NULL : &local_err;
            dc->unrealize(dev, local_errp);
909
        }
910
        dev->pending_deleted_event = true;
P
Paul Durrant 已提交
911
        DEVICE_LISTENER_CALL(unrealize, Reverse, dev);
912
    }
913

914 915
    if (local_err != NULL) {
        goto fail;
916 917
    }

918
    dev->realized = value;
919 920 921 922 923 924 925 926 927 928 929 930 931
    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:
932 933
    g_free(dev->canonical_path);
    dev->canonical_path = NULL;
934 935 936 937 938 939
    if (dc->unrealize) {
        dc->unrealize(dev, NULL);
    }

fail:
    error_propagate(errp, local_err);
940 941 942 943
    if (unattached_parent) {
        object_unparent(OBJECT(dev));
        unattached_count--;
    }
944 945
}

946
static bool device_get_hotpluggable(Object *obj, Error **errp)
947 948 949 950
{
    DeviceClass *dc = DEVICE_GET_CLASS(obj);
    DeviceState *dev = DEVICE(obj);

951
    return dc->hotpluggable && (dev->parent_bus == NULL ||
952
                                qbus_is_hotpluggable(dev->parent_bus));
953 954
}

955 956 957 958 959 960 961
static bool device_get_hotplugged(Object *obj, Error **err)
{
    DeviceState *dev = DEVICE(obj);

    return dev->hotplugged;
}

962 963 964
static void device_initfn(Object *obj)
{
    DeviceState *dev = DEVICE(obj);
965
    ObjectClass *class;
966 967 968 969 970 971 972 973
    Property *prop;

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

    dev->instance_id_alias = -1;
974
    dev->realized = false;
975

976 977
    object_property_add_bool(obj, "realized",
                             device_get_realized, device_set_realized, NULL);
978 979
    object_property_add_bool(obj, "hotpluggable",
                             device_get_hotpluggable, NULL, NULL);
980
    object_property_add_bool(obj, "hotplugged",
981
                             device_get_hotplugged, NULL,
982
                             &error_abort);
983

984 985 986
    class = object_get_class(OBJECT(dev));
    do {
        for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
987 988
            qdev_property_add_legacy(dev, prop, &error_abort);
            qdev_property_add_static(dev, prop, &error_abort);
989 990 991
        }
        class = object_class_get_parent(class);
    } while (class != object_class_by_name(TYPE_DEVICE));
992

993
    object_property_add_link(OBJECT(dev), "parent_bus", TYPE_BUS,
994
                             (Object **)&dev->parent_bus, NULL, 0,
995
                             &error_abort);
P
Peter Crosthwaite 已提交
996
    QLIST_INIT(&dev->gpios);
997 998
}

999 1000
static void device_post_init(Object *obj)
{
1001
    qdev_prop_set_globals(DEVICE(obj));
1002 1003
}

1004 1005 1006
/* Unlink device from bus and free the structure.  */
static void device_finalize(Object *obj)
{
P
Peter Crosthwaite 已提交
1007 1008
    NamedGPIOList *ngl, *next;

1009
    DeviceState *dev = DEVICE(obj);
P
Peter Crosthwaite 已提交
1010 1011 1012

    QLIST_FOREACH_SAFE(ngl, &dev->gpios, node, next) {
        QLIST_REMOVE(ngl, node);
1013
        qemu_free_irqs(ngl->in, ngl->num_in);
P
Peter Crosthwaite 已提交
1014 1015 1016 1017 1018 1019
        g_free(ngl->name);
        g_free(ngl);
        /* ngl->out irqs are owned by the other end and should not be freed
         * here
         */
    }
1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031

    /* 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);
1032 1033
}

1034 1035 1036 1037 1038 1039 1040 1041
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;
1042 1043
}

1044
static void device_unparent(Object *obj)
1045 1046
{
    DeviceState *dev = DEVICE(obj);
1047
    BusState *bus;
1048

1049 1050 1051
    if (dev->realized) {
        object_property_set_bool(obj, false, "realized", NULL);
    }
1052 1053
    while (dev->num_child_bus) {
        bus = QLIST_FIRST(&dev->child_bus);
1054
        object_unparent(OBJECT(bus));
1055 1056
    }
    if (dev->parent_bus) {
1057
        bus_remove_child(dev->parent_bus, dev);
1058 1059
        object_unref(OBJECT(dev->parent_bus));
        dev->parent_bus = NULL;
1060
    }
1061 1062 1063 1064
}

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

1067
    class->unparent = device_unparent;
1068
    dc->realize = device_realize;
1069
    dc->unrealize = device_unrealize;
1070 1071 1072 1073 1074 1075 1076 1077

    /* 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;
1078
    dc->user_creatable = true;
1079 1080
}

1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104
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;
}

1105 1106 1107 1108 1109 1110 1111 1112 1113
void device_reset(DeviceState *dev)
{
    DeviceClass *klass = DEVICE_GET_CLASS(dev);

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

1114 1115 1116 1117 1118
Object *qdev_get_machine(void)
{
    static Object *dev;

    if (dev == NULL) {
1119
        dev = container_get(object_get_root(), "/machine");
1120 1121 1122 1123 1124
    }

    return dev;
}

1125
static const TypeInfo device_type_info = {
1126 1127 1128
    .name = TYPE_DEVICE,
    .parent = TYPE_OBJECT,
    .instance_size = sizeof(DeviceState),
1129
    .instance_init = device_initfn,
1130
    .instance_post_init = device_post_init,
1131
    .instance_finalize = device_finalize,
1132
    .class_base_init = device_class_base_init,
1133
    .class_init = device_class_init,
1134 1135 1136 1137
    .abstract = true,
    .class_size = sizeof(DeviceClass),
};

A
Andreas Färber 已提交
1138
static void qdev_register_types(void)
1139 1140 1141 1142
{
    type_register_static(&device_type_info);
}

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