qdev.c 33.7 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 "hw/fw-path-provider.h"
31
#include "sysemu/sysemu.h"
32
#include "qapi/qmp/qerror.h"
33
#include "qapi/visitor.h"
M
Michael S. Tsirkin 已提交
34
#include "qapi/qmp/qjson.h"
35
#include "qemu/error-report.h"
36
#include "hw/hotplug.h"
37
#include "hw/boards.h"
38
#include "hw/sysbus.h"
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 51 52
}

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

A
Anthony Liguori 已提交
55 56
    if (dc->fw_name) {
        return dc->fw_name;
A
Anthony Liguori 已提交
57 58 59 60 61
    }

    return object_get_typename(OBJECT(dev));
}

A
Anthony Liguori 已提交
62
static void bus_remove_child(BusState *bus, DeviceState *child)
63
{
A
Anthony Liguori 已提交
64 65 66 67 68 69 70 71
    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);
72 73

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

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

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

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

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

void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
{
105 106 107 108 109 110 111 112 113 114 115
    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));
    }
116
    dev->parent_bus = bus;
117
    object_ref(OBJECT(bus));
A
Anthony Liguori 已提交
118
    bus_add_child(bus, dev);
119 120 121
    if (replugging) {
        object_unref(OBJECT(dev));
    }
122 123
}

124 125 126
/* 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 已提交
127
DeviceState *qdev_create(BusState *bus, const char *name)
128 129 130 131 132
{
    DeviceState *dev;

    dev = qdev_try_create(bus, name);
    if (!dev) {
133
        if (bus) {
134
            error_report("Unknown device '%s' for bus '%s'", name,
135
                         object_get_typename(OBJECT(bus)));
136
        } else {
137
            error_report("Unknown device '%s' for default sysbus", name);
138
        }
L
liguang 已提交
139
        abort();
140 141 142 143 144
    }

    return dev;
}

145
DeviceState *qdev_try_create(BusState *bus, const char *type)
P
Paul Brook 已提交
146
{
147 148
    DeviceState *dev;

149
    if (object_class_by_name(type) == NULL) {
150 151
        return NULL;
    }
152
    dev = DEVICE(object_new(type));
153 154 155 156
    if (!dev) {
        return NULL;
    }

157
    if (!bus) {
158 159 160 161 162 163
        /* 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));
164
        bus = sysbus_get_default();
165 166
    }

167
    qdev_set_parent_bus(dev, bus);
168
    object_unref(OBJECT(dev));
169
    return dev;
P
Paul Brook 已提交
170 171
}

P
Paul Durrant 已提交
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 211 212 213 214 215 216 217 218 219 220 221
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);
}

222
static void device_realize(DeviceState *dev, Error **errp)
223 224
{
    DeviceClass *dc = DEVICE_GET_CLASS(dev);
225

226 227 228
    if (dc->init) {
        int rc = dc->init(dev);
        if (rc < 0) {
229
            error_setg(errp, "Device initialization failed.");
230 231
            return;
        }
J
Jan Kiszka 已提交
232
    }
P
Paul Brook 已提交
233 234
}

235 236 237 238 239 240 241 242 243 244 245 246 247
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 已提交
248 249 250
void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
                                 int required_for_version)
{
251
    assert(!dev->realized);
J
Jan Kiszka 已提交
252 253 254 255
    dev->instance_id_alias = alias_id;
    dev->alias_required_for_version = required_for_version;
}

256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272
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;
}

273
HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev)
274
{
275
    HotplugHandler *hotplug_ctrl;
276 277 278

    if (dev->parent_bus && dev->parent_bus->hotplug_handler) {
        hotplug_ctrl = dev->parent_bus->hotplug_handler;
279 280
    } else {
        hotplug_ctrl = qdev_get_machine_hotplug_handler(dev);
281 282 283 284
    }
    return hotplug_ctrl;
}

285 286
static int qdev_reset_one(DeviceState *dev, void *opaque)
{
287
    device_reset(dev);
288 289 290 291

    return 0;
}

292 293
static int qbus_reset_one(BusState *bus, void *opaque)
{
294 295
    BusClass *bc = BUS_GET_CLASS(bus);
    if (bc->reset) {
P
Paolo Bonzini 已提交
296
        bc->reset(bus);
297 298 299 300
    }
    return 0;
}

301 302
void qdev_reset_all(DeviceState *dev)
{
P
Paolo Bonzini 已提交
303
    qdev_walk_children(dev, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
304 305
}

306 307 308 309 310
void qdev_reset_all_fn(void *opaque)
{
    qdev_reset_all(DEVICE(opaque));
}

P
Paolo Bonzini 已提交
311 312
void qbus_reset_all(BusState *bus)
{
P
Paolo Bonzini 已提交
313
    qbus_walk_children(bus, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
P
Paolo Bonzini 已提交
314 315
}

316 317 318
void qbus_reset_all_fn(void *opaque)
{
    BusState *bus = opaque;
P
Paolo Bonzini 已提交
319
    qbus_reset_all(bus);
320 321
}

322
/* can be used as ->unplug() callback for the simple cases */
323 324 325
void qdev_simple_device_unplug_cb(HotplugHandler *hotplug_dev,
                                  DeviceState *dev, Error **errp)
{
326 327
    /* just zap it */
    object_unparent(OBJECT(dev));
328
}
329

330 331 332 333 334 335 336 337 338 339 340 341 342
/*
 * 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 已提交
343 344
void qdev_init_nofail(DeviceState *dev)
{
345
    Error *err = NULL;
346

347 348
    assert(!dev->realized);

349
    object_ref(OBJECT(dev));
350 351
    object_property_set_bool(OBJECT(dev), true, "realized", &err);
    if (err) {
352 353
        error_reportf_err(err, "Initialization of device %s failed: ",
                          object_get_typename(OBJECT(dev)));
354 355
        exit(1);
    }
356
    object_unref(OBJECT(dev));
M
Markus Armbruster 已提交
357 358
}

359 360 361 362 363 364
void qdev_machine_creation_done(void)
{
    /*
     * ok, initial machine setup is done, starting from now we can
     * only create hotpluggable devices
     */
365
    qdev_hotplug = true;
366 367
}

368 369 370 371 372
bool qdev_machine_modified(void)
{
    return qdev_hot_added || qdev_hot_removed;
}

P
Paul Brook 已提交
373
BusState *qdev_get_parent_bus(DeviceState *dev)
P
Paul Brook 已提交
374
{
P
Paul Brook 已提交
375
    return dev->parent_bus;
P
Paul Brook 已提交
376 377
}

P
Peter Crosthwaite 已提交
378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401
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;
}

void qdev_init_gpio_in_named(DeviceState *dev, qemu_irq_handler handler,
                             const char *name, int n)
{
402
    int i;
P
Peter Crosthwaite 已提交
403 404
    NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);

405
    assert(gpio_list->num_out == 0 || !name);
P
Peter Crosthwaite 已提交
406 407
    gpio_list->in = qemu_extend_irqs(gpio_list->in, gpio_list->num_in, handler,
                                     dev, n);
408

409 410 411
    if (!name) {
        name = "unnamed-gpio-in";
    }
412
    for (i = gpio_list->num_in; i < gpio_list->num_in + n; i++) {
413 414
        gchar *propname = g_strdup_printf("%s[%u]", name, i);

415 416
        object_property_add_child(OBJECT(dev), propname,
                                  OBJECT(gpio_list->in[i]), &error_abort);
417
        g_free(propname);
418 419
    }

P
Peter Crosthwaite 已提交
420 421 422
    gpio_list->num_in += n;
}

P
Paul Brook 已提交
423 424
void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
{
P
Peter Crosthwaite 已提交
425 426 427 428 429 430
    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)
{
431
    int i;
P
Peter Crosthwaite 已提交
432 433
    NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);

434
    assert(gpio_list->num_in == 0 || !name);
435

436 437 438 439
    if (!name) {
        name = "unnamed-gpio-out";
    }
    memset(pins, 0, sizeof(*pins) * n);
440
    for (i = 0; i < n; ++i) {
441 442 443
        gchar *propname = g_strdup_printf("%s[%u]", name,
                                          gpio_list->num_out + i);

444 445 446 447 448
        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);
449
        g_free(propname);
450
    }
451
    gpio_list->num_out += n;
P
Paul Brook 已提交
452 453 454 455
}

