qemu/hw/s390x/css.c
<<
>>
Prefs
   1/*
   2 * Channel subsystem base support.
   3 *
   4 * Copyright 2012 IBM Corp.
   5 * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
   6 *
   7 * This work is licensed under the terms of the GNU GPL, version 2 or (at
   8 * your option) any later version. See the COPYING file in the top-level
   9 * directory.
  10 */
  11
  12#include <hw/qdev.h>
  13#include "qemu/bitops.h"
  14#include "exec/address-spaces.h"
  15#include "cpu.h"
  16#include "ioinst.h"
  17#include "css.h"
  18#include "trace.h"
  19#include "hw/s390x/s390_flic.h"
  20
  21typedef struct CrwContainer {
  22    CRW crw;
  23    QTAILQ_ENTRY(CrwContainer) sibling;
  24} CrwContainer;
  25
  26typedef struct ChpInfo {
  27    uint8_t in_use;
  28    uint8_t type;
  29    uint8_t is_virtual;
  30} ChpInfo;
  31
  32typedef struct SubchSet {
  33    SubchDev *sch[MAX_SCHID + 1];
  34    unsigned long schids_used[BITS_TO_LONGS(MAX_SCHID + 1)];
  35    unsigned long devnos_used[BITS_TO_LONGS(MAX_SCHID + 1)];
  36} SubchSet;
  37
  38typedef struct CssImage {
  39    SubchSet *sch_set[MAX_SSID + 1];
  40    ChpInfo chpids[MAX_CHPID + 1];
  41} CssImage;
  42
  43typedef struct IoAdapter {
  44    uint32_t id;
  45    uint8_t type;
  46    uint8_t isc;
  47    QTAILQ_ENTRY(IoAdapter) sibling;
  48} IoAdapter;
  49
  50typedef struct ChannelSubSys {
  51    QTAILQ_HEAD(, CrwContainer) pending_crws;
  52    bool do_crw_mchk;
  53    bool crws_lost;
  54    uint8_t max_cssid;
  55    uint8_t max_ssid;
  56    bool chnmon_active;
  57    uint64_t chnmon_area;
  58    CssImage *css[MAX_CSSID + 1];
  59    uint8_t default_cssid;
  60    QTAILQ_HEAD(, IoAdapter) io_adapters;
  61} ChannelSubSys;
  62
  63static ChannelSubSys *channel_subsys;
  64
  65int css_create_css_image(uint8_t cssid, bool default_image)
  66{
  67    trace_css_new_image(cssid, default_image ? "(default)" : "");
  68    if (cssid > MAX_CSSID) {
  69        return -EINVAL;
  70    }
  71    if (channel_subsys->css[cssid]) {
  72        return -EBUSY;
  73    }
  74    channel_subsys->css[cssid] = g_malloc0(sizeof(CssImage));
  75    if (default_image) {
  76        channel_subsys->default_cssid = cssid;
  77    }
  78    return 0;
  79}
  80
  81int css_register_io_adapter(uint8_t type, uint8_t isc, bool swap,
  82                            bool maskable, uint32_t *id)
  83{
  84    IoAdapter *adapter;
  85    bool found = false;
  86    int ret;
  87    S390FLICState *fs = s390_get_flic();
  88    S390FLICStateClass *fsc = S390_FLIC_COMMON_GET_CLASS(fs);
  89
  90    *id = 0;
  91    QTAILQ_FOREACH(adapter, &channel_subsys->io_adapters, sibling) {
  92        if ((adapter->type == type) && (adapter->isc == isc)) {
  93            *id = adapter->id;
  94            found = true;
  95            ret = 0;
  96            break;
  97        }
  98        if (adapter->id >= *id) {
  99            *id = adapter->id + 1;
 100        }
 101    }
 102    if (found) {
 103        goto out;
 104    }
 105    adapter = g_new0(IoAdapter, 1);
 106    ret = fsc->register_io_adapter(fs, *id, isc, swap, maskable);
 107    if (ret == 0) {
 108        adapter->id = *id;
 109        adapter->isc = isc;
 110        adapter->type = type;
 111        QTAILQ_INSERT_TAIL(&channel_subsys->io_adapters, adapter, sibling);
 112    } else {
 113        g_free(adapter);
 114        fprintf(stderr, "Unexpected error %d when registering adapter %d\n",
 115                ret, *id);
 116    }
 117out:
 118    return ret;
 119}
 120
 121uint16_t css_build_subchannel_id(SubchDev *sch)
 122{
 123    if (channel_subsys->max_cssid > 0) {
 124        return (sch->cssid << 8) | (1 << 3) | (sch->ssid << 1) | 1;
 125    }
 126    return (sch->ssid << 1) | 1;
 127}
 128
 129static void css_inject_io_interrupt(SubchDev *sch)
 130{
 131    uint8_t isc = (sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_ISC) >> 11;
 132
 133    trace_css_io_interrupt(sch->cssid, sch->ssid, sch->schid,
 134                           sch->curr_status.pmcw.intparm, isc, "");
 135    s390_io_interrupt(css_build_subchannel_id(sch),
 136                      sch->schid,
 137                      sch->curr_status.pmcw.intparm,
 138                      isc << 27);
 139}
 140
 141void css_conditional_io_interrupt(SubchDev *sch)
 142{
 143    /*
 144     * If the subchannel is not currently status pending, make it pending
 145     * with alert status.
 146     */
 147    if (!(sch->curr_status.scsw.ctrl & SCSW_STCTL_STATUS_PEND)) {
 148        uint8_t isc = (sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_ISC) >> 11;
 149
 150        trace_css_io_interrupt(sch->cssid, sch->ssid, sch->schid,
 151                               sch->curr_status.pmcw.intparm, isc,
 152                               "(unsolicited)");
 153        sch->curr_status.scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
 154        sch->curr_status.scsw.ctrl |=
 155            SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
 156        /* Inject an I/O interrupt. */
 157        s390_io_interrupt(css_build_subchannel_id(sch),
 158                          sch->schid,
 159                          sch->curr_status.pmcw.intparm,
 160                          isc << 27);
 161    }
 162}
 163
 164void css_adapter_interrupt(uint8_t isc)
 165{
 166    uint32_t io_int_word = (isc << 27) | IO_INT_WORD_AI;
 167
 168    trace_css_adapter_interrupt(isc);
 169    s390_io_interrupt(0, 0, 0, io_int_word);
 170}
 171
 172static void sch_handle_clear_func(SubchDev *sch)
 173{
 174    PMCW *p = &sch->curr_status.pmcw;
 175    SCSW *s = &sch->curr_status.scsw;
 176    int path;
 177
 178    /* Path management: In our simple css, we always choose the only path. */
 179    path = 0x80;
 180
 181    /* Reset values prior to 'issuing the clear signal'. */
 182    p->lpum = 0;
 183    p->pom = 0xff;
 184    s->flags &= ~SCSW_FLAGS_MASK_PNO;
 185
 186    /* We always 'attempt to issue the clear signal', and we always succeed. */
 187    sch->channel_prog = 0x0;
 188    sch->last_cmd_valid = false;
 189    s->ctrl &= ~SCSW_ACTL_CLEAR_PEND;
 190    s->ctrl |= SCSW_STCTL_STATUS_PEND;
 191
 192    s->dstat = 0;
 193    s->cstat = 0;
 194    p->lpum = path;
 195
 196}
 197
 198static void sch_handle_halt_func(SubchDev *sch)
 199{
 200
 201    PMCW *p = &sch->curr_status.pmcw;
 202    SCSW *s = &sch->curr_status.scsw;
 203    hwaddr curr_ccw = sch->channel_prog;
 204    int path;
 205
 206    /* Path management: In our simple css, we always choose the only path. */
 207    path = 0x80;
 208
 209    /* We always 'attempt to issue the halt signal', and we always succeed. */
 210    sch->channel_prog = 0x0;
 211    sch->last_cmd_valid = false;
 212    s->ctrl &= ~SCSW_ACTL_HALT_PEND;
 213    s->ctrl |= SCSW_STCTL_STATUS_PEND;
 214
 215    if ((s->ctrl & (SCSW_ACTL_SUBCH_ACTIVE | SCSW_ACTL_DEVICE_ACTIVE)) ||
 216        !((s->ctrl & SCSW_ACTL_START_PEND) ||
 217          (s->ctrl & SCSW_ACTL_SUSP))) {
 218        s->dstat = SCSW_DSTAT_DEVICE_END;
 219    }
 220    if ((s->ctrl & (SCSW_ACTL_SUBCH_ACTIVE | SCSW_ACTL_DEVICE_ACTIVE)) ||
 221        (s->ctrl & SCSW_ACTL_SUSP)) {
 222        s->cpa = curr_ccw + 8;
 223    }
 224    s->cstat = 0;
 225    p->lpum = path;
 226
 227}
 228
 229static void copy_sense_id_to_guest(SenseId *dest, SenseId *src)
 230{
 231    int i;
 232
 233    dest->reserved = src->reserved;
 234    dest->cu_type = cpu_to_be16(src->cu_type);
 235    dest->cu_model = src->cu_model;
 236    dest->dev_type = cpu_to_be16(src->dev_type);
 237    dest->dev_model = src->dev_model;
 238    dest->unused = src->unused;
 239    for (i = 0; i < ARRAY_SIZE(dest->ciw); i++) {
 240        dest->ciw[i].type = src->ciw[i].type;
 241        dest->ciw[i].command = src->ciw[i].command;
 242        dest->ciw[i].count = cpu_to_be16(src->ciw[i].count);
 243    }
 244}
 245
 246static CCW1 copy_ccw_from_guest(hwaddr addr, bool fmt1)
 247{
 248    CCW0 tmp0;
 249    CCW1 tmp1;
 250    CCW1 ret;
 251
 252    if (fmt1) {
 253        cpu_physical_memory_read(addr, &tmp1, sizeof(tmp1));
 254        ret.cmd_code = tmp1.cmd_code;
 255        ret.flags = tmp1.flags;
 256        ret.count = be16_to_cpu(tmp1.count);
 257        ret.cda = be32_to_cpu(tmp1.cda);
 258    } else {
 259        cpu_physical_memory_read(addr, &tmp0, sizeof(tmp0));
 260        ret.cmd_code = tmp0.cmd_code;
 261        ret.flags = tmp0.flags;
 262        ret.count = be16_to_cpu(tmp0.count);
 263        ret.cda = be16_to_cpu(tmp0.cda1) | (tmp0.cda0 << 16);
 264    }
 265    return ret;
 266}
 267
 268static int css_interpret_ccw(SubchDev *sch, hwaddr ccw_addr)
 269{
 270    int ret;
 271    bool check_len;
 272    int len;
 273    CCW1 ccw;
 274
 275    if (!ccw_addr) {
 276        return -EIO;
 277    }
 278
 279    /* Translate everything to format-1 ccws - the information is the same. */
 280    ccw = copy_ccw_from_guest(ccw_addr, sch->ccw_fmt_1);
 281
 282    /* Check for invalid command codes. */
 283    if ((ccw.cmd_code & 0x0f) == 0) {
 284        return -EINVAL;
 285    }
 286    if (((ccw.cmd_code & 0x0f) == CCW_CMD_TIC) &&
 287        ((ccw.cmd_code & 0xf0) != 0)) {
 288        return -EINVAL;
 289    }
 290
 291    if (ccw.flags & CCW_FLAG_SUSPEND) {
 292        return -EINPROGRESS;
 293    }
 294
 295    check_len = !((ccw.flags & CCW_FLAG_SLI) && !(ccw.flags & CCW_FLAG_DC));
 296
 297    if (!ccw.cda) {
 298        if (sch->ccw_no_data_cnt == 255) {
 299            return -EINVAL;
 300        }
 301        sch->ccw_no_data_cnt++;
 302    }
 303
 304    /* Look at the command. */
 305    switch (ccw.cmd_code) {
 306    case CCW_CMD_NOOP:
 307        /* Nothing to do. */
 308        ret = 0;
 309        break;
 310    case CCW_CMD_BASIC_SENSE:
 311        if (check_len) {
 312            if (ccw.count != sizeof(sch->sense_data)) {
 313                ret = -EINVAL;
 314                break;
 315            }
 316        }
 317        len = MIN(ccw.count, sizeof(sch->sense_data));
 318        cpu_physical_memory_write(ccw.cda, sch->sense_data, len);
 319        sch->curr_status.scsw.count = ccw.count - len;
 320        memset(sch->sense_data, 0, sizeof(sch->sense_data));
 321        ret = 0;
 322        break;
 323    case CCW_CMD_SENSE_ID:
 324    {
 325        SenseId sense_id;
 326
 327        copy_sense_id_to_guest(&sense_id, &sch->id);
 328        /* Sense ID information is device specific. */
 329        if (check_len) {
 330            if (ccw.count != sizeof(sense_id)) {
 331                ret = -EINVAL;
 332                break;
 333            }
 334        }
 335        len = MIN(ccw.count, sizeof(sense_id));
 336        /*
 337         * Only indicate 0xff in the first sense byte if we actually
 338         * have enough place to store at least bytes 0-3.
 339         */
 340        if (len >= 4) {
 341            sense_id.reserved = 0xff;
 342        } else {
 343            sense_id.reserved = 0;
 344        }
 345        cpu_physical_memory_write(ccw.cda, &sense_id, len);
 346        sch->curr_status.scsw.count = ccw.count - len;
 347        ret = 0;
 348        break;
 349    }
 350    case CCW_CMD_TIC:
 351        if (sch->last_cmd_valid && (sch->last_cmd.cmd_code == CCW_CMD_TIC)) {
 352            ret = -EINVAL;
 353            break;
 354        }
 355        if (ccw.flags & (CCW_FLAG_CC | CCW_FLAG_DC)) {
 356            ret = -EINVAL;
 357            break;
 358        }
 359        sch->channel_prog = ccw.cda;
 360        ret = -EAGAIN;
 361        break;
 362    default:
 363        if (sch->ccw_cb) {
 364            /* Handle device specific commands. */
 365            ret = sch->ccw_cb(sch, ccw);
 366        } else {
 367            ret = -ENOSYS;
 368        }
 369        break;
 370    }
 371    sch->last_cmd = ccw;
 372    sch->last_cmd_valid = true;
 373    if (ret == 0) {
 374        if (ccw.flags & CCW_FLAG_CC) {
 375            sch->channel_prog += 8;
 376            ret = -EAGAIN;
 377        }
 378    }
 379
 380    return ret;
 381}
 382
 383static void sch_handle_start_func(SubchDev *sch, ORB *orb)
 384{
 385
 386    PMCW *p = &sch->curr_status.pmcw;
 387    SCSW *s = &sch->curr_status.scsw;
 388    int path;
 389    int ret;
 390
 391    /* Path management: In our simple css, we always choose the only path. */
 392    path = 0x80;
 393
 394    if (!(s->ctrl & SCSW_ACTL_SUSP)) {
 395        /* Look at the orb and try to execute the channel program. */
 396        assert(orb != NULL); /* resume does not pass an orb */
 397        p->intparm = orb->intparm;
 398        if (!(orb->lpm & path)) {
 399            /* Generate a deferred cc 3 condition. */
 400            s->flags |= SCSW_FLAGS_MASK_CC;
 401            s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
 402            s->ctrl |= (SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND);
 403            return;
 404        }
 405        sch->ccw_fmt_1 = !!(orb->ctrl0 & ORB_CTRL0_MASK_FMT);
 406        sch->ccw_no_data_cnt = 0;
 407    } else {
 408        s->ctrl &= ~(SCSW_ACTL_SUSP | SCSW_ACTL_RESUME_PEND);
 409    }
 410    sch->last_cmd_valid = false;
 411    do {
 412        ret = css_interpret_ccw(sch, sch->channel_prog);
 413        switch (ret) {
 414        case -EAGAIN:
 415            /* ccw chain, continue processing */
 416            break;
 417        case 0:
 418            /* success */
 419            s->ctrl &= ~SCSW_ACTL_START_PEND;
 420            s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
 421            s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
 422                    SCSW_STCTL_STATUS_PEND;
 423            s->dstat = SCSW_DSTAT_CHANNEL_END | SCSW_DSTAT_DEVICE_END;
 424            s->cpa = sch->channel_prog + 8;
 425            break;
 426        case -ENOSYS:
 427            /* unsupported command, generate unit check (command reject) */
 428            s->ctrl &= ~SCSW_ACTL_START_PEND;
 429            s->dstat = SCSW_DSTAT_UNIT_CHECK;
 430            /* Set sense bit 0 in ecw0. */
 431            sch->sense_data[0] = 0x80;
 432            s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
 433            s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
 434                    SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
 435            s->cpa = sch->channel_prog + 8;
 436            break;
 437        case -EFAULT:
 438            /* memory problem, generate channel data check */
 439            s->ctrl &= ~SCSW_ACTL_START_PEND;
 440            s->cstat = SCSW_CSTAT_DATA_CHECK;
 441            s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
 442            s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
 443                    SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
 444            s->cpa = sch->channel_prog + 8;
 445            break;
 446        case -EBUSY:
 447            /* subchannel busy, generate deferred cc 1 */
 448            s->flags &= ~SCSW_FLAGS_MASK_CC;
 449            s->flags |= (1 << 8);
 450            s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
 451            s->ctrl |= SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
 452            break;
 453        case -EINPROGRESS:
 454            /* channel program has been suspended */
 455            s->ctrl &= ~SCSW_ACTL_START_PEND;
 456            s->ctrl |= SCSW_ACTL_SUSP;
 457            break;
 458        default:
 459            /* error, generate channel program check */
 460            s->ctrl &= ~SCSW_ACTL_START_PEND;
 461            s->cstat = SCSW_CSTAT_PROG_CHECK;
 462            s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
 463            s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
 464                    SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
 465            s->cpa = sch->channel_prog + 8;
 466            break;
 467        }
 468    } while (ret == -EAGAIN);
 469
 470}
 471
 472/*
 473 * On real machines, this would run asynchronously to the main vcpus.
 474 * We might want to make some parts of the ssch handling (interpreting
 475 * read/writes) asynchronous later on if we start supporting more than
 476 * our current very simple devices.
 477 */
 478static void do_subchannel_work(SubchDev *sch, ORB *orb)
 479{
 480
 481    SCSW *s = &sch->curr_status.scsw;
 482
 483    if (s->ctrl & SCSW_FCTL_CLEAR_FUNC) {
 484        sch_handle_clear_func(sch);
 485    } else if (s->ctrl & SCSW_FCTL_HALT_FUNC) {
 486        sch_handle_halt_func(sch);
 487    } else if (s->ctrl & SCSW_FCTL_START_FUNC) {
 488        sch_handle_start_func(sch, orb);
 489    } else {
 490        /* Cannot happen. */
 491        return;
 492    }
 493    css_inject_io_interrupt(sch);
 494}
 495
 496static void copy_pmcw_to_guest(PMCW *dest, const PMCW *src)
 497{
 498    int i;
 499
 500    dest->intparm = cpu_to_be32(src->intparm);
 501    dest->flags = cpu_to_be16(src->flags);
 502    dest->devno = cpu_to_be16(src->devno);
 503    dest->lpm = src->lpm;
 504    dest->pnom = src->pnom;
 505    dest->lpum = src->lpum;
 506    dest->pim = src->pim;
 507    dest->mbi = cpu_to_be16(src->mbi);
 508    dest->pom = src->pom;
 509    dest->pam = src->pam;
 510    for (i = 0; i < ARRAY_SIZE(dest->chpid); i++) {
 511        dest->chpid[i] = src->chpid[i];
 512    }
 513    dest->chars = cpu_to_be32(src->chars);
 514}
 515
 516static void copy_scsw_to_guest(SCSW *dest, const SCSW *src)
 517{
 518    dest->flags = cpu_to_be16(src->flags);
 519    dest->ctrl = cpu_to_be16(src->ctrl);
 520    dest->cpa = cpu_to_be32(src->cpa);
 521    dest->dstat = src->dstat;
 522    dest->cstat = src->cstat;
 523    dest->count = cpu_to_be16(src->count);
 524}
 525
 526static void copy_schib_to_guest(SCHIB *dest, const SCHIB *src)
 527{
 528    int i;
 529
 530    copy_pmcw_to_guest(&dest->pmcw, &src->pmcw);
 531    copy_scsw_to_guest(&dest->scsw, &src->scsw);
 532    dest->mba = cpu_to_be64(src->mba);
 533    for (i = 0; i < ARRAY_SIZE(dest->mda); i++) {
 534        dest->mda[i] = src->mda[i];
 535    }
 536}
 537
 538int css_do_stsch(SubchDev *sch, SCHIB *schib)
 539{
 540    /* Use current status. */
 541    copy_schib_to_guest(schib, &sch->curr_status);
 542    return 0;
 543}
 544
 545static void copy_pmcw_from_guest(PMCW *dest, const PMCW *src)
 546{
 547    int i;
 548
 549    dest->intparm = be32_to_cpu(src->intparm);
 550    dest->flags = be16_to_cpu(src->flags);
 551    dest->devno = be16_to_cpu(src->devno);
 552    dest->lpm = src->lpm;
 553    dest->pnom = src->pnom;
 554    dest->lpum = src->lpum;
 555    dest->pim = src->pim;
 556    dest->mbi = be16_to_cpu(src->mbi);
 557    dest->pom = src->pom;
 558    dest->pam = src->pam;
 559    for (i = 0; i < ARRAY_SIZE(dest->chpid); i++) {
 560        dest->chpid[i] = src->chpid[i];
 561    }
 562    dest->chars = be32_to_cpu(src->chars);
 563}
 564
 565static void copy_scsw_from_guest(SCSW *dest, const SCSW *src)
 566{
 567    dest->flags = be16_to_cpu(src->flags);
 568    dest->ctrl = be16_to_cpu(src->ctrl);
 569    dest->cpa = be32_to_cpu(src->cpa);
 570    dest->dstat = src->dstat;
 571    dest->cstat = src->cstat;
 572    dest->count = be16_to_cpu(src->count);
 573}
 574
 575static void copy_schib_from_guest(SCHIB *dest, const SCHIB *src)
 576{
 577    int i;
 578
 579    copy_pmcw_from_guest(&dest->pmcw, &src->pmcw);
 580    copy_scsw_from_guest(&dest->scsw, &src->scsw);
 581    dest->mba = be64_to_cpu(src->mba);
 582    for (i = 0; i < ARRAY_SIZE(dest->mda); i++) {
 583        dest->mda[i] = src->mda[i];
 584    }
 585}
 586
 587int css_do_msch(SubchDev *sch, const SCHIB *orig_schib)
 588{
 589    SCSW *s = &sch->curr_status.scsw;
 590    PMCW *p = &sch->curr_status.pmcw;
 591    uint16_t oldflags;
 592    int ret;
 593    SCHIB schib;
 594
 595    if (!(sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_DNV)) {
 596        ret = 0;
 597        goto out;
 598    }
 599
 600    if (s->ctrl & SCSW_STCTL_STATUS_PEND) {
 601        ret = -EINPROGRESS;
 602        goto out;
 603    }
 604
 605    if (s->ctrl &
 606        (SCSW_FCTL_START_FUNC|SCSW_FCTL_HALT_FUNC|SCSW_FCTL_CLEAR_FUNC)) {
 607        ret = -EBUSY;
 608        goto out;
 609    }
 610
 611    copy_schib_from_guest(&schib, orig_schib);
 612    /* Only update the program-modifiable fields. */
 613    p->intparm = schib.pmcw.intparm;
 614    oldflags = p->flags;
 615    p->flags &= ~(PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA |
 616                  PMCW_FLAGS_MASK_LM | PMCW_FLAGS_MASK_MME |
 617                  PMCW_FLAGS_MASK_MP);
 618    p->flags |= schib.pmcw.flags &
 619            (PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA |
 620             PMCW_FLAGS_MASK_LM | PMCW_FLAGS_MASK_MME |
 621             PMCW_FLAGS_MASK_MP);
 622    p->lpm = schib.pmcw.lpm;
 623    p->mbi = schib.pmcw.mbi;
 624    p->pom = schib.pmcw.pom;
 625    p->chars &= ~(PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_CSENSE);
 626    p->chars |= schib.pmcw.chars &
 627            (PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_CSENSE);
 628    sch->curr_status.mba = schib.mba;
 629
 630    /* Has the channel been disabled? */
 631    if (sch->disable_cb && (oldflags & PMCW_FLAGS_MASK_ENA) != 0
 632        && (p->flags & PMCW_FLAGS_MASK_ENA) == 0) {
 633        sch->disable_cb(sch);
 634    }
 635
 636    ret = 0;
 637
 638out:
 639    return ret;
 640}
 641
 642int css_do_xsch(SubchDev *sch)
 643{
 644    SCSW *s = &sch->curr_status.scsw;
 645    PMCW *p = &sch->curr_status.pmcw;
 646    int ret;
 647
 648    if (!(p->flags & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA))) {
 649        ret = -ENODEV;
 650        goto out;
 651    }
 652
 653    if (!(s->ctrl & SCSW_CTRL_MASK_FCTL) ||
 654        ((s->ctrl & SCSW_CTRL_MASK_FCTL) != SCSW_FCTL_START_FUNC) ||
 655        (!(s->ctrl &
 656           (SCSW_ACTL_RESUME_PEND | SCSW_ACTL_START_PEND | SCSW_ACTL_SUSP))) ||
 657        (s->ctrl & SCSW_ACTL_SUBCH_ACTIVE)) {
 658        ret = -EINPROGRESS;
 659        goto out;
 660    }
 661
 662    if (s->ctrl & SCSW_CTRL_MASK_STCTL) {
 663        ret = -EBUSY;
 664        goto out;
 665    }
 666
 667    /* Cancel the current operation. */
 668    s->ctrl &= ~(SCSW_FCTL_START_FUNC |
 669                 SCSW_ACTL_RESUME_PEND |
 670                 SCSW_ACTL_START_PEND |
 671                 SCSW_ACTL_SUSP);
 672    sch->channel_prog = 0x0;
 673    sch->last_cmd_valid = false;
 674    s->dstat = 0;
 675    s->cstat = 0;
 676    ret = 0;
 677
 678out:
 679    return ret;
 680}
 681
 682int css_do_csch(SubchDev *sch)
 683{
 684    SCSW *s = &sch->curr_status.scsw;
 685    PMCW *p = &sch->curr_status.pmcw;
 686    int ret;
 687
 688    if (!(p->flags & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA))) {
 689        ret = -ENODEV;
 690        goto out;
 691    }
 692
 693    /* Trigger the clear function. */
 694    s->ctrl &= ~(SCSW_CTRL_MASK_FCTL | SCSW_CTRL_MASK_ACTL);
 695    s->ctrl |= SCSW_FCTL_CLEAR_FUNC | SCSW_FCTL_CLEAR_FUNC;
 696
 697    do_subchannel_work(sch, NULL);
 698    ret = 0;
 699
 700out:
 701    return ret;
 702}
 703
 704int css_do_hsch(SubchDev *sch)
 705{
 706    SCSW *s = &sch->curr_status.scsw;
 707    PMCW *p = &sch->curr_status.pmcw;
 708    int ret;
 709
 710    if (!(p->flags & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA))) {
 711        ret = -ENODEV;
 712        goto out;
 713    }
 714
 715    if (((s->ctrl & SCSW_CTRL_MASK_STCTL) == SCSW_STCTL_STATUS_PEND) ||
 716        (s->ctrl & (SCSW_STCTL_PRIMARY |
 717                    SCSW_STCTL_SECONDARY |
 718                    SCSW_STCTL_ALERT))) {
 719        ret = -EINPROGRESS;
 720        goto out;
 721    }
 722
 723    if (s->ctrl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
 724        ret = -EBUSY;
 725        goto out;
 726    }
 727
 728    /* Trigger the halt function. */
 729    s->ctrl |= SCSW_FCTL_HALT_FUNC;
 730    s->ctrl &= ~SCSW_FCTL_START_FUNC;
 731    if (((s->ctrl & SCSW_CTRL_MASK_ACTL) ==
 732         (SCSW_ACTL_SUBCH_ACTIVE | SCSW_ACTL_DEVICE_ACTIVE)) &&
 733        ((s->ctrl & SCSW_CTRL_MASK_STCTL) == SCSW_STCTL_INTERMEDIATE)) {
 734        s->ctrl &= ~SCSW_STCTL_STATUS_PEND;
 735    }
 736    s->ctrl |= SCSW_ACTL_HALT_PEND;
 737
 738    do_subchannel_work(sch, NULL);
 739    ret = 0;
 740
 741out:
 742    return ret;
 743}
 744
 745static void css_update_chnmon(SubchDev *sch)
 746{
 747    if (!(sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_MME)) {
 748        /* Not active. */
 749        return;
 750    }
 751    /* The counter is conveniently located at the beginning of the struct. */
 752    if (sch->curr_status.pmcw.chars & PMCW_CHARS_MASK_MBFC) {
 753        /* Format 1, per-subchannel area. */
 754        uint32_t count;
 755
 756        count = address_space_ldl(&address_space_memory,
 757                                  sch->curr_status.mba,
 758                                  MEMTXATTRS_UNSPECIFIED,
 759                                  NULL);
 760        count++;
 761        address_space_stl(&address_space_memory, sch->curr_status.mba, count,
 762                          MEMTXATTRS_UNSPECIFIED, NULL);
 763    } else {
 764        /* Format 0, global area. */
 765        uint32_t offset;
 766        uint16_t count;
 767
 768        offset = sch->curr_status.pmcw.mbi << 5;
 769        count = address_space_lduw(&address_space_memory,
 770                                   channel_subsys->chnmon_area + offset,
 771                                   MEMTXATTRS_UNSPECIFIED,
 772                                   NULL);
 773        count++;
 774        address_space_stw(&address_space_memory,
 775                          channel_subsys->chnmon_area + offset, count,
 776                          MEMTXATTRS_UNSPECIFIED, NULL);
 777    }
 778}
 779
 780int css_do_ssch(SubchDev *sch, ORB *orb)
 781{
 782    SCSW *s = &sch->curr_status.scsw;
 783    PMCW *p = &sch->curr_status.pmcw;
 784    int ret;
 785
 786    if (!(p->flags & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA))) {
 787        ret = -ENODEV;
 788        goto out;
 789    }
 790
 791    if (s->ctrl & SCSW_STCTL_STATUS_PEND) {
 792        ret = -EINPROGRESS;
 793        goto out;
 794    }
 795
 796    if (s->ctrl & (SCSW_FCTL_START_FUNC |
 797                   SCSW_FCTL_HALT_FUNC |
 798                   SCSW_FCTL_CLEAR_FUNC)) {
 799        ret = -EBUSY;
 800        goto out;
 801    }
 802
 803    /* If monitoring is active, update counter. */
 804    if (channel_subsys->chnmon_active) {
 805        css_update_chnmon(sch);
 806    }
 807    sch->channel_prog = orb->cpa;
 808    /* Trigger the start function. */
 809    s->ctrl |= (SCSW_FCTL_START_FUNC | SCSW_ACTL_START_PEND);
 810    s->flags &= ~SCSW_FLAGS_MASK_PNO;
 811
 812    do_subchannel_work(sch, orb);
 813    ret = 0;
 814
 815out:
 816    return ret;
 817}
 818
 819static void copy_irb_to_guest(IRB *dest, const IRB *src, PMCW *pmcw,
 820                              int *irb_len)
 821{
 822    int i;
 823    uint16_t stctl = src->scsw.ctrl & SCSW_CTRL_MASK_STCTL;
 824    uint16_t actl = src->scsw.ctrl & SCSW_CTRL_MASK_ACTL;
 825
 826    copy_scsw_to_guest(&dest->scsw, &src->scsw);
 827
 828    for (i = 0; i < ARRAY_SIZE(dest->esw); i++) {
 829        dest->esw[i] = cpu_to_be32(src->esw[i]);
 830    }
 831    for (i = 0; i < ARRAY_SIZE(dest->ecw); i++) {
 832        dest->ecw[i] = cpu_to_be32(src->ecw[i]);
 833    }
 834    *irb_len = sizeof(*dest) - sizeof(dest->emw);
 835
 836    /* extended measurements enabled? */
 837    if ((src->scsw.flags & SCSW_FLAGS_MASK_ESWF) ||
 838        !(pmcw->flags & PMCW_FLAGS_MASK_TF) ||
 839        !(pmcw->chars & PMCW_CHARS_MASK_XMWME)) {
 840        return;
 841    }
 842    /* extended measurements pending? */
 843    if (!(stctl & SCSW_STCTL_STATUS_PEND)) {
 844        return;
 845    }
 846    if ((stctl & SCSW_STCTL_PRIMARY) ||
 847        (stctl == SCSW_STCTL_SECONDARY) ||
 848        ((stctl & SCSW_STCTL_INTERMEDIATE) && (actl & SCSW_ACTL_SUSP))) {
 849        for (i = 0; i < ARRAY_SIZE(dest->emw); i++) {
 850            dest->emw[i] = cpu_to_be32(src->emw[i]);
 851        }
 852    }
 853    *irb_len = sizeof(*dest);
 854}
 855
 856int css_do_tsch_get_irb(SubchDev *sch, IRB *target_irb, int *irb_len)
 857{
 858    SCSW *s = &sch->curr_status.scsw;
 859    PMCW *p = &sch->curr_status.pmcw;
 860    uint16_t stctl;
 861    IRB irb;
 862
 863    if (!(p->flags & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA))) {
 864        return 3;
 865    }
 866
 867    stctl = s->ctrl & SCSW_CTRL_MASK_STCTL;
 868
 869    /* Prepare the irb for the guest. */
 870    memset(&irb, 0, sizeof(IRB));
 871
 872    /* Copy scsw from current status. */
 873    memcpy(&irb.scsw, s, sizeof(SCSW));
 874    if (stctl & SCSW_STCTL_STATUS_PEND) {
 875        if (s->cstat & (SCSW_CSTAT_DATA_CHECK |
 876                        SCSW_CSTAT_CHN_CTRL_CHK |
 877                        SCSW_CSTAT_INTF_CTRL_CHK)) {
 878            irb.scsw.flags |= SCSW_FLAGS_MASK_ESWF;
 879            irb.esw[0] = 0x04804000;
 880        } else {
 881            irb.esw[0] = 0x00800000;
 882        }
 883        /* If a unit check is pending, copy sense data. */
 884        if ((s->dstat & SCSW_DSTAT_UNIT_CHECK) &&
 885            (p->chars & PMCW_CHARS_MASK_CSENSE)) {
 886            irb.scsw.flags |= SCSW_FLAGS_MASK_ESWF | SCSW_FLAGS_MASK_ECTL;
 887            memcpy(irb.ecw, sch->sense_data, sizeof(sch->sense_data));
 888            irb.esw[1] = 0x01000000 | (sizeof(sch->sense_data) << 8);
 889        }
 890    }
 891    /* Store the irb to the guest. */
 892    copy_irb_to_guest(target_irb, &irb, p, irb_len);
 893
 894    return ((stctl & SCSW_STCTL_STATUS_PEND) == 0);
 895}
 896
 897void css_do_tsch_update_subch(SubchDev *sch)
 898{
 899    SCSW *s = &sch->curr_status.scsw;
 900    PMCW *p = &sch->curr_status.pmcw;
 901    uint16_t stctl;
 902    uint16_t fctl;
 903    uint16_t actl;
 904
 905    stctl = s->ctrl & SCSW_CTRL_MASK_STCTL;
 906    fctl = s->ctrl & SCSW_CTRL_MASK_FCTL;
 907    actl = s->ctrl & SCSW_CTRL_MASK_ACTL;
 908
 909    /* Clear conditions on subchannel, if applicable. */
 910    if (stctl & SCSW_STCTL_STATUS_PEND) {
 911        s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
 912        if ((stctl != (SCSW_STCTL_INTERMEDIATE | SCSW_STCTL_STATUS_PEND)) ||
 913            ((fctl & SCSW_FCTL_HALT_FUNC) &&
 914             (actl & SCSW_ACTL_SUSP))) {
 915            s->ctrl &= ~SCSW_CTRL_MASK_FCTL;
 916        }
 917        if (stctl != (SCSW_STCTL_INTERMEDIATE | SCSW_STCTL_STATUS_PEND)) {
 918            s->flags &= ~SCSW_FLAGS_MASK_PNO;
 919            s->ctrl &= ~(SCSW_ACTL_RESUME_PEND |
 920                         SCSW_ACTL_START_PEND |
 921                         SCSW_ACTL_HALT_PEND |
 922                         SCSW_ACTL_CLEAR_PEND |
 923                         SCSW_ACTL_SUSP);
 924        } else {
 925            if ((actl & SCSW_ACTL_SUSP) &&
 926                (fctl & SCSW_FCTL_START_FUNC)) {
 927                s->flags &= ~SCSW_FLAGS_MASK_PNO;
 928                if (fctl & SCSW_FCTL_HALT_FUNC) {
 929                    s->ctrl &= ~(SCSW_ACTL_RESUME_PEND |
 930                                 SCSW_ACTL_START_PEND |
 931                                 SCSW_ACTL_HALT_PEND |
 932                                 SCSW_ACTL_CLEAR_PEND |
 933                                 SCSW_ACTL_SUSP);
 934                } else {
 935                    s->ctrl &= ~SCSW_ACTL_RESUME_PEND;
 936                }
 937            }
 938        }
 939        /* Clear pending sense data. */
 940        if (p->chars & PMCW_CHARS_MASK_CSENSE) {
 941            memset(sch->sense_data, 0 , sizeof(sch->sense_data));
 942        }
 943    }
 944}
 945
 946static void copy_crw_to_guest(CRW *dest, const CRW *src)
 947{
 948    dest->flags = cpu_to_be16(src->flags);
 949    dest->rsid = cpu_to_be16(src->rsid);
 950}
 951
 952int css_do_stcrw(CRW *crw)
 953{
 954    CrwContainer *crw_cont;
 955    int ret;
 956
 957    crw_cont = QTAILQ_FIRST(&channel_subsys->pending_crws);
 958    if (crw_cont) {
 959        QTAILQ_REMOVE(&channel_subsys->pending_crws, crw_cont, sibling);
 960        copy_crw_to_guest(crw, &crw_cont->crw);
 961        g_free(crw_cont);
 962        ret = 0;
 963    } else {
 964        /* List was empty, turn crw machine checks on again. */
 965        memset(crw, 0, sizeof(*crw));
 966        channel_subsys->do_crw_mchk = true;
 967        ret = 1;
 968    }
 969
 970    return ret;
 971}
 972
 973static void copy_crw_from_guest(CRW *dest, const CRW *src)
 974{
 975    dest->flags = be16_to_cpu(src->flags);
 976    dest->rsid = be16_to_cpu(src->rsid);
 977}
 978
 979void css_undo_stcrw(CRW *crw)
 980{
 981    CrwContainer *crw_cont;
 982
 983    crw_cont = g_try_malloc0(sizeof(CrwContainer));
 984    if (!crw_cont) {
 985        channel_subsys->crws_lost = true;
 986        return;
 987    }
 988    copy_crw_from_guest(&crw_cont->crw, crw);
 989
 990    QTAILQ_INSERT_HEAD(&channel_subsys->pending_crws, crw_cont, sibling);
 991}
 992
 993int css_do_tpi(IOIntCode *int_code, int lowcore)
 994{
 995    /* No pending interrupts for !KVM. */
 996    return 0;
 997 }
 998
 999int css_collect_chp_desc(int m, uint8_t cssid, uint8_t f_chpid, uint8_t l_chpid,
1000                         int rfmt, void *buf)
1001{
1002    int i, desc_size;
1003    uint32_t words[8];
1004    uint32_t chpid_type_word;
1005    CssImage *css;
1006
1007    if (!m && !cssid) {
1008        css = channel_subsys->css[channel_subsys->default_cssid];
1009    } else {
1010        css = channel_subsys->css[cssid];
1011    }
1012    if (!css) {
1013        return 0;
1014    }
1015    desc_size = 0;
1016    for (i = f_chpid; i <= l_chpid; i++) {
1017        if (css->chpids[i].in_use) {
1018            chpid_type_word = 0x80000000 | (css->chpids[i].type << 8) | i;
1019            if (rfmt == 0) {
1020                words[0] = cpu_to_be32(chpid_type_word);
1021                words[1] = 0;
1022                memcpy(buf + desc_size, words, 8);
1023                desc_size += 8;
1024            } else if (rfmt == 1) {
1025                words[0] = cpu_to_be32(chpid_type_word);
1026                words[1] = 0;
1027                words[2] = 0;
1028                words[3] = 0;
1029                words[4] = 0;
1030                words[5] = 0;
1031                words[6] = 0;
1032                words[7] = 0;
1033                memcpy(buf + desc_size, words, 32);
1034                desc_size += 32;
1035            }
1036        }
1037    }
1038    return desc_size;
1039}
1040
1041void css_do_schm(uint8_t mbk, int update, int dct, uint64_t mbo)
1042{
1043    /* dct is currently ignored (not really meaningful for our devices) */
1044    /* TODO: Don't ignore mbk. */
1045    if (update && !channel_subsys->chnmon_active) {
1046        /* Enable measuring. */
1047        channel_subsys->chnmon_area = mbo;
1048        channel_subsys->chnmon_active = true;
1049    }
1050    if (!update && channel_subsys->chnmon_active) {
1051        /* Disable measuring. */
1052        channel_subsys->chnmon_area = 0;
1053        channel_subsys->chnmon_active = false;
1054    }
1055}
1056
1057int css_do_rsch(SubchDev *sch)
1058{
1059    SCSW *s = &sch->curr_status.scsw;
1060    PMCW *p = &sch->curr_status.pmcw;
1061    int ret;
1062
1063    if (!(p->flags & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA))) {
1064        ret = -ENODEV;
1065        goto out;
1066    }
1067
1068    if (s->ctrl & SCSW_STCTL_STATUS_PEND) {
1069        ret = -EINPROGRESS;
1070        goto out;
1071    }
1072
1073    if (((s->ctrl & SCSW_CTRL_MASK_FCTL) != SCSW_FCTL_START_FUNC) ||
1074        (s->ctrl & SCSW_ACTL_RESUME_PEND) ||
1075        (!(s->ctrl & SCSW_ACTL_SUSP))) {
1076        ret = -EINVAL;
1077        goto out;
1078    }
1079
1080    /* If monitoring is active, update counter. */
1081    if (channel_subsys->chnmon_active) {
1082        css_update_chnmon(sch);
1083    }
1084
1085    s->ctrl |= SCSW_ACTL_RESUME_PEND;
1086    do_subchannel_work(sch, NULL);
1087    ret = 0;
1088
1089out:
1090    return ret;
1091}
1092
1093int css_do_rchp(uint8_t cssid, uint8_t chpid)
1094{
1095    uint8_t real_cssid;
1096
1097    if (cssid > channel_subsys->max_cssid) {
1098        return -EINVAL;
1099    }
1100    if (channel_subsys->max_cssid == 0) {
1101        real_cssid = channel_subsys->default_cssid;
1102    } else {
1103        real_cssid = cssid;
1104    }
1105    if (!channel_subsys->css[real_cssid]) {
1106        return -EINVAL;
1107    }
1108
1109    if (!channel_subsys->css[real_cssid]->chpids[chpid].in_use) {
1110        return -ENODEV;
1111    }
1112
1113    if (!channel_subsys->css[real_cssid]->chpids[chpid].is_virtual) {
1114        fprintf(stderr,
1115                "rchp unsupported for non-virtual chpid %x.%02x!\n",
1116                real_cssid, chpid);
1117        return -ENODEV;
1118    }
1119
1120    /* We don't really use a channel path, so we're done here. */
1121    css_queue_crw(CRW_RSC_CHP, CRW_ERC_INIT,
1122                  channel_subsys->max_cssid > 0 ? 1 : 0, chpid);
1123    if (channel_subsys->max_cssid > 0) {
1124        css_queue_crw(CRW_RSC_CHP, CRW_ERC_INIT, 0, real_cssid << 8);
1125    }
1126    return 0;
1127}
1128
1129bool css_schid_final(int m, uint8_t cssid, uint8_t ssid, uint16_t schid)
1130{
1131    SubchSet *set;
1132    uint8_t real_cssid;
1133
1134    real_cssid = (!m && (cssid == 0)) ? channel_subsys->default_cssid : cssid;
1135    if (real_cssid > MAX_CSSID || ssid > MAX_SSID ||
1136        !channel_subsys->css[real_cssid] ||
1137        !channel_subsys->css[real_cssid]->sch_set[ssid]) {
1138        return true;
1139    }
1140    set = channel_subsys->css[real_cssid]->sch_set[ssid];
1141    return schid > find_last_bit(set->schids_used,
1142                                 (MAX_SCHID + 1) / sizeof(unsigned long));
1143}
1144
1145static int css_add_virtual_chpid(uint8_t cssid, uint8_t chpid, uint8_t type)
1146{
1147    CssImage *css;
1148
1149    trace_css_chpid_add(cssid, chpid, type);
1150    if (cssid > MAX_CSSID) {
1151        return -EINVAL;
1152    }
1153    css = channel_subsys->css[cssid];
1154    if (!css) {
1155        return -EINVAL;
1156    }
1157    if (css->chpids[chpid].in_use) {
1158        return -EEXIST;
1159    }
1160    css->chpids[chpid].in_use = 1;
1161    css->chpids[chpid].type = type;
1162    css->chpids[chpid].is_virtual = 1;
1163
1164    css_generate_chp_crws(cssid, chpid);
1165
1166    return 0;
1167}
1168
1169void css_sch_build_virtual_schib(SubchDev *sch, uint8_t chpid, uint8_t type)
1170{
1171    PMCW *p = &sch->curr_status.pmcw;
1172    SCSW *s = &sch->curr_status.scsw;
1173    int i;
1174    CssImage *css = channel_subsys->css[sch->cssid];
1175
1176    assert(css != NULL);
1177    memset(p, 0, sizeof(PMCW));
1178    p->flags |= PMCW_FLAGS_MASK_DNV;
1179    p->devno = sch->devno;
1180    /* single path */
1181    p->pim = 0x80;
1182    p->pom = 0xff;
1183    p->pam = 0x80;
1184    p->chpid[0] = chpid;
1185    if (!css->chpids[chpid].in_use) {
1186        css_add_virtual_chpid(sch->cssid, chpid, type);
1187    }
1188
1189    memset(s, 0, sizeof(SCSW));
1190    sch->curr_status.mba = 0;
1191    for (i = 0; i < ARRAY_SIZE(sch->curr_status.mda); i++) {
1192        sch->curr_status.mda[i] = 0;
1193    }
1194}
1195
1196SubchDev *css_find_subch(uint8_t m, uint8_t cssid, uint8_t ssid, uint16_t schid)
1197{
1198    uint8_t real_cssid;
1199
1200    real_cssid = (!m && (cssid == 0)) ? channel_subsys->default_cssid : cssid;
1201
1202    if (!channel_subsys->css[real_cssid]) {
1203        return NULL;
1204    }
1205
1206    if (!channel_subsys->css[real_cssid]->sch_set[ssid]) {
1207        return NULL;
1208    }
1209
1210    return channel_subsys->css[real_cssid]->sch_set[ssid]->sch[schid];
1211}
1212
1213bool css_subch_visible(SubchDev *sch)
1214{
1215    if (sch->ssid > channel_subsys->max_ssid) {
1216        return false;
1217    }
1218
1219    if (sch->cssid != channel_subsys->default_cssid) {
1220        return (channel_subsys->max_cssid > 0);
1221    }
1222
1223    return true;
1224}
1225
1226bool css_present(uint8_t cssid)
1227{
1228    return (channel_subsys->css[cssid] != NULL);
1229}
1230
1231bool css_devno_used(uint8_t cssid, uint8_t ssid, uint16_t devno)
1232{
1233    if (!channel_subsys->css[cssid]) {
1234        return false;
1235    }
1236    if (!channel_subsys->css[cssid]->sch_set[ssid]) {
1237        return false;
1238    }
1239
1240    return !!test_bit(devno,
1241                      channel_subsys->css[cssid]->sch_set[ssid]->devnos_used);
1242}
1243
1244void css_subch_assign(uint8_t cssid, uint8_t ssid, uint16_t schid,
1245                      uint16_t devno, SubchDev *sch)
1246{
1247    CssImage *css;
1248    SubchSet *s_set;
1249
1250    trace_css_assign_subch(sch ? "assign" : "deassign", cssid, ssid, schid,
1251                           devno);
1252    if (!channel_subsys->css[cssid]) {
1253        fprintf(stderr,
1254                "Suspicious call to %s (%x.%x.%04x) for non-existing css!\n",
1255                __func__, cssid, ssid, schid);
1256        return;
1257    }
1258    css = channel_subsys->css[cssid];
1259
1260    if (!css->sch_set[ssid]) {
1261        css->sch_set[ssid] = g_malloc0(sizeof(SubchSet));
1262    }
1263    s_set = css->sch_set[ssid];
1264
1265    s_set->sch[schid] = sch;
1266    if (sch) {
1267        set_bit(schid, s_set->schids_used);
1268        set_bit(devno, s_set->devnos_used);
1269    } else {
1270        clear_bit(schid, s_set->schids_used);
1271        clear_bit(devno, s_set->devnos_used);
1272    }
1273}
1274
1275void css_queue_crw(uint8_t rsc, uint8_t erc, int chain, uint16_t rsid)
1276{
1277    CrwContainer *crw_cont;
1278
1279    trace_css_crw(rsc, erc, rsid, chain ? "(chained)" : "");
1280    /* TODO: Maybe use a static crw pool? */
1281    crw_cont = g_try_malloc0(sizeof(CrwContainer));
1282    if (!crw_cont) {
1283        channel_subsys->crws_lost = true;
1284        return;
1285    }
1286    crw_cont->crw.flags = (rsc << 8) | erc;
1287    if (chain) {
1288        crw_cont->crw.flags |= CRW_FLAGS_MASK_C;
1289    }
1290    crw_cont->crw.rsid = rsid;
1291    if (channel_subsys->crws_lost) {
1292        crw_cont->crw.flags |= CRW_FLAGS_MASK_R;
1293        channel_subsys->crws_lost = false;
1294    }
1295
1296    QTAILQ_INSERT_TAIL(&channel_subsys->pending_crws, crw_cont, sibling);
1297
1298    if (channel_subsys->do_crw_mchk) {
1299        channel_subsys->do_crw_mchk = false;
1300        /* Inject crw pending machine check. */
1301        s390_crw_mchk();
1302    }
1303}
1304
1305void css_generate_sch_crws(uint8_t cssid, uint8_t ssid, uint16_t schid,
1306                           int hotplugged, int add)
1307{
1308    uint8_t guest_cssid;
1309    bool chain_crw;
1310
1311    if (add && !hotplugged) {
1312        return;
1313    }
1314    if (channel_subsys->max_cssid == 0) {
1315        /* Default cssid shows up as 0. */
1316        guest_cssid = (cssid == channel_subsys->default_cssid) ? 0 : cssid;
1317    } else {
1318        /* Show real cssid to the guest. */
1319        guest_cssid = cssid;
1320    }
1321    /*
1322     * Only notify for higher subchannel sets/channel subsystems if the
1323     * guest has enabled it.
1324     */
1325    if ((ssid > channel_subsys->max_ssid) ||
1326        (guest_cssid > channel_subsys->max_cssid) ||
1327        ((channel_subsys->max_cssid == 0) &&
1328         (cssid != channel_subsys->default_cssid))) {
1329        return;
1330    }
1331    chain_crw = (channel_subsys->max_ssid > 0) ||
1332            (channel_subsys->max_cssid > 0);
1333    css_queue_crw(CRW_RSC_SUBCH, CRW_ERC_IPI, chain_crw ? 1 : 0, schid);
1334    if (chain_crw) {
1335        css_queue_crw(CRW_RSC_SUBCH, CRW_ERC_IPI, 0,
1336                      (guest_cssid << 8) | (ssid << 4));
1337    }
1338}
1339
1340void css_generate_chp_crws(uint8_t cssid, uint8_t chpid)
1341{
1342    /* TODO */
1343}
1344
1345void css_generate_css_crws(uint8_t cssid)
1346{
1347    css_queue_crw(CRW_RSC_CSS, 0, 0, cssid);
1348}
1349
1350int css_enable_mcsse(void)
1351{
1352    trace_css_enable_facility("mcsse");
1353    channel_subsys->max_cssid = MAX_CSSID;
1354    return 0;
1355}
1356
1357int css_enable_mss(void)
1358{
1359    trace_css_enable_facility("mss");
1360    channel_subsys->max_ssid = MAX_SSID;
1361    return 0;
1362}
1363
1364void subch_device_save(SubchDev *s, QEMUFile *f)
1365{
1366    int i;
1367
1368    qemu_put_byte(f, s->cssid);
1369    qemu_put_byte(f, s->ssid);
1370    qemu_put_be16(f, s->schid);
1371    qemu_put_be16(f, s->devno);
1372    qemu_put_byte(f, s->thinint_active);
1373    /* SCHIB */
1374    /*     PMCW */
1375    qemu_put_be32(f, s->curr_status.pmcw.intparm);
1376    qemu_put_be16(f, s->curr_status.pmcw.flags);
1377    qemu_put_be16(f, s->curr_status.pmcw.devno);
1378    qemu_put_byte(f, s->curr_status.pmcw.lpm);
1379    qemu_put_byte(f, s->curr_status.pmcw.pnom);
1380    qemu_put_byte(f, s->curr_status.pmcw.lpum);
1381    qemu_put_byte(f, s->curr_status.pmcw.pim);
1382    qemu_put_be16(f, s->curr_status.pmcw.mbi);
1383    qemu_put_byte(f, s->curr_status.pmcw.pom);
1384    qemu_put_byte(f, s->curr_status.pmcw.pam);
1385    qemu_put_buffer(f, s->curr_status.pmcw.chpid, 8);
1386    qemu_put_be32(f, s->curr_status.pmcw.chars);
1387    /*     SCSW */
1388    qemu_put_be16(f, s->curr_status.scsw.flags);
1389    qemu_put_be16(f, s->curr_status.scsw.ctrl);
1390    qemu_put_be32(f, s->curr_status.scsw.cpa);
1391    qemu_put_byte(f, s->curr_status.scsw.dstat);
1392    qemu_put_byte(f, s->curr_status.scsw.cstat);
1393    qemu_put_be16(f, s->curr_status.scsw.count);
1394    qemu_put_be64(f, s->curr_status.mba);
1395    qemu_put_buffer(f, s->curr_status.mda, 4);
1396    /* end SCHIB */
1397    qemu_put_buffer(f, s->sense_data, 32);
1398    qemu_put_be64(f, s->channel_prog);
1399    /* last cmd */
1400    qemu_put_byte(f, s->last_cmd.cmd_code);
1401    qemu_put_byte(f, s->last_cmd.flags);
1402    qemu_put_be16(f, s->last_cmd.count);
1403    qemu_put_be32(f, s->last_cmd.cda);
1404    qemu_put_byte(f, s->last_cmd_valid);
1405    qemu_put_byte(f, s->id.reserved);
1406    qemu_put_be16(f, s->id.cu_type);
1407    qemu_put_byte(f, s->id.cu_model);
1408    qemu_put_be16(f, s->id.dev_type);
1409    qemu_put_byte(f, s->id.dev_model);
1410    qemu_put_byte(f, s->id.unused);
1411    for (i = 0; i < ARRAY_SIZE(s->id.ciw); i++) {
1412        qemu_put_byte(f, s->id.ciw[i].type);
1413        qemu_put_byte(f, s->id.ciw[i].command);
1414        qemu_put_be16(f, s->id.ciw[i].count);
1415    }
1416    qemu_put_byte(f, s->ccw_fmt_1);
1417    qemu_put_byte(f, s->ccw_no_data_cnt);
1418    return;
1419}
1420
1421int subch_device_load(SubchDev *s, QEMUFile *f)
1422{
1423    int i;
1424
1425    s->cssid = qemu_get_byte(f);
1426    s->ssid = qemu_get_byte(f);
1427    s->schid = qemu_get_be16(f);
1428    s->devno = qemu_get_be16(f);
1429    s->thinint_active = qemu_get_byte(f);
1430    /* SCHIB */
1431    /*     PMCW */
1432    s->curr_status.pmcw.intparm = qemu_get_be32(f);
1433    s->curr_status.pmcw.flags = qemu_get_be16(f);
1434    s->curr_status.pmcw.devno = qemu_get_be16(f);
1435    s->curr_status.pmcw.lpm = qemu_get_byte(f);
1436    s->curr_status.pmcw.pnom  = qemu_get_byte(f);
1437    s->curr_status.pmcw.lpum = qemu_get_byte(f);
1438    s->curr_status.pmcw.pim = qemu_get_byte(f);
1439    s->curr_status.pmcw.mbi = qemu_get_be16(f);
1440    s->curr_status.pmcw.pom = qemu_get_byte(f);
1441    s->curr_status.pmcw.pam = qemu_get_byte(f);
1442    qemu_get_buffer(f, s->curr_status.pmcw.chpid, 8);
1443    s->curr_status.pmcw.chars = qemu_get_be32(f);
1444    /*     SCSW */
1445    s->curr_status.scsw.flags = qemu_get_be16(f);
1446    s->curr_status.scsw.ctrl = qemu_get_be16(f);
1447    s->curr_status.scsw.cpa = qemu_get_be32(f);
1448    s->curr_status.scsw.dstat = qemu_get_byte(f);
1449    s->curr_status.scsw.cstat = qemu_get_byte(f);
1450    s->curr_status.scsw.count = qemu_get_be16(f);
1451    s->curr_status.mba = qemu_get_be64(f);
1452    qemu_get_buffer(f, s->curr_status.mda, 4);
1453    /* end SCHIB */
1454    qemu_get_buffer(f, s->sense_data, 32);
1455    s->channel_prog = qemu_get_be64(f);
1456    /* last cmd */
1457    s->last_cmd.cmd_code = qemu_get_byte(f);
1458    s->last_cmd.flags = qemu_get_byte(f);
1459    s->last_cmd.count = qemu_get_be16(f);
1460    s->last_cmd.cda = qemu_get_be32(f);
1461    s->last_cmd_valid = qemu_get_byte(f);
1462    s->id.reserved = qemu_get_byte(f);
1463    s->id.cu_type = qemu_get_be16(f);
1464    s->id.cu_model = qemu_get_byte(f);
1465    s->id.dev_type = qemu_get_be16(f);
1466    s->id.dev_model = qemu_get_byte(f);
1467    s->id.unused = qemu_get_byte(f);
1468    for (i = 0; i < ARRAY_SIZE(s->id.ciw); i++) {
1469        s->id.ciw[i].type = qemu_get_byte(f);
1470        s->id.ciw[i].command = qemu_get_byte(f);
1471        s->id.ciw[i].count = qemu_get_be16(f);
1472    }
1473    s->ccw_fmt_1 = qemu_get_byte(f);
1474    s->ccw_no_data_cnt = qemu_get_byte(f);
1475    /*
1476     * Hack alert. We don't migrate the channel subsystem status (no
1477     * device!), but we need to find out if the guest enabled mss/mcss-e.
1478     * If the subchannel is enabled, it certainly was able to access it,
1479     * so adjust the max_ssid/max_cssid values for relevant ssid/cssid
1480     * values. This is not watertight, but better than nothing.
1481     */
1482    if (s->curr_status.pmcw.flags & PMCW_FLAGS_MASK_ENA) {
1483        if (s->ssid) {
1484            channel_subsys->max_ssid = MAX_SSID;
1485        }
1486        if (s->cssid != channel_subsys->default_cssid) {
1487            channel_subsys->max_cssid = MAX_CSSID;
1488        }
1489    }
1490    return 0;
1491}
1492
1493
1494static void css_init(void)
1495{
1496    channel_subsys = g_malloc0(sizeof(*channel_subsys));
1497    QTAILQ_INIT(&channel_subsys->pending_crws);
1498    channel_subsys->do_crw_mchk = true;
1499    channel_subsys->crws_lost = false;
1500    channel_subsys->chnmon_active = false;
1501    QTAILQ_INIT(&channel_subsys->io_adapters);
1502}
1503machine_init(css_init);
1504
1505void css_reset_sch(SubchDev *sch)
1506{
1507    PMCW *p = &sch->curr_status.pmcw;
1508
1509    if ((p->flags & PMCW_FLAGS_MASK_ENA) != 0 && sch->disable_cb) {
1510        sch->disable_cb(sch);
1511    }
1512
1513    p->intparm = 0;
1514    p->flags &= ~(PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA |
1515                  PMCW_FLAGS_MASK_LM | PMCW_FLAGS_MASK_MME |
1516                  PMCW_FLAGS_MASK_MP | PMCW_FLAGS_MASK_TF);
1517    p->flags |= PMCW_FLAGS_MASK_DNV;
1518    p->devno = sch->devno;
1519    p->pim = 0x80;
1520    p->lpm = p->pim;
1521    p->pnom = 0;
1522    p->lpum = 0;
1523    p->mbi = 0;
1524    p->pom = 0xff;
1525    p->pam = 0x80;
1526    p->chars &= ~(PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_XMWME |
1527                  PMCW_CHARS_MASK_CSENSE);
1528
1529    memset(&sch->curr_status.scsw, 0, sizeof(sch->curr_status.scsw));
1530    sch->curr_status.mba = 0;
1531
1532    sch->channel_prog = 0x0;
1533    sch->last_cmd_valid = false;
1534    sch->thinint_active = false;
1535}
1536
1537void css_reset(void)
1538{
1539    CrwContainer *crw_cont;
1540
1541    /* Clean up monitoring. */
1542    channel_subsys->chnmon_active = false;
1543    channel_subsys->chnmon_area = 0;
1544
1545    /* Clear pending CRWs. */
1546    while ((crw_cont = QTAILQ_FIRST(&channel_subsys->pending_crws))) {
1547        QTAILQ_REMOVE(&channel_subsys->pending_crws, crw_cont, sibling);
1548        g_free(crw_cont);
1549    }
1550    channel_subsys->do_crw_mchk = true;
1551    channel_subsys->crws_lost = false;
1552
1553    /* Reset maximum ids. */
1554    channel_subsys->max_cssid = 0;
1555    channel_subsys->max_ssid = 0;
1556}
1557