/*
 *  Dynamic device configuration and creation -- buses.
 *
 *  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.1 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
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "hw/qdev-properties.h"
#include "qemu/ctype.h"
#include "qemu/module.h"
#include "qapi/error.h"

void qbus_set_hotplug_handler(BusState *bus, Object *handler)
{
    object_property_set_link(OBJECT(bus), QDEV_HOTPLUG_HANDLER_PROPERTY,
                             handler, &error_abort);
}

void qbus_set_bus_hotplug_handler(BusState *bus)
{
    qbus_set_hotplug_handler(bus, OBJECT(bus));
}

int qbus_walk_children(BusState *bus,
                       qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
                       qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
                       void *opaque)
{
    BusChild *kid;
    int err;

    if (pre_busfn) {
        err = pre_busfn(bus, opaque);
        if (err) {
            return err;
        }
    }

    WITH_RCU_READ_LOCK_GUARD() {
        QTAILQ_FOREACH_RCU(kid, &bus->children, sibling) {
            err = qdev_walk_children(kid->child,
                                     pre_devfn, pre_busfn,
                                     post_devfn, post_busfn, opaque);
            if (err < 0) {
                return err;
            }
        }
    }

    if (post_busfn) {
        err = post_busfn(bus, opaque);
        if (err) {
            return err;
        }
    }

    return 0;
}

void bus_cold_reset(BusState *bus)
{
    resettable_reset(OBJECT(bus), RESET_TYPE_COLD);
}

bool bus_is_in_reset(BusState *bus)
{
    return resettable_is_in_reset(OBJECT(bus));
}

static ResettableState *bus_get_reset_state(Object *obj)
{
    BusState *bus = BUS(obj);
    return &bus->reset;
}

static void bus_reset_child_foreach(Object *obj, ResettableChildCallback cb,
                                    void *opaque, ResetType type)
{
    BusState *bus = BUS(obj);
    BusChild *kid;

    WITH_RCU_READ_LOCK_GUARD() {
        QTAILQ_FOREACH_RCU(kid, &bus->children, sibling) {
            cb(OBJECT(kid->child), opaque, type);
        }
    }
}

static void qbus_init(BusState *bus, DeviceState *parent, const char *name)
{
    const char *typename = object_get_typename(OBJECT(bus));
    BusClass *bc;
    int i, bus_id;

    bus->parent = parent;

    if (name) {
        bus->name = g_strdup(name);
    } else if (bus->parent && bus->parent->id) {
        /* parent device has id -> use it plus parent-bus-id for bus name */
        bus_id = bus->parent->num_child_bus;
        bus->name = g_strdup_printf("%s.%d", bus->parent->id, bus_id);
    } else {
        /* no id -> use lowercase bus type plus global bus-id for bus name */
        bc = BUS_GET_CLASS(bus);
        bus_id = bc->automatic_ids++;
        bus->name = g_strdup_printf("%s.%d", typename, bus_id);
        for (i = 0; bus->name[i]; i++) {
            bus->name[i] = qemu_tolower(bus->name[i]);
        }
    }

    if (bus->parent) {
        QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
        bus->parent->num_child_bus++;
        object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus));
        object_unref(OBJECT(bus));
    } else {
        /* The only bus without a parent is the main system bus */
        assert(bus == sysbus_get_default());
    }
}

static void bus_unparent(Object *obj)
{
    BusState *bus = BUS(obj);
    BusChild *kid;

    /* Only the main system bus has no parent, and that bus is never freed */
    assert(bus->parent);

    while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) {
        DeviceState *dev = kid->child;
        object_unparent(OBJECT(dev));
    }
    QLIST_REMOVE(bus, sibling);
    bus->parent->num_child_bus--;
    bus->parent = NULL;
}

void qbus_create_inplace(void *bus, size_t size, const char *typename,
                         DeviceState *parent, const char *name)
{
    object_initialize(bus, size, typename);
    qbus_init(bus, parent, name);
}

BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
{
    BusState *bus;

    bus = BUS(object_new(typename));
    qbus_init(bus, parent, name);

    return bus;
}

bool qbus_realize(BusState *bus, Error **errp)
{
    return object_property_set_bool(OBJECT(bus), "realized", true, errp);
}

void qbus_unrealize(BusState *bus)
{
    object_property_set_bool(OBJECT(bus), "realized", false, &error_abort);
}

static bool bus_get_realized(Object *obj, Error **errp)
{
    BusState *bus = BUS(obj);

    return bus->realized;
}

static void bus_set_realized(Object *obj, bool value, Error **errp)
{
    BusState *bus = BUS(obj);
    BusClass *bc = BUS_GET_CLASS(bus);
    BusChild *kid;

    if (value && !bus->realized) {
        if (bc->realize) {
            bc->realize(bus, errp);
        }

        /* TODO: recursive realization */
    } else if (!value && bus->realized) {
        WITH_RCU_READ_LOCK_GUARD() {
            QTAILQ_FOREACH_RCU(kid, &bus->children, sibling) {
                DeviceState *dev = kid->child;
                qdev_unrealize(dev);
            }
        }
        if (bc->unrealize) {
            bc->unrealize(bus);
        }
    }

    bus->realized = value;
}

static void qbus_initfn(Object *obj)
{
    BusState *bus = BUS(obj);

    QTAILQ_INIT(&bus->children);
    object_property_add_link(obj, QDEV_HOTPLUG_HANDLER_PROPERTY,
                             TYPE_HOTPLUG_HANDLER,
                             (Object **)&bus->hotplug_handler,
                             object_property_allow_set_link,
                             0);
    object_property_add_bool(obj, "realized",
                             bus_get_realized, bus_set_realized);
}

static char *default_bus_get_fw_dev_path(DeviceState *dev)
{
    return g_strdup(object_get_typename(OBJECT(dev)));
}

/**
 * bus_phases_reset:
 * Transition reset method for buses to allow moving
 * smoothly from legacy reset method to multi-phases
 */
static void bus_phases_reset(BusState *bus)
{
    ResettableClass *rc = RESETTABLE_GET_CLASS(bus);

    if (rc->phases.enter) {
        rc->phases.enter(OBJECT(bus), RESET_TYPE_COLD);
    }
    if (rc->phases.hold) {
        rc->phases.hold(OBJECT(bus));
    }
    if (rc->phases.exit) {
        rc->phases.exit(OBJECT(bus));
    }
}

static void bus_transitional_reset(Object *obj)
{
    BusClass *bc = BUS_GET_CLASS(obj);

    /*
     * This will call either @bus_phases_reset (for multi-phases transitioned
     * buses) or a bus's specific method for not-yet transitioned buses.
     * In both case, it does not reset children.
     */
    if (bc->reset) {
        bc->reset(BUS(obj));
    }
}

/**
 * bus_get_transitional_reset:
 * check if the bus's class is ready for multi-phase
 */
static ResettableTrFunction bus_get_transitional_reset(Object *obj)
{
    BusClass *dc = BUS_GET_CLASS(obj);
    if (dc->reset != bus_phases_reset) {
        /*
         * dc->reset has been overridden by a subclass,
         * the bus is not ready for multi phase yet.
         */
        return bus_transitional_reset;
    }
    return NULL;
}

static void bus_class_init(ObjectClass *class, void *data)
{
    BusClass *bc = BUS_CLASS(class);
    ResettableClass *rc = RESETTABLE_CLASS(class);

    class->unparent = bus_unparent;
    bc->get_fw_dev_path = default_bus_get_fw_dev_path;

    rc->get_state = bus_get_reset_state;
    rc->child_foreach = bus_reset_child_foreach;

    /*
     * @bus_phases_reset is put as the default reset method below, allowing
     * to do the multi-phase transition from base classes to leaf classes. It
     * allows a legacy-reset Bus class to extend a multi-phases-reset
     * Bus class for the following reason:
     * + If a base class B has been moved to multi-phase, then it does not
     *   override this default reset method and may have defined phase methods.
     * + A child class C (extending class B) which uses
     *   bus_class_set_parent_reset() (or similar means) to override the
     *   reset method will still work as expected. @bus_phases_reset function
     *   will be registered as the parent reset method and effectively call
     *   parent reset phases.
     */
    bc->reset = bus_phases_reset;
    rc->get_transitional_function = bus_get_transitional_reset;
}

static void qbus_finalize(Object *obj)
{
    BusState *bus = BUS(obj);

    g_free(bus->name);
}

static const TypeInfo bus_info = {
    .name = TYPE_BUS,
    .parent = TYPE_OBJECT,
    .instance_size = sizeof(BusState),
    .abstract = true,
    .class_size = sizeof(BusClass),
    .instance_init = qbus_initfn,
    .instance_finalize = qbus_finalize,
    .class_init = bus_class_init,
    .interfaces = (InterfaceInfo[]) {
        { TYPE_RESETTABLE_INTERFACE },
        { }
    },
};

static void bus_register_types(void)
{
    type_register_static(&bus_info);
}

type_init(bus_register_types)
