/*
 * qdev property parsing
 * (parts specific for qemu-system-*)
 *
 * This file is based on code from hw/qdev-properties.c from
 * commit 074a86fccd185616469dfcdc0e157f438aebba18,
 * Copyright (c) Gerd Hoffmann <kraxel@redhat.com> and other contributors.
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
#include "qapi/error.h"
#include "qapi/visitor.h"
#include "qapi/qapi-types-block.h"
#include "qapi/qapi-types-machine.h"
#include "qapi/qapi-types-migration.h"
#include "qapi/qmp/qerror.h"
#include "qemu/ctype.h"
#include "qemu/cutils.h"
#include "qemu/units.h"
#include "qemu/uuid.h"
#include "qemu/error-report.h"
#include "qdev-prop-internal.h"

#include "audio/audio.h"
#include "chardev/char-fe.h"
#include "sysemu/block-backend.h"
#include "sysemu/blockdev.h"
#include "net/net.h"
#include "hw/pci/pci.h"
#include "hw/pci/pcie.h"
#include "hw/i386/x86.h"
#include "util/block-helpers.h"

static bool check_prop_still_unset(Object *obj, const char *name,
                                   const void *old_val, const char *new_val,
                                   bool allow_override, Error **errp)
{
    const GlobalProperty *prop = qdev_find_global_prop(obj, name);

    if (!old_val || (!prop && allow_override)) {
        return true;
    }

    if (prop) {
        error_setg(errp, "-global %s.%s=... conflicts with %s=%s",
                   prop->driver, prop->property, name, new_val);
    } else {
        /* Error message is vague, but a better one would be hard */
        error_setg(errp, "%s=%s conflicts, and override is not implemented",
                   name, new_val);
    }
    return false;
}


/* --- drive --- */

static void get_drive(Object *obj, Visitor *v, const char *name, void *opaque,
                      Error **errp)
{
    Property *prop = opaque;
    void **ptr = object_field_prop_ptr(obj, prop);
    const char *value;
    char *p;

    if (*ptr) {
        value = blk_name(*ptr);
        if (!*value) {
            BlockDriverState *bs = blk_bs(*ptr);
            if (bs) {
                value = bdrv_get_node_name(bs);
            }
        }
    } else {
        value = "";
    }

    p = g_strdup(value);
    visit_type_str(v, name, &p, errp);
    g_free(p);
}

static void set_drive_helper(Object *obj, Visitor *v, const char *name,
                             void *opaque, bool iothread, Error **errp)
{
    DeviceState *dev = DEVICE(obj);
    Property *prop = opaque;
    void **ptr = object_field_prop_ptr(obj, prop);
    char *str;
    BlockBackend *blk;
    bool blk_created = false;
    int ret;
    BlockDriverState *bs;
    AioContext *ctx;

    if (!visit_type_str(v, name, &str, errp)) {
        return;
    }

    if (!check_prop_still_unset(obj, name, *ptr, str, true, errp)) {
        return;
    }

    if (*ptr) {
        /* BlockBackend alread exists. So, we want to change attached node */
        blk = *ptr;
        ctx = blk_get_aio_context(blk);
        bs = bdrv_lookup_bs(NULL, str, errp);
        if (!bs) {
            return;
        }

        if (ctx != bdrv_get_aio_context(bs)) {
            error_setg(errp, "Different aio context is not supported for new "
                       "node");
        }

        aio_context_acquire(ctx);
        blk_replace_bs(blk, bs, errp);
        aio_context_release(ctx);
        return;
    }

    if (!*str) {
        g_free(str);
        *ptr = NULL;
        return;
    }

    blk = blk_by_name(str);
    if (!blk) {
        bs = bdrv_lookup_bs(NULL, str, NULL);
        if (bs) {
            /*
             * If the device supports iothreads, it will make sure to move the
             * block node to the right AioContext if necessary (or fail if this
             * isn't possible because of other users). Devices that are not
             * aware of iothreads require their BlockBackends to be in the main
             * AioContext.
             */
            ctx = bdrv_get_aio_context(bs);
            blk = blk_new(iothread ? ctx : qemu_get_aio_context(),
                          0, BLK_PERM_ALL);
            blk_created = true;

            aio_context_acquire(ctx);
            ret = blk_insert_bs(blk, bs, errp);
            aio_context_release(ctx);

            if (ret < 0) {
                goto fail;
            }
        }
    }
    if (!blk) {
        error_setg(errp, "Property '%s.%s' can't find value '%s'",
                   object_get_typename(OBJECT(dev)), name, str);
        goto fail;
    }
    if (blk_attach_dev(blk, dev) < 0) {
        DriveInfo *dinfo = blk_legacy_dinfo(blk);

        if (dinfo && dinfo->type != IF_NONE) {
            error_setg(errp, "Drive '%s' is already in use because "
                       "it has been automatically connected to another "
                       "device (did you need 'if=none' in the drive options?)",
                       str);
        } else {
            error_setg(errp, "Drive '%s' is already in use by another device",
                       str);
        }
        goto fail;
    }

    *ptr = blk;

fail:
    if (blk_created) {
        /* If we need to keep a reference, blk_attach_dev() took it */
        blk_unref(blk);
    }

    g_free(str);
}

static void set_drive(Object *obj, Visitor *v, const char *name, void *opaque,
                      Error **errp)
{
    set_drive_helper(obj, v, name, opaque, false, errp);
}

static void set_drive_iothread(Object *obj, Visitor *v, const char *name,
                               void *opaque, Error **errp)
{
    set_drive_helper(obj, v, name, opaque, true, errp);
}

static void release_drive(Object *obj, const char *name, void *opaque)
{
    DeviceState *dev = DEVICE(obj);
    Property *prop = opaque;
    BlockBackend **ptr = object_field_prop_ptr(obj, prop);

    if (*ptr) {
        AioContext *ctx = blk_get_aio_context(*ptr);

        aio_context_acquire(ctx);
        blockdev_auto_del(*ptr);
        blk_detach_dev(*ptr, dev);
        aio_context_release(ctx);
    }
}

const PropertyInfo qdev_prop_drive = {
    .name  = "str",
    .description = "Node name or ID of a block device to use as a backend",
    .realized_set_allowed = true,
    .get   = get_drive,
    .set   = set_drive,
    .release = release_drive,
};

const PropertyInfo qdev_prop_drive_iothread = {
    .name  = "str",
    .description = "Node name or ID of a block device to use as a backend",
    .realized_set_allowed = true,
    .get   = get_drive,
    .set   = set_drive_iothread,
    .release = release_drive,
};

/* --- character device --- */

static void get_chr(Object *obj, Visitor *v, const char *name, void *opaque,
                    Error **errp)
{
    CharBackend *be = object_field_prop_ptr(obj, opaque);
    char *p;

    p = g_strdup(be->chr && be->chr->label ? be->chr->label : "");
    visit_type_str(v, name, &p, errp);
    g_free(p);
}

static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
                    Error **errp)
{
    Property *prop = opaque;
    CharBackend *be = object_field_prop_ptr(obj, prop);
    Chardev *s;
    char *str;

    if (!visit_type_str(v, name, &str, errp)) {
        return;
    }

    /*
     * TODO Should this really be an error?  If no, the old value
     * needs to be released before we store the new one.
     */
    if (!check_prop_still_unset(obj, name, be->chr, str, false, errp)) {
        return;
    }

    if (!*str) {
        g_free(str);
        be->chr = NULL;
        return;
    }

    s = qemu_chr_find(str);
    if (s == NULL) {
        error_setg(errp, "Property '%s.%s' can't find value '%s'",
                   object_get_typename(obj), name, str);
    } else if (!qemu_chr_fe_init(be, s, errp)) {
        error_prepend(errp, "Property '%s.%s' can't take value '%s': ",
                      object_get_typename(obj), name, str);
    }
    g_free(str);
}

static void release_chr(Object *obj, const char *name, void *opaque)
{
    Property *prop = opaque;
    CharBackend *be = object_field_prop_ptr(obj, prop);

    qemu_chr_fe_deinit(be, false);
}

const PropertyInfo qdev_prop_chr = {
    .name  = "str",
    .description = "ID of a chardev to use as a backend",
    .get   = get_chr,
    .set   = set_chr,
    .release = release_chr,
};

/* --- mac address --- */

/*
 * accepted syntax versions:
 *   01:02:03:04:05:06
 *   01-02-03-04-05-06
 */
static void get_mac(Object *obj, Visitor *v, const char *name, void *opaque,
                    Error **errp)
{
    Property *prop = opaque;
    MACAddr *mac = object_field_prop_ptr(obj, prop);
    char buffer[2 * 6 + 5 + 1];
    char *p = buffer;

    snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x",
             mac->a[0], mac->a[1], mac->a[2],
             mac->a[3], mac->a[4], mac->a[5]);

    visit_type_str(v, name, &p, errp);
}

static void set_mac(Object *obj, Visitor *v, const char *name, void *opaque,
                    Error **errp)
{
    Property *prop = opaque;
    MACAddr *mac = object_field_prop_ptr(obj, prop);
    int i, pos;
    char *str;
    const char *p;

    if (!visit_type_str(v, name, &str, errp)) {
        return;
    }

    for (i = 0, pos = 0; i < 6; i++, pos += 3) {
        long val;

        if (!qemu_isxdigit(str[pos])) {
            goto inval;
        }
        if (!qemu_isxdigit(str[pos + 1])) {
            goto inval;
        }
        if (i == 5) {
            if (str[pos + 2] != '\0') {
                goto inval;
            }
        } else {
            if (str[pos + 2] != ':' && str[pos + 2] != '-') {
                goto inval;
            }
        }
        if (qemu_strtol(str + pos, &p, 16, &val) < 0 || val > 0xff) {
            goto inval;
        }
        mac->a[i] = val;
    }
    g_free(str);
    return;

inval:
    error_set_from_qdev_prop_error(errp, EINVAL, obj, name, str);
    g_free(str);
}

const PropertyInfo qdev_prop_macaddr = {
    .name  = "str",
    .description = "Ethernet 6-byte MAC Address, example: 52:54:00:12:34:56",
    .get   = get_mac,
    .set   = set_mac,
};

void qdev_prop_set_macaddr(DeviceState *dev, const char *name,
                           const uint8_t *value)
{
    char str[2 * 6 + 5 + 1];
    snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
             value[0], value[1], value[2], value[3], value[4], value[5]);

    object_property_set_str(OBJECT(dev), name, str, &error_abort);
}

/* --- netdev device --- */
static void get_netdev(Object *obj, Visitor *v, const char *name,
                       void *opaque, Error **errp)
{
    Property *prop = opaque;
    NICPeers *peers_ptr = object_field_prop_ptr(obj, prop);
    char *p = g_strdup(peers_ptr->ncs[0] ? peers_ptr->ncs[0]->name : "");

    visit_type_str(v, name, &p, errp);
    g_free(p);
}

static void set_netdev(Object *obj, Visitor *v, const char *name,
                       void *opaque, Error **errp)
{
    Property *prop = opaque;
    NICPeers *peers_ptr = object_field_prop_ptr(obj, prop);
    NetClientState **ncs = peers_ptr->ncs;
    NetClientState *peers[MAX_QUEUE_NUM];
    int queues, err = 0, i = 0;
    char *str;

    if (!visit_type_str(v, name, &str, errp)) {
        return;
    }

    queues = qemu_find_net_clients_except(str, peers,
                                          NET_CLIENT_DRIVER_NIC,
                                          MAX_QUEUE_NUM);
    if (queues == 0) {
        err = -ENOENT;
        goto out;
    }

    if (queues > MAX_QUEUE_NUM) {
        error_setg(errp, "queues of backend '%s'(%d) exceeds QEMU limitation(%d)",
                   str, queues, MAX_QUEUE_NUM);
        goto out;
    }

    for (i = 0; i < queues; i++) {
        if (peers[i]->peer) {
            err = -EEXIST;
            goto out;
        }

        /*
         * TODO Should this really be an error?  If no, the old value
         * needs to be released before we store the new one.
         */
        if (!check_prop_still_unset(obj, name, ncs[i], str, false, errp)) {
            goto out;
        }

        if (peers[i]->info->check_peer_type) {
            if (!peers[i]->info->check_peer_type(peers[i], obj->class, errp)) {
                goto out;
            }
        }

        ncs[i] = peers[i];
        ncs[i]->queue_index = i;
    }

    peers_ptr->queues = queues;

out:
    error_set_from_qdev_prop_error(errp, err, obj, name, str);
    g_free(str);
}

const PropertyInfo qdev_prop_netdev = {
    .name  = "str",
    .description = "ID of a netdev to use as a backend",
    .get   = get_netdev,
    .set   = set_netdev,
};


/* --- audiodev --- */
static void get_audiodev(Object *obj, Visitor *v, const char* name,
                         void *opaque, Error **errp)
{
    Property *prop = opaque;
    QEMUSoundCard *card = object_field_prop_ptr(obj, prop);
    char *p = g_strdup(audio_get_id(card));

    visit_type_str(v, name, &p, errp);
    g_free(p);
}

static void set_audiodev(Object *obj, Visitor *v, const char* name,
                         void *opaque, Error **errp)
{
    Property *prop = opaque;
    QEMUSoundCard *card = object_field_prop_ptr(obj, prop);
    AudioState *state;
    int err = 0;
    char *str;

    if (!visit_type_str(v, name, &str, errp)) {
        return;
    }

    state = audio_state_by_name(str);

    if (!state) {
        err = -ENOENT;
        goto out;
    }
    card->state = state;

out:
    error_set_from_qdev_prop_error(errp, err, obj, name, str);
    g_free(str);
}

const PropertyInfo qdev_prop_audiodev = {
    .name = "str",
    .description = "ID of an audiodev to use as a backend",
    /* release done on shutdown */
    .get = get_audiodev,
    .set = set_audiodev,
};

bool qdev_prop_set_drive_err(DeviceState *dev, const char *name,
                             BlockBackend *value, Error **errp)
{
    const char *ref = "";

    if (value) {
        ref = blk_name(value);
        if (!*ref) {
            const BlockDriverState *bs = blk_bs(value);
            if (bs) {
                ref = bdrv_get_node_name(bs);
            }
        }
    }

    return object_property_set_str(OBJECT(dev), name, ref, errp);
}

void qdev_prop_set_drive(DeviceState *dev, const char *name,
                         BlockBackend *value)
{
    qdev_prop_set_drive_err(dev, name, value, &error_abort);
}

void qdev_prop_set_chr(DeviceState *dev, const char *name,
                       Chardev *value)
{
    assert(!value || value->label);
    object_property_set_str(OBJECT(dev), name, value ? value->label : "",
                            &error_abort);
}

void qdev_prop_set_netdev(DeviceState *dev, const char *name,
                          NetClientState *value)
{
    assert(!value || value->name);
    object_property_set_str(OBJECT(dev), name, value ? value->name : "",
                            &error_abort);
}

void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
{
    qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a);
    if (nd->netdev) {
        qdev_prop_set_netdev(dev, "netdev", nd->netdev);
    }
    if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
        object_property_find(OBJECT(dev), "vectors")) {
        qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
    }
    nd->instantiated = 1;
}

/* --- lost tick policy --- */

static void qdev_propinfo_set_losttickpolicy(Object *obj, Visitor *v,
                                             const char *name, void *opaque,
                                             Error **errp)
{
    Property *prop = opaque;
    int *ptr = object_field_prop_ptr(obj, prop);
    int value;

    if (!visit_type_enum(v, name, &value, prop->info->enum_table, errp)) {
        return;
    }

    if (value == LOST_TICK_POLICY_SLEW) {
        MachineState *ms = MACHINE(qdev_get_machine());

        if (!object_dynamic_cast(OBJECT(ms), TYPE_X86_MACHINE)) {
            error_setg(errp,
                       "the 'slew' policy is only available for x86 machines");
            return;
        }
    }

    *ptr = value;
}

QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));

const PropertyInfo qdev_prop_losttickpolicy = {
    .name  = "LostTickPolicy",
    .enum_table  = &LostTickPolicy_lookup,
    .get   = qdev_propinfo_get_enum,
    .set   = qdev_propinfo_set_losttickpolicy,
    .set_default_value = qdev_propinfo_set_default_value_enum,
};

/* --- blocksize --- */

static void set_blocksize(Object *obj, Visitor *v, const char *name,
                          void *opaque, Error **errp)
{
    DeviceState *dev = DEVICE(obj);
    Property *prop = opaque;
    uint32_t *ptr = object_field_prop_ptr(obj, prop);
    uint64_t value;
    Error *local_err = NULL;

    if (!visit_type_size(v, name, &value, errp)) {
        return;
    }
    check_block_size(dev->id ? : "", name, value, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        return;
    }
    *ptr = value;
}

const PropertyInfo qdev_prop_blocksize = {
    .name  = "size",
    .description = "A power of two between " MIN_BLOCK_SIZE_STR
                   " and " MAX_BLOCK_SIZE_STR,
    .get   = qdev_propinfo_get_size32,
    .set   = set_blocksize,
    .set_default_value = qdev_propinfo_set_default_value_uint,
};

/* --- Block device error handling policy --- */

QEMU_BUILD_BUG_ON(sizeof(BlockdevOnError) != sizeof(int));

const PropertyInfo qdev_prop_blockdev_on_error = {
    .name = "BlockdevOnError",
    .description = "Error handling policy, "
                   "report/ignore/enospc/stop/auto",
    .enum_table = &BlockdevOnError_lookup,
    .get = qdev_propinfo_get_enum,
    .set = qdev_propinfo_set_enum,
    .set_default_value = qdev_propinfo_set_default_value_enum,
};

/* --- BIOS CHS translation */

QEMU_BUILD_BUG_ON(sizeof(BiosAtaTranslation) != sizeof(int));

const PropertyInfo qdev_prop_bios_chs_trans = {
    .name = "BiosAtaTranslation",
    .description = "Logical CHS translation algorithm, "
                   "auto/none/lba/large/rechs",
    .enum_table = &BiosAtaTranslation_lookup,
    .get = qdev_propinfo_get_enum,
    .set = qdev_propinfo_set_enum,
    .set_default_value = qdev_propinfo_set_default_value_enum,
};

/* --- FDC default drive types */

const PropertyInfo qdev_prop_fdc_drive_type = {
    .name = "FdcDriveType",
    .description = "FDC drive type, "
                   "144/288/120/none/auto",
    .enum_table = &FloppyDriveType_lookup,
    .get = qdev_propinfo_get_enum,
    .set = qdev_propinfo_set_enum,
    .set_default_value = qdev_propinfo_set_default_value_enum,
};

/* --- MultiFDCompression --- */

const PropertyInfo qdev_prop_multifd_compression = {
    .name = "MultiFDCompression",
    .description = "multifd_compression values, "
                   "none/zlib/zstd",
    .enum_table = &MultiFDCompression_lookup,
    .get = qdev_propinfo_get_enum,
    .set = qdev_propinfo_set_enum,
    .set_default_value = qdev_propinfo_set_default_value_enum,
};

/* --- Reserved Region --- */

/*
 * Accepted syntax:
 *   <low address>:<high address>:<type>
 *   where low/high addresses are uint64_t in hexadecimal
 *   and type is a non-negative decimal integer
 */
static void get_reserved_region(Object *obj, Visitor *v, const char *name,
                                void *opaque, Error **errp)
{
    Property *prop = opaque;
    ReservedRegion *rr = object_field_prop_ptr(obj, prop);
    char buffer[64];
    char *p = buffer;
    int rc;

    rc = snprintf(buffer, sizeof(buffer), "0x%"PRIx64":0x%"PRIx64":%u",
                  rr->low, rr->high, rr->type);
    assert(rc < sizeof(buffer));

    visit_type_str(v, name, &p, errp);
}

static void set_reserved_region(Object *obj, Visitor *v, const char *name,
                                void *opaque, Error **errp)
{
    Property *prop = opaque;
    ReservedRegion *rr = object_field_prop_ptr(obj, prop);
    const char *endptr;
    char *str;
    int ret;

    if (!visit_type_str(v, name, &str, errp)) {
        return;
    }

    ret = qemu_strtou64(str, &endptr, 16, &rr->low);
    if (ret) {
        error_setg(errp, "start address of '%s'"
                   " must be a hexadecimal integer", name);
        goto out;
    }
    if (*endptr != ':') {
        goto separator_error;
    }

    ret = qemu_strtou64(endptr + 1, &endptr, 16, &rr->high);
    if (ret) {
        error_setg(errp, "end address of '%s'"
                   " must be a hexadecimal integer", name);
        goto out;
    }
    if (*endptr != ':') {
        goto separator_error;
    }

    ret = qemu_strtoui(endptr + 1, &endptr, 10, &rr->type);
    if (ret) {
        error_setg(errp, "type of '%s'"
                   " must be a non-negative decimal integer", name);
    }
    goto out;

separator_error:
    error_setg(errp, "reserved region fields must be separated with ':'");
out:
    g_free(str);
    return;
}

const PropertyInfo qdev_prop_reserved_region = {
    .name  = "reserved_region",
    .description = "Reserved Region, example: 0xFEE00000:0xFEEFFFFF:0",
    .get   = get_reserved_region,
    .set   = set_reserved_region,
};

/* --- pci address --- */

/*
 * bus-local address, i.e. "$slot" or "$slot.$fn"
 */
static void set_pci_devfn(Object *obj, Visitor *v, const char *name,
                          void *opaque, Error **errp)
{
    Property *prop = opaque;
    int32_t value, *ptr = object_field_prop_ptr(obj, prop);
    unsigned int slot, fn, n;
    char *str;

    if (!visit_type_str(v, name, &str, NULL)) {
        if (!visit_type_int32(v, name, &value, errp)) {
            return;
        }
        if (value < -1 || value > 255) {
            error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
                       name ? name : "null", "a value between -1 and 255");
            return;
        }
        *ptr = value;
        return;
    }

    if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
        fn = 0;
        if (sscanf(str, "%x%n", &slot, &n) != 1) {
            goto invalid;
        }
    }
    if (str[n] != '\0' || fn > 7 || slot > 31) {
        goto invalid;
    }
    *ptr = slot << 3 | fn;
    g_free(str);
    return;

invalid:
    error_set_from_qdev_prop_error(errp, EINVAL, obj, name, str);
    g_free(str);
}

static int print_pci_devfn(Object *obj, Property *prop, char *dest,
                           size_t len)
{
    int32_t *ptr = object_field_prop_ptr(obj, prop);

    if (*ptr == -1) {
        return snprintf(dest, len, "<unset>");
    } else {
        return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7);
    }
}

const PropertyInfo qdev_prop_pci_devfn = {
    .name  = "int32",
    .description = "Slot and optional function number, example: 06.0 or 06",
    .print = print_pci_devfn,
    .get   = qdev_propinfo_get_int32,
    .set   = set_pci_devfn,
    .set_default_value = qdev_propinfo_set_default_value_int,
};

/* --- pci host address --- */

static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
                                 void *opaque, Error **errp)
{
    Property *prop = opaque;
    PCIHostDeviceAddress *addr = object_field_prop_ptr(obj, prop);
    char buffer[] = "ffff:ff:ff.f";
    char *p = buffer;
    int rc = 0;

    /*
     * Catch "invalid" device reference from vfio-pci and allow the
     * default buffer representing the non-existent device to be used.
     */
    if (~addr->domain || ~addr->bus || ~addr->slot || ~addr->function) {
        rc = snprintf(buffer, sizeof(buffer), "%04x:%02x:%02x.%0d",
                      addr->domain, addr->bus, addr->slot, addr->function);
        assert(rc == sizeof(buffer) - 1);
    }

    visit_type_str(v, name, &p, errp);
}

/*
 * Parse [<domain>:]<bus>:<slot>.<func>
 *   if <domain> is not supplied, it's assumed to be 0.
 */
static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
                                 void *opaque, Error **errp)
{
    Property *prop = opaque;
    PCIHostDeviceAddress *addr = object_field_prop_ptr(obj, prop);
    char *str, *p;
    char *e;
    unsigned long val;
    unsigned long dom = 0, bus = 0;
    unsigned int slot = 0, func = 0;

    if (!visit_type_str(v, name, &str, errp)) {
        return;
    }

    p = str;
    val = strtoul(p, &e, 16);
    if (e == p || *e != ':') {
        goto inval;
    }
    bus = val;

    p = e + 1;
    val = strtoul(p, &e, 16);
    if (e == p) {
        goto inval;
    }
    if (*e == ':') {
        dom = bus;
        bus = val;
        p = e + 1;
        val = strtoul(p, &e, 16);
        if (e == p) {
            goto inval;
        }
    }
    slot = val;

    if (*e != '.') {
        goto inval;
    }
    p = e + 1;
    val = strtoul(p, &e, 10);
    if (e == p) {
        goto inval;
    }
    func = val;

    if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) {
        goto inval;
    }

    if (*e) {
        goto inval;
    }

    addr->domain = dom;
    addr->bus = bus;
    addr->slot = slot;
    addr->function = func;

    g_free(str);
    return;

inval:
    error_set_from_qdev_prop_error(errp, EINVAL, obj, name, str);
    g_free(str);
}

const PropertyInfo qdev_prop_pci_host_devaddr = {
    .name = "str",
    .description = "Address (bus/device/function) of "
                   "the host device, example: 04:10.0",
    .get = get_pci_host_devaddr,
    .set = set_pci_host_devaddr,
};

/* --- OffAutoPCIBAR off/auto/bar0/bar1/bar2/bar3/bar4/bar5 --- */

const PropertyInfo qdev_prop_off_auto_pcibar = {
    .name = "OffAutoPCIBAR",
    .description = "off/auto/bar0/bar1/bar2/bar3/bar4/bar5",
    .enum_table = &OffAutoPCIBAR_lookup,
    .get = qdev_propinfo_get_enum,
    .set = qdev_propinfo_set_enum,
    .set_default_value = qdev_propinfo_set_default_value_enum,
};

/* --- PCIELinkSpeed 2_5/5/8/16 -- */

static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
                                   void *opaque, Error **errp)
{
    Property *prop = opaque;
    PCIExpLinkSpeed *p = object_field_prop_ptr(obj, prop);
    int speed;

    switch (*p) {
    case QEMU_PCI_EXP_LNK_2_5GT:
        speed = PCIE_LINK_SPEED_2_5;
        break;
    case QEMU_PCI_EXP_LNK_5GT:
        speed = PCIE_LINK_SPEED_5;
        break;
    case QEMU_PCI_EXP_LNK_8GT:
        speed = PCIE_LINK_SPEED_8;
        break;
    case QEMU_PCI_EXP_LNK_16GT:
        speed = PCIE_LINK_SPEED_16;
        break;
    default:
        /* Unreachable */
        abort();
    }

    visit_type_enum(v, name, &speed, prop->info->enum_table, errp);
}

static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
                                   void *opaque, Error **errp)
{
    Property *prop = opaque;
    PCIExpLinkSpeed *p = object_field_prop_ptr(obj, prop);
    int speed;

    if (!visit_type_enum(v, name, &speed, prop->info->enum_table,
                         errp)) {
        return;
    }

    switch (speed) {
    case PCIE_LINK_SPEED_2_5:
        *p = QEMU_PCI_EXP_LNK_2_5GT;
        break;
    case PCIE_LINK_SPEED_5:
        *p = QEMU_PCI_EXP_LNK_5GT;
        break;
    case PCIE_LINK_SPEED_8:
        *p = QEMU_PCI_EXP_LNK_8GT;
        break;
    case PCIE_LINK_SPEED_16:
        *p = QEMU_PCI_EXP_LNK_16GT;
        break;
    default:
        /* Unreachable */
        abort();
    }
}

const PropertyInfo qdev_prop_pcie_link_speed = {
    .name = "PCIELinkSpeed",
    .description = "2_5/5/8/16",
    .enum_table = &PCIELinkSpeed_lookup,
    .get = get_prop_pcielinkspeed,
    .set = set_prop_pcielinkspeed,
    .set_default_value = qdev_propinfo_set_default_value_enum,
};

/* --- PCIELinkWidth 1/2/4/8/12/16/32 -- */

static void get_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
                                   void *opaque, Error **errp)
{
    Property *prop = opaque;
    PCIExpLinkWidth *p = object_field_prop_ptr(obj, prop);
    int width;

    switch (*p) {
    case QEMU_PCI_EXP_LNK_X1:
        width = PCIE_LINK_WIDTH_1;
        break;
    case QEMU_PCI_EXP_LNK_X2:
        width = PCIE_LINK_WIDTH_2;
        break;
    case QEMU_PCI_EXP_LNK_X4:
        width = PCIE_LINK_WIDTH_4;
        break;
    case QEMU_PCI_EXP_LNK_X8:
        width = PCIE_LINK_WIDTH_8;
        break;
    case QEMU_PCI_EXP_LNK_X12:
        width = PCIE_LINK_WIDTH_12;
        break;
    case QEMU_PCI_EXP_LNK_X16:
        width = PCIE_LINK_WIDTH_16;
        break;
    case QEMU_PCI_EXP_LNK_X32:
        width = PCIE_LINK_WIDTH_32;
        break;
    default:
        /* Unreachable */
        abort();
    }

    visit_type_enum(v, name, &width, prop->info->enum_table, errp);
}

static void set_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
                                   void *opaque, Error **errp)
{
    Property *prop = opaque;
    PCIExpLinkWidth *p = object_field_prop_ptr(obj, prop);
    int width;

    if (!visit_type_enum(v, name, &width, prop->info->enum_table,
                         errp)) {
        return;
    }

    switch (width) {
    case PCIE_LINK_WIDTH_1:
        *p = QEMU_PCI_EXP_LNK_X1;
        break;
    case PCIE_LINK_WIDTH_2:
        *p = QEMU_PCI_EXP_LNK_X2;
        break;
    case PCIE_LINK_WIDTH_4:
        *p = QEMU_PCI_EXP_LNK_X4;
        break;
    case PCIE_LINK_WIDTH_8:
        *p = QEMU_PCI_EXP_LNK_X8;
        break;
    case PCIE_LINK_WIDTH_12:
        *p = QEMU_PCI_EXP_LNK_X12;
        break;
    case PCIE_LINK_WIDTH_16:
        *p = QEMU_PCI_EXP_LNK_X16;
        break;
    case PCIE_LINK_WIDTH_32:
        *p = QEMU_PCI_EXP_LNK_X32;
        break;
    default:
        /* Unreachable */
        abort();
    }
}

const PropertyInfo qdev_prop_pcie_link_width = {
    .name = "PCIELinkWidth",
    .description = "1/2/4/8/12/16/32",
    .enum_table = &PCIELinkWidth_lookup,
    .get = get_prop_pcielinkwidth,
    .set = set_prop_pcielinkwidth,
    .set_default_value = qdev_propinfo_set_default_value_enum,
};

/* --- UUID --- */

static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
{
    Property *prop = opaque;
    QemuUUID *uuid = object_field_prop_ptr(obj, prop);
    char buffer[UUID_FMT_LEN + 1];
    char *p = buffer;

    qemu_uuid_unparse(uuid, buffer);

    visit_type_str(v, name, &p, errp);
}

#define UUID_VALUE_AUTO        "auto"

static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
                    Error **errp)
{
    Property *prop = opaque;
    QemuUUID *uuid = object_field_prop_ptr(obj, prop);
    char *str;

    if (!visit_type_str(v, name, &str, errp)) {
        return;
    }

    if (!strcmp(str, UUID_VALUE_AUTO)) {
        qemu_uuid_generate(uuid);
    } else if (qemu_uuid_parse(str, uuid) < 0) {
        error_set_from_qdev_prop_error(errp, EINVAL, obj, name, str);
    }
    g_free(str);
}

static void set_default_uuid_auto(ObjectProperty *op, const Property *prop)
{
    object_property_set_default_str(op, UUID_VALUE_AUTO);
}

const PropertyInfo qdev_prop_uuid = {
    .name  = "str",
    .description = "UUID (aka GUID) or \"" UUID_VALUE_AUTO
        "\" for random value (default)",
    .get   = get_uuid,
    .set   = set_uuid,
    .set_default_value = set_default_uuid_auto,
};
