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