/*
 * 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 "hw/qdev.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/s390x/css.h"
#include "trace.h"
#include "hw/s390x/s390_flic.h"
#include "hw/s390x/s390-virtio-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,
    .do_crw_mchk = true,
    .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 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)
{
    PMCW *p = &sch->curr_status.pmcw;
    SCSW *s = &sch->curr_status.scsw;
    int path;

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

    /* Reset values prior to 'issuing the clear signal'. */
    p->lpum = 0;
    p->pom = 0xff;
    s->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;
    s->ctrl &= ~SCSW_ACTL_CLEAR_PEND;
    s->ctrl |= SCSW_STCTL_STATUS_PEND;

    s->dstat = 0;
    s->cstat = 0;
    p->lpum = path;

}

static void sch_handle_halt_func(SubchDev *sch)
{

    PMCW *p = &sch->curr_status.pmcw;
    SCSW *s = &sch->curr_status.scsw;
    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;
    s->ctrl &= ~SCSW_ACTL_HALT_PEND;
    s->ctrl |= SCSW_STCTL_STATUS_PEND;

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

}

static void copy_sense_id_to_guest(SenseId *dest, SenseId *src)
{
    int i;

    dest->reserved = src->reserved;
    dest->cu_type = cpu_to_be16(src->cu_type);
    dest->cu_model = src->cu_model;
    dest->dev_type = cpu_to_be16(src->dev_type);
    dest->dev_model = src->dev_model;
    dest->unused = src->unused;
    for (i = 0; i < ARRAY_SIZE(dest->ciw); i++) {
        dest->ciw[i].type = src->ciw[i].type;
        dest->ciw[i].command = src->ciw[i].command;
        dest->ciw[i].count = cpu_to_be16(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;
    }
    ret = address_space_rw(&address_space_memory, cds->cda,
                           MEMTXATTRS_UNSPECIFIED, buff, len, op);
    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_rw(&address_space_memory, idaw_addr,
                               MEMTXATTRS_UNSPECIFIED, (void *) &idaw.fmt2,
                               sizeof(idaw.fmt2), false);
        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_rw(&address_space_memory, idaw_addr,
                               MEMTXATTRS_UNSPECIFIED, (void *) &idaw.fmt1,
                               sizeof(idaw.fmt1), false);
        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) {
            ret = address_space_rw(&address_space_memory, cds->cda,
                                   MEMTXATTRS_UNSPECIFIED, buff, iter_len, op);
            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;
    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:
    {
        SenseId sense_id;

        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.reserved = 0xff;
        } else {
            sense_id.reserved = 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)
{

    PMCW *p = &sch->curr_status.pmcw;
    SCSW *s = &sch->curr_status.scsw;
    int path;
    int ret;
    bool suspend_allowed;

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

    if (!(s->ctrl & SCSW_ACTL_SUSP)) {
        /* Start Function triggered via ssch, i.e. we have an ORB */
        ORB *orb = &sch->orb;
        s->cstat = 0;
        s->dstat = 0;
        /* Look at the orb and try to execute the channel program. */
        p->intparm = orb->intparm;
        if (!(orb->lpm & path)) {
            /* Generate a deferred cc 3 condition. */
            s->flags |= SCSW_FLAGS_MASK_CC;
            s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
            s->ctrl |= (SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND);
            return;
        }
        sch->ccw_fmt_1 = !!(orb->ctrl0 & ORB_CTRL0_MASK_FMT);
        s->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 */
        s->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 */
            s->ctrl &= ~SCSW_ACTL_START_PEND;
            s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
            s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
                    SCSW_STCTL_STATUS_PEND;
            s->dstat = SCSW_DSTAT_CHANNEL_END | SCSW_DSTAT_DEVICE_END;
            s->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) */
            s->ctrl &= ~SCSW_ACTL_START_PEND;
            s->dstat = SCSW_DSTAT_UNIT_CHECK;
            /* Set sense bit 0 in ecw0. */
            sch->sense_data[0] = 0x80;
            s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
            s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
                    SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
            s->cpa = sch->channel_prog + 8;
            break;
        case -EINPROGRESS:
            /* channel program has been suspended */
            s->ctrl &= ~SCSW_ACTL_START_PEND;
            s->ctrl |= SCSW_ACTL_SUSP;
            break;
        default:
            /* error, generate channel program check */
            s->ctrl &= ~SCSW_ACTL_START_PEND;
            s->cstat = SCSW_CSTAT_PROG_CHECK;
            s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
            s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
                    SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
            s->cpa = sch->channel_prog + 8;
            break;
        }
    } while (ret == -EAGAIN);

}

static IOInstEnding sch_handle_start_func_passthrough(SubchDev *sch)
{

    PMCW *p = &sch->curr_status.pmcw;
    SCSW *s = &sch->curr_status.scsw;

    ORB *orb = &sch->orb;
    if (!(s->ctrl & SCSW_ACTL_SUSP)) {
        assert(orb != NULL);
        p->intparm = orb->intparm;
    }

    /*
     * Only support prefetch enable mode.
     * Only support 64bit addressing idal.
     */
    if (!(orb->ctrl0 & ORB_CTRL0_MASK_PFCH) ||
        !(orb->ctrl0 & ORB_CTRL0_MASK_C64)) {
        warn_report("vfio-ccw requires PFCH and C64 flags set");
        sch_gen_unit_exception(sch);
        css_inject_io_interrupt(sch);
        return IOINST_CC_EXPECTED;
    }
    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)
{

    SCSW *s = &sch->curr_status.scsw;

    if (s->ctrl & SCSW_FCTL_CLEAR_FUNC) {
        sch_handle_clear_func(sch);
    } else if (s->ctrl & SCSW_FCTL_HALT_FUNC) {
        sch_handle_halt_func(sch);
    } else if (s->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)
{
    SCSW *s = &sch->curr_status.scsw;

    if (s->ctrl & SCSW_FCTL_CLEAR_FUNC) {
        /* TODO: Clear handling */
        sch_handle_clear_func(sch);
    } else if (s->ctrl & SCSW_FCTL_HALT_FUNC) {
        /* TODO: Halt handling */
        sch_handle_halt_func(sch);
    } else if (s->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;

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

int css_do_stsch(SubchDev *sch, SCHIB *schib)
{
    /* Use current status. */
    copy_schib_to_guest(schib, &sch->curr_status);
    return 0;
}

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;

    copy_pmcw_from_guest(&dest->pmcw, &src->pmcw);
    copy_scsw_from_guest(&dest->scsw, &src->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)
{
    SCSW *s = &sch->curr_status.scsw;
    PMCW *p = &sch->curr_status.pmcw;
    uint16_t oldflags;
    SCHIB schib;

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

    if (s->ctrl & SCSW_STCTL_STATUS_PEND) {
        return IOINST_CC_STATUS_PRESENT;
    }

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

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

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

IOInstEnding css_do_xsch(SubchDev *sch)
{
    SCSW *s = &sch->curr_status.scsw;
    PMCW *p = &sch->curr_status.pmcw;

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

    if (s->ctrl & SCSW_CTRL_MASK_STCTL) {
        return IOINST_CC_STATUS_PRESENT;
    }

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

    /* Cancel the current operation. */
    s->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;
    s->dstat = 0;
    s->cstat = 0;
    return IOINST_CC_EXPECTED;
}

IOInstEnding css_do_csch(SubchDev *sch)
{
    SCSW *s = &sch->curr_status.scsw;
    PMCW *p = &sch->curr_status.pmcw;

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

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

    return do_subchannel_work(sch);
}

IOInstEnding css_do_hsch(SubchDev *sch)
{
    SCSW *s = &sch->curr_status.scsw;
    PMCW *p = &sch->curr_status.pmcw;

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

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

    if (s->ctrl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
        return IOINST_CC_BUSY;
    }

    /* Trigger the halt function. */
    s->ctrl |= SCSW_FCTL_HALT_FUNC;
    s->ctrl &= ~SCSW_FCTL_START_FUNC;
    if (((s->ctrl & SCSW_CTRL_MASK_ACTL) ==
         (SCSW_ACTL_SUBCH_ACTIVE | SCSW_ACTL_DEVICE_ACTIVE)) &&
        ((s->ctrl & SCSW_CTRL_MASK_STCTL) == SCSW_STCTL_INTERMEDIATE)) {
        s->ctrl &= ~SCSW_STCTL_STATUS_PEND;
    }
    s->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)
{
    SCSW *s = &sch->curr_status.scsw;
    PMCW *p = &sch->curr_status.pmcw;

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

    if (s->ctrl & SCSW_STCTL_STATUS_PEND) {
        return IOINST_CC_STATUS_PRESENT;
    }

    if (s->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. */
    s->ctrl |= (SCSW_FCTL_START_FUNC | SCSW_ACTL_START_PEND);
    s->flags &= ~SCSW_FLAGS_MASK_PNO;

    return do_subchannel_work(sch);
}

static void copy_irb_to_guest(IRB *dest, const IRB *src, 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)
{
    SCSW *s = &sch->curr_status.scsw;
    PMCW *p = &sch->curr_status.pmcw;
    uint16_t stctl;
    IRB irb;

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

    stctl = s->ctrl & SCSW_CTRL_MASK_STCTL;

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

    /* Copy scsw from current status. */
    memcpy(&irb.scsw, s, sizeof(SCSW));
    if (stctl & SCSW_STCTL_STATUS_PEND) {
        if (s->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 ((s->dstat & SCSW_DSTAT_UNIT_CHECK) &&
            (p->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. */
    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)
{
    SCSW *s = &sch->curr_status.scsw;
    PMCW *p = &sch->curr_status.pmcw;
    uint16_t stctl;
    uint16_t fctl;
    uint16_t actl;

    stctl = s->ctrl & SCSW_CTRL_MASK_STCTL;
    fctl = s->ctrl & SCSW_CTRL_MASK_FCTL;
    actl = s->ctrl & SCSW_CTRL_MASK_ACTL;

    /* Clear conditions on subchannel, if applicable. */
    if (stctl & SCSW_STCTL_STATUS_PEND) {
        s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
        if ((stctl != (SCSW_STCTL_INTERMEDIATE | SCSW_STCTL_STATUS_PEND)) ||
            ((fctl & SCSW_FCTL_HALT_FUNC) &&
             (actl & SCSW_ACTL_SUSP))) {
            s->ctrl &= ~SCSW_CTRL_MASK_FCTL;
        }
        if (stctl != (SCSW_STCTL_INTERMEDIATE | SCSW_STCTL_STATUS_PEND)) {
            s->flags &= ~SCSW_FLAGS_MASK_PNO;
            s->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)) {
                s->flags &= ~SCSW_FLAGS_MASK_PNO;
                if (fctl & SCSW_FCTL_HALT_FUNC) {
                    s->ctrl &= ~(SCSW_ACTL_RESUME_PEND |
                                 SCSW_ACTL_START_PEND |
                                 SCSW_ACTL_HALT_PEND |
                                 SCSW_ACTL_CLEAR_PEND |
                                 SCSW_ACTL_SUSP);
                } else {
                    s->ctrl &= ~SCSW_ACTL_RESUME_PEND;
                }
            }
        }
        /* Clear pending sense data. */
        if (p->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)
{
    SCSW *s = &sch->curr_status.scsw;
    PMCW *p = &sch->curr_status.pmcw;

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

    if (s->ctrl & SCSW_STCTL_STATUS_PEND) {
        return IOINST_CC_STATUS_PRESENT;
    }

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

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

    s->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)
{
    PMCW *p = &sch->curr_status.pmcw;
    SCSW *s = &sch->curr_status.scsw;
    int i;
    CssImage *css = channel_subsys.css[sch->cssid];

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

    memset(s, 0, sizeof(SCSW));
    sch->curr_status.mba = 0;
    for (i = 0; i < ARRAY_SIZE(sch->curr_status.mda); i++) {
        sch->curr_status.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_queue_crw(uint8_t rsc, uint8_t erc, int solicited,
                   int chain, uint16_t rsid)
{
    CrwContainer *crw_cont;

    trace_css_crw(rsc, erc, rsid, chain ? "(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.flags = (rsc << 8) | erc;
    if (solicited) {
        crw_cont->crw.flags |= CRW_FLAGS_MASK_S;
    }
    if (chain) {
        crw_cont->crw.flags |= CRW_FLAGS_MASK_C;
    }
    crw_cont->crw.rsid = rsid;
    if (channel_subsys.crws_lost) {
        crw_cont->crw.flags |= CRW_FLAGS_MASK_R;
        channel_subsys.crws_lost = false;
    }

    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_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)
{
    PMCW *p = &sch->curr_status.pmcw;

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

    p->intparm = 0;
    p->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);
    p->flags |= PMCW_FLAGS_MASK_DNV;
    p->devno = sch->devno;
    p->pim = 0x80;
    p->lpm = p->pim;
    p->pnom = 0;
    p->lpum = 0;
    p->mbi = 0;
    p->pom = 0xff;
    p->pam = 0x80;
    p->chars &= ~(PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_XMWME |
                  PMCW_CHARS_MASK_CSENSE);

    memset(&sch->curr_status.scsw, 0, sizeof(sch->curr_status.scsw));
    sch->curr_status.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)
{
    DeviceState *dev = DEVICE(obj);
    Property *prop = opaque;
    CssDevId *dev_id = qdev_get_prop_ptr(dev, 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)
{
    DeviceState *dev = DEVICE(obj);
    Property *prop = opaque;
    CssDevId *dev_id = qdev_get_prop_ptr(dev, prop);
    Error *local_err = NULL;
    char *str;
    int num, n1, n2;
    unsigned int cssid, ssid, devid;

    if (dev->realized) {
        qdev_prop_set_after_realize(dev, name, errp);
        return;
    }

    visit_type_str(v, name, &str, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        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, dev, prop, 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, bool squash_mcss, Error **errp)
{
    uint16_t schid = 0;
    SubchDev *sch;

    if (bus_id.valid) {
        if (squash_mcss) {
            bus_id.cssid = channel_subsys.default_cssid;
        } else 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;
    PMCW *p = &sch->curr_status.pmcw;

    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(p->chpid); i++) {
        p->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;
    PMCW *p = &sch->curr_status.pmcw;

    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;
    }

    p->pim = pim;
    p->pam = pam;
    p->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];
    PMCW *p = &sch->curr_status.pmcw;
    SCSW *s = &sch->curr_status.scsw;
    uint32_t type;
    int i, ret;

    assert(css != NULL);
    memset(p, 0, sizeof(PMCW));
    p->flags |= PMCW_FLAGS_MASK_DNV;
    /* We are dealing with I/O subchannels only. */
    p->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(p->chpid); i++) {
        if (p->chpid[i] && !css->chpids[p->chpid[i]].in_use) {
            ret = css_sch_get_chpid_type(p->chpid[i], &type, dev_id);
            if (ret) {
                return ret;
            }
            css_add_chpid(sch->cssid, p->chpid[i], type, false);
        }
    }

    memset(s, 0, sizeof(SCSW));
    sch->curr_status.mba = 0;
    for (i = 0; i < ARRAY_SIZE(sch->curr_status.mda); i++) {
        sch->curr_status.mda[i] = 0;
    }

    return 0;
}
