/*
 * Channel subsystem base support.
 *
 * Copyright 2012 IBM Corp.
 * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or (at
 * your option) any later version. See the COPYING file in the top-level
 * directory.
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qapi/visitor.h"
#include "qemu/bitops.h"
#include "qemu/error-report.h"
#include "exec/address-spaces.h"
#include "cpu.h"
#include "hw/s390x/ioinst.h"
#include "hw/qdev-properties.h"
#include "hw/s390x/css.h"
#include "trace.h"
#include "hw/s390x/s390_flic.h"
#include "hw/s390x/s390-virtio-ccw.h"
#include "hw/s390x/s390-ccw.h"

typedef struct CrwContainer {
    CRW crw;
    QTAILQ_ENTRY(CrwContainer) sibling;
} CrwContainer;

static const VMStateDescription vmstate_crw = {
    .name = "s390_crw",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT16(flags, CRW),
        VMSTATE_UINT16(rsid, CRW),
        VMSTATE_END_OF_LIST()
    },
};

static const VMStateDescription vmstate_crw_container = {
    .name = "s390_crw_container",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_STRUCT(crw, CrwContainer, 0, vmstate_crw, CRW),
        VMSTATE_END_OF_LIST()
    },
};

typedef struct ChpInfo {
    uint8_t in_use;
    uint8_t type;
    uint8_t is_virtual;
} ChpInfo;

static const VMStateDescription vmstate_chp_info = {
    .name = "s390_chp_info",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT8(in_use, ChpInfo),
        VMSTATE_UINT8(type, ChpInfo),
        VMSTATE_UINT8(is_virtual, ChpInfo),
        VMSTATE_END_OF_LIST()
    }
};

typedef struct SubchSet {
    SubchDev *sch[MAX_SCHID + 1];
    unsigned long schids_used[BITS_TO_LONGS(MAX_SCHID + 1)];
    unsigned long devnos_used[BITS_TO_LONGS(MAX_SCHID + 1)];
} SubchSet;

static const VMStateDescription vmstate_scsw = {
    .name = "s390_scsw",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT16(flags, SCSW),
        VMSTATE_UINT16(ctrl, SCSW),
        VMSTATE_UINT32(cpa, SCSW),
        VMSTATE_UINT8(dstat, SCSW),
        VMSTATE_UINT8(cstat, SCSW),
        VMSTATE_UINT16(count, SCSW),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription vmstate_pmcw = {
    .name = "s390_pmcw",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(intparm, PMCW),
        VMSTATE_UINT16(flags, PMCW),
        VMSTATE_UINT16(devno, PMCW),
        VMSTATE_UINT8(lpm, PMCW),
        VMSTATE_UINT8(pnom, PMCW),
        VMSTATE_UINT8(lpum, PMCW),
        VMSTATE_UINT8(pim, PMCW),
        VMSTATE_UINT16(mbi, PMCW),
        VMSTATE_UINT8(pom, PMCW),
        VMSTATE_UINT8(pam, PMCW),
        VMSTATE_UINT8_ARRAY(chpid, PMCW, 8),
        VMSTATE_UINT32(chars, PMCW),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription vmstate_schib = {
    .name = "s390_schib",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_STRUCT(pmcw, SCHIB, 0, vmstate_pmcw, PMCW),
        VMSTATE_STRUCT(scsw, SCHIB, 0, vmstate_scsw, SCSW),
        VMSTATE_UINT64(mba, SCHIB),
        VMSTATE_UINT8_ARRAY(mda, SCHIB, 4),
        VMSTATE_END_OF_LIST()
    }
};


static const VMStateDescription vmstate_ccw1 = {
    .name = "s390_ccw1",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT8(cmd_code, CCW1),
        VMSTATE_UINT8(flags, CCW1),
        VMSTATE_UINT16(count, CCW1),
        VMSTATE_UINT32(cda, CCW1),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription vmstate_ciw = {
    .name = "s390_ciw",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT8(type, CIW),
        VMSTATE_UINT8(command, CIW),
        VMSTATE_UINT16(count, CIW),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription vmstate_sense_id = {
    .name = "s390_sense_id",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT8(reserved, SenseId),
        VMSTATE_UINT16(cu_type, SenseId),
        VMSTATE_UINT8(cu_model, SenseId),
        VMSTATE_UINT16(dev_type, SenseId),
        VMSTATE_UINT8(dev_model, SenseId),
        VMSTATE_UINT8(unused, SenseId),
        VMSTATE_STRUCT_ARRAY(ciw, SenseId, MAX_CIWS, 0, vmstate_ciw, CIW),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription vmstate_orb = {
    .name = "s390_orb",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(intparm, ORB),
        VMSTATE_UINT16(ctrl0, ORB),
        VMSTATE_UINT8(lpm, ORB),
        VMSTATE_UINT8(ctrl1, ORB),
        VMSTATE_UINT32(cpa, ORB),
        VMSTATE_END_OF_LIST()
    }
};

static bool vmstate_schdev_orb_needed(void *opaque)
{
    return css_migration_enabled();
}

static const VMStateDescription vmstate_schdev_orb = {
    .name = "s390_subch_dev/orb",
    .version_id = 1,
    .minimum_version_id = 1,
    .needed = vmstate_schdev_orb_needed,
    .fields = (VMStateField[]) {
        VMSTATE_STRUCT(orb, SubchDev, 1, vmstate_orb, ORB),
        VMSTATE_END_OF_LIST()
    }
};

static int subch_dev_post_load(void *opaque, int version_id);
static int subch_dev_pre_save(void *opaque);

const char err_hint_devno[] = "Devno mismatch, tried to load wrong section!"
    " Likely reason: some sequences of plug and unplug  can break"
    " migration for machine versions prior to  2.7 (known design flaw).";

const VMStateDescription vmstate_subch_dev = {
    .name = "s390_subch_dev",
    .version_id = 1,
    .minimum_version_id = 1,
    .post_load = subch_dev_post_load,
    .pre_save = subch_dev_pre_save,
    .fields = (VMStateField[]) {
        VMSTATE_UINT8_EQUAL(cssid, SubchDev, "Bug!"),
        VMSTATE_UINT8_EQUAL(ssid, SubchDev, "Bug!"),
        VMSTATE_UINT16(migrated_schid, SubchDev),
        VMSTATE_UINT16_EQUAL(devno, SubchDev, err_hint_devno),
        VMSTATE_BOOL(thinint_active, SubchDev),
        VMSTATE_STRUCT(curr_status, SubchDev, 0, vmstate_schib, SCHIB),
        VMSTATE_UINT8_ARRAY(sense_data, SubchDev, 32),
        VMSTATE_UINT64(channel_prog, SubchDev),
        VMSTATE_STRUCT(last_cmd, SubchDev, 0, vmstate_ccw1, CCW1),
        VMSTATE_BOOL(last_cmd_valid, SubchDev),
        VMSTATE_STRUCT(id, SubchDev, 0, vmstate_sense_id, SenseId),
        VMSTATE_BOOL(ccw_fmt_1, SubchDev),
        VMSTATE_UINT8(ccw_no_data_cnt, SubchDev),
        VMSTATE_END_OF_LIST()
    },
    .subsections = (const VMStateDescription * []) {
        &vmstate_schdev_orb,
        NULL
    }
};

typedef struct IndAddrPtrTmp {
    IndAddr **parent;
    uint64_t addr;
    int32_t len;
} IndAddrPtrTmp;

static int post_load_ind_addr(void *opaque, int version_id)
{
    IndAddrPtrTmp *ptmp = opaque;
    IndAddr **ind_addr = ptmp->parent;

    if (ptmp->len != 0) {
        *ind_addr = get_indicator(ptmp->addr, ptmp->len);
    } else {
        *ind_addr = NULL;
    }
    return 0;
}

static int pre_save_ind_addr(void *opaque)
{
    IndAddrPtrTmp *ptmp = opaque;
    IndAddr *ind_addr = *(ptmp->parent);

    if (ind_addr != NULL) {
        ptmp->len = ind_addr->len;
        ptmp->addr = ind_addr->addr;
    } else {
        ptmp->len = 0;
        ptmp->addr = 0L;
    }

    return 0;
}

const VMStateDescription vmstate_ind_addr_tmp = {
    .name = "s390_ind_addr_tmp",
    .pre_save = pre_save_ind_addr,
    .post_load = post_load_ind_addr,

    .fields = (VMStateField[]) {
        VMSTATE_INT32(len, IndAddrPtrTmp),
        VMSTATE_UINT64(addr, IndAddrPtrTmp),
        VMSTATE_END_OF_LIST()
    }
};

const VMStateDescription vmstate_ind_addr = {
    .name = "s390_ind_addr_tmp",
    .fields = (VMStateField[]) {
        VMSTATE_WITH_TMP(IndAddr*, IndAddrPtrTmp, vmstate_ind_addr_tmp),
        VMSTATE_END_OF_LIST()
    }
};

typedef struct CssImage {
    SubchSet *sch_set[MAX_SSID + 1];
    ChpInfo chpids[MAX_CHPID + 1];
} CssImage;

static const VMStateDescription vmstate_css_img = {
    .name = "s390_css_img",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        /* Subchannel sets have no relevant state. */
        VMSTATE_STRUCT_ARRAY(chpids, CssImage, MAX_CHPID + 1, 0,
                             vmstate_chp_info, ChpInfo),
        VMSTATE_END_OF_LIST()
    }

};

typedef struct IoAdapter {
    uint32_t id;
    uint8_t type;
    uint8_t isc;
    uint8_t flags;
} IoAdapter;

typedef struct ChannelSubSys {
    QTAILQ_HEAD(, CrwContainer) pending_crws;
    bool sei_pending;
    bool do_crw_mchk;
    bool crws_lost;
    uint8_t max_cssid;
    uint8_t max_ssid;
    bool chnmon_active;
    uint64_t chnmon_area;
    CssImage *css[MAX_CSSID + 1];
    uint8_t default_cssid;
    /* don't migrate, see css_register_io_adapters */
    IoAdapter *io_adapters[CSS_IO_ADAPTER_TYPE_NUMS][MAX_ISC + 1];
    /* don't migrate, see get_indicator and IndAddrPtrTmp */
    QTAILQ_HEAD(, IndAddr) indicator_addresses;
} ChannelSubSys;

static const VMStateDescription vmstate_css = {
    .name = "s390_css",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_QTAILQ_V(pending_crws, ChannelSubSys, 1, vmstate_crw_container,
                         CrwContainer, sibling),
        VMSTATE_BOOL(sei_pending, ChannelSubSys),
        VMSTATE_BOOL(do_crw_mchk, ChannelSubSys),
        VMSTATE_BOOL(crws_lost, ChannelSubSys),
        /* These were kind of migrated by virtio */
        VMSTATE_UINT8(max_cssid, ChannelSubSys),
        VMSTATE_UINT8(max_ssid, ChannelSubSys),
        VMSTATE_BOOL(chnmon_active, ChannelSubSys),
        VMSTATE_UINT64(chnmon_area, ChannelSubSys),
        VMSTATE_ARRAY_OF_POINTER_TO_STRUCT(css, ChannelSubSys, MAX_CSSID + 1,
                0, vmstate_css_img, CssImage),
        VMSTATE_UINT8(default_cssid, ChannelSubSys),
        VMSTATE_END_OF_LIST()
    }
};

static ChannelSubSys channel_subsys = {
    .pending_crws = QTAILQ_HEAD_INITIALIZER(channel_subsys.pending_crws),
    .do_crw_mchk = true,
    .sei_pending = false,
    .crws_lost = false,
    .chnmon_active = false,
    .indicator_addresses =
        QTAILQ_HEAD_INITIALIZER(channel_subsys.indicator_addresses),
};

static int subch_dev_pre_save(void *opaque)
{
    SubchDev *s = opaque;

    /* Prepare remote_schid for save */
    s->migrated_schid = s->schid;

    return 0;
}

static int subch_dev_post_load(void *opaque, int version_id)
{

    SubchDev *s = opaque;

    /* Re-assign the subchannel to remote_schid if necessary */
    if (s->migrated_schid != s->schid) {
        if (css_find_subch(true, s->cssid, s->ssid, s->schid) == s) {
            /*
             * Cleanup the slot before moving to s->migrated_schid provided
             * it still belongs to us, i.e. it was not changed by previous
             * invocation of this function.
             */
            css_subch_assign(s->cssid, s->ssid, s->schid, s->devno, NULL);
        }
        /* It's OK to re-assign without a prior de-assign. */
        s->schid = s->migrated_schid;
        css_subch_assign(s->cssid, s->ssid, s->schid, s->devno, s);
    }

    if (css_migration_enabled()) {
        /* No compat voodoo to do ;) */
        return 0;
    }
    /*
     * Hack alert. If we don't migrate the channel subsystem status
     * we still need to find out if the guest enabled mss/mcss-e.
     * If the subchannel is enabled, it certainly was able to access it,
     * so adjust the max_ssid/max_cssid values for relevant ssid/cssid
     * values. This is not watertight, but better than nothing.
     */
    if (s->curr_status.pmcw.flags & PMCW_FLAGS_MASK_ENA) {
        if (s->ssid) {
            channel_subsys.max_ssid = MAX_SSID;
        }
        if (s->cssid != channel_subsys.default_cssid) {
            channel_subsys.max_cssid = MAX_CSSID;
        }
    }
    return 0;
}

void css_register_vmstate(void)
{
    vmstate_register(NULL, 0, &vmstate_css, &channel_subsys);
}

IndAddr *get_indicator(hwaddr ind_addr, int len)
{
    IndAddr *indicator;

    QTAILQ_FOREACH(indicator, &channel_subsys.indicator_addresses, sibling) {
        if (indicator->addr == ind_addr) {
            indicator->refcnt++;
            return indicator;
        }
    }
    indicator = g_new0(IndAddr, 1);
    indicator->addr = ind_addr;
    indicator->len = len;
    indicator->refcnt = 1;
    QTAILQ_INSERT_TAIL(&channel_subsys.indicator_addresses,
                       indicator, sibling);
    return indicator;
}

static int s390_io_adapter_map(AdapterInfo *adapter, uint64_t map_addr,
                               bool do_map)
{
    S390FLICState *fs = s390_get_flic();
    S390FLICStateClass *fsc = s390_get_flic_class(fs);

    return fsc->io_adapter_map(fs, adapter->adapter_id, map_addr, do_map);
}

void release_indicator(AdapterInfo *adapter, IndAddr *indicator)
{
    assert(indicator->refcnt > 0);
    indicator->refcnt--;
    if (indicator->refcnt > 0) {
        return;
    }
    QTAILQ_REMOVE(&channel_subsys.indicator_addresses, indicator, sibling);
    if (indicator->map) {
        s390_io_adapter_map(adapter, indicator->map, false);
    }
    g_free(indicator);
}

int map_indicator(AdapterInfo *adapter, IndAddr *indicator)
{
    int ret;

    if (indicator->map) {
        return 0; /* already mapped is not an error */
    }
    indicator->map = indicator->addr;
    ret = s390_io_adapter_map(adapter, indicator->map, true);
    if ((ret != 0) && (ret != -ENOSYS)) {
        goto out_err;
    }
    return 0;

out_err:
    indicator->map = 0;
    return ret;
}

int css_create_css_image(uint8_t cssid, bool default_image)
{
    trace_css_new_image(cssid, default_image ? "(default)" : "");
    /* 255 is reserved */
    if (cssid == 255) {
        return -EINVAL;
    }
    if (channel_subsys.css[cssid]) {
        return -EBUSY;
    }
    channel_subsys.css[cssid] = g_new0(CssImage, 1);
    if (default_image) {
        channel_subsys.default_cssid = cssid;
    }
    return 0;
}

uint32_t css_get_adapter_id(CssIoAdapterType type, uint8_t isc)
{
    if (type >= CSS_IO_ADAPTER_TYPE_NUMS || isc > MAX_ISC ||
        !channel_subsys.io_adapters[type][isc]) {
        return -1;
    }

    return channel_subsys.io_adapters[type][isc]->id;
}

/**
 * css_register_io_adapters: Register I/O adapters per ISC during init
 *
 * @swap: an indication if byte swap is needed.
 * @maskable: an indication if the adapter is subject to the mask operation.
 * @flags: further characteristics of the adapter.
 *         e.g. suppressible, an indication if the adapter is subject to AIS.
 * @errp: location to store error information.
 */
void css_register_io_adapters(CssIoAdapterType type, bool swap, bool maskable,
                              uint8_t flags, Error **errp)
{
    uint32_t id;
    int ret, isc;
    IoAdapter *adapter;
    S390FLICState *fs = s390_get_flic();
    S390FLICStateClass *fsc = s390_get_flic_class(fs);

    /*
     * Disallow multiple registrations for the same device type.
     * Report an error if registering for an already registered type.
     */
    if (channel_subsys.io_adapters[type][0]) {
        error_setg(errp, "Adapters for type %d already registered", type);
    }

    for (isc = 0; isc <= MAX_ISC; isc++) {
        id = (type << 3) | isc;
        ret = fsc->register_io_adapter(fs, id, isc, swap, maskable, flags);
        if (ret == 0) {
            adapter = g_new0(IoAdapter, 1);
            adapter->id = id;
            adapter->isc = isc;
            adapter->type = type;
            adapter->flags = flags;
            channel_subsys.io_adapters[type][isc] = adapter;
        } else {
            error_setg_errno(errp, -ret, "Unexpected error %d when "
                             "registering adapter %d", ret, id);
            break;
        }
    }

    /*
     * No need to free registered adapters in kvm: kvm will clean up
     * when the machine goes away.
     */
    if (ret) {
        for (isc--; isc >= 0; isc--) {
            g_free(channel_subsys.io_adapters[type][isc]);
            channel_subsys.io_adapters[type][isc] = NULL;
        }
    }

}

static void css_clear_io_interrupt(uint16_t subchannel_id,
                                   uint16_t subchannel_nr)
{
    Error *err = NULL;
    static bool no_clear_irq;
    S390FLICState *fs = s390_get_flic();
    S390FLICStateClass *fsc = s390_get_flic_class(fs);
    int r;

    if (unlikely(no_clear_irq)) {
        return;
    }
    r = fsc->clear_io_irq(fs, subchannel_id, subchannel_nr);
    switch (r) {
    case 0:
        break;
    case -ENOSYS:
        no_clear_irq = true;
        /*
        * Ignore unavailability, as the user can't do anything
        * about it anyway.
        */
        break;
    default:
        error_setg_errno(&err, -r, "unexpected error condition");
        error_propagate(&error_abort, err);
    }
}

static inline uint16_t css_do_build_subchannel_id(uint8_t cssid, uint8_t ssid)
{
    if (channel_subsys.max_cssid > 0) {
        return (cssid << 8) | (1 << 3) | (ssid << 1) | 1;
    }
    return (ssid << 1) | 1;
}

uint16_t css_build_subchannel_id(SubchDev *sch)
{
    return css_do_build_subchannel_id(sch->cssid, sch->ssid);
}

void css_inject_io_interrupt(SubchDev *sch)
{
    uint8_t isc = (sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_ISC) >> 11;

    trace_css_io_interrupt(sch->cssid, sch->ssid, sch->schid,
                           sch->curr_status.pmcw.intparm, isc, "");
    s390_io_interrupt(css_build_subchannel_id(sch),
                      sch->schid,
                      sch->curr_status.pmcw.intparm,
                      isc << 27);
}

void css_conditional_io_interrupt(SubchDev *sch)
{
    /*
     * If the subchannel is not enabled, it is not made status pending
     * (see PoP p. 16-17, "Status Control").
     */
    if (!(sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_ENA)) {
        return;
    }

    /*
     * If the subchannel is not currently status pending, make it pending
     * with alert status.
     */
    if (!(sch->curr_status.scsw.ctrl & SCSW_STCTL_STATUS_PEND)) {
        uint8_t isc = (sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_ISC) >> 11;

        trace_css_io_interrupt(sch->cssid, sch->ssid, sch->schid,
                               sch->curr_status.pmcw.intparm, isc,
                               "(unsolicited)");
        sch->curr_status.scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
        sch->curr_status.scsw.ctrl |=
            SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
        /* Inject an I/O interrupt. */
        s390_io_interrupt(css_build_subchannel_id(sch),
                          sch->schid,
                          sch->curr_status.pmcw.intparm,
                          isc << 27);
    }
}

int css_do_sic(CPUS390XState *env, uint8_t isc, uint16_t mode)
{
    S390FLICState *fs = s390_get_flic();
    S390FLICStateClass *fsc = s390_get_flic_class(fs);
    int r;

    if (env->psw.mask & PSW_MASK_PSTATE) {
        r = -PGM_PRIVILEGED;
        goto out;
    }

    trace_css_do_sic(mode, isc);
    switch (mode) {
    case SIC_IRQ_MODE_ALL:
    case SIC_IRQ_MODE_SINGLE:
        break;
    default:
        r = -PGM_OPERAND;
        goto out;
    }

    r = fsc->modify_ais_mode(fs, isc, mode) ? -PGM_OPERATION : 0;
out:
    return r;
}

void css_adapter_interrupt(CssIoAdapterType type, uint8_t isc)
{
    S390FLICState *fs = s390_get_flic();
    S390FLICStateClass *fsc = s390_get_flic_class(fs);
    uint32_t io_int_word = (isc << 27) | IO_INT_WORD_AI;
    IoAdapter *adapter = channel_subsys.io_adapters[type][isc];

    if (!adapter) {
        return;
    }

    trace_css_adapter_interrupt(isc);
    if (fs->ais_supported) {
        if (fsc->inject_airq(fs, type, isc, adapter->flags)) {
            error_report("Failed to inject airq with AIS supported");
            exit(1);
        }
    } else {
        s390_io_interrupt(0, 0, 0, io_int_word);
    }
}

static void sch_handle_clear_func(SubchDev *sch)
{
    SCHIB *schib = &sch->curr_status;
    int path;

    /* Path management: In our simple css, we always choose the only path. */
    path = 0x80;

    /* Reset values prior to 'issuing the clear signal'. */
    schib->pmcw.lpum = 0;
    schib->pmcw.pom = 0xff;
    schib->scsw.flags &= ~SCSW_FLAGS_MASK_PNO;

    /* We always 'attempt to issue the clear signal', and we always succeed. */
    sch->channel_prog = 0x0;
    sch->last_cmd_valid = false;
    schib->scsw.ctrl &= ~SCSW_ACTL_CLEAR_PEND;
    schib->scsw.ctrl |= SCSW_STCTL_STATUS_PEND;

    schib->scsw.dstat = 0;
    schib->scsw.cstat = 0;
    schib->pmcw.lpum = path;

}

static void sch_handle_halt_func(SubchDev *sch)
{
    SCHIB *schib = &sch->curr_status;
    hwaddr curr_ccw = sch->channel_prog;
    int path;

    /* Path management: In our simple css, we always choose the only path. */
    path = 0x80;

    /* We always 'attempt to issue the halt signal', and we always succeed. */
    sch->channel_prog = 0x0;
    sch->last_cmd_valid = false;
    schib->scsw.ctrl &= ~SCSW_ACTL_HALT_PEND;
    schib->scsw.ctrl |= SCSW_STCTL_STATUS_PEND;

    if ((schib->scsw.ctrl & (SCSW_ACTL_SUBCH_ACTIVE |
                             SCSW_ACTL_DEVICE_ACTIVE)) ||
        !((schib->scsw.ctrl & SCSW_ACTL_START_PEND) ||
          (schib->scsw.ctrl & SCSW_ACTL_SUSP))) {
        schib->scsw.dstat = SCSW_DSTAT_DEVICE_END;
    }
    if ((schib->scsw.ctrl & (SCSW_ACTL_SUBCH_ACTIVE |
                             SCSW_ACTL_DEVICE_ACTIVE)) ||
        (schib->scsw.ctrl & SCSW_ACTL_SUSP)) {
        schib->scsw.cpa = curr_ccw + 8;
    }
    schib->scsw.cstat = 0;
    schib->pmcw.lpum = path;

}

/*
 * As the SenseId struct cannot be packed (would cause unaligned accesses), we
 * have to copy the individual fields to an unstructured area using the correct
 * layout (see SA22-7204-01 "Common I/O-Device Commands").
 */
static void copy_sense_id_to_guest(uint8_t *dest, SenseId *src)
{
    int i;

    dest[0] = src->reserved;
    stw_be_p(dest + 1, src->cu_type);
    dest[3] = src->cu_model;
    stw_be_p(dest + 4, src->dev_type);
    dest[6] = src->dev_model;
    dest[7] = src->unused;
    for (i = 0; i < ARRAY_SIZE(src->ciw); i++) {
        dest[8 + i * 4] = src->ciw[i].type;
        dest[9 + i * 4] = src->ciw[i].command;
        stw_be_p(dest + 10 + i * 4, src->ciw[i].count);
    }
}

static CCW1 copy_ccw_from_guest(hwaddr addr, bool fmt1)
{
    CCW0 tmp0;
    CCW1 tmp1;
    CCW1 ret;

    if (fmt1) {
        cpu_physical_memory_read(addr, &tmp1, sizeof(tmp1));
        ret.cmd_code = tmp1.cmd_code;
        ret.flags = tmp1.flags;
        ret.count = be16_to_cpu(tmp1.count);
        ret.cda = be32_to_cpu(tmp1.cda);
    } else {
        cpu_physical_memory_read(addr, &tmp0, sizeof(tmp0));
        if ((tmp0.cmd_code & 0x0f) == CCW_CMD_TIC) {
            ret.cmd_code = CCW_CMD_TIC;
            ret.flags = 0;
            ret.count = 0;
        } else {
            ret.cmd_code = tmp0.cmd_code;
            ret.flags = tmp0.flags;
            ret.count = be16_to_cpu(tmp0.count);
        }
        ret.cda = be16_to_cpu(tmp0.cda1) | (tmp0.cda0 << 16);
    }
    return ret;
}
/**
 * If out of bounds marks the stream broken. If broken returns -EINVAL,
 * otherwise the requested length (may be zero)
 */
static inline int cds_check_len(CcwDataStream *cds, int len)
{
    if (cds->at_byte + len > cds->count) {
        cds->flags |= CDS_F_STREAM_BROKEN;
    }
    return cds->flags & CDS_F_STREAM_BROKEN ? -EINVAL : len;
}

static inline bool cds_ccw_addrs_ok(hwaddr addr, int len, bool ccw_fmt1)
{
    return (addr + len) < (ccw_fmt1 ? (1UL << 31) : (1UL << 24));
}

static int ccw_dstream_rw_noflags(CcwDataStream *cds, void *buff, int len,
                                  CcwDataStreamOp op)
{
    int ret;

    ret = cds_check_len(cds, len);
    if (ret <= 0) {
        return ret;
    }
    if (!cds_ccw_addrs_ok(cds->cda, len, cds->flags & CDS_F_FMT)) {
        return -EINVAL; /* channel program check */
    }
    if (op == CDS_OP_A) {
        goto incr;
    }
    if (!cds->do_skip) {
        ret = address_space_rw(&address_space_memory, cds->cda,
                               MEMTXATTRS_UNSPECIFIED, buff, len, op);
    } else {
        ret = MEMTX_OK;
    }
    if (ret != MEMTX_OK) {
        cds->flags |= CDS_F_STREAM_BROKEN;
        return -EINVAL;
    }
incr:
    cds->at_byte += len;
    cds->cda += len;
    return 0;
}

/* returns values between 1 and bsz, where bsz is a power of 2 */
static inline uint16_t ida_continuous_left(hwaddr cda, uint64_t bsz)
{
    return bsz - (cda & (bsz - 1));
}

static inline uint64_t ccw_ida_block_size(uint8_t flags)
{
    if ((flags & CDS_F_C64) && !(flags & CDS_F_I2K)) {
        return 1ULL << 12;
    }
    return 1ULL << 11;
}

static inline int ida_read_next_idaw(CcwDataStream *cds)
{
    union {uint64_t fmt2; uint32_t fmt1; } idaw;
    int ret;
    hwaddr idaw_addr;
    bool idaw_fmt2 = cds->flags & CDS_F_C64;
    bool ccw_fmt1 = cds->flags & CDS_F_FMT;

    if (idaw_fmt2) {
        idaw_addr = cds->cda_orig + sizeof(idaw.fmt2) * cds->at_idaw;
        if (idaw_addr & 0x07 || !cds_ccw_addrs_ok(idaw_addr, 0, ccw_fmt1)) {
            return -EINVAL; /* channel program check */
        }
        ret = address_space_read(&address_space_memory, idaw_addr,
                                 MEMTXATTRS_UNSPECIFIED, &idaw.fmt2,
                                 sizeof(idaw.fmt2));
        cds->cda = be64_to_cpu(idaw.fmt2);
    } else {
        idaw_addr = cds->cda_orig + sizeof(idaw.fmt1) * cds->at_idaw;
        if (idaw_addr & 0x03 || !cds_ccw_addrs_ok(idaw_addr, 0, ccw_fmt1)) {
            return -EINVAL; /* channel program check */
        }
        ret = address_space_read(&address_space_memory, idaw_addr,
                                 MEMTXATTRS_UNSPECIFIED, &idaw.fmt1,
                                 sizeof(idaw.fmt1));
        cds->cda = be64_to_cpu(idaw.fmt1);
        if (cds->cda & 0x80000000) {
            return -EINVAL; /* channel program check */
        }
    }
    ++(cds->at_idaw);
    if (ret != MEMTX_OK) {
        /* assume inaccessible address */
        return -EINVAL; /* channel program check */
    }
    return 0;
}

static int ccw_dstream_rw_ida(CcwDataStream *cds, void *buff, int len,
                              CcwDataStreamOp op)
{
    uint64_t bsz = ccw_ida_block_size(cds->flags);
    int ret = 0;
    uint16_t cont_left, iter_len;

    ret = cds_check_len(cds, len);
    if (ret <= 0) {
        return ret;
    }
    if (!cds->at_idaw) {
        /* read first idaw */
        ret = ida_read_next_idaw(cds);
        if (ret) {
            goto err;
        }
        cont_left = ida_continuous_left(cds->cda, bsz);
    } else {
        cont_left = ida_continuous_left(cds->cda, bsz);
        if (cont_left == bsz) {
            ret = ida_read_next_idaw(cds);
            if (ret) {
                goto err;
            }
            if (cds->cda & (bsz - 1)) {
                ret = -EINVAL; /* channel program check */
                goto err;
            }
        }
    }
    do {
        iter_len = MIN(len, cont_left);
        if (op != CDS_OP_A) {
            if (!cds->do_skip) {
                ret = address_space_rw(&address_space_memory, cds->cda,
                                       MEMTXATTRS_UNSPECIFIED, buff, iter_len,
                                       op);
            } else {
                ret = MEMTX_OK;
            }
            if (ret != MEMTX_OK) {
                /* assume inaccessible address */
                ret = -EINVAL; /* channel program check */
                goto err;
            }
        }
        cds->at_byte += iter_len;
        cds->cda += iter_len;
        len -= iter_len;
        if (!len) {
            break;
        }
        ret = ida_read_next_idaw(cds);
        if (ret) {
            goto err;
        }
        cont_left = bsz;
    } while (true);
    return ret;
err:
    cds->flags |= CDS_F_STREAM_BROKEN;
    return ret;
}

void ccw_dstream_init(CcwDataStream *cds, CCW1 const *ccw, ORB const *orb)
{
    /*
     * We don't support MIDA (an optional facility) yet and we
     * catch this earlier. Just for expressing the precondition.
     */
    g_assert(!(orb->ctrl1 & ORB_CTRL1_MASK_MIDAW));
    cds->flags = (orb->ctrl0 & ORB_CTRL0_MASK_I2K ? CDS_F_I2K : 0) |
                 (orb->ctrl0 & ORB_CTRL0_MASK_C64 ? CDS_F_C64 : 0) |
                 (orb->ctrl0 & ORB_CTRL0_MASK_FMT ? CDS_F_FMT : 0) |
                 (ccw->flags & CCW_FLAG_IDA ? CDS_F_IDA : 0);

    cds->count = ccw->count;
    cds->cda_orig = ccw->cda;
    /* skip is only effective for read, read backwards, or sense commands */
    cds->do_skip = (ccw->flags & CCW_FLAG_SKIP) &&
        ((ccw->cmd_code & 0x0f) == CCW_CMD_BASIC_SENSE ||
         (ccw->cmd_code & 0x03) == 0x02 /* read */ ||
         (ccw->cmd_code & 0x0f) == 0x0c /* read backwards */);
    ccw_dstream_rewind(cds);
    if (!(cds->flags & CDS_F_IDA)) {
        cds->op_handler = ccw_dstream_rw_noflags;
    } else {
        cds->op_handler = ccw_dstream_rw_ida;
    }
}

static int css_interpret_ccw(SubchDev *sch, hwaddr ccw_addr,
                             bool suspend_allowed)
{
    int ret;
    bool check_len;
    int len;
    CCW1 ccw;

    if (!ccw_addr) {
        return -EINVAL; /* channel-program check */
    }
    /* Check doubleword aligned and 31 or 24 (fmt 0) bit addressable. */
    if (ccw_addr & (sch->ccw_fmt_1 ? 0x80000007 : 0xff000007)) {
        return -EINVAL;
    }

    /* Translate everything to format-1 ccws - the information is the same. */
    ccw = copy_ccw_from_guest(ccw_addr, sch->ccw_fmt_1);

    /* Check for invalid command codes. */
    if ((ccw.cmd_code & 0x0f) == 0) {
        return -EINVAL;
    }
    if (((ccw.cmd_code & 0x0f) == CCW_CMD_TIC) &&
        ((ccw.cmd_code & 0xf0) != 0)) {
        return -EINVAL;
    }
    if (!sch->ccw_fmt_1 && (ccw.count == 0) &&
        (ccw.cmd_code != CCW_CMD_TIC)) {
        return -EINVAL;
    }

    /* We don't support MIDA. */
    if (ccw.flags & CCW_FLAG_MIDA) {
        return -EINVAL;
    }

    if (ccw.flags & CCW_FLAG_SUSPEND) {
        return suspend_allowed ? -EINPROGRESS : -EINVAL;
    }

    check_len = !((ccw.flags & CCW_FLAG_SLI) && !(ccw.flags & CCW_FLAG_DC));

    if (!ccw.cda) {
        if (sch->ccw_no_data_cnt == 255) {
            return -EINVAL;
        }
        sch->ccw_no_data_cnt++;
    }

    /* Look at the command. */
    ccw_dstream_init(&sch->cds, &ccw, &(sch->orb));
    switch (ccw.cmd_code) {
    case CCW_CMD_NOOP:
        /* Nothing to do. */
        ret = 0;
        break;
    case CCW_CMD_BASIC_SENSE:
        if (check_len) {
            if (ccw.count != sizeof(sch->sense_data)) {
                ret = -EINVAL;
                break;
            }
        }
        len = MIN(ccw.count, sizeof(sch->sense_data));
        ccw_dstream_write_buf(&sch->cds, sch->sense_data, len);
        sch->curr_status.scsw.count = ccw_dstream_residual_count(&sch->cds);
        memset(sch->sense_data, 0, sizeof(sch->sense_data));
        ret = 0;
        break;
    case CCW_CMD_SENSE_ID:
    {
        /* According to SA22-7204-01, Sense-ID can store up to 256 bytes */
        uint8_t sense_id[256];

        copy_sense_id_to_guest(sense_id, &sch->id);
        /* Sense ID information is device specific. */
        if (check_len) {
            if (ccw.count != sizeof(sense_id)) {
                ret = -EINVAL;
                break;
            }
        }
        len = MIN(ccw.count, sizeof(sense_id));
        /*
         * Only indicate 0xff in the first sense byte if we actually
         * have enough place to store at least bytes 0-3.
         */
        if (len >= 4) {
            sense_id[0] = 0xff;
        } else {
            sense_id[0] = 0;
        }
        ccw_dstream_write_buf(&sch->cds, sense_id, len);
        sch->curr_status.scsw.count = ccw_dstream_residual_count(&sch->cds);
        ret = 0;
        break;
    }
    case CCW_CMD_TIC:
        if (sch->last_cmd_valid && (sch->last_cmd.cmd_code == CCW_CMD_TIC)) {
            ret = -EINVAL;
            break;
        }
        if (ccw.flags || ccw.count) {
            /* We have already sanitized these if converted from fmt 0. */
            ret = -EINVAL;
            break;
        }
        sch->channel_prog = ccw.cda;
        ret = -EAGAIN;
        break;
    default:
        if (sch->ccw_cb) {
            /* Handle device specific commands. */
            ret = sch->ccw_cb(sch, ccw);
        } else {
            ret = -ENOSYS;
        }
        break;
    }
    sch->last_cmd = ccw;
    sch->last_cmd_valid = true;
    if (ret == 0) {
        if (ccw.flags & CCW_FLAG_CC) {
            sch->channel_prog += 8;
            ret = -EAGAIN;
        }
    }

    return ret;
}

static void sch_handle_start_func_virtual(SubchDev *sch)
{
    SCHIB *schib = &sch->curr_status;
    int path;
    int ret;
    bool suspend_allowed;

    /* Path management: In our simple css, we always choose the only path. */
    path = 0x80;

    if (!(schib->scsw.ctrl & SCSW_ACTL_SUSP)) {
        /* Start Function triggered via ssch, i.e. we have an ORB */
        ORB *orb = &sch->orb;
        schib->scsw.cstat = 0;
        schib->scsw.dstat = 0;
        /* Look at the orb and try to execute the channel program. */
        schib->pmcw.intparm = orb->intparm;
        if (!(orb->lpm & path)) {
            /* Generate a deferred cc 3 condition. */
            schib->scsw.flags |= SCSW_FLAGS_MASK_CC;
            schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
            schib->scsw.ctrl |= (SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND);
            return;
        }
        sch->ccw_fmt_1 = !!(orb->ctrl0 & ORB_CTRL0_MASK_FMT);
        schib->scsw.flags |= (sch->ccw_fmt_1) ? SCSW_FLAGS_MASK_FMT : 0;
        sch->ccw_no_data_cnt = 0;
        suspend_allowed = !!(orb->ctrl0 & ORB_CTRL0_MASK_SPND);
    } else {
        /* Start Function resumed via rsch */
        schib->scsw.ctrl &= ~(SCSW_ACTL_SUSP | SCSW_ACTL_RESUME_PEND);
        /* The channel program had been suspended before. */
        suspend_allowed = true;
    }
    sch->last_cmd_valid = false;
    do {
        ret = css_interpret_ccw(sch, sch->channel_prog, suspend_allowed);
        switch (ret) {
        case -EAGAIN:
            /* ccw chain, continue processing */
            break;
        case 0:
            /* success */
            schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
            schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
            schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
                    SCSW_STCTL_STATUS_PEND;
            schib->scsw.dstat = SCSW_DSTAT_CHANNEL_END | SCSW_DSTAT_DEVICE_END;
            schib->scsw.cpa = sch->channel_prog + 8;
            break;
        case -EIO:
            /* I/O errors, status depends on specific devices */
            break;
        case -ENOSYS:
            /* unsupported command, generate unit check (command reject) */
            schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
            schib->scsw.dstat = SCSW_DSTAT_UNIT_CHECK;
            /* Set sense bit 0 in ecw0. */
            sch->sense_data[0] = 0x80;
            schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
            schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
                    SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
            schib->scsw.cpa = sch->channel_prog + 8;
            break;
        case -EINPROGRESS:
            /* channel program has been suspended */
            schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
            schib->scsw.ctrl |= SCSW_ACTL_SUSP;
            break;
        default:
            /* error, generate channel program check */
            schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
            schib->scsw.cstat = SCSW_CSTAT_PROG_CHECK;
            schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
            schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
                    SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
            schib->scsw.cpa = sch->channel_prog + 8;
            break;
        }
    } while (ret == -EAGAIN);

}

static void sch_handle_halt_func_passthrough(SubchDev *sch)
{
    int ret;

    ret = s390_ccw_halt(sch);
    if (ret == -ENOSYS) {
        sch_handle_halt_func(sch);
    }
}

static void sch_handle_clear_func_passthrough(SubchDev *sch)
{
    int ret;

    ret = s390_ccw_clear(sch);
    if (ret == -ENOSYS) {
        sch_handle_clear_func(sch);
    }
}

static IOInstEnding sch_handle_start_func_passthrough(SubchDev *sch)
{
    SCHIB *schib = &sch->curr_status;
    ORB *orb = &sch->orb;
    if (!(schib->scsw.ctrl & SCSW_ACTL_SUSP)) {
        assert(orb != NULL);
        schib->pmcw.intparm = orb->intparm;
    }
    return s390_ccw_cmd_request(sch);
}

/*
 * On real machines, this would run asynchronously to the main vcpus.
 * We might want to make some parts of the ssch handling (interpreting
 * read/writes) asynchronous later on if we start supporting more than
 * our current very simple devices.
 */
IOInstEnding do_subchannel_work_virtual(SubchDev *sch)
{
    SCHIB *schib = &sch->curr_status;

    if (schib->scsw.ctrl & SCSW_FCTL_CLEAR_FUNC) {
        sch_handle_clear_func(sch);
    } else if (schib->scsw.ctrl & SCSW_FCTL_HALT_FUNC) {
        sch_handle_halt_func(sch);
    } else if (schib->scsw.ctrl & SCSW_FCTL_START_FUNC) {
        /* Triggered by both ssch and rsch. */
        sch_handle_start_func_virtual(sch);
    }
    css_inject_io_interrupt(sch);
    /* inst must succeed if this func is called */
    return IOINST_CC_EXPECTED;
}

IOInstEnding do_subchannel_work_passthrough(SubchDev *sch)
{
    SCHIB *schib = &sch->curr_status;

    if (schib->scsw.ctrl & SCSW_FCTL_CLEAR_FUNC) {
        sch_handle_clear_func_passthrough(sch);
    } else if (schib->scsw.ctrl & SCSW_FCTL_HALT_FUNC) {
        sch_handle_halt_func_passthrough(sch);
    } else if (schib->scsw.ctrl & SCSW_FCTL_START_FUNC) {
        return sch_handle_start_func_passthrough(sch);
    }
    return IOINST_CC_EXPECTED;
}

static IOInstEnding do_subchannel_work(SubchDev *sch)
{
    if (!sch->do_subchannel_work) {
        return IOINST_CC_STATUS_PRESENT;
    }
    g_assert(sch->curr_status.scsw.ctrl & SCSW_CTRL_MASK_FCTL);
    return sch->do_subchannel_work(sch);
}

static void copy_pmcw_to_guest(PMCW *dest, const PMCW *src)
{
    int i;

    dest->intparm = cpu_to_be32(src->intparm);
    dest->flags = cpu_to_be16(src->flags);
    dest->devno = cpu_to_be16(src->devno);
    dest->lpm = src->lpm;
    dest->pnom = src->pnom;
    dest->lpum = src->lpum;
    dest->pim = src->pim;
    dest->mbi = cpu_to_be16(src->mbi);
    dest->pom = src->pom;
    dest->pam = src->pam;
    for (i = 0; i < ARRAY_SIZE(dest->chpid); i++) {
        dest->chpid[i] = src->chpid[i];
    }
    dest->chars = cpu_to_be32(src->chars);
}

void copy_scsw_to_guest(SCSW *dest, const SCSW *src)
{
    dest->flags = cpu_to_be16(src->flags);
    dest->ctrl = cpu_to_be16(src->ctrl);
    dest->cpa = cpu_to_be32(src->cpa);
    dest->dstat = src->dstat;
    dest->cstat = src->cstat;
    dest->count = cpu_to_be16(src->count);
}

static void copy_schib_to_guest(SCHIB *dest, const SCHIB *src)
{
    int i;
    /*
     * We copy the PMCW and SCSW in and out of local variables to
     * avoid taking the address of members of a packed struct.
     */
    PMCW src_pmcw, dest_pmcw;
    SCSW src_scsw, dest_scsw;

    src_pmcw = src->pmcw;
    copy_pmcw_to_guest(&dest_pmcw, &src_pmcw);
    dest->pmcw = dest_pmcw;
    src_scsw = src->scsw;
    copy_scsw_to_guest(&dest_scsw, &src_scsw);
    dest->scsw = dest_scsw;
    dest->mba = cpu_to_be64(src->mba);
    for (i = 0; i < ARRAY_SIZE(dest->mda); i++) {
        dest->mda[i] = src->mda[i];
    }
}

IOInstEnding css_do_stsch(SubchDev *sch, SCHIB *schib)
{
    int ret;

    /*
     * For some subchannels, we may want to update parts of
     * the schib (e.g., update path masks from the host device
     * for passthrough subchannels).
     */
    ret = s390_ccw_store(sch);

    /* Use current status. */
    copy_schib_to_guest(schib, &sch->curr_status);
    return ret;
}

static void copy_pmcw_from_guest(PMCW *dest, const PMCW *src)
{
    int i;

    dest->intparm = be32_to_cpu(src->intparm);
    dest->flags = be16_to_cpu(src->flags);
    dest->devno = be16_to_cpu(src->devno);
    dest->lpm = src->lpm;
    dest->pnom = src->pnom;
    dest->lpum = src->lpum;
    dest->pim = src->pim;
    dest->mbi = be16_to_cpu(src->mbi);
    dest->pom = src->pom;
    dest->pam = src->pam;
    for (i = 0; i < ARRAY_SIZE(dest->chpid); i++) {
        dest->chpid[i] = src->chpid[i];
    }
    dest->chars = be32_to_cpu(src->chars);
}

static void copy_scsw_from_guest(SCSW *dest, const SCSW *src)
{
    dest->flags = be16_to_cpu(src->flags);
    dest->ctrl = be16_to_cpu(src->ctrl);
    dest->cpa = be32_to_cpu(src->cpa);
    dest->dstat = src->dstat;
    dest->cstat = src->cstat;
    dest->count = be16_to_cpu(src->count);
}

static void copy_schib_from_guest(SCHIB *dest, const SCHIB *src)
{
    int i;
    /*
     * We copy the PMCW and SCSW in and out of local variables to
     * avoid taking the address of members of a packed struct.
     */
    PMCW src_pmcw, dest_pmcw;
    SCSW src_scsw, dest_scsw;

    src_pmcw = src->pmcw;
    copy_pmcw_from_guest(&dest_pmcw, &src_pmcw);
    dest->pmcw = dest_pmcw;
    src_scsw = src->scsw;
    copy_scsw_from_guest(&dest_scsw, &src_scsw);
    dest->scsw = dest_scsw;
    dest->mba = be64_to_cpu(src->mba);
    for (i = 0; i < ARRAY_SIZE(dest->mda); i++) {
        dest->mda[i] = src->mda[i];
    }
}

IOInstEnding css_do_msch(SubchDev *sch, const SCHIB *orig_schib)
{
    SCHIB *schib = &sch->curr_status;
    uint16_t oldflags;
    SCHIB schib_copy;

    if (!(schib->pmcw.flags & PMCW_FLAGS_MASK_DNV)) {
        return IOINST_CC_EXPECTED;
    }

    if (schib->scsw.ctrl & SCSW_STCTL_STATUS_PEND) {
        return IOINST_CC_STATUS_PRESENT;
    }

    if (schib->scsw.ctrl &
        (SCSW_FCTL_START_FUNC|SCSW_FCTL_HALT_FUNC|SCSW_FCTL_CLEAR_FUNC)) {
        return IOINST_CC_BUSY;
    }

    copy_schib_from_guest(&schib_copy, orig_schib);
    /* Only update the program-modifiable fields. */
    schib->pmcw.intparm = schib_copy.pmcw.intparm;
    oldflags = schib->pmcw.flags;
    schib->pmcw.flags &= ~(PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA |
                  PMCW_FLAGS_MASK_LM | PMCW_FLAGS_MASK_MME |
                  PMCW_FLAGS_MASK_MP);
    schib->pmcw.flags |= schib_copy.pmcw.flags &
            (PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA |
             PMCW_FLAGS_MASK_LM | PMCW_FLAGS_MASK_MME |
             PMCW_FLAGS_MASK_MP);
    schib->pmcw.lpm = schib_copy.pmcw.lpm;
    schib->pmcw.mbi = schib_copy.pmcw.mbi;
    schib->pmcw.pom = schib_copy.pmcw.pom;
    schib->pmcw.chars &= ~(PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_CSENSE);
    schib->pmcw.chars |= schib_copy.pmcw.chars &
            (PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_CSENSE);
    schib->mba = schib_copy.mba;

    /* Has the channel been disabled? */
    if (sch->disable_cb && (oldflags & PMCW_FLAGS_MASK_ENA) != 0
        && (schib->pmcw.flags & PMCW_FLAGS_MASK_ENA) == 0) {
        sch->disable_cb(sch);
    }
    return IOINST_CC_EXPECTED;
}

IOInstEnding css_do_xsch(SubchDev *sch)
{
    SCHIB *schib = &sch->curr_status;

    if (~(schib->pmcw.flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
        return IOINST_CC_NOT_OPERATIONAL;
    }

    if (schib->scsw.ctrl & SCSW_CTRL_MASK_STCTL) {
        return IOINST_CC_STATUS_PRESENT;
    }

    if (!(schib->scsw.ctrl & SCSW_CTRL_MASK_FCTL) ||
        ((schib->scsw.ctrl & SCSW_CTRL_MASK_FCTL) != SCSW_FCTL_START_FUNC) ||
        (!(schib->scsw.ctrl &
           (SCSW_ACTL_RESUME_PEND | SCSW_ACTL_START_PEND | SCSW_ACTL_SUSP))) ||
        (schib->scsw.ctrl & SCSW_ACTL_SUBCH_ACTIVE)) {
        return IOINST_CC_BUSY;
    }

    /* Cancel the current operation. */
    schib->scsw.ctrl &= ~(SCSW_FCTL_START_FUNC |
                 SCSW_ACTL_RESUME_PEND |
                 SCSW_ACTL_START_PEND |
                 SCSW_ACTL_SUSP);
    sch->channel_prog = 0x0;
    sch->last_cmd_valid = false;
    schib->scsw.dstat = 0;
    schib->scsw.cstat = 0;
    return IOINST_CC_EXPECTED;
}

IOInstEnding css_do_csch(SubchDev *sch)
{
    SCHIB *schib = &sch->curr_status;

    if (~(schib->pmcw.flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
        return IOINST_CC_NOT_OPERATIONAL;
    }

    /* Trigger the clear function. */
    schib->scsw.ctrl &= ~(SCSW_CTRL_MASK_FCTL | SCSW_CTRL_MASK_ACTL);
    schib->scsw.ctrl |= SCSW_FCTL_CLEAR_FUNC | SCSW_ACTL_CLEAR_PEND;

    return do_subchannel_work(sch);
}

IOInstEnding css_do_hsch(SubchDev *sch)
{
    SCHIB *schib = &sch->curr_status;

    if (~(schib->pmcw.flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
        return IOINST_CC_NOT_OPERATIONAL;
    }

    if (((schib->scsw.ctrl & SCSW_CTRL_MASK_STCTL) == SCSW_STCTL_STATUS_PEND) ||
        (schib->scsw.ctrl & (SCSW_STCTL_PRIMARY |
                    SCSW_STCTL_SECONDARY |
                    SCSW_STCTL_ALERT))) {
        return IOINST_CC_STATUS_PRESENT;
    }

    if (schib->scsw.ctrl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
        return IOINST_CC_BUSY;
    }

    /* Trigger the halt function. */
    schib->scsw.ctrl |= SCSW_FCTL_HALT_FUNC;
    schib->scsw.ctrl &= ~SCSW_FCTL_START_FUNC;
    if (((schib->scsw.ctrl & SCSW_CTRL_MASK_ACTL) ==
         (SCSW_ACTL_SUBCH_ACTIVE | SCSW_ACTL_DEVICE_ACTIVE)) &&
        ((schib->scsw.ctrl & SCSW_CTRL_MASK_STCTL) ==
         SCSW_STCTL_INTERMEDIATE)) {
        schib->scsw.ctrl &= ~SCSW_STCTL_STATUS_PEND;
    }
    schib->scsw.ctrl |= SCSW_ACTL_HALT_PEND;

    return do_subchannel_work(sch);
}

static void css_update_chnmon(SubchDev *sch)
{
    if (!(sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_MME)) {
        /* Not active. */
        return;
    }
    /* The counter is conveniently located at the beginning of the struct. */
    if (sch->curr_status.pmcw.chars & PMCW_CHARS_MASK_MBFC) {
        /* Format 1, per-subchannel area. */
        uint32_t count;

        count = address_space_ldl(&address_space_memory,
                                  sch->curr_status.mba,
                                  MEMTXATTRS_UNSPECIFIED,
                                  NULL);
        count++;
        address_space_stl(&address_space_memory, sch->curr_status.mba, count,
                          MEMTXATTRS_UNSPECIFIED, NULL);
    } else {
        /* Format 0, global area. */
        uint32_t offset;
        uint16_t count;

        offset = sch->curr_status.pmcw.mbi << 5;
        count = address_space_lduw(&address_space_memory,
                                   channel_subsys.chnmon_area + offset,
                                   MEMTXATTRS_UNSPECIFIED,
                                   NULL);
        count++;
        address_space_stw(&address_space_memory,
                          channel_subsys.chnmon_area + offset, count,
                          MEMTXATTRS_UNSPECIFIED, NULL);
    }
}

IOInstEnding css_do_ssch(SubchDev *sch, ORB *orb)
{
    SCHIB *schib = &sch->curr_status;

    if (~(schib->pmcw.flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
        return IOINST_CC_NOT_OPERATIONAL;
    }

    if (schib->scsw.ctrl & SCSW_STCTL_STATUS_PEND) {
        return IOINST_CC_STATUS_PRESENT;
    }

    if (schib->scsw.ctrl & (SCSW_FCTL_START_FUNC |
                   SCSW_FCTL_HALT_FUNC |
                   SCSW_FCTL_CLEAR_FUNC)) {
        return IOINST_CC_BUSY;
    }

    /* If monitoring is active, update counter. */
    if (channel_subsys.chnmon_active) {
        css_update_chnmon(sch);
    }
    sch->orb = *orb;
    sch->channel_prog = orb->cpa;
    /* Trigger the start function. */
    schib->scsw.ctrl |= (SCSW_FCTL_START_FUNC | SCSW_ACTL_START_PEND);
    schib->scsw.flags &= ~SCSW_FLAGS_MASK_PNO;

    return do_subchannel_work(sch);
}

static void copy_irb_to_guest(IRB *dest, const IRB *src, const PMCW *pmcw,
                              int *irb_len)
{
    int i;
    uint16_t stctl = src->scsw.ctrl & SCSW_CTRL_MASK_STCTL;
    uint16_t actl = src->scsw.ctrl & SCSW_CTRL_MASK_ACTL;

    copy_scsw_to_guest(&dest->scsw, &src->scsw);

    for (i = 0; i < ARRAY_SIZE(dest->esw); i++) {
        dest->esw[i] = cpu_to_be32(src->esw[i]);
    }
    for (i = 0; i < ARRAY_SIZE(dest->ecw); i++) {
        dest->ecw[i] = cpu_to_be32(src->ecw[i]);
    }
    *irb_len = sizeof(*dest) - sizeof(dest->emw);

    /* extended measurements enabled? */
    if ((src->scsw.flags & SCSW_FLAGS_MASK_ESWF) ||
        !(pmcw->flags & PMCW_FLAGS_MASK_TF) ||
        !(pmcw->chars & PMCW_CHARS_MASK_XMWME)) {
        return;
    }
    /* extended measurements pending? */
    if (!(stctl & SCSW_STCTL_STATUS_PEND)) {
        return;
    }
    if ((stctl & SCSW_STCTL_PRIMARY) ||
        (stctl == SCSW_STCTL_SECONDARY) ||
        ((stctl & SCSW_STCTL_INTERMEDIATE) && (actl & SCSW_ACTL_SUSP))) {
        for (i = 0; i < ARRAY_SIZE(dest->emw); i++) {
            dest->emw[i] = cpu_to_be32(src->emw[i]);
        }
    }
    *irb_len = sizeof(*dest);
}

int css_do_tsch_get_irb(SubchDev *sch, IRB *target_irb, int *irb_len)
{
    SCHIB *schib = &sch->curr_status;
    PMCW p;
    uint16_t stctl;
    IRB irb;

    if (~(schib->pmcw.flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
        return 3;
    }

    stctl = schib->scsw.ctrl & SCSW_CTRL_MASK_STCTL;

    /* Prepare the irb for the guest. */
    memset(&irb, 0, sizeof(IRB));

    /* Copy scsw from current status. */
    irb.scsw = schib->scsw;
    if (stctl & SCSW_STCTL_STATUS_PEND) {
        if (schib->scsw.cstat & (SCSW_CSTAT_DATA_CHECK |
                        SCSW_CSTAT_CHN_CTRL_CHK |
                        SCSW_CSTAT_INTF_CTRL_CHK)) {
            irb.scsw.flags |= SCSW_FLAGS_MASK_ESWF;
            irb.esw[0] = 0x04804000;
        } else {
            irb.esw[0] = 0x00800000;
        }
        /* If a unit check is pending, copy sense data. */
        if ((schib->scsw.dstat & SCSW_DSTAT_UNIT_CHECK) &&
            (schib->pmcw.chars & PMCW_CHARS_MASK_CSENSE)) {
            int i;

            irb.scsw.flags |= SCSW_FLAGS_MASK_ESWF | SCSW_FLAGS_MASK_ECTL;
            /* Attention: sense_data is already BE! */
            memcpy(irb.ecw, sch->sense_data, sizeof(sch->sense_data));
            for (i = 0; i < ARRAY_SIZE(irb.ecw); i++) {
                irb.ecw[i] = be32_to_cpu(irb.ecw[i]);
            }
            irb.esw[1] = 0x01000000 | (sizeof(sch->sense_data) << 8);
        }
    }
    /* Store the irb to the guest. */
    p = schib->pmcw;
    copy_irb_to_guest(target_irb, &irb, &p, irb_len);

    return ((stctl & SCSW_STCTL_STATUS_PEND) == 0);
}

void css_do_tsch_update_subch(SubchDev *sch)
{
    SCHIB *schib = &sch->curr_status;
    uint16_t stctl;
    uint16_t fctl;
    uint16_t actl;

    stctl = schib->scsw.ctrl & SCSW_CTRL_MASK_STCTL;
    fctl = schib->scsw.ctrl & SCSW_CTRL_MASK_FCTL;
    actl = schib->scsw.ctrl & SCSW_CTRL_MASK_ACTL;

    /* Clear conditions on subchannel, if applicable. */
    if (stctl & SCSW_STCTL_STATUS_PEND) {
        schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
        if ((stctl != (SCSW_STCTL_INTERMEDIATE | SCSW_STCTL_STATUS_PEND)) ||
            ((fctl & SCSW_FCTL_HALT_FUNC) &&
             (actl & SCSW_ACTL_SUSP))) {
            schib->scsw.ctrl &= ~SCSW_CTRL_MASK_FCTL;
        }
        if (stctl != (SCSW_STCTL_INTERMEDIATE | SCSW_STCTL_STATUS_PEND)) {
            schib->scsw.flags &= ~SCSW_FLAGS_MASK_PNO;
            schib->scsw.ctrl &= ~(SCSW_ACTL_RESUME_PEND |
                         SCSW_ACTL_START_PEND |
                         SCSW_ACTL_HALT_PEND |
                         SCSW_ACTL_CLEAR_PEND |
                         SCSW_ACTL_SUSP);
        } else {
            if ((actl & SCSW_ACTL_SUSP) &&
                (fctl & SCSW_FCTL_START_FUNC)) {
                schib->scsw.flags &= ~SCSW_FLAGS_MASK_PNO;
                if (fctl & SCSW_FCTL_HALT_FUNC) {
                    schib->scsw.ctrl &= ~(SCSW_ACTL_RESUME_PEND |
                                 SCSW_ACTL_START_PEND |
                                 SCSW_ACTL_HALT_PEND |
                                 SCSW_ACTL_CLEAR_PEND |
                                 SCSW_ACTL_SUSP);
                } else {
                    schib->scsw.ctrl &= ~SCSW_ACTL_RESUME_PEND;
                }
            }
        }
        /* Clear pending sense data. */
        if (schib->pmcw.chars & PMCW_CHARS_MASK_CSENSE) {
            memset(sch->sense_data, 0 , sizeof(sch->sense_data));
        }
    }
}

static void copy_crw_to_guest(CRW *dest, const CRW *src)
{
    dest->flags = cpu_to_be16(src->flags);
    dest->rsid = cpu_to_be16(src->rsid);
}

int css_do_stcrw(CRW *crw)
{
    CrwContainer *crw_cont;
    int ret;

    crw_cont = QTAILQ_FIRST(&channel_subsys.pending_crws);
    if (crw_cont) {
        QTAILQ_REMOVE(&channel_subsys.pending_crws, crw_cont, sibling);
        copy_crw_to_guest(crw, &crw_cont->crw);
        g_free(crw_cont);
        ret = 0;
    } else {
        /* List was empty, turn crw machine checks on again. */
        memset(crw, 0, sizeof(*crw));
        channel_subsys.do_crw_mchk = true;
        ret = 1;
    }

    return ret;
}

static void copy_crw_from_guest(CRW *dest, const CRW *src)
{
    dest->flags = be16_to_cpu(src->flags);
    dest->rsid = be16_to_cpu(src->rsid);
}

void css_undo_stcrw(CRW *crw)
{
    CrwContainer *crw_cont;

    crw_cont = g_try_new0(CrwContainer, 1);
    if (!crw_cont) {
        channel_subsys.crws_lost = true;
        return;
    }
    copy_crw_from_guest(&crw_cont->crw, crw);

    QTAILQ_INSERT_HEAD(&channel_subsys.pending_crws, crw_cont, sibling);
}

int css_collect_chp_desc(int m, uint8_t cssid, uint8_t f_chpid, uint8_t l_chpid,
                         int rfmt, void *buf)
{
    int i, desc_size;
    uint32_t words[8];
    uint32_t chpid_type_word;
    CssImage *css;

    if (!m && !cssid) {
        css = channel_subsys.css[channel_subsys.default_cssid];
    } else {
        css = channel_subsys.css[cssid];
    }
    if (!css) {
        return 0;
    }
    desc_size = 0;
    for (i = f_chpid; i <= l_chpid; i++) {
        if (css->chpids[i].in_use) {
            chpid_type_word = 0x80000000 | (css->chpids[i].type << 8) | i;
            if (rfmt == 0) {
                words[0] = cpu_to_be32(chpid_type_word);
                words[1] = 0;
                memcpy(buf + desc_size, words, 8);
                desc_size += 8;
            } else if (rfmt == 1) {
                words[0] = cpu_to_be32(chpid_type_word);
                words[1] = 0;
                words[2] = 0;
                words[3] = 0;
                words[4] = 0;
                words[5] = 0;
                words[6] = 0;
                words[7] = 0;
                memcpy(buf + desc_size, words, 32);
                desc_size += 32;
            }
        }
    }
    return desc_size;
}

void css_do_schm(uint8_t mbk, int update, int dct, uint64_t mbo)
{
    /* dct is currently ignored (not really meaningful for our devices) */
    /* TODO: Don't ignore mbk. */
    if (update && !channel_subsys.chnmon_active) {
        /* Enable measuring. */
        channel_subsys.chnmon_area = mbo;
        channel_subsys.chnmon_active = true;
    }
    if (!update && channel_subsys.chnmon_active) {
        /* Disable measuring. */
        channel_subsys.chnmon_area = 0;
        channel_subsys.chnmon_active = false;
    }
}

IOInstEnding css_do_rsch(SubchDev *sch)
{
    SCHIB *schib = &sch->curr_status;

    if (~(schib->pmcw.flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
        return IOINST_CC_NOT_OPERATIONAL;
    }

    if (schib->scsw.ctrl & SCSW_STCTL_STATUS_PEND) {
        return IOINST_CC_STATUS_PRESENT;
    }

    if (((schib->scsw.ctrl & SCSW_CTRL_MASK_FCTL) != SCSW_FCTL_START_FUNC) ||
        (schib->scsw.ctrl & SCSW_ACTL_RESUME_PEND) ||
        (!(schib->scsw.ctrl & SCSW_ACTL_SUSP))) {
        return IOINST_CC_BUSY;
    }

    /* If monitoring is active, update counter. */
    if (channel_subsys.chnmon_active) {
        css_update_chnmon(sch);
    }

    schib->scsw.ctrl |= SCSW_ACTL_RESUME_PEND;
    return do_subchannel_work(sch);
}

int css_do_rchp(uint8_t cssid, uint8_t chpid)
{
    uint8_t real_cssid;

    if (cssid > channel_subsys.max_cssid) {
        return -EINVAL;
    }
    if (channel_subsys.max_cssid == 0) {
        real_cssid = channel_subsys.default_cssid;
    } else {
        real_cssid = cssid;
    }
    if (!channel_subsys.css[real_cssid]) {
        return -EINVAL;
    }

    if (!channel_subsys.css[real_cssid]->chpids[chpid].in_use) {
        return -ENODEV;
    }

    if (!channel_subsys.css[real_cssid]->chpids[chpid].is_virtual) {
        fprintf(stderr,
                "rchp unsupported for non-virtual chpid %x.%02x!\n",
                real_cssid, chpid);
        return -ENODEV;
    }

    /* We don't really use a channel path, so we're done here. */
    css_queue_crw(CRW_RSC_CHP, CRW_ERC_INIT, 1,
                  channel_subsys.max_cssid > 0 ? 1 : 0, chpid);
    if (channel_subsys.max_cssid > 0) {
        css_queue_crw(CRW_RSC_CHP, CRW_ERC_INIT, 1, 0, real_cssid << 8);
    }
    return 0;
}

bool css_schid_final(int m, uint8_t cssid, uint8_t ssid, uint16_t schid)
{
    SubchSet *set;
    uint8_t real_cssid;

    real_cssid = (!m && (cssid == 0)) ? channel_subsys.default_cssid : cssid;
    if (ssid > MAX_SSID ||
        !channel_subsys.css[real_cssid] ||
        !channel_subsys.css[real_cssid]->sch_set[ssid]) {
        return true;
    }
    set = channel_subsys.css[real_cssid]->sch_set[ssid];
    return schid > find_last_bit(set->schids_used,
                                 (MAX_SCHID + 1) / sizeof(unsigned long));
}

unsigned int css_find_free_chpid(uint8_t cssid)
{
    CssImage *css = channel_subsys.css[cssid];
    unsigned int chpid;

    if (!css) {
        return MAX_CHPID + 1;
    }

    for (chpid = 0; chpid <= MAX_CHPID; chpid++) {
        /* skip reserved chpid */
        if (chpid == VIRTIO_CCW_CHPID) {
            continue;
        }
        if (!css->chpids[chpid].in_use) {
            return chpid;
        }
    }
    return MAX_CHPID + 1;
}

static int css_add_chpid(uint8_t cssid, uint8_t chpid, uint8_t type,
                         bool is_virt)
{
    CssImage *css;

    trace_css_chpid_add(cssid, chpid, type);
    css = channel_subsys.css[cssid];
    if (!css) {
        return -EINVAL;
    }
    if (css->chpids[chpid].in_use) {
        return -EEXIST;
    }
    css->chpids[chpid].in_use = 1;
    css->chpids[chpid].type = type;
    css->chpids[chpid].is_virtual = is_virt;

    css_generate_chp_crws(cssid, chpid);

    return 0;
}

void css_sch_build_virtual_schib(SubchDev *sch, uint8_t chpid, uint8_t type)
{
    SCHIB *schib = &sch->curr_status;
    int i;
    CssImage *css = channel_subsys.css[sch->cssid];

    assert(css != NULL);
    memset(&schib->pmcw, 0, sizeof(PMCW));
    schib->pmcw.flags |= PMCW_FLAGS_MASK_DNV;
    schib->pmcw.devno = sch->devno;
    /* single path */
    schib->pmcw.pim = 0x80;
    schib->pmcw.pom = 0xff;
    schib->pmcw.pam = 0x80;
    schib->pmcw.chpid[0] = chpid;
    if (!css->chpids[chpid].in_use) {
        css_add_chpid(sch->cssid, chpid, type, true);
    }

    memset(&schib->scsw, 0, sizeof(SCSW));
    schib->mba = 0;
    for (i = 0; i < ARRAY_SIZE(schib->mda); i++) {
        schib->mda[i] = 0;
    }
}

SubchDev *css_find_subch(uint8_t m, uint8_t cssid, uint8_t ssid, uint16_t schid)
{
    uint8_t real_cssid;

    real_cssid = (!m && (cssid == 0)) ? channel_subsys.default_cssid : cssid;

    if (!channel_subsys.css[real_cssid]) {
        return NULL;
    }

    if (!channel_subsys.css[real_cssid]->sch_set[ssid]) {
        return NULL;
    }

    return channel_subsys.css[real_cssid]->sch_set[ssid]->sch[schid];
}

/**
 * Return free device number in subchannel set.
 *
 * Return index of the first free device number in the subchannel set
 * identified by @p cssid and @p ssid, beginning the search at @p
 * start and wrapping around at MAX_DEVNO. Return a value exceeding
 * MAX_SCHID if there are no free device numbers in the subchannel
 * set.
 */
static uint32_t css_find_free_devno(uint8_t cssid, uint8_t ssid,
                                    uint16_t start)
{
    uint32_t round;

    for (round = 0; round <= MAX_DEVNO; round++) {
        uint16_t devno = (start + round) % MAX_DEVNO;

        if (!css_devno_used(cssid, ssid, devno)) {
            return devno;
        }
    }
    return MAX_DEVNO + 1;
}

/**
 * Return first free subchannel (id) in subchannel set.
 *
 * Return index of the first free subchannel in the subchannel set
 * identified by @p cssid and @p ssid, if there is any. Return a value
 * exceeding MAX_SCHID if there are no free subchannels in the
 * subchannel set.
 */
static uint32_t css_find_free_subch(uint8_t cssid, uint8_t ssid)
{
    uint32_t schid;

    for (schid = 0; schid <= MAX_SCHID; schid++) {
        if (!css_find_subch(1, cssid, ssid, schid)) {
            return schid;
        }
    }
    return MAX_SCHID + 1;
}

/**
 * Return first free subchannel (id) in subchannel set for a device number
 *
 * Verify the device number @p devno is not used yet in the subchannel
 * set identified by @p cssid and @p ssid. Set @p schid to the index
 * of the first free subchannel in the subchannel set, if there is
 * any. Return true if everything succeeded and false otherwise.
 */
static bool css_find_free_subch_for_devno(uint8_t cssid, uint8_t ssid,
                                          uint16_t devno, uint16_t *schid,
                                          Error **errp)
{
    uint32_t free_schid;

    assert(schid);
    if (css_devno_used(cssid, ssid, devno)) {
        error_setg(errp, "Device %x.%x.%04x already exists",
                   cssid, ssid, devno);
        return false;
    }
    free_schid = css_find_free_subch(cssid, ssid);
    if (free_schid > MAX_SCHID) {
        error_setg(errp, "No free subchannel found for %x.%x.%04x",
                   cssid, ssid, devno);
        return false;
    }
    *schid = free_schid;
    return true;
}

/**
 * Return first free subchannel (id) and device number
 *
 * Locate the first free subchannel and first free device number in
 * any of the subchannel sets of the channel subsystem identified by
 * @p cssid. Return false if no free subchannel / device number could
 * be found. Otherwise set @p ssid, @p devno and @p schid to identify
 * the available subchannel and device number and return true.
 *
 * May modify @p ssid, @p devno and / or @p schid even if no free
 * subchannel / device number could be found.
 */
static bool css_find_free_subch_and_devno(uint8_t cssid, uint8_t *ssid,
                                          uint16_t *devno, uint16_t *schid,
                                          Error **errp)
{
    uint32_t free_schid, free_devno;

    assert(ssid && devno && schid);
    for (*ssid = 0; *ssid <= MAX_SSID; (*ssid)++) {
        free_schid = css_find_free_subch(cssid, *ssid);
        if (free_schid > MAX_SCHID) {
            continue;
        }
        free_devno = css_find_free_devno(cssid, *ssid, free_schid);
        if (free_devno > MAX_DEVNO) {
            continue;
        }
        *schid = free_schid;
        *devno = free_devno;
        return true;
    }
    error_setg(errp, "Virtual channel subsystem is full!");
    return false;
}

bool css_subch_visible(SubchDev *sch)
{
    if (sch->ssid > channel_subsys.max_ssid) {
        return false;
    }

    if (sch->cssid != channel_subsys.default_cssid) {
        return (channel_subsys.max_cssid > 0);
    }

    return true;
}

bool css_present(uint8_t cssid)
{
    return (channel_subsys.css[cssid] != NULL);
}

bool css_devno_used(uint8_t cssid, uint8_t ssid, uint16_t devno)
{
    if (!channel_subsys.css[cssid]) {
        return false;
    }
    if (!channel_subsys.css[cssid]->sch_set[ssid]) {
        return false;
    }

    return !!test_bit(devno,
                      channel_subsys.css[cssid]->sch_set[ssid]->devnos_used);
}

void css_subch_assign(uint8_t cssid, uint8_t ssid, uint16_t schid,
                      uint16_t devno, SubchDev *sch)
{
    CssImage *css;
    SubchSet *s_set;

    trace_css_assign_subch(sch ? "assign" : "deassign", cssid, ssid, schid,
                           devno);
    if (!channel_subsys.css[cssid]) {
        fprintf(stderr,
                "Suspicious call to %s (%x.%x.%04x) for non-existing css!\n",
                __func__, cssid, ssid, schid);
        return;
    }
    css = channel_subsys.css[cssid];

    if (!css->sch_set[ssid]) {
        css->sch_set[ssid] = g_new0(SubchSet, 1);
    }
    s_set = css->sch_set[ssid];

    s_set->sch[schid] = sch;
    if (sch) {
        set_bit(schid, s_set->schids_used);
        set_bit(devno, s_set->devnos_used);
    } else {
        clear_bit(schid, s_set->schids_used);
        clear_bit(devno, s_set->devnos_used);
    }
}

void css_crw_add_to_queue(CRW crw)
{
    CrwContainer *crw_cont;

    trace_css_crw((crw.flags & CRW_FLAGS_MASK_RSC) >> 8,
                  crw.flags & CRW_FLAGS_MASK_ERC,
                  crw.rsid,
                  (crw.flags & CRW_FLAGS_MASK_C) ? "(chained)" : "");

    /* TODO: Maybe use a static crw pool? */
    crw_cont = g_try_new0(CrwContainer, 1);
    if (!crw_cont) {
        channel_subsys.crws_lost = true;
        return;
    }

    crw_cont->crw = crw;

    QTAILQ_INSERT_TAIL(&channel_subsys.pending_crws, crw_cont, sibling);

    if (channel_subsys.do_crw_mchk) {
        channel_subsys.do_crw_mchk = false;
        /* Inject crw pending machine check. */
        s390_crw_mchk();
    }
}

void css_queue_crw(uint8_t rsc, uint8_t erc, int solicited,
                   int chain, uint16_t rsid)
{
    CRW crw;

    crw.flags = (rsc << 8) | erc;
    if (solicited) {
        crw.flags |= CRW_FLAGS_MASK_S;
    }
    if (chain) {
        crw.flags |= CRW_FLAGS_MASK_C;
    }
    crw.rsid = rsid;
    if (channel_subsys.crws_lost) {
        crw.flags |= CRW_FLAGS_MASK_R;
        channel_subsys.crws_lost = false;
    }

    css_crw_add_to_queue(crw);
}

void css_generate_sch_crws(uint8_t cssid, uint8_t ssid, uint16_t schid,
                           int hotplugged, int add)
{
    uint8_t guest_cssid;
    bool chain_crw;

    if (add && !hotplugged) {
        return;
    }
    if (channel_subsys.max_cssid == 0) {
        /* Default cssid shows up as 0. */
        guest_cssid = (cssid == channel_subsys.default_cssid) ? 0 : cssid;
    } else {
        /* Show real cssid to the guest. */
        guest_cssid = cssid;
    }
    /*
     * Only notify for higher subchannel sets/channel subsystems if the
     * guest has enabled it.
     */
    if ((ssid > channel_subsys.max_ssid) ||
        (guest_cssid > channel_subsys.max_cssid) ||
        ((channel_subsys.max_cssid == 0) &&
         (cssid != channel_subsys.default_cssid))) {
        return;
    }
    chain_crw = (channel_subsys.max_ssid > 0) ||
            (channel_subsys.max_cssid > 0);
    css_queue_crw(CRW_RSC_SUBCH, CRW_ERC_IPI, 0, chain_crw ? 1 : 0, schid);
    if (chain_crw) {
        css_queue_crw(CRW_RSC_SUBCH, CRW_ERC_IPI, 0, 0,
                      (guest_cssid << 8) | (ssid << 4));
    }
    /* RW_ERC_IPI --> clear pending interrupts */
    css_clear_io_interrupt(css_do_build_subchannel_id(cssid, ssid), schid);
}

void css_generate_chp_crws(uint8_t cssid, uint8_t chpid)
{
    /* TODO */
}

void css_generate_css_crws(uint8_t cssid)
{
    if (!channel_subsys.sei_pending) {
        css_queue_crw(CRW_RSC_CSS, CRW_ERC_EVENT, 0, 0, cssid);
    }
    channel_subsys.sei_pending = true;
}

void css_clear_sei_pending(void)
{
    channel_subsys.sei_pending = false;
}

int css_enable_mcsse(void)
{
    trace_css_enable_facility("mcsse");
    channel_subsys.max_cssid = MAX_CSSID;
    return 0;
}

int css_enable_mss(void)
{
    trace_css_enable_facility("mss");
    channel_subsys.max_ssid = MAX_SSID;
    return 0;
}

void css_reset_sch(SubchDev *sch)
{
    SCHIB *schib = &sch->curr_status;

    if ((schib->pmcw.flags & PMCW_FLAGS_MASK_ENA) != 0 && sch->disable_cb) {
        sch->disable_cb(sch);
    }

    schib->pmcw.intparm = 0;
    schib->pmcw.flags &= ~(PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA |
                  PMCW_FLAGS_MASK_LM | PMCW_FLAGS_MASK_MME |
                  PMCW_FLAGS_MASK_MP | PMCW_FLAGS_MASK_TF);
    schib->pmcw.flags |= PMCW_FLAGS_MASK_DNV;
    schib->pmcw.devno = sch->devno;
    schib->pmcw.pim = 0x80;
    schib->pmcw.lpm = schib->pmcw.pim;
    schib->pmcw.pnom = 0;
    schib->pmcw.lpum = 0;
    schib->pmcw.mbi = 0;
    schib->pmcw.pom = 0xff;
    schib->pmcw.pam = 0x80;
    schib->pmcw.chars &= ~(PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_XMWME |
                  PMCW_CHARS_MASK_CSENSE);

    memset(&schib->scsw, 0, sizeof(schib->scsw));
    schib->mba = 0;

    sch->channel_prog = 0x0;
    sch->last_cmd_valid = false;
    sch->thinint_active = false;
}

void css_reset(void)
{
    CrwContainer *crw_cont;

    /* Clean up monitoring. */
    channel_subsys.chnmon_active = false;
    channel_subsys.chnmon_area = 0;

    /* Clear pending CRWs. */
    while ((crw_cont = QTAILQ_FIRST(&channel_subsys.pending_crws))) {
        QTAILQ_REMOVE(&channel_subsys.pending_crws, crw_cont, sibling);
        g_free(crw_cont);
    }
    channel_subsys.sei_pending = false;
    channel_subsys.do_crw_mchk = true;
    channel_subsys.crws_lost = false;

    /* Reset maximum ids. */
    channel_subsys.max_cssid = 0;
    channel_subsys.max_ssid = 0;
}

static void get_css_devid(Object *obj, Visitor *v, const char *name,
                          void *opaque, Error **errp)
{
    Property *prop = opaque;
    CssDevId *dev_id = object_field_prop_ptr(obj, prop);
    char buffer[] = "xx.x.xxxx";
    char *p = buffer;
    int r;

    if (dev_id->valid) {

        r = snprintf(buffer, sizeof(buffer), "%02x.%1x.%04x", dev_id->cssid,
                     dev_id->ssid, dev_id->devid);
        assert(r == sizeof(buffer) - 1);

        /* drop leading zero */
        if (dev_id->cssid <= 0xf) {
            p++;
        }
    } else {
        snprintf(buffer, sizeof(buffer), "<unset>");
    }

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

/*
 * parse <cssid>.<ssid>.<devid> and assert valid range for cssid/ssid
 */
static void set_css_devid(Object *obj, Visitor *v, const char *name,
                          void *opaque, Error **errp)
{
    Property *prop = opaque;
    CssDevId *dev_id = object_field_prop_ptr(obj, prop);
    char *str;
    int num, n1, n2;
    unsigned int cssid, ssid, devid;

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

    num = sscanf(str, "%2x.%1x%n.%4x%n", &cssid, &ssid, &n1, &devid, &n2);
    if (num != 3 || (n2 - n1) != 5 || strlen(str) != n2) {
        error_set_from_qdev_prop_error(errp, EINVAL, obj, name, str);
        goto out;
    }
    if ((cssid > MAX_CSSID) || (ssid > MAX_SSID)) {
        error_setg(errp, "Invalid cssid or ssid: cssid %x, ssid %x",
                   cssid, ssid);
        goto out;
    }

    dev_id->cssid = cssid;
    dev_id->ssid = ssid;
    dev_id->devid = devid;
    dev_id->valid = true;

out:
    g_free(str);
}

const PropertyInfo css_devid_propinfo = {
    .name = "str",
    .description = "Identifier of an I/O device in the channel "
                   "subsystem, example: fe.1.23ab",
    .get = get_css_devid,
    .set = set_css_devid,
};

const PropertyInfo css_devid_ro_propinfo = {
    .name = "str",
    .description = "Read-only identifier of an I/O device in the channel "
                   "subsystem, example: fe.1.23ab",
    .get = get_css_devid,
};

SubchDev *css_create_sch(CssDevId bus_id, Error **errp)
{
    uint16_t schid = 0;
    SubchDev *sch;

    if (bus_id.valid) {
        if (!channel_subsys.css[bus_id.cssid]) {
            css_create_css_image(bus_id.cssid, false);
        }

        if (!css_find_free_subch_for_devno(bus_id.cssid, bus_id.ssid,
                                           bus_id.devid, &schid, errp)) {
            return NULL;
        }
    } else {
        for (bus_id.cssid = channel_subsys.default_cssid;;) {
            if (!channel_subsys.css[bus_id.cssid]) {
                css_create_css_image(bus_id.cssid, false);
            }

            if   (css_find_free_subch_and_devno(bus_id.cssid, &bus_id.ssid,
                                                &bus_id.devid, &schid,
                                                NULL)) {
                break;
            }
            bus_id.cssid = (bus_id.cssid + 1) % MAX_CSSID;
            if (bus_id.cssid == channel_subsys.default_cssid) {
                error_setg(errp, "Virtual channel subsystem is full!");
                return NULL;
            }
        }
    }

    sch = g_new0(SubchDev, 1);
    sch->cssid = bus_id.cssid;
    sch->ssid = bus_id.ssid;
    sch->devno = bus_id.devid;
    sch->schid = schid;
    css_subch_assign(sch->cssid, sch->ssid, schid, sch->devno, sch);
    return sch;
}

static int css_sch_get_chpids(SubchDev *sch, CssDevId *dev_id)
{
    char *fid_path;
    FILE *fd;
    uint32_t chpid[8];
    int i;
    SCHIB *schib = &sch->curr_status;

    fid_path = g_strdup_printf("/sys/bus/css/devices/%x.%x.%04x/chpids",
                               dev_id->cssid, dev_id->ssid, dev_id->devid);
    fd = fopen(fid_path, "r");
    if (fd == NULL) {
        error_report("%s: open %s failed", __func__, fid_path);
        g_free(fid_path);
        return -EINVAL;
    }

    if (fscanf(fd, "%x %x %x %x %x %x %x %x",
        &chpid[0], &chpid[1], &chpid[2], &chpid[3],
        &chpid[4], &chpid[5], &chpid[6], &chpid[7]) != 8) {
        fclose(fd);
        g_free(fid_path);
        return -EINVAL;
    }

    for (i = 0; i < ARRAY_SIZE(schib->pmcw.chpid); i++) {
        schib->pmcw.chpid[i] = chpid[i];
    }

    fclose(fd);
    g_free(fid_path);

    return 0;
}

static int css_sch_get_path_masks(SubchDev *sch, CssDevId *dev_id)
{
    char *fid_path;
    FILE *fd;
    uint32_t pim, pam, pom;
    SCHIB *schib = &sch->curr_status;

    fid_path = g_strdup_printf("/sys/bus/css/devices/%x.%x.%04x/pimpampom",
                               dev_id->cssid, dev_id->ssid, dev_id->devid);
    fd = fopen(fid_path, "r");
    if (fd == NULL) {
        error_report("%s: open %s failed", __func__, fid_path);
        g_free(fid_path);
        return -EINVAL;
    }

    if (fscanf(fd, "%x %x %x", &pim, &pam, &pom) != 3) {
        fclose(fd);
        g_free(fid_path);
        return -EINVAL;
    }

    schib->pmcw.pim = pim;
    schib->pmcw.pam = pam;
    schib->pmcw.pom = pom;
    fclose(fd);
    g_free(fid_path);

    return 0;
}

static int css_sch_get_chpid_type(uint8_t chpid, uint32_t *type,
                                  CssDevId *dev_id)
{
    char *fid_path;
    FILE *fd;

    fid_path = g_strdup_printf("/sys/devices/css%x/chp0.%02x/type",
                               dev_id->cssid, chpid);
    fd = fopen(fid_path, "r");
    if (fd == NULL) {
        error_report("%s: open %s failed", __func__, fid_path);
        g_free(fid_path);
        return -EINVAL;
    }

    if (fscanf(fd, "%x", type) != 1) {
        fclose(fd);
        g_free(fid_path);
        return -EINVAL;
    }

    fclose(fd);
    g_free(fid_path);

    return 0;
}

/*
 * We currently retrieve the real device information from sysfs to build the
 * guest subchannel information block without considering the migration feature.
 * We need to revisit this problem when we want to add migration support.
 */
int css_sch_build_schib(SubchDev *sch, CssDevId *dev_id)
{
    CssImage *css = channel_subsys.css[sch->cssid];
    SCHIB *schib = &sch->curr_status;
    uint32_t type;
    int i, ret;

    assert(css != NULL);
    memset(&schib->pmcw, 0, sizeof(PMCW));
    schib->pmcw.flags |= PMCW_FLAGS_MASK_DNV;
    /* We are dealing with I/O subchannels only. */
    schib->pmcw.devno = sch->devno;

    /* Grab path mask from sysfs. */
    ret = css_sch_get_path_masks(sch, dev_id);
    if (ret) {
        return ret;
    }

    /* Grab chpids from sysfs. */
    ret = css_sch_get_chpids(sch, dev_id);
    if (ret) {
        return ret;
    }

   /* Build chpid type. */
    for (i = 0; i < ARRAY_SIZE(schib->pmcw.chpid); i++) {
        if (schib->pmcw.chpid[i] && !css->chpids[schib->pmcw.chpid[i]].in_use) {
            ret = css_sch_get_chpid_type(schib->pmcw.chpid[i], &type, dev_id);
            if (ret) {
                return ret;
            }
            css_add_chpid(sch->cssid, schib->pmcw.chpid[i], type, false);
        }
    }

    memset(&schib->scsw, 0, sizeof(SCSW));
    schib->mba = 0;
    for (i = 0; i < ARRAY_SIZE(schib->mda); i++) {
        schib->mda[i] = 0;
    }

    return 0;
}