void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
{
P
Peter Crosthwaite 已提交
456 457 458 459 460 461 462 463 464
    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 已提交
465 466 467 468
}

qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
{
P
Peter Crosthwaite 已提交
469 470 471 472 473 474
    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)
{
475 476 477 478 479 480 481 482
    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.
         */
483 484 485
        object_property_add_child(container_get(qdev_get_machine(),
                                                "/unattached"),
                                  "non-qdev-gpio[*]", OBJECT(pin), NULL);
486 487 488
    }
    object_property_set_link(OBJECT(dev), OBJECT(pin), propname, &error_abort);
    g_free(propname);
P
Paul Brook 已提交
489 490
}

491 492 493 494 495 496 497 498 499 500 501
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 已提交
502
/* disconnect a GPIO output, returning the disconnected input (if any) */
503 504 505 506 507 508 509 510 511 512 513 514 515 516 517

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

519 520 521 522 523 524
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 已提交
525 526 527 528
}

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

532 533 534 535 536 537 538 539 540 541 542 543 544
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);
545
        g_free(propname);
546 547 548 549 550 551 552 553
    }
    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);
554
        g_free(propname);
555 556 557 558 559
    }
    QLIST_REMOVE(ngl, node);
    QLIST_INSERT_HEAD(&container->gpios, ngl, node);
}

P
Paul Brook 已提交
560
BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
P
Paul Brook 已提交
561
{
P
Paul Brook 已提交
562
    BusState *bus;
563 564 565 566 567 568
    Object *child = object_resolve_path_component(OBJECT(dev), name);

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

B
Blue Swirl 已提交
570
    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
P
Paul Brook 已提交
571
        if (strcmp(name, bus->name) == 0) {
P
Paul Brook 已提交
572
            return bus;
P
Paul Brook 已提交
573 574 575 576 577
        }
    }
    return NULL;
}

578 579 580 581
int qdev_walk_children(DeviceState *dev,
                       qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
                       qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
                       void *opaque)
582 583 584 585
{
    BusState *bus;
    int err;

586 587
    if (pre_devfn) {
        err = pre_devfn(dev, opaque);
588 589 590 591 592 593
        if (err) {
            return err;
        }
    }

    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
594 595
        err = qbus_walk_children(bus, pre_devfn, pre_busfn,
                                 post_devfn, post_busfn, opaque);
596 597 598 599 600
        if (err < 0) {
            return err;
        }
    }

601 602 603 604 605 606 607
    if (post_devfn) {
        err = post_devfn(dev, opaque);
        if (err) {
            return err;
        }
    }

608 609 610
    return 0;
}

611
DeviceState *qdev_find_recursive(BusState *bus, const char *id)
612
{
A
Anthony Liguori 已提交
613 614
    BusChild *kid;
    DeviceState *ret;
615 616
    BusState *child;

A
Anthony Liguori 已提交
617 618 619 620
    QTAILQ_FOREACH(kid, &bus->children, sibling) {
        DeviceState *dev = kid->child;

        if (dev->id && strcmp(dev->id, id) == 0) {
621
            return dev;
A
Anthony Liguori 已提交
622 623
        }

624 625 626 627 628 629 630 631 632 633
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
            ret = qdev_find_recursive(child, id);
            if (ret) {
                return ret;
            }
        }
    }
    return NULL;
}

634 635 636 637 638 639
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 已提交
640
    }
641 642

    return NULL;
G
Gerd Hoffmann 已提交
643 644
}

645 646 647 648 649 650 651 652 653 654 655 656
static char *qdev_get_fw_dev_path_from_handler(BusState *bus, DeviceState *dev)
{
    Object *obj = OBJECT(dev);
    char *d = NULL;

    while (!d && obj->parent) {
        obj = obj->parent;
        d = fw_path_provider_try_get_dev_path(obj, bus, dev);
    }
    return d;
}

657 658 659 660 661 662 663
char *qdev_get_own_fw_dev_path_from_handler(BusState *bus, DeviceState *dev)
{
    Object *obj = OBJECT(dev);

    return fw_path_provider_try_get_dev_path(obj, bus, dev);
}

664 665 666 667 668 669 670
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);
671 672 673 674
        d = qdev_get_fw_dev_path_from_handler(dev->parent_bus, dev);
        if (!d) {
            d = bus_get_fw_dev_path(dev->parent_bus, dev);
        }
675
        if (d) {
676
            l += snprintf(p + l, size - l, "%s", d);
677
            g_free(d);
678
        } else {
679
            return l;
680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695
        }
    }
    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';

696
    return g_strdup(path);
697
}
698

699
char *qdev_get_dev_path(DeviceState *dev)
700
{
701
    BusClass *bc;
702 703 704 705 706

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

707 708 709
    bc = BUS_GET_CLASS(dev->parent_bus);
    if (bc->get_dev_path) {
        return bc->get_dev_path(dev);
710 711 712
    }

    return NULL;
713
}
714 715 716 717 718

/**
 * Legacy property handling
 */

719 720 721
static void qdev_get_legacy_property(Object *obj, Visitor *v,
                                     const char *name, void *opaque,
                                     Error **errp)
722
{
723
    DeviceState *dev = DEVICE(obj);
724 725
    Property *prop = opaque;

726 727
    char buffer[1024];
    char *ptr = buffer;
728

729
    prop->info->print(dev, prop, buffer, sizeof(buffer));
730
    visit_type_str(v, name, &ptr, errp);
731 732 733
}

/**
C
Cao jin 已提交
734 735 736 737 738 739 740
 * 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.
741
 *
C
Cao jin 已提交
742 743 744
 * 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".
745
 *
C
Cao jin 已提交
746 747
 * Do not use this is new code!  QOM Properties added through this interface
 * will be given names in the "legacy" namespace.
748
 */
749 750
static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
                                     Error **errp)
751
{
752
    gchar *name;
753

754
    /* Register pointer properties as legacy properties */
755
    if (!prop->info->print && prop->info->get) {
756 757
        return;
    }
758

F
Fam Zheng 已提交
759 760 761 762
    if (prop->info->create) {
        return;
    }

763
    name = g_strdup_printf("legacy-%s", prop->name);
764
    object_property_add(OBJECT(dev), name, "str",
765
                        prop->info->print ? qdev_get_legacy_property : prop->info->get,
766
                        NULL,
767 768
                        NULL,
                        prop, errp);
769

770 771 772 773
    g_free(name);
}

/**
C
Cao jin 已提交
774 775 776 777
 * qdev_property_add_static:
 * @dev: Device to add the property to.
 * @prop: The qdev property definition.
 * @errp: location to store error information.
778
 *
C
Cao jin 已提交
779 780 781
 * 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.
782 783 784 785
 */
void qdev_property_add_static(DeviceState *dev, Property *prop,
                              Error **errp)
{
786 787 788
    Error *local_err = NULL;
    Object *obj = OBJECT(dev);

F
Fam Zheng 已提交
789 790 791 792 793 794 795 796 797 798 799 800 801 802 803
    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);
804 805
    }

806 807 808 809
    if (local_err) {
        error_propagate(errp, local_err);
        return;
    }
810 811 812 813 814

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

815
    if (prop->set_default) {
816
        prop->info->set_default_value(obj, prop);
817
    }
A
Anthony Liguori 已提交
818
}
819

820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840
/* @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));
}

841
static int qdev_add_hotpluggable_device(Object *obj, void *opaque)
842 843
{
    GSList **list = opaque;
844 845 846 847 848 849
    DeviceState *dev = (DeviceState *)object_dynamic_cast(OBJECT(obj),
                                                          TYPE_DEVICE);

    if (dev == NULL) {
        return 0;
    }
850 851 852 853 854 855 856 857

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

    return 0;
}

858 859 860 861 862 863 864 865 866
GSList *qdev_build_hotpluggable_device_list(Object *peripheral)
{
    GSList *list = NULL;

    object_child_foreach(peripheral, qdev_add_hotpluggable_device, &list);

    return list;
}

867
static bool device_get_realized(Object *obj, Error **errp)
868 869 870 871 872
{
    DeviceState *dev = DEVICE(obj);
    return dev->realized;
}

873 874 875 876 877 878 879 880 881 882 883 884 885 886
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;
}

887
static void device_set_realized(Object *obj, bool value, Error **errp)
888 889 890
{
    DeviceState *dev = DEVICE(obj);
    DeviceClass *dc = DEVICE_GET_CLASS(dev);
891
    HotplugHandler *hotplug_ctrl;
892
    BusState *bus;
893
    Error *local_err = NULL;
894 895
    bool unattached_parent = false;
    static int unattached_count;
896

897
    if (dev->hotplugged && !dc->hotpluggable) {
898
        error_setg(errp, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj));
899 900 901
        return;
    }

902
    if (value && !dev->realized) {
903
        if (!check_only_migratable(obj, &local_err)) {
904 905 906
            goto fail;
        }

907
        if (!obj->parent) {
908 909 910 911
            gchar *name = g_strdup_printf("device[%d]", unattached_count++);

            object_property_add_child(container_get(qdev_get_machine(),
                                                    "/unattached"),
912
                                      name, obj, &error_abort);
913
            unattached_parent = true;
914 915 916
            g_free(name);
        }

917 918 919 920 921 922 923 924
        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;
            }
        }

925 926 927 928
        if (dc->realize) {
            dc->realize(dev, &local_err);
        }

929 930 931 932
        if (local_err != NULL) {
            goto fail;
        }

P
Paul Durrant 已提交
933 934
        DEVICE_LISTENER_CALL(realize, Forward, dev);

935 936
        if (hotplug_ctrl) {
            hotplug_handler_plug(hotplug_ctrl, dev, &local_err);
937 938
        }

939 940 941 942
        if (local_err != NULL) {
            goto post_realize_fail;
        }

943 944 945 946 947 948 949
        /*
         * 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));

950
        if (qdev_get_vmsd(dev)) {
951 952 953 954 955 956
            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;
            }
957
        }
958 959 960

        QLIST_FOREACH(bus, &dev->child_bus, sibling) {
            object_property_set_bool(OBJECT(bus), true, "realized",
961
                                         &local_err);
962 963
            if (local_err != NULL) {
                goto child_realize_fail;
964 965
            }
        }
966
        if (dev->hotplugged) {
967 968
            device_reset(dev);
        }
969
        dev->pending_deleted_event = false;
970
    } else if (!value && dev->realized) {
971
        Error **local_errp = NULL;
972
        QLIST_FOREACH(bus, &dev->child_bus, sibling) {
973
            local_errp = local_err ? NULL : &local_err;
974
            object_property_set_bool(OBJECT(bus), false, "realized",
975
                                     local_errp);
976
        }
977
        if (qdev_get_vmsd(dev)) {
978 979
            vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
        }
980 981 982
        if (dc->unrealize) {
            local_errp = local_err ? NULL : &local_err;
            dc->unrealize(dev, local_errp);
983
        }
984
        dev->pending_deleted_event = true;
P
Paul Durrant 已提交
985
        DEVICE_LISTENER_CALL(unrealize, Reverse, dev);
986
    }
987

988 989
    if (local_err != NULL) {
        goto fail;
990 991
    }

992
    dev->realized = value;
993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005
    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:
1006 1007
    g_free(dev->canonical_path);
    dev->canonical_path = NULL;
1008 1009 1010 1011 1012 1013
    if (dc->unrealize) {
        dc->unrealize(dev, NULL);
    }

fail:
    error_propagate(errp, local_err);
1014 1015 1016 1017
    if (unattached_parent) {
        object_unparent(OBJECT(dev));
        unattached_count--;
    }
1018 1019
}

1020
static bool device_get_hotpluggable(Object *obj, Error **errp)
1021 1022 1023 1024
{
    DeviceClass *dc = DEVICE_GET_CLASS(obj);
    DeviceState *dev = DEVICE(obj);

1025
    return dc->hotpluggable && (dev->parent_bus == NULL ||
1026
                                qbus_is_hotpluggable(dev->parent_bus));
1027 1028
}

1029 1030 1031 1032 1033 1034 1035
static bool device_get_hotplugged(Object *obj, Error **err)
{
    DeviceState *dev = DEVICE(obj);

    return dev->hotplugged;
}

1036 1037 1038
static void device_initfn(Object *obj)
{
    DeviceState *dev = DEVICE(obj);
1039
    ObjectClass *class;
1040 1041 1042 1043 1044 1045 1046 1047
    Property *prop;

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

    dev->instance_id_alias = -1;
1048
    dev->realized = false;
1049

1050 1051
    object_property_add_bool(obj, "realized",
                             device_get_realized, device_set_realized, NULL);
1052 1053
    object_property_add_bool(obj, "hotpluggable",
                             device_get_hotpluggable, NULL, NULL);
1054
    object_property_add_bool(obj, "hotplugged",
1055
                             device_get_hotplugged, NULL,
1056
                             &error_abort);
1057

1058 1059 1060
    class = object_get_class(OBJECT(dev));
    do {
        for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
1061 1062
            qdev_property_add_legacy(dev, prop, &error_abort);
            qdev_property_add_static(dev, prop, &error_abort);
1063 1064 1065
        }
        class = object_class_get_parent(class);
    } while (class != object_class_by_name(TYPE_DEVICE));
1066

1067
    object_property_add_link(OBJECT(dev), "parent_bus", TYPE_BUS,
1068
                             (Object **)&dev->parent_bus, NULL, 0,
1069
                             &error_abort);
P
Peter Crosthwaite 已提交
1070
    QLIST_INIT(&dev->gpios);
1071 1072
}

1073 1074
static void device_post_init(Object *obj)
{
1075
    qdev_prop_set_globals(DEVICE(obj));
1076 1077
}

1078 1079 1080
/* Unlink device from bus and free the structure.  */
static void device_finalize(Object *obj)
{
P
Peter Crosthwaite 已提交
1081 1082
    NamedGPIOList *ngl, *next;

1083
    DeviceState *dev = DEVICE(obj);
P
Peter Crosthwaite 已提交
1084 1085 1086

    QLIST_FOREACH_SAFE(ngl, &dev->gpios, node, next) {
        QLIST_REMOVE(ngl, node);
1087
        qemu_free_irqs(ngl->in, ngl->num_in);
P
Peter Crosthwaite 已提交
1088 1089 1090 1091 1092 1093
        g_free(ngl->name);
        g_free(ngl);
        /* ngl->out irqs are owned by the other end and should not be freed
         * here
         */
    }
1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105

    /* 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);
1106 1107
}

1108 1109 1110 1111 1112 1113 1114 1115
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;
1116 1117
}

1118
static void device_unparent(Object *obj)
1119 1120
{
    DeviceState *dev = DEVICE(obj);
1121
    BusState *bus;
1122

1123 1124 1125
    if (dev->realized) {
        object_property_set_bool(obj, false, "realized", NULL);
    }
1126 1127
    while (dev->num_child_bus) {
        bus = QLIST_FIRST(&dev->child_bus);
1128
        object_unparent(OBJECT(bus));
1129 1130
    }
    if (dev->parent_bus) {
1131
        bus_remove_child(dev->parent_bus, dev);
1132 1133
        object_unref(OBJECT(dev->parent_bus));
        dev->parent_bus = NULL;
1134
    }
1135 1136 1137 1138
}

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

1141
    class->unparent = device_unparent;
1142
    dc->realize = device_realize;
1143
    dc->unrealize = device_unrealize;
1144 1145 1146 1147 1148 1149 1150 1151

    /* 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;
1152
    dc->user_creatable = true;
1153 1154
}

1155 1156 1157 1158 1159 1160 1161 1162 1163
void device_reset(DeviceState *dev)
{
    DeviceClass *klass = DEVICE_GET_CLASS(dev);

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

1164 1165 1166 1167 1168
Object *qdev_get_machine(void)
{
    static Object *dev;

    if (dev == NULL) {
1169
        dev = container_get(object_get_root(), "/machine");
1170 1171 1172 1173 1174
    }

    return dev;
}

1175
static const TypeInfo device_type_info = {
1176 1177 1178
    .name = TYPE_DEVICE,
    .parent = TYPE_OBJECT,
    .instance_size = sizeof(DeviceState),
1179
    .instance_init = device_initfn,
1180
    .instance_post_init = device_post_init,
1181
    .instance_finalize = device_finalize,
1182
    .class_base_init = device_class_base_init,
1183
    .class_init = device_class_init,
1184 1185 1186 1187
    .abstract = true,
    .class_size = sizeof(DeviceClass),
};

A
Andreas Färber 已提交
1188
static void qdev_register_types(void)
1189 1190 1191 1192
{
    type_register_static(&device_type_info);
}

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