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 "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"
40
#include "migration/migration.h"
P
Paul Brook 已提交
41

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

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

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

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

    return object_get_typename(OBJECT(dev));
}

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

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

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

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

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

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

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

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

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

    return dev;
}

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

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

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

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

P
Paul Durrant 已提交
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 222
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);
}

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

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

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

257
HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev)
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
{
    HotplugHandler *hotplug_ctrl = NULL;

    if (dev->parent_bus && dev->parent_bus->hotplug_handler) {
        hotplug_ctrl = dev->parent_bus->hotplug_handler;
    } else if (object_dynamic_cast(qdev_get_machine(), TYPE_MACHINE)) {
        MachineState *machine = MACHINE(qdev_get_machine());
        MachineClass *mc = MACHINE_GET_CLASS(machine);

        if (mc->get_hotplug_handler) {
            hotplug_ctrl = mc->get_hotplug_handler(machine, dev);
        }
    }
    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 388 389 390
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)
{
391
    int i;
P
Peter Crosthwaite 已提交
392 393
    NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);

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

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

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

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

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

423
    assert(gpio_list->num_in == 0 || !name);
424

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

433 434 435 436 437
        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);
438
        g_free(propname);
439
    }
440
    gpio_list->num_out += n;
P
Paul Brook 已提交
441 442 443 444
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

597 598 599
    return 0;
}

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

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

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

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

623 624 625 626 627 628
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 已提交
629
    }
630 631

    return NULL;
G
Gerd Hoffmann 已提交
632 633
}

634 635 636 637 638 639 640 641 642 643 644 645
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;
}

646 647 648 649 650 651 652
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);
}

653 654 655 656 657 658 659
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);
660 661 662 663
        d = qdev_get_fw_dev_path_from_handler(dev->parent_bus, dev);
        if (!d) {
            d = bus_get_fw_dev_path(dev->parent_bus, dev);
        }
664
        if (d) {
665
            l += snprintf(p + l, size - l, "%s", d);
666
            g_free(d);
667
        } else {
668
            return l;
669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684
        }
    }
    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';

685
    return g_strdup(path);
686
}
687

688
char *qdev_get_dev_path(DeviceState *dev)
689
{
690
    BusClass *bc;
691 692 693 694 695

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

696 697 698
    bc = BUS_GET_CLASS(dev->parent_bus);
    if (bc->get_dev_path) {
        return bc->get_dev_path(dev);
699 700 701
    }

    return NULL;
702
}
703 704 705 706 707

/**
 * Legacy property handling
 */

708 709 710
static void qdev_get_legacy_property(Object *obj, Visitor *v,
                                     const char *name, void *opaque,
                                     Error **errp)
711
{
712
    DeviceState *dev = DEVICE(obj);
713 714
    Property *prop = opaque;

715 716
    char buffer[1024];
    char *ptr = buffer;
717

718
    prop->info->print(dev, prop, buffer, sizeof(buffer));
719
    visit_type_str(v, name, &ptr, errp);
720 721 722
}

/**
C
Cao jin 已提交
723 724 725 726 727 728 729
 * 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.
730
 *
C
Cao jin 已提交
731 732 733
 * 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".
734
 *
C
Cao jin 已提交
735 736
 * Do not use this is new code!  QOM Properties added through this interface
 * will be given names in the "legacy" namespace.
737
 */
738 739
static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
                                     Error **errp)
740
{
741
    gchar *name;
742

743
    /* Register pointer properties as legacy properties */
744
    if (!prop->info->print && prop->info->get) {
745 746
        return;
    }
747

748
    name = g_strdup_printf("legacy-%s", prop->name);
749
    object_property_add(OBJECT(dev), name, "str",
750
                        prop->info->print ? qdev_get_legacy_property : prop->info->get,
751
                        NULL,
752 753
                        NULL,
                        prop, errp);
754

755 756 757 758
    g_free(name);
}

/**
C
Cao jin 已提交
759 760 761 762
 * qdev_property_add_static:
 * @dev: Device to add the property to.
 * @prop: The qdev property definition.
 * @errp: location to store error information.
763
 *
C
Cao jin 已提交
764 765 766
 * 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.
767 768 769 770
 */
void qdev_property_add_static(DeviceState *dev, Property *prop,
                              Error **errp)
{
771 772 773
    Error *local_err = NULL;
    Object *obj = OBJECT(dev);

774 775 776 777 778 779 780 781 782
    /*
     * 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;
    }

783
    object_property_add(obj, prop->name, prop->info->name,
784
                        prop->info->get, prop->info->set,
P
Paolo Bonzini 已提交
785
                        prop->info->release,
786 787 788 789 790 791
                        prop, &local_err);

    if (local_err) {
        error_propagate(errp, local_err);
        return;
    }
792 793 794 795 796

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

797 798 799 800 801
    if (prop->qtype == QTYPE_NONE) {
        return;
    }

    if (prop->qtype == QTYPE_QBOOL) {
802
        object_property_set_bool(obj, prop->defval, prop->name, &error_abort);
803 804
    } else if (prop->info->enum_table) {
        object_property_set_str(obj, prop->info->enum_table[prop->defval],
805
                                prop->name, &error_abort);
806
    } else if (prop->qtype == QTYPE_QINT) {
807
        object_property_set_int(obj, prop->defval, prop->name, &error_abort);
808
    }
A
Anthony Liguori 已提交
809
}
810

811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831
/* @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));
}

832
static int qdev_add_hotpluggable_device(Object *obj, void *opaque)
833 834
{
    GSList **list = opaque;
835 836 837 838 839 840
    DeviceState *dev = (DeviceState *)object_dynamic_cast(OBJECT(obj),
                                                          TYPE_DEVICE);

    if (dev == NULL) {
        return 0;
    }
841 842 843 844 845 846 847 848

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

    return 0;
}

849 850 851 852 853 854 855 856 857
GSList *qdev_build_hotpluggable_device_list(Object *peripheral)
{
    GSList *list = NULL;

    object_child_foreach(peripheral, qdev_add_hotpluggable_device, &list);

    return list;
}

858
static bool device_get_realized(Object *obj, Error **errp)
859 860 861 862 863
{
    DeviceState *dev = DEVICE(obj);
    return dev->realized;
}

864
static void device_set_realized(Object *obj, bool value, Error **errp)
865 866 867
{
    DeviceState *dev = DEVICE(obj);
    DeviceClass *dc = DEVICE_GET_CLASS(dev);
868
    HotplugHandler *hotplug_ctrl;
869
    BusState *bus;
870
    Error *local_err = NULL;
871 872
    bool unattached_parent = false;
    static int unattached_count;
873
    int ret;
874

875
    if (dev->hotplugged && !dc->hotpluggable) {
876
        error_setg(errp, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj));
877 878 879
        return;
    }

880
    if (value && !dev->realized) {
881 882 883 884 885
        ret = check_migratable(obj, &local_err);
        if (ret < 0) {
            goto fail;
        }

886
        if (!obj->parent) {
887 888 889 890
            gchar *name = g_strdup_printf("device[%d]", unattached_count++);

            object_property_add_child(container_get(qdev_get_machine(),
                                                    "/unattached"),
891
                                      name, obj, &error_abort);
892
            unattached_parent = true;
893 894 895
            g_free(name);
        }

896 897 898 899 900 901 902 903
        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;
            }
        }

904 905 906 907
        if (dc->realize) {
            dc->realize(dev, &local_err);
        }

908 909 910 911
        if (local_err != NULL) {
            goto fail;
        }

P
Paul Durrant 已提交
912 913
        DEVICE_LISTENER_CALL(realize, Forward, dev);

914 915
        if (hotplug_ctrl) {
            hotplug_handler_plug(hotplug_ctrl, dev, &local_err);
916 917
        }

918 919 920 921 922
        if (local_err != NULL) {
            goto post_realize_fail;
        }

        if (qdev_get_vmsd(dev)) {
923 924 925 926 927 928
            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;
            }
929
        }
930 931 932

        QLIST_FOREACH(bus, &dev->child_bus, sibling) {
            object_property_set_bool(OBJECT(bus), true, "realized",
933
                                         &local_err);
934 935
            if (local_err != NULL) {
                goto child_realize_fail;
936 937
            }
        }
938
        if (dev->hotplugged) {
939 940
            device_reset(dev);
        }
941
        dev->pending_deleted_event = false;
942
    } else if (!value && dev->realized) {
943
        Error **local_errp = NULL;
944
        QLIST_FOREACH(bus, &dev->child_bus, sibling) {
945
            local_errp = local_err ? NULL : &local_err;
946
            object_property_set_bool(OBJECT(bus), false, "realized",
947
                                     local_errp);
948
        }
949
        if (qdev_get_vmsd(dev)) {
950 951
            vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
        }
952 953 954
        if (dc->unrealize) {
            local_errp = local_err ? NULL : &local_err;
            dc->unrealize(dev, local_errp);
955
        }
956
        dev->pending_deleted_event = true;
P
Paul Durrant 已提交
957
        DEVICE_LISTENER_CALL(unrealize, Reverse, dev);
958
    }
959

960 961
    if (local_err != NULL) {
        goto fail;
962 963
    }

964
    dev->realized = value;
965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983
    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:
    if (dc->unrealize) {
        dc->unrealize(dev, NULL);
    }

fail:
    error_propagate(errp, local_err);
984 985 986 987
    if (unattached_parent) {
        object_unparent(OBJECT(dev));
        unattached_count--;
    }
988 989
}

990
static bool device_get_hotpluggable(Object *obj, Error **errp)
991 992 993 994
{
    DeviceClass *dc = DEVICE_GET_CLASS(obj);
    DeviceState *dev = DEVICE(obj);

995
    return dc->hotpluggable && (dev->parent_bus == NULL ||
996
                                qbus_is_hotpluggable(dev->parent_bus));
997 998
}

999 1000 1001 1002 1003 1004 1005
static bool device_get_hotplugged(Object *obj, Error **err)
{
    DeviceState *dev = DEVICE(obj);

    return dev->hotplugged;
}

1006 1007 1008
static void device_initfn(Object *obj)
{
    DeviceState *dev = DEVICE(obj);
1009
    ObjectClass *class;
1010 1011 1012 1013 1014 1015 1016 1017
    Property *prop;

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

    dev->instance_id_alias = -1;
1018
    dev->realized = false;
1019

1020 1021
    object_property_add_bool(obj, "realized",
                             device_get_realized, device_set_realized, NULL);
1022 1023
    object_property_add_bool(obj, "hotpluggable",
                             device_get_hotpluggable, NULL, NULL);
1024
    object_property_add_bool(obj, "hotplugged",
1025
                             device_get_hotplugged, NULL,
1026
                             &error_abort);
1027

1028 1029 1030
    class = object_get_class(OBJECT(dev));
    do {
        for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
1031 1032
            qdev_property_add_legacy(dev, prop, &error_abort);
            qdev_property_add_static(dev, prop, &error_abort);
1033 1034 1035
        }
        class = object_class_get_parent(class);
    } while (class != object_class_by_name(TYPE_DEVICE));
1036

1037
    object_property_add_link(OBJECT(dev), "parent_bus", TYPE_BUS,
1038
                             (Object **)&dev->parent_bus, NULL, 0,
1039
                             &error_abort);
P
Peter Crosthwaite 已提交
1040
    QLIST_INIT(&dev->gpios);
1041 1042
}

1043 1044
static void device_post_init(Object *obj)
{
1045
    qdev_prop_set_globals(DEVICE(obj));
1046 1047
}

1048 1049 1050
/* Unlink device from bus and free the structure.  */
static void device_finalize(Object *obj)
{
P
Peter Crosthwaite 已提交
1051 1052
    NamedGPIOList *ngl, *next;

1053
    DeviceState *dev = DEVICE(obj);
P
Peter Crosthwaite 已提交
1054 1055 1056

    QLIST_FOREACH_SAFE(ngl, &dev->gpios, node, next) {
        QLIST_REMOVE(ngl, node);
1057
        qemu_free_irqs(ngl->in, ngl->num_in);
P
Peter Crosthwaite 已提交
1058 1059 1060 1061 1062 1063
        g_free(ngl->name);
        g_free(ngl);
        /* ngl->out irqs are owned by the other end and should not be freed
         * here
         */
    }
1064 1065
}

1066 1067 1068 1069 1070 1071 1072 1073
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;
1074 1075
}

1076
static void device_unparent(Object *obj)
1077 1078
{
    DeviceState *dev = DEVICE(obj);
1079
    BusState *bus;
1080

1081 1082 1083
    if (dev->realized) {
        object_property_set_bool(obj, false, "realized", NULL);
    }
1084 1085
    while (dev->num_child_bus) {
        bus = QLIST_FIRST(&dev->child_bus);
1086
        object_unparent(OBJECT(bus));
1087 1088
    }
    if (dev->parent_bus) {
1089
        bus_remove_child(dev->parent_bus, dev);
1090 1091
        object_unref(OBJECT(dev->parent_bus));
        dev->parent_bus = NULL;
1092
    }
M
Michael S. Tsirkin 已提交
1093

1094
    /* Only send event if the device had been completely realized */
1095
    if (dev->pending_deleted_event) {
1096 1097
        gchar *path = object_get_canonical_path(OBJECT(dev));

W
Wenchao Xia 已提交
1098
        qapi_event_send_device_deleted(!!dev->id, dev->id, path, &error_abort);
1099
        g_free(path);
M
Michael S. Tsirkin 已提交
1100
    }
1101 1102 1103

    qemu_opts_del(dev->opts);
    dev->opts = NULL;
1104 1105 1106 1107
}

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

1110
    class->unparent = device_unparent;
1111
    dc->realize = device_realize;
1112
    dc->unrealize = device_unrealize;
1113 1114 1115 1116 1117 1118 1119 1120

    /* 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;
1121
    dc->user_creatable = true;
1122 1123
}

1124 1125 1126 1127 1128 1129 1130 1131 1132
void device_reset(DeviceState *dev)
{
    DeviceClass *klass = DEVICE_GET_CLASS(dev);

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

1133 1134 1135 1136 1137
Object *qdev_get_machine(void)
{
    static Object *dev;

    if (dev == NULL) {
1138
        dev = container_get(object_get_root(), "/machine");
1139 1140 1141 1142 1143
    }

    return dev;
}

1144
static const TypeInfo device_type_info = {
1145 1146 1147
    .name = TYPE_DEVICE,
    .parent = TYPE_OBJECT,
    .instance_size = sizeof(DeviceState),
1148
    .instance_init = device_initfn,
1149
    .instance_post_init = device_post_init,
1150
    .instance_finalize = device_finalize,
1151
    .class_base_init = device_class_base_init,
1152
    .class_init = device_class_init,
1153 1154 1155 1156
    .abstract = true,
    .class_size = sizeof(DeviceClass),
};

A
Andreas Färber 已提交
1157
static void qdev_register_types(void)
1158 1159 1160 1161
{
    type_register_static(&device_type_info);
}

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