xref: /openbmc/qemu/hw/s390x/css.c (revision 7562f907)
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 "qemu/osdep.h"
13 #include "qapi/error.h"
14 #include "qapi/visitor.h"
15 #include "hw/qdev.h"
16 #include "qemu/bitops.h"
17 #include "exec/address-spaces.h"
18 #include "cpu.h"
19 #include "hw/s390x/ioinst.h"
20 #include "hw/s390x/css.h"
21 #include "trace.h"
22 #include "hw/s390x/s390_flic.h"
23 
24 typedef struct CrwContainer {
25     CRW crw;
26     QTAILQ_ENTRY(CrwContainer) sibling;
27 } CrwContainer;
28 
29 typedef struct ChpInfo {
30     uint8_t in_use;
31     uint8_t type;
32     uint8_t is_virtual;
33 } ChpInfo;
34 
35 typedef struct SubchSet {
36     SubchDev *sch[MAX_SCHID + 1];
37     unsigned long schids_used[BITS_TO_LONGS(MAX_SCHID + 1)];
38     unsigned long devnos_used[BITS_TO_LONGS(MAX_SCHID + 1)];
39 } SubchSet;
40 
41 typedef struct CssImage {
42     SubchSet *sch_set[MAX_SSID + 1];
43     ChpInfo chpids[MAX_CHPID + 1];
44 } CssImage;
45 
46 typedef struct IoAdapter {
47     uint32_t id;
48     uint8_t type;
49     uint8_t isc;
50     QTAILQ_ENTRY(IoAdapter) sibling;
51 } IoAdapter;
52 
53 typedef struct ChannelSubSys {
54     QTAILQ_HEAD(, CrwContainer) pending_crws;
55     bool sei_pending;
56     bool do_crw_mchk;
57     bool crws_lost;
58     uint8_t max_cssid;
59     uint8_t max_ssid;
60     bool chnmon_active;
61     uint64_t chnmon_area;
62     CssImage *css[MAX_CSSID + 1];
63     uint8_t default_cssid;
64     QTAILQ_HEAD(, IoAdapter) io_adapters;
65     QTAILQ_HEAD(, IndAddr) indicator_addresses;
66 } ChannelSubSys;
67 
68 static ChannelSubSys channel_subsys = {
69     .pending_crws = QTAILQ_HEAD_INITIALIZER(channel_subsys.pending_crws),
70     .do_crw_mchk = true,
71     .sei_pending = false,
72     .do_crw_mchk = true,
73     .crws_lost = false,
74     .chnmon_active = false,
75     .io_adapters = QTAILQ_HEAD_INITIALIZER(channel_subsys.io_adapters),
76     .indicator_addresses =
77         QTAILQ_HEAD_INITIALIZER(channel_subsys.indicator_addresses),
78 };
79 
80 IndAddr *get_indicator(hwaddr ind_addr, int len)
81 {
82     IndAddr *indicator;
83 
84     QTAILQ_FOREACH(indicator, &channel_subsys.indicator_addresses, sibling) {
85         if (indicator->addr == ind_addr) {
86             indicator->refcnt++;
87             return indicator;
88         }
89     }
90     indicator = g_new0(IndAddr, 1);
91     indicator->addr = ind_addr;
92     indicator->len = len;
93     indicator->refcnt = 1;
94     QTAILQ_INSERT_TAIL(&channel_subsys.indicator_addresses,
95                        indicator, sibling);
96     return indicator;
97 }
98 
99 static int s390_io_adapter_map(AdapterInfo *adapter, uint64_t map_addr,
100                                bool do_map)
101 {
102     S390FLICState *fs = s390_get_flic();
103     S390FLICStateClass *fsc = S390_FLIC_COMMON_GET_CLASS(fs);
104 
105     return fsc->io_adapter_map(fs, adapter->adapter_id, map_addr, do_map);
106 }
107 
108 void release_indicator(AdapterInfo *adapter, IndAddr *indicator)
109 {
110     assert(indicator->refcnt > 0);
111     indicator->refcnt--;
112     if (indicator->refcnt > 0) {
113         return;
114     }
115     QTAILQ_REMOVE(&channel_subsys.indicator_addresses, indicator, sibling);
116     if (indicator->map) {
117         s390_io_adapter_map(adapter, indicator->map, false);
118     }
119     g_free(indicator);
120 }
121 
122 int map_indicator(AdapterInfo *adapter, IndAddr *indicator)
123 {
124     int ret;
125 
126     if (indicator->map) {
127         return 0; /* already mapped is not an error */
128     }
129     indicator->map = indicator->addr;
130     ret = s390_io_adapter_map(adapter, indicator->map, true);
131     if ((ret != 0) && (ret != -ENOSYS)) {
132         goto out_err;
133     }
134     return 0;
135 
136 out_err:
137     indicator->map = 0;
138     return ret;
139 }
140 
141 int css_create_css_image(uint8_t cssid, bool default_image)
142 {
143     trace_css_new_image(cssid, default_image ? "(default)" : "");
144     /* 255 is reserved */
145     if (cssid == 255) {
146         return -EINVAL;
147     }
148     if (channel_subsys.css[cssid]) {
149         return -EBUSY;
150     }
151     channel_subsys.css[cssid] = g_malloc0(sizeof(CssImage));
152     if (default_image) {
153         channel_subsys.default_cssid = cssid;
154     }
155     return 0;
156 }
157 
158 int css_register_io_adapter(uint8_t type, uint8_t isc, bool swap,
159                             bool maskable, uint32_t *id)
160 {
161     IoAdapter *adapter;
162     bool found = false;
163     int ret;
164     S390FLICState *fs = s390_get_flic();
165     S390FLICStateClass *fsc = S390_FLIC_COMMON_GET_CLASS(fs);
166 
167     *id = 0;
168     QTAILQ_FOREACH(adapter, &channel_subsys.io_adapters, sibling) {
169         if ((adapter->type == type) && (adapter->isc == isc)) {
170             *id = adapter->id;
171             found = true;
172             ret = 0;
173             break;
174         }
175         if (adapter->id >= *id) {
176             *id = adapter->id + 1;
177         }
178     }
179     if (found) {
180         goto out;
181     }
182     adapter = g_new0(IoAdapter, 1);
183     ret = fsc->register_io_adapter(fs, *id, isc, swap, maskable);
184     if (ret == 0) {
185         adapter->id = *id;
186         adapter->isc = isc;
187         adapter->type = type;
188         QTAILQ_INSERT_TAIL(&channel_subsys.io_adapters, adapter, sibling);
189     } else {
190         g_free(adapter);
191         fprintf(stderr, "Unexpected error %d when registering adapter %d\n",
192                 ret, *id);
193     }
194 out:
195     return ret;
196 }
197 
198 static void css_clear_io_interrupt(uint16_t subchannel_id,
199                                    uint16_t subchannel_nr)
200 {
201     Error *err = NULL;
202     static bool no_clear_irq;
203     S390FLICState *fs = s390_get_flic();
204     S390FLICStateClass *fsc = S390_FLIC_COMMON_GET_CLASS(fs);
205     int r;
206 
207     if (unlikely(no_clear_irq)) {
208         return;
209     }
210     r = fsc->clear_io_irq(fs, subchannel_id, subchannel_nr);
211     switch (r) {
212     case 0:
213         break;
214     case -ENOSYS:
215         no_clear_irq = true;
216         /*
217         * Ignore unavailability, as the user can't do anything
218         * about it anyway.
219         */
220         break;
221     default:
222         error_setg_errno(&err, -r, "unexpected error condition");
223         error_propagate(&error_abort, err);
224     }
225 }
226 
227 static inline uint16_t css_do_build_subchannel_id(uint8_t cssid, uint8_t ssid)
228 {
229     if (channel_subsys.max_cssid > 0) {
230         return (cssid << 8) | (1 << 3) | (ssid << 1) | 1;
231     }
232     return (ssid << 1) | 1;
233 }
234 
235 uint16_t css_build_subchannel_id(SubchDev *sch)
236 {
237     return css_do_build_subchannel_id(sch->cssid, sch->ssid);
238 }
239 
240 static void css_inject_io_interrupt(SubchDev *sch)
241 {
242     uint8_t isc = (sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_ISC) >> 11;
243 
244     trace_css_io_interrupt(sch->cssid, sch->ssid, sch->schid,
245                            sch->curr_status.pmcw.intparm, isc, "");
246     s390_io_interrupt(css_build_subchannel_id(sch),
247                       sch->schid,
248                       sch->curr_status.pmcw.intparm,
249                       isc << 27);
250 }
251 
252 void css_conditional_io_interrupt(SubchDev *sch)
253 {
254     /*
255      * If the subchannel is not currently status pending, make it pending
256      * with alert status.
257      */
258     if (!(sch->curr_status.scsw.ctrl & SCSW_STCTL_STATUS_PEND)) {
259         uint8_t isc = (sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_ISC) >> 11;
260 
261         trace_css_io_interrupt(sch->cssid, sch->ssid, sch->schid,
262                                sch->curr_status.pmcw.intparm, isc,
263                                "(unsolicited)");
264         sch->curr_status.scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
265         sch->curr_status.scsw.ctrl |=
266             SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
267         /* Inject an I/O interrupt. */
268         s390_io_interrupt(css_build_subchannel_id(sch),
269                           sch->schid,
270                           sch->curr_status.pmcw.intparm,
271                           isc << 27);
272     }
273 }
274 
275 void css_adapter_interrupt(uint8_t isc)
276 {
277     uint32_t io_int_word = (isc << 27) | IO_INT_WORD_AI;
278 
279     trace_css_adapter_interrupt(isc);
280     s390_io_interrupt(0, 0, 0, io_int_word);
281 }
282 
283 static void sch_handle_clear_func(SubchDev *sch)
284 {
285     PMCW *p = &sch->curr_status.pmcw;
286     SCSW *s = &sch->curr_status.scsw;
287     int path;
288 
289     /* Path management: In our simple css, we always choose the only path. */
290     path = 0x80;
291 
292     /* Reset values prior to 'issuing the clear signal'. */
293     p->lpum = 0;
294     p->pom = 0xff;
295     s->flags &= ~SCSW_FLAGS_MASK_PNO;
296 
297     /* We always 'attempt to issue the clear signal', and we always succeed. */
298     sch->channel_prog = 0x0;
299     sch->last_cmd_valid = false;
300     s->ctrl &= ~SCSW_ACTL_CLEAR_PEND;
301     s->ctrl |= SCSW_STCTL_STATUS_PEND;
302 
303     s->dstat = 0;
304     s->cstat = 0;
305     p->lpum = path;
306 
307 }
308 
309 static void sch_handle_halt_func(SubchDev *sch)
310 {
311 
312     PMCW *p = &sch->curr_status.pmcw;
313     SCSW *s = &sch->curr_status.scsw;
314     hwaddr curr_ccw = sch->channel_prog;
315     int path;
316 
317     /* Path management: In our simple css, we always choose the only path. */
318     path = 0x80;
319 
320     /* We always 'attempt to issue the halt signal', and we always succeed. */
321     sch->channel_prog = 0x0;
322     sch->last_cmd_valid = false;
323     s->ctrl &= ~SCSW_ACTL_HALT_PEND;
324     s->ctrl |= SCSW_STCTL_STATUS_PEND;
325 
326     if ((s->ctrl & (SCSW_ACTL_SUBCH_ACTIVE | SCSW_ACTL_DEVICE_ACTIVE)) ||
327         !((s->ctrl & SCSW_ACTL_START_PEND) ||
328           (s->ctrl & SCSW_ACTL_SUSP))) {
329         s->dstat = SCSW_DSTAT_DEVICE_END;
330     }
331     if ((s->ctrl & (SCSW_ACTL_SUBCH_ACTIVE | SCSW_ACTL_DEVICE_ACTIVE)) ||
332         (s->ctrl & SCSW_ACTL_SUSP)) {
333         s->cpa = curr_ccw + 8;
334     }
335     s->cstat = 0;
336     p->lpum = path;
337 
338 }
339 
340 static void copy_sense_id_to_guest(SenseId *dest, SenseId *src)
341 {
342     int i;
343 
344     dest->reserved = src->reserved;
345     dest->cu_type = cpu_to_be16(src->cu_type);
346     dest->cu_model = src->cu_model;
347     dest->dev_type = cpu_to_be16(src->dev_type);
348     dest->dev_model = src->dev_model;
349     dest->unused = src->unused;
350     for (i = 0; i < ARRAY_SIZE(dest->ciw); i++) {
351         dest->ciw[i].type = src->ciw[i].type;
352         dest->ciw[i].command = src->ciw[i].command;
353         dest->ciw[i].count = cpu_to_be16(src->ciw[i].count);
354     }
355 }
356 
357 static CCW1 copy_ccw_from_guest(hwaddr addr, bool fmt1)
358 {
359     CCW0 tmp0;
360     CCW1 tmp1;
361     CCW1 ret;
362 
363     if (fmt1) {
364         cpu_physical_memory_read(addr, &tmp1, sizeof(tmp1));
365         ret.cmd_code = tmp1.cmd_code;
366         ret.flags = tmp1.flags;
367         ret.count = be16_to_cpu(tmp1.count);
368         ret.cda = be32_to_cpu(tmp1.cda);
369     } else {
370         cpu_physical_memory_read(addr, &tmp0, sizeof(tmp0));
371         if ((tmp0.cmd_code & 0x0f) == CCW_CMD_TIC) {
372             ret.cmd_code = CCW_CMD_TIC;
373             ret.flags = 0;
374             ret.count = 0;
375         } else {
376             ret.cmd_code = tmp0.cmd_code;
377             ret.flags = tmp0.flags;
378             ret.count = be16_to_cpu(tmp0.count);
379         }
380         ret.cda = be16_to_cpu(tmp0.cda1) | (tmp0.cda0 << 16);
381     }
382     return ret;
383 }
384 
385 static int css_interpret_ccw(SubchDev *sch, hwaddr ccw_addr,
386                              bool suspend_allowed)
387 {
388     int ret;
389     bool check_len;
390     int len;
391     CCW1 ccw;
392 
393     if (!ccw_addr) {
394         return -EIO;
395     }
396 
397     /* Translate everything to format-1 ccws - the information is the same. */
398     ccw = copy_ccw_from_guest(ccw_addr, sch->ccw_fmt_1);
399 
400     /* Check for invalid command codes. */
401     if ((ccw.cmd_code & 0x0f) == 0) {
402         return -EINVAL;
403     }
404     if (((ccw.cmd_code & 0x0f) == CCW_CMD_TIC) &&
405         ((ccw.cmd_code & 0xf0) != 0)) {
406         return -EINVAL;
407     }
408     if (!sch->ccw_fmt_1 && (ccw.count == 0) &&
409         (ccw.cmd_code != CCW_CMD_TIC)) {
410         return -EINVAL;
411     }
412 
413     if (ccw.flags & CCW_FLAG_SUSPEND) {
414         return suspend_allowed ? -EINPROGRESS : -EINVAL;
415     }
416 
417     check_len = !((ccw.flags & CCW_FLAG_SLI) && !(ccw.flags & CCW_FLAG_DC));
418 
419     if (!ccw.cda) {
420         if (sch->ccw_no_data_cnt == 255) {
421             return -EINVAL;
422         }
423         sch->ccw_no_data_cnt++;
424     }
425 
426     /* Look at the command. */
427     switch (ccw.cmd_code) {
428     case CCW_CMD_NOOP:
429         /* Nothing to do. */
430         ret = 0;
431         break;
432     case CCW_CMD_BASIC_SENSE:
433         if (check_len) {
434             if (ccw.count != sizeof(sch->sense_data)) {
435                 ret = -EINVAL;
436                 break;
437             }
438         }
439         len = MIN(ccw.count, sizeof(sch->sense_data));
440         cpu_physical_memory_write(ccw.cda, sch->sense_data, len);
441         sch->curr_status.scsw.count = ccw.count - len;
442         memset(sch->sense_data, 0, sizeof(sch->sense_data));
443         ret = 0;
444         break;
445     case CCW_CMD_SENSE_ID:
446     {
447         SenseId sense_id;
448 
449         copy_sense_id_to_guest(&sense_id, &sch->id);
450         /* Sense ID information is device specific. */
451         if (check_len) {
452             if (ccw.count != sizeof(sense_id)) {
453                 ret = -EINVAL;
454                 break;
455             }
456         }
457         len = MIN(ccw.count, sizeof(sense_id));
458         /*
459          * Only indicate 0xff in the first sense byte if we actually
460          * have enough place to store at least bytes 0-3.
461          */
462         if (len >= 4) {
463             sense_id.reserved = 0xff;
464         } else {
465             sense_id.reserved = 0;
466         }
467         cpu_physical_memory_write(ccw.cda, &sense_id, len);
468         sch->curr_status.scsw.count = ccw.count - len;
469         ret = 0;
470         break;
471     }
472     case CCW_CMD_TIC:
473         if (sch->last_cmd_valid && (sch->last_cmd.cmd_code == CCW_CMD_TIC)) {
474             ret = -EINVAL;
475             break;
476         }
477         if (ccw.flags & (CCW_FLAG_CC | CCW_FLAG_DC)) {
478             ret = -EINVAL;
479             break;
480         }
481         sch->channel_prog = ccw.cda;
482         ret = -EAGAIN;
483         break;
484     default:
485         if (sch->ccw_cb) {
486             /* Handle device specific commands. */
487             ret = sch->ccw_cb(sch, ccw);
488         } else {
489             ret = -ENOSYS;
490         }
491         break;
492     }
493     sch->last_cmd = ccw;
494     sch->last_cmd_valid = true;
495     if (ret == 0) {
496         if (ccw.flags & CCW_FLAG_CC) {
497             sch->channel_prog += 8;
498             ret = -EAGAIN;
499         }
500     }
501 
502     return ret;
503 }
504 
505 static void sch_handle_start_func(SubchDev *sch, ORB *orb)
506 {
507 
508     PMCW *p = &sch->curr_status.pmcw;
509     SCSW *s = &sch->curr_status.scsw;
510     int path;
511     int ret;
512     bool suspend_allowed;
513 
514     /* Path management: In our simple css, we always choose the only path. */
515     path = 0x80;
516 
517     if (!(s->ctrl & SCSW_ACTL_SUSP)) {
518         /* Start Function triggered via ssch, i.e. we have an ORB */
519         s->cstat = 0;
520         s->dstat = 0;
521         /* Look at the orb and try to execute the channel program. */
522         assert(orb != NULL); /* resume does not pass an orb */
523         p->intparm = orb->intparm;
524         if (!(orb->lpm & path)) {
525             /* Generate a deferred cc 3 condition. */
526             s->flags |= SCSW_FLAGS_MASK_CC;
527             s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
528             s->ctrl |= (SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND);
529             return;
530         }
531         sch->ccw_fmt_1 = !!(orb->ctrl0 & ORB_CTRL0_MASK_FMT);
532         s->flags |= (sch->ccw_fmt_1) ? SCSW_FLAGS_MASK_FMT : 0;
533         sch->ccw_no_data_cnt = 0;
534         suspend_allowed = !!(orb->ctrl0 & ORB_CTRL0_MASK_SPND);
535     } else {
536         /* Start Function resumed via rsch, i.e. we don't have an
537          * ORB */
538         s->ctrl &= ~(SCSW_ACTL_SUSP | SCSW_ACTL_RESUME_PEND);
539         /* The channel program had been suspended before. */
540         suspend_allowed = true;
541     }
542     sch->last_cmd_valid = false;
543     do {
544         ret = css_interpret_ccw(sch, sch->channel_prog, suspend_allowed);
545         switch (ret) {
546         case -EAGAIN:
547             /* ccw chain, continue processing */
548             break;
549         case 0:
550             /* success */
551             s->ctrl &= ~SCSW_ACTL_START_PEND;
552             s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
553             s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
554                     SCSW_STCTL_STATUS_PEND;
555             s->dstat = SCSW_DSTAT_CHANNEL_END | SCSW_DSTAT_DEVICE_END;
556             s->cpa = sch->channel_prog + 8;
557             break;
558         case -ENOSYS:
559             /* unsupported command, generate unit check (command reject) */
560             s->ctrl &= ~SCSW_ACTL_START_PEND;
561             s->dstat = SCSW_DSTAT_UNIT_CHECK;
562             /* Set sense bit 0 in ecw0. */
563             sch->sense_data[0] = 0x80;
564             s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
565             s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
566                     SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
567             s->cpa = sch->channel_prog + 8;
568             break;
569         case -EFAULT:
570             /* memory problem, generate channel data check */
571             s->ctrl &= ~SCSW_ACTL_START_PEND;
572             s->cstat = SCSW_CSTAT_DATA_CHECK;
573             s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
574             s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
575                     SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
576             s->cpa = sch->channel_prog + 8;
577             break;
578         case -EBUSY:
579             /* subchannel busy, generate deferred cc 1 */
580             s->flags &= ~SCSW_FLAGS_MASK_CC;
581             s->flags |= (1 << 8);
582             s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
583             s->ctrl |= SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
584             break;
585         case -EINPROGRESS:
586             /* channel program has been suspended */
587             s->ctrl &= ~SCSW_ACTL_START_PEND;
588             s->ctrl |= SCSW_ACTL_SUSP;
589             break;
590         default:
591             /* error, generate channel program check */
592             s->ctrl &= ~SCSW_ACTL_START_PEND;
593             s->cstat = SCSW_CSTAT_PROG_CHECK;
594             s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
595             s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
596                     SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
597             s->cpa = sch->channel_prog + 8;
598             break;
599         }
600     } while (ret == -EAGAIN);
601 
602 }
603 
604 /*
605  * On real machines, this would run asynchronously to the main vcpus.
606  * We might want to make some parts of the ssch handling (interpreting
607  * read/writes) asynchronous later on if we start supporting more than
608  * our current very simple devices.
609  */
610 static void do_subchannel_work(SubchDev *sch, ORB *orb)
611 {
612 
613     SCSW *s = &sch->curr_status.scsw;
614 
615     if (s->ctrl & SCSW_FCTL_CLEAR_FUNC) {
616         sch_handle_clear_func(sch);
617     } else if (s->ctrl & SCSW_FCTL_HALT_FUNC) {
618         sch_handle_halt_func(sch);
619     } else if (s->ctrl & SCSW_FCTL_START_FUNC) {
620         /* Triggered by both ssch and rsch. */
621         sch_handle_start_func(sch, orb);
622     } else {
623         /* Cannot happen. */
624         return;
625     }
626     css_inject_io_interrupt(sch);
627 }
628 
629 static void copy_pmcw_to_guest(PMCW *dest, const PMCW *src)
630 {
631     int i;
632 
633     dest->intparm = cpu_to_be32(src->intparm);
634     dest->flags = cpu_to_be16(src->flags);
635     dest->devno = cpu_to_be16(src->devno);
636     dest->lpm = src->lpm;
637     dest->pnom = src->pnom;
638     dest->lpum = src->lpum;
639     dest->pim = src->pim;
640     dest->mbi = cpu_to_be16(src->mbi);
641     dest->pom = src->pom;
642     dest->pam = src->pam;
643     for (i = 0; i < ARRAY_SIZE(dest->chpid); i++) {
644         dest->chpid[i] = src->chpid[i];
645     }
646     dest->chars = cpu_to_be32(src->chars);
647 }
648 
649 static void copy_scsw_to_guest(SCSW *dest, const SCSW *src)
650 {
651     dest->flags = cpu_to_be16(src->flags);
652     dest->ctrl = cpu_to_be16(src->ctrl);
653     dest->cpa = cpu_to_be32(src->cpa);
654     dest->dstat = src->dstat;
655     dest->cstat = src->cstat;
656     dest->count = cpu_to_be16(src->count);
657 }
658 
659 static void copy_schib_to_guest(SCHIB *dest, const SCHIB *src)
660 {
661     int i;
662 
663     copy_pmcw_to_guest(&dest->pmcw, &src->pmcw);
664     copy_scsw_to_guest(&dest->scsw, &src->scsw);
665     dest->mba = cpu_to_be64(src->mba);
666     for (i = 0; i < ARRAY_SIZE(dest->mda); i++) {
667         dest->mda[i] = src->mda[i];
668     }
669 }
670 
671 int css_do_stsch(SubchDev *sch, SCHIB *schib)
672 {
673     /* Use current status. */
674     copy_schib_to_guest(schib, &sch->curr_status);
675     return 0;
676 }
677 
678 static void copy_pmcw_from_guest(PMCW *dest, const PMCW *src)
679 {
680     int i;
681 
682     dest->intparm = be32_to_cpu(src->intparm);
683     dest->flags = be16_to_cpu(src->flags);
684     dest->devno = be16_to_cpu(src->devno);
685     dest->lpm = src->lpm;
686     dest->pnom = src->pnom;
687     dest->lpum = src->lpum;
688     dest->pim = src->pim;
689     dest->mbi = be16_to_cpu(src->mbi);
690     dest->pom = src->pom;
691     dest->pam = src->pam;
692     for (i = 0; i < ARRAY_SIZE(dest->chpid); i++) {
693         dest->chpid[i] = src->chpid[i];
694     }
695     dest->chars = be32_to_cpu(src->chars);
696 }
697 
698 static void copy_scsw_from_guest(SCSW *dest, const SCSW *src)
699 {
700     dest->flags = be16_to_cpu(src->flags);
701     dest->ctrl = be16_to_cpu(src->ctrl);
702     dest->cpa = be32_to_cpu(src->cpa);
703     dest->dstat = src->dstat;
704     dest->cstat = src->cstat;
705     dest->count = be16_to_cpu(src->count);
706 }
707 
708 static void copy_schib_from_guest(SCHIB *dest, const SCHIB *src)
709 {
710     int i;
711 
712     copy_pmcw_from_guest(&dest->pmcw, &src->pmcw);
713     copy_scsw_from_guest(&dest->scsw, &src->scsw);
714     dest->mba = be64_to_cpu(src->mba);
715     for (i = 0; i < ARRAY_SIZE(dest->mda); i++) {
716         dest->mda[i] = src->mda[i];
717     }
718 }
719 
720 int css_do_msch(SubchDev *sch, const SCHIB *orig_schib)
721 {
722     SCSW *s = &sch->curr_status.scsw;
723     PMCW *p = &sch->curr_status.pmcw;
724     uint16_t oldflags;
725     int ret;
726     SCHIB schib;
727 
728     if (!(sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_DNV)) {
729         ret = 0;
730         goto out;
731     }
732 
733     if (s->ctrl & SCSW_STCTL_STATUS_PEND) {
734         ret = -EINPROGRESS;
735         goto out;
736     }
737 
738     if (s->ctrl &
739         (SCSW_FCTL_START_FUNC|SCSW_FCTL_HALT_FUNC|SCSW_FCTL_CLEAR_FUNC)) {
740         ret = -EBUSY;
741         goto out;
742     }
743 
744     copy_schib_from_guest(&schib, orig_schib);
745     /* Only update the program-modifiable fields. */
746     p->intparm = schib.pmcw.intparm;
747     oldflags = p->flags;
748     p->flags &= ~(PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA |
749                   PMCW_FLAGS_MASK_LM | PMCW_FLAGS_MASK_MME |
750                   PMCW_FLAGS_MASK_MP);
751     p->flags |= schib.pmcw.flags &
752             (PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA |
753              PMCW_FLAGS_MASK_LM | PMCW_FLAGS_MASK_MME |
754              PMCW_FLAGS_MASK_MP);
755     p->lpm = schib.pmcw.lpm;
756     p->mbi = schib.pmcw.mbi;
757     p->pom = schib.pmcw.pom;
758     p->chars &= ~(PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_CSENSE);
759     p->chars |= schib.pmcw.chars &
760             (PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_CSENSE);
761     sch->curr_status.mba = schib.mba;
762 
763     /* Has the channel been disabled? */
764     if (sch->disable_cb && (oldflags & PMCW_FLAGS_MASK_ENA) != 0
765         && (p->flags & PMCW_FLAGS_MASK_ENA) == 0) {
766         sch->disable_cb(sch);
767     }
768 
769     ret = 0;
770 
771 out:
772     return ret;
773 }
774 
775 int css_do_xsch(SubchDev *sch)
776 {
777     SCSW *s = &sch->curr_status.scsw;
778     PMCW *p = &sch->curr_status.pmcw;
779     int ret;
780 
781     if (~(p->flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
782         ret = -ENODEV;
783         goto out;
784     }
785 
786     if (!(s->ctrl & SCSW_CTRL_MASK_FCTL) ||
787         ((s->ctrl & SCSW_CTRL_MASK_FCTL) != SCSW_FCTL_START_FUNC) ||
788         (!(s->ctrl &
789            (SCSW_ACTL_RESUME_PEND | SCSW_ACTL_START_PEND | SCSW_ACTL_SUSP))) ||
790         (s->ctrl & SCSW_ACTL_SUBCH_ACTIVE)) {
791         ret = -EINPROGRESS;
792         goto out;
793     }
794 
795     if (s->ctrl & SCSW_CTRL_MASK_STCTL) {
796         ret = -EBUSY;
797         goto out;
798     }
799 
800     /* Cancel the current operation. */
801     s->ctrl &= ~(SCSW_FCTL_START_FUNC |
802                  SCSW_ACTL_RESUME_PEND |
803                  SCSW_ACTL_START_PEND |
804                  SCSW_ACTL_SUSP);
805     sch->channel_prog = 0x0;
806     sch->last_cmd_valid = false;
807     s->dstat = 0;
808     s->cstat = 0;
809     ret = 0;
810 
811 out:
812     return ret;
813 }
814 
815 int css_do_csch(SubchDev *sch)
816 {
817     SCSW *s = &sch->curr_status.scsw;
818     PMCW *p = &sch->curr_status.pmcw;
819     int ret;
820 
821     if (~(p->flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
822         ret = -ENODEV;
823         goto out;
824     }
825 
826     /* Trigger the clear function. */
827     s->ctrl &= ~(SCSW_CTRL_MASK_FCTL | SCSW_CTRL_MASK_ACTL);
828     s->ctrl |= SCSW_FCTL_CLEAR_FUNC | SCSW_ACTL_CLEAR_PEND;
829 
830     do_subchannel_work(sch, NULL);
831     ret = 0;
832 
833 out:
834     return ret;
835 }
836 
837 int css_do_hsch(SubchDev *sch)
838 {
839     SCSW *s = &sch->curr_status.scsw;
840     PMCW *p = &sch->curr_status.pmcw;
841     int ret;
842 
843     if (~(p->flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
844         ret = -ENODEV;
845         goto out;
846     }
847 
848     if (((s->ctrl & SCSW_CTRL_MASK_STCTL) == SCSW_STCTL_STATUS_PEND) ||
849         (s->ctrl & (SCSW_STCTL_PRIMARY |
850                     SCSW_STCTL_SECONDARY |
851                     SCSW_STCTL_ALERT))) {
852         ret = -EINPROGRESS;
853         goto out;
854     }
855 
856     if (s->ctrl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
857         ret = -EBUSY;
858         goto out;
859     }
860 
861     /* Trigger the halt function. */
862     s->ctrl |= SCSW_FCTL_HALT_FUNC;
863     s->ctrl &= ~SCSW_FCTL_START_FUNC;
864     if (((s->ctrl & SCSW_CTRL_MASK_ACTL) ==
865          (SCSW_ACTL_SUBCH_ACTIVE | SCSW_ACTL_DEVICE_ACTIVE)) &&
866         ((s->ctrl & SCSW_CTRL_MASK_STCTL) == SCSW_STCTL_INTERMEDIATE)) {
867         s->ctrl &= ~SCSW_STCTL_STATUS_PEND;
868     }
869     s->ctrl |= SCSW_ACTL_HALT_PEND;
870 
871     do_subchannel_work(sch, NULL);
872     ret = 0;
873 
874 out:
875     return ret;
876 }
877 
878 static void css_update_chnmon(SubchDev *sch)
879 {
880     if (!(sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_MME)) {
881         /* Not active. */
882         return;
883     }
884     /* The counter is conveniently located at the beginning of the struct. */
885     if (sch->curr_status.pmcw.chars & PMCW_CHARS_MASK_MBFC) {
886         /* Format 1, per-subchannel area. */
887         uint32_t count;
888 
889         count = address_space_ldl(&address_space_memory,
890                                   sch->curr_status.mba,
891                                   MEMTXATTRS_UNSPECIFIED,
892                                   NULL);
893         count++;
894         address_space_stl(&address_space_memory, sch->curr_status.mba, count,
895                           MEMTXATTRS_UNSPECIFIED, NULL);
896     } else {
897         /* Format 0, global area. */
898         uint32_t offset;
899         uint16_t count;
900 
901         offset = sch->curr_status.pmcw.mbi << 5;
902         count = address_space_lduw(&address_space_memory,
903                                    channel_subsys.chnmon_area + offset,
904                                    MEMTXATTRS_UNSPECIFIED,
905                                    NULL);
906         count++;
907         address_space_stw(&address_space_memory,
908                           channel_subsys.chnmon_area + offset, count,
909                           MEMTXATTRS_UNSPECIFIED, NULL);
910     }
911 }
912 
913 int css_do_ssch(SubchDev *sch, ORB *orb)
914 {
915     SCSW *s = &sch->curr_status.scsw;
916     PMCW *p = &sch->curr_status.pmcw;
917     int ret;
918 
919     if (~(p->flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
920         ret = -ENODEV;
921         goto out;
922     }
923 
924     if (s->ctrl & SCSW_STCTL_STATUS_PEND) {
925         ret = -EINPROGRESS;
926         goto out;
927     }
928 
929     if (s->ctrl & (SCSW_FCTL_START_FUNC |
930                    SCSW_FCTL_HALT_FUNC |
931                    SCSW_FCTL_CLEAR_FUNC)) {
932         ret = -EBUSY;
933         goto out;
934     }
935 
936     /* If monitoring is active, update counter. */
937     if (channel_subsys.chnmon_active) {
938         css_update_chnmon(sch);
939     }
940     sch->channel_prog = orb->cpa;
941     /* Trigger the start function. */
942     s->ctrl |= (SCSW_FCTL_START_FUNC | SCSW_ACTL_START_PEND);
943     s->flags &= ~SCSW_FLAGS_MASK_PNO;
944 
945     do_subchannel_work(sch, orb);
946     ret = 0;
947 
948 out:
949     return ret;
950 }
951 
952 static void copy_irb_to_guest(IRB *dest, const IRB *src, PMCW *pmcw,
953                               int *irb_len)
954 {
955     int i;
956     uint16_t stctl = src->scsw.ctrl & SCSW_CTRL_MASK_STCTL;
957     uint16_t actl = src->scsw.ctrl & SCSW_CTRL_MASK_ACTL;
958 
959     copy_scsw_to_guest(&dest->scsw, &src->scsw);
960 
961     for (i = 0; i < ARRAY_SIZE(dest->esw); i++) {
962         dest->esw[i] = cpu_to_be32(src->esw[i]);
963     }
964     for (i = 0; i < ARRAY_SIZE(dest->ecw); i++) {
965         dest->ecw[i] = cpu_to_be32(src->ecw[i]);
966     }
967     *irb_len = sizeof(*dest) - sizeof(dest->emw);
968 
969     /* extended measurements enabled? */
970     if ((src->scsw.flags & SCSW_FLAGS_MASK_ESWF) ||
971         !(pmcw->flags & PMCW_FLAGS_MASK_TF) ||
972         !(pmcw->chars & PMCW_CHARS_MASK_XMWME)) {
973         return;
974     }
975     /* extended measurements pending? */
976     if (!(stctl & SCSW_STCTL_STATUS_PEND)) {
977         return;
978     }
979     if ((stctl & SCSW_STCTL_PRIMARY) ||
980         (stctl == SCSW_STCTL_SECONDARY) ||
981         ((stctl & SCSW_STCTL_INTERMEDIATE) && (actl & SCSW_ACTL_SUSP))) {
982         for (i = 0; i < ARRAY_SIZE(dest->emw); i++) {
983             dest->emw[i] = cpu_to_be32(src->emw[i]);
984         }
985     }
986     *irb_len = sizeof(*dest);
987 }
988 
989 int css_do_tsch_get_irb(SubchDev *sch, IRB *target_irb, int *irb_len)
990 {
991     SCSW *s = &sch->curr_status.scsw;
992     PMCW *p = &sch->curr_status.pmcw;
993     uint16_t stctl;
994     IRB irb;
995 
996     if (~(p->flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
997         return 3;
998     }
999 
1000     stctl = s->ctrl & SCSW_CTRL_MASK_STCTL;
1001 
1002     /* Prepare the irb for the guest. */
1003     memset(&irb, 0, sizeof(IRB));
1004 
1005     /* Copy scsw from current status. */
1006     memcpy(&irb.scsw, s, sizeof(SCSW));
1007     if (stctl & SCSW_STCTL_STATUS_PEND) {
1008         if (s->cstat & (SCSW_CSTAT_DATA_CHECK |
1009                         SCSW_CSTAT_CHN_CTRL_CHK |
1010                         SCSW_CSTAT_INTF_CTRL_CHK)) {
1011             irb.scsw.flags |= SCSW_FLAGS_MASK_ESWF;
1012             irb.esw[0] = 0x04804000;
1013         } else {
1014             irb.esw[0] = 0x00800000;
1015         }
1016         /* If a unit check is pending, copy sense data. */
1017         if ((s->dstat & SCSW_DSTAT_UNIT_CHECK) &&
1018             (p->chars & PMCW_CHARS_MASK_CSENSE)) {
1019             int i;
1020 
1021             irb.scsw.flags |= SCSW_FLAGS_MASK_ESWF | SCSW_FLAGS_MASK_ECTL;
1022             /* Attention: sense_data is already BE! */
1023             memcpy(irb.ecw, sch->sense_data, sizeof(sch->sense_data));
1024             for (i = 0; i < ARRAY_SIZE(irb.ecw); i++) {
1025                 irb.ecw[i] = be32_to_cpu(irb.ecw[i]);
1026             }
1027             irb.esw[1] = 0x01000000 | (sizeof(sch->sense_data) << 8);
1028         }
1029     }
1030     /* Store the irb to the guest. */
1031     copy_irb_to_guest(target_irb, &irb, p, irb_len);
1032 
1033     return ((stctl & SCSW_STCTL_STATUS_PEND) == 0);
1034 }
1035 
1036 void css_do_tsch_update_subch(SubchDev *sch)
1037 {
1038     SCSW *s = &sch->curr_status.scsw;
1039     PMCW *p = &sch->curr_status.pmcw;
1040     uint16_t stctl;
1041     uint16_t fctl;
1042     uint16_t actl;
1043 
1044     stctl = s->ctrl & SCSW_CTRL_MASK_STCTL;
1045     fctl = s->ctrl & SCSW_CTRL_MASK_FCTL;
1046     actl = s->ctrl & SCSW_CTRL_MASK_ACTL;
1047 
1048     /* Clear conditions on subchannel, if applicable. */
1049     if (stctl & SCSW_STCTL_STATUS_PEND) {
1050         s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
1051         if ((stctl != (SCSW_STCTL_INTERMEDIATE | SCSW_STCTL_STATUS_PEND)) ||
1052             ((fctl & SCSW_FCTL_HALT_FUNC) &&
1053              (actl & SCSW_ACTL_SUSP))) {
1054             s->ctrl &= ~SCSW_CTRL_MASK_FCTL;
1055         }
1056         if (stctl != (SCSW_STCTL_INTERMEDIATE | SCSW_STCTL_STATUS_PEND)) {
1057             s->flags &= ~SCSW_FLAGS_MASK_PNO;
1058             s->ctrl &= ~(SCSW_ACTL_RESUME_PEND |
1059                          SCSW_ACTL_START_PEND |
1060                          SCSW_ACTL_HALT_PEND |
1061                          SCSW_ACTL_CLEAR_PEND |
1062                          SCSW_ACTL_SUSP);
1063         } else {
1064             if ((actl & SCSW_ACTL_SUSP) &&
1065                 (fctl & SCSW_FCTL_START_FUNC)) {
1066                 s->flags &= ~SCSW_FLAGS_MASK_PNO;
1067                 if (fctl & SCSW_FCTL_HALT_FUNC) {
1068                     s->ctrl &= ~(SCSW_ACTL_RESUME_PEND |
1069                                  SCSW_ACTL_START_PEND |
1070                                  SCSW_ACTL_HALT_PEND |
1071                                  SCSW_ACTL_CLEAR_PEND |
1072                                  SCSW_ACTL_SUSP);
1073                 } else {
1074                     s->ctrl &= ~SCSW_ACTL_RESUME_PEND;
1075                 }
1076             }
1077         }
1078         /* Clear pending sense data. */
1079         if (p->chars & PMCW_CHARS_MASK_CSENSE) {
1080             memset(sch->sense_data, 0 , sizeof(sch->sense_data));
1081         }
1082     }
1083 }
1084 
1085 static void copy_crw_to_guest(CRW *dest, const CRW *src)
1086 {
1087     dest->flags = cpu_to_be16(src->flags);
1088     dest->rsid = cpu_to_be16(src->rsid);
1089 }
1090 
1091 int css_do_stcrw(CRW *crw)
1092 {
1093     CrwContainer *crw_cont;
1094     int ret;
1095 
1096     crw_cont = QTAILQ_FIRST(&channel_subsys.pending_crws);
1097     if (crw_cont) {
1098         QTAILQ_REMOVE(&channel_subsys.pending_crws, crw_cont, sibling);
1099         copy_crw_to_guest(crw, &crw_cont->crw);
1100         g_free(crw_cont);
1101         ret = 0;
1102     } else {
1103         /* List was empty, turn crw machine checks on again. */
1104         memset(crw, 0, sizeof(*crw));
1105         channel_subsys.do_crw_mchk = true;
1106         ret = 1;
1107     }
1108 
1109     return ret;
1110 }
1111 
1112 static void copy_crw_from_guest(CRW *dest, const CRW *src)
1113 {
1114     dest->flags = be16_to_cpu(src->flags);
1115     dest->rsid = be16_to_cpu(src->rsid);
1116 }
1117 
1118 void css_undo_stcrw(CRW *crw)
1119 {
1120     CrwContainer *crw_cont;
1121 
1122     crw_cont = g_try_malloc0(sizeof(CrwContainer));
1123     if (!crw_cont) {
1124         channel_subsys.crws_lost = true;
1125         return;
1126     }
1127     copy_crw_from_guest(&crw_cont->crw, crw);
1128 
1129     QTAILQ_INSERT_HEAD(&channel_subsys.pending_crws, crw_cont, sibling);
1130 }
1131 
1132 int css_do_tpi(IOIntCode *int_code, int lowcore)
1133 {
1134     /* No pending interrupts for !KVM. */
1135     return 0;
1136  }
1137 
1138 int css_collect_chp_desc(int m, uint8_t cssid, uint8_t f_chpid, uint8_t l_chpid,
1139                          int rfmt, void *buf)
1140 {
1141     int i, desc_size;
1142     uint32_t words[8];
1143     uint32_t chpid_type_word;
1144     CssImage *css;
1145 
1146     if (!m && !cssid) {
1147         css = channel_subsys.css[channel_subsys.default_cssid];
1148     } else {
1149         css = channel_subsys.css[cssid];
1150     }
1151     if (!css) {
1152         return 0;
1153     }
1154     desc_size = 0;
1155     for (i = f_chpid; i <= l_chpid; i++) {
1156         if (css->chpids[i].in_use) {
1157             chpid_type_word = 0x80000000 | (css->chpids[i].type << 8) | i;
1158             if (rfmt == 0) {
1159                 words[0] = cpu_to_be32(chpid_type_word);
1160                 words[1] = 0;
1161                 memcpy(buf + desc_size, words, 8);
1162                 desc_size += 8;
1163             } else if (rfmt == 1) {
1164                 words[0] = cpu_to_be32(chpid_type_word);
1165                 words[1] = 0;
1166                 words[2] = 0;
1167                 words[3] = 0;
1168                 words[4] = 0;
1169                 words[5] = 0;
1170                 words[6] = 0;
1171                 words[7] = 0;
1172                 memcpy(buf + desc_size, words, 32);
1173                 desc_size += 32;
1174             }
1175         }
1176     }
1177     return desc_size;
1178 }
1179 
1180 void css_do_schm(uint8_t mbk, int update, int dct, uint64_t mbo)
1181 {
1182     /* dct is currently ignored (not really meaningful for our devices) */
1183     /* TODO: Don't ignore mbk. */
1184     if (update && !channel_subsys.chnmon_active) {
1185         /* Enable measuring. */
1186         channel_subsys.chnmon_area = mbo;
1187         channel_subsys.chnmon_active = true;
1188     }
1189     if (!update && channel_subsys.chnmon_active) {
1190         /* Disable measuring. */
1191         channel_subsys.chnmon_area = 0;
1192         channel_subsys.chnmon_active = false;
1193     }
1194 }
1195 
1196 int css_do_rsch(SubchDev *sch)
1197 {
1198     SCSW *s = &sch->curr_status.scsw;
1199     PMCW *p = &sch->curr_status.pmcw;
1200     int ret;
1201 
1202     if (~(p->flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
1203         ret = -ENODEV;
1204         goto out;
1205     }
1206 
1207     if (s->ctrl & SCSW_STCTL_STATUS_PEND) {
1208         ret = -EINPROGRESS;
1209         goto out;
1210     }
1211 
1212     if (((s->ctrl & SCSW_CTRL_MASK_FCTL) != SCSW_FCTL_START_FUNC) ||
1213         (s->ctrl & SCSW_ACTL_RESUME_PEND) ||
1214         (!(s->ctrl & SCSW_ACTL_SUSP))) {
1215         ret = -EINVAL;
1216         goto out;
1217     }
1218 
1219     /* If monitoring is active, update counter. */
1220     if (channel_subsys.chnmon_active) {
1221         css_update_chnmon(sch);
1222     }
1223 
1224     s->ctrl |= SCSW_ACTL_RESUME_PEND;
1225     do_subchannel_work(sch, NULL);
1226     ret = 0;
1227 
1228 out:
1229     return ret;
1230 }
1231 
1232 int css_do_rchp(uint8_t cssid, uint8_t chpid)
1233 {
1234     uint8_t real_cssid;
1235 
1236     if (cssid > channel_subsys.max_cssid) {
1237         return -EINVAL;
1238     }
1239     if (channel_subsys.max_cssid == 0) {
1240         real_cssid = channel_subsys.default_cssid;
1241     } else {
1242         real_cssid = cssid;
1243     }
1244     if (!channel_subsys.css[real_cssid]) {
1245         return -EINVAL;
1246     }
1247 
1248     if (!channel_subsys.css[real_cssid]->chpids[chpid].in_use) {
1249         return -ENODEV;
1250     }
1251 
1252     if (!channel_subsys.css[real_cssid]->chpids[chpid].is_virtual) {
1253         fprintf(stderr,
1254                 "rchp unsupported for non-virtual chpid %x.%02x!\n",
1255                 real_cssid, chpid);
1256         return -ENODEV;
1257     }
1258 
1259     /* We don't really use a channel path, so we're done here. */
1260     css_queue_crw(CRW_RSC_CHP, CRW_ERC_INIT,
1261                   channel_subsys.max_cssid > 0 ? 1 : 0, chpid);
1262     if (channel_subsys.max_cssid > 0) {
1263         css_queue_crw(CRW_RSC_CHP, CRW_ERC_INIT, 0, real_cssid << 8);
1264     }
1265     return 0;
1266 }
1267 
1268 bool css_schid_final(int m, uint8_t cssid, uint8_t ssid, uint16_t schid)
1269 {
1270     SubchSet *set;
1271     uint8_t real_cssid;
1272 
1273     real_cssid = (!m && (cssid == 0)) ? channel_subsys.default_cssid : cssid;
1274     if (ssid > MAX_SSID ||
1275         !channel_subsys.css[real_cssid] ||
1276         !channel_subsys.css[real_cssid]->sch_set[ssid]) {
1277         return true;
1278     }
1279     set = channel_subsys.css[real_cssid]->sch_set[ssid];
1280     return schid > find_last_bit(set->schids_used,
1281                                  (MAX_SCHID + 1) / sizeof(unsigned long));
1282 }
1283 
1284 static int css_add_virtual_chpid(uint8_t cssid, uint8_t chpid, uint8_t type)
1285 {
1286     CssImage *css;
1287 
1288     trace_css_chpid_add(cssid, chpid, type);
1289     css = channel_subsys.css[cssid];
1290     if (!css) {
1291         return -EINVAL;
1292     }
1293     if (css->chpids[chpid].in_use) {
1294         return -EEXIST;
1295     }
1296     css->chpids[chpid].in_use = 1;
1297     css->chpids[chpid].type = type;
1298     css->chpids[chpid].is_virtual = 1;
1299 
1300     css_generate_chp_crws(cssid, chpid);
1301 
1302     return 0;
1303 }
1304 
1305 void css_sch_build_virtual_schib(SubchDev *sch, uint8_t chpid, uint8_t type)
1306 {
1307     PMCW *p = &sch->curr_status.pmcw;
1308     SCSW *s = &sch->curr_status.scsw;
1309     int i;
1310     CssImage *css = channel_subsys.css[sch->cssid];
1311 
1312     assert(css != NULL);
1313     memset(p, 0, sizeof(PMCW));
1314     p->flags |= PMCW_FLAGS_MASK_DNV;
1315     p->devno = sch->devno;
1316     /* single path */
1317     p->pim = 0x80;
1318     p->pom = 0xff;
1319     p->pam = 0x80;
1320     p->chpid[0] = chpid;
1321     if (!css->chpids[chpid].in_use) {
1322         css_add_virtual_chpid(sch->cssid, chpid, type);
1323     }
1324 
1325     memset(s, 0, sizeof(SCSW));
1326     sch->curr_status.mba = 0;
1327     for (i = 0; i < ARRAY_SIZE(sch->curr_status.mda); i++) {
1328         sch->curr_status.mda[i] = 0;
1329     }
1330 }
1331 
1332 SubchDev *css_find_subch(uint8_t m, uint8_t cssid, uint8_t ssid, uint16_t schid)
1333 {
1334     uint8_t real_cssid;
1335 
1336     real_cssid = (!m && (cssid == 0)) ? channel_subsys.default_cssid : cssid;
1337 
1338     if (!channel_subsys.css[real_cssid]) {
1339         return NULL;
1340     }
1341 
1342     if (!channel_subsys.css[real_cssid]->sch_set[ssid]) {
1343         return NULL;
1344     }
1345 
1346     return channel_subsys.css[real_cssid]->sch_set[ssid]->sch[schid];
1347 }
1348 
1349 /**
1350  * Return free device number in subchannel set.
1351  *
1352  * Return index of the first free device number in the subchannel set
1353  * identified by @p cssid and @p ssid, beginning the search at @p
1354  * start and wrapping around at MAX_DEVNO. Return a value exceeding
1355  * MAX_SCHID if there are no free device numbers in the subchannel
1356  * set.
1357  */
1358 static uint32_t css_find_free_devno(uint8_t cssid, uint8_t ssid,
1359                                     uint16_t start)
1360 {
1361     uint32_t round;
1362 
1363     for (round = 0; round <= MAX_DEVNO; round++) {
1364         uint16_t devno = (start + round) % MAX_DEVNO;
1365 
1366         if (!css_devno_used(cssid, ssid, devno)) {
1367             return devno;
1368         }
1369     }
1370     return MAX_DEVNO + 1;
1371 }
1372 
1373 /**
1374  * Return first free subchannel (id) in subchannel set.
1375  *
1376  * Return index of the first free subchannel in the subchannel set
1377  * identified by @p cssid and @p ssid, if there is any. Return a value
1378  * exceeding MAX_SCHID if there are no free subchannels in the
1379  * subchannel set.
1380  */
1381 static uint32_t css_find_free_subch(uint8_t cssid, uint8_t ssid)
1382 {
1383     uint32_t schid;
1384 
1385     for (schid = 0; schid <= MAX_SCHID; schid++) {
1386         if (!css_find_subch(1, cssid, ssid, schid)) {
1387             return schid;
1388         }
1389     }
1390     return MAX_SCHID + 1;
1391 }
1392 
1393 /**
1394  * Return first free subchannel (id) in subchannel set for a device number
1395  *
1396  * Verify the device number @p devno is not used yet in the subchannel
1397  * set identified by @p cssid and @p ssid. Set @p schid to the index
1398  * of the first free subchannel in the subchannel set, if there is
1399  * any. Return true if everything succeeded and false otherwise.
1400  */
1401 static bool css_find_free_subch_for_devno(uint8_t cssid, uint8_t ssid,
1402                                           uint16_t devno, uint16_t *schid,
1403                                           Error **errp)
1404 {
1405     uint32_t free_schid;
1406 
1407     assert(schid);
1408     if (css_devno_used(cssid, ssid, devno)) {
1409         error_setg(errp, "Device %x.%x.%04x already exists",
1410                    cssid, ssid, devno);
1411         return false;
1412     }
1413     free_schid = css_find_free_subch(cssid, ssid);
1414     if (free_schid > MAX_SCHID) {
1415         error_setg(errp, "No free subchannel found for %x.%x.%04x",
1416                    cssid, ssid, devno);
1417         return false;
1418     }
1419     *schid = free_schid;
1420     return true;
1421 }
1422 
1423 /**
1424  * Return first free subchannel (id) and device number
1425  *
1426  * Locate the first free subchannel and first free device number in
1427  * any of the subchannel sets of the channel subsystem identified by
1428  * @p cssid. Return false if no free subchannel / device number could
1429  * be found. Otherwise set @p ssid, @p devno and @p schid to identify
1430  * the available subchannel and device number and return true.
1431  *
1432  * May modify @p ssid, @p devno and / or @p schid even if no free
1433  * subchannel / device number could be found.
1434  */
1435 static bool css_find_free_subch_and_devno(uint8_t cssid, uint8_t *ssid,
1436                                           uint16_t *devno, uint16_t *schid,
1437                                           Error **errp)
1438 {
1439     uint32_t free_schid, free_devno;
1440 
1441     assert(ssid && devno && schid);
1442     for (*ssid = 0; *ssid <= MAX_SSID; (*ssid)++) {
1443         free_schid = css_find_free_subch(cssid, *ssid);
1444         if (free_schid > MAX_SCHID) {
1445             continue;
1446         }
1447         free_devno = css_find_free_devno(cssid, *ssid, free_schid);
1448         if (free_devno > MAX_DEVNO) {
1449             continue;
1450         }
1451         *schid = free_schid;
1452         *devno = free_devno;
1453         return true;
1454     }
1455     error_setg(errp, "Virtual channel subsystem is full!");
1456     return false;
1457 }
1458 
1459 bool css_subch_visible(SubchDev *sch)
1460 {
1461     if (sch->ssid > channel_subsys.max_ssid) {
1462         return false;
1463     }
1464 
1465     if (sch->cssid != channel_subsys.default_cssid) {
1466         return (channel_subsys.max_cssid > 0);
1467     }
1468 
1469     return true;
1470 }
1471 
1472 bool css_present(uint8_t cssid)
1473 {
1474     return (channel_subsys.css[cssid] != NULL);
1475 }
1476 
1477 bool css_devno_used(uint8_t cssid, uint8_t ssid, uint16_t devno)
1478 {
1479     if (!channel_subsys.css[cssid]) {
1480         return false;
1481     }
1482     if (!channel_subsys.css[cssid]->sch_set[ssid]) {
1483         return false;
1484     }
1485 
1486     return !!test_bit(devno,
1487                       channel_subsys.css[cssid]->sch_set[ssid]->devnos_used);
1488 }
1489 
1490 void css_subch_assign(uint8_t cssid, uint8_t ssid, uint16_t schid,
1491                       uint16_t devno, SubchDev *sch)
1492 {
1493     CssImage *css;
1494     SubchSet *s_set;
1495 
1496     trace_css_assign_subch(sch ? "assign" : "deassign", cssid, ssid, schid,
1497                            devno);
1498     if (!channel_subsys.css[cssid]) {
1499         fprintf(stderr,
1500                 "Suspicious call to %s (%x.%x.%04x) for non-existing css!\n",
1501                 __func__, cssid, ssid, schid);
1502         return;
1503     }
1504     css = channel_subsys.css[cssid];
1505 
1506     if (!css->sch_set[ssid]) {
1507         css->sch_set[ssid] = g_malloc0(sizeof(SubchSet));
1508     }
1509     s_set = css->sch_set[ssid];
1510 
1511     s_set->sch[schid] = sch;
1512     if (sch) {
1513         set_bit(schid, s_set->schids_used);
1514         set_bit(devno, s_set->devnos_used);
1515     } else {
1516         clear_bit(schid, s_set->schids_used);
1517         clear_bit(devno, s_set->devnos_used);
1518     }
1519 }
1520 
1521 void css_queue_crw(uint8_t rsc, uint8_t erc, int chain, uint16_t rsid)
1522 {
1523     CrwContainer *crw_cont;
1524 
1525     trace_css_crw(rsc, erc, rsid, chain ? "(chained)" : "");
1526     /* TODO: Maybe use a static crw pool? */
1527     crw_cont = g_try_malloc0(sizeof(CrwContainer));
1528     if (!crw_cont) {
1529         channel_subsys.crws_lost = true;
1530         return;
1531     }
1532     crw_cont->crw.flags = (rsc << 8) | erc;
1533     if (chain) {
1534         crw_cont->crw.flags |= CRW_FLAGS_MASK_C;
1535     }
1536     crw_cont->crw.rsid = rsid;
1537     if (channel_subsys.crws_lost) {
1538         crw_cont->crw.flags |= CRW_FLAGS_MASK_R;
1539         channel_subsys.crws_lost = false;
1540     }
1541 
1542     QTAILQ_INSERT_TAIL(&channel_subsys.pending_crws, crw_cont, sibling);
1543 
1544     if (channel_subsys.do_crw_mchk) {
1545         channel_subsys.do_crw_mchk = false;
1546         /* Inject crw pending machine check. */
1547         s390_crw_mchk();
1548     }
1549 }
1550 
1551 void css_generate_sch_crws(uint8_t cssid, uint8_t ssid, uint16_t schid,
1552                            int hotplugged, int add)
1553 {
1554     uint8_t guest_cssid;
1555     bool chain_crw;
1556 
1557     if (add && !hotplugged) {
1558         return;
1559     }
1560     if (channel_subsys.max_cssid == 0) {
1561         /* Default cssid shows up as 0. */
1562         guest_cssid = (cssid == channel_subsys.default_cssid) ? 0 : cssid;
1563     } else {
1564         /* Show real cssid to the guest. */
1565         guest_cssid = cssid;
1566     }
1567     /*
1568      * Only notify for higher subchannel sets/channel subsystems if the
1569      * guest has enabled it.
1570      */
1571     if ((ssid > channel_subsys.max_ssid) ||
1572         (guest_cssid > channel_subsys.max_cssid) ||
1573         ((channel_subsys.max_cssid == 0) &&
1574          (cssid != channel_subsys.default_cssid))) {
1575         return;
1576     }
1577     chain_crw = (channel_subsys.max_ssid > 0) ||
1578             (channel_subsys.max_cssid > 0);
1579     css_queue_crw(CRW_RSC_SUBCH, CRW_ERC_IPI, chain_crw ? 1 : 0, schid);
1580     if (chain_crw) {
1581         css_queue_crw(CRW_RSC_SUBCH, CRW_ERC_IPI, 0,
1582                       (guest_cssid << 8) | (ssid << 4));
1583     }
1584     /* RW_ERC_IPI --> clear pending interrupts */
1585     css_clear_io_interrupt(css_do_build_subchannel_id(cssid, ssid), schid);
1586 }
1587 
1588 void css_generate_chp_crws(uint8_t cssid, uint8_t chpid)
1589 {
1590     /* TODO */
1591 }
1592 
1593 void css_generate_css_crws(uint8_t cssid)
1594 {
1595     if (!channel_subsys.sei_pending) {
1596         css_queue_crw(CRW_RSC_CSS, 0, 0, cssid);
1597     }
1598     channel_subsys.sei_pending = true;
1599 }
1600 
1601 void css_clear_sei_pending(void)
1602 {
1603     channel_subsys.sei_pending = false;
1604 }
1605 
1606 int css_enable_mcsse(void)
1607 {
1608     trace_css_enable_facility("mcsse");
1609     channel_subsys.max_cssid = MAX_CSSID;
1610     return 0;
1611 }
1612 
1613 int css_enable_mss(void)
1614 {
1615     trace_css_enable_facility("mss");
1616     channel_subsys.max_ssid = MAX_SSID;
1617     return 0;
1618 }
1619 
1620 void subch_device_save(SubchDev *s, QEMUFile *f)
1621 {
1622     int i;
1623 
1624     qemu_put_byte(f, s->cssid);
1625     qemu_put_byte(f, s->ssid);
1626     qemu_put_be16(f, s->schid);
1627     qemu_put_be16(f, s->devno);
1628     qemu_put_byte(f, s->thinint_active);
1629     /* SCHIB */
1630     /*     PMCW */
1631     qemu_put_be32(f, s->curr_status.pmcw.intparm);
1632     qemu_put_be16(f, s->curr_status.pmcw.flags);
1633     qemu_put_be16(f, s->curr_status.pmcw.devno);
1634     qemu_put_byte(f, s->curr_status.pmcw.lpm);
1635     qemu_put_byte(f, s->curr_status.pmcw.pnom);
1636     qemu_put_byte(f, s->curr_status.pmcw.lpum);
1637     qemu_put_byte(f, s->curr_status.pmcw.pim);
1638     qemu_put_be16(f, s->curr_status.pmcw.mbi);
1639     qemu_put_byte(f, s->curr_status.pmcw.pom);
1640     qemu_put_byte(f, s->curr_status.pmcw.pam);
1641     qemu_put_buffer(f, s->curr_status.pmcw.chpid, 8);
1642     qemu_put_be32(f, s->curr_status.pmcw.chars);
1643     /*     SCSW */
1644     qemu_put_be16(f, s->curr_status.scsw.flags);
1645     qemu_put_be16(f, s->curr_status.scsw.ctrl);
1646     qemu_put_be32(f, s->curr_status.scsw.cpa);
1647     qemu_put_byte(f, s->curr_status.scsw.dstat);
1648     qemu_put_byte(f, s->curr_status.scsw.cstat);
1649     qemu_put_be16(f, s->curr_status.scsw.count);
1650     qemu_put_be64(f, s->curr_status.mba);
1651     qemu_put_buffer(f, s->curr_status.mda, 4);
1652     /* end SCHIB */
1653     qemu_put_buffer(f, s->sense_data, 32);
1654     qemu_put_be64(f, s->channel_prog);
1655     /* last cmd */
1656     qemu_put_byte(f, s->last_cmd.cmd_code);
1657     qemu_put_byte(f, s->last_cmd.flags);
1658     qemu_put_be16(f, s->last_cmd.count);
1659     qemu_put_be32(f, s->last_cmd.cda);
1660     qemu_put_byte(f, s->last_cmd_valid);
1661     qemu_put_byte(f, s->id.reserved);
1662     qemu_put_be16(f, s->id.cu_type);
1663     qemu_put_byte(f, s->id.cu_model);
1664     qemu_put_be16(f, s->id.dev_type);
1665     qemu_put_byte(f, s->id.dev_model);
1666     qemu_put_byte(f, s->id.unused);
1667     for (i = 0; i < ARRAY_SIZE(s->id.ciw); i++) {
1668         qemu_put_byte(f, s->id.ciw[i].type);
1669         qemu_put_byte(f, s->id.ciw[i].command);
1670         qemu_put_be16(f, s->id.ciw[i].count);
1671     }
1672     qemu_put_byte(f, s->ccw_fmt_1);
1673     qemu_put_byte(f, s->ccw_no_data_cnt);
1674 }
1675 
1676 int subch_device_load(SubchDev *s, QEMUFile *f)
1677 {
1678     int i;
1679 
1680     s->cssid = qemu_get_byte(f);
1681     s->ssid = qemu_get_byte(f);
1682     s->schid = qemu_get_be16(f);
1683     s->devno = qemu_get_be16(f);
1684     s->thinint_active = qemu_get_byte(f);
1685     /* SCHIB */
1686     /*     PMCW */
1687     s->curr_status.pmcw.intparm = qemu_get_be32(f);
1688     s->curr_status.pmcw.flags = qemu_get_be16(f);
1689     s->curr_status.pmcw.devno = qemu_get_be16(f);
1690     s->curr_status.pmcw.lpm = qemu_get_byte(f);
1691     s->curr_status.pmcw.pnom  = qemu_get_byte(f);
1692     s->curr_status.pmcw.lpum = qemu_get_byte(f);
1693     s->curr_status.pmcw.pim = qemu_get_byte(f);
1694     s->curr_status.pmcw.mbi = qemu_get_be16(f);
1695     s->curr_status.pmcw.pom = qemu_get_byte(f);
1696     s->curr_status.pmcw.pam = qemu_get_byte(f);
1697     qemu_get_buffer(f, s->curr_status.pmcw.chpid, 8);
1698     s->curr_status.pmcw.chars = qemu_get_be32(f);
1699     /*     SCSW */
1700     s->curr_status.scsw.flags = qemu_get_be16(f);
1701     s->curr_status.scsw.ctrl = qemu_get_be16(f);
1702     s->curr_status.scsw.cpa = qemu_get_be32(f);
1703     s->curr_status.scsw.dstat = qemu_get_byte(f);
1704     s->curr_status.scsw.cstat = qemu_get_byte(f);
1705     s->curr_status.scsw.count = qemu_get_be16(f);
1706     s->curr_status.mba = qemu_get_be64(f);
1707     qemu_get_buffer(f, s->curr_status.mda, 4);
1708     /* end SCHIB */
1709     qemu_get_buffer(f, s->sense_data, 32);
1710     s->channel_prog = qemu_get_be64(f);
1711     /* last cmd */
1712     s->last_cmd.cmd_code = qemu_get_byte(f);
1713     s->last_cmd.flags = qemu_get_byte(f);
1714     s->last_cmd.count = qemu_get_be16(f);
1715     s->last_cmd.cda = qemu_get_be32(f);
1716     s->last_cmd_valid = qemu_get_byte(f);
1717     s->id.reserved = qemu_get_byte(f);
1718     s->id.cu_type = qemu_get_be16(f);
1719     s->id.cu_model = qemu_get_byte(f);
1720     s->id.dev_type = qemu_get_be16(f);
1721     s->id.dev_model = qemu_get_byte(f);
1722     s->id.unused = qemu_get_byte(f);
1723     for (i = 0; i < ARRAY_SIZE(s->id.ciw); i++) {
1724         s->id.ciw[i].type = qemu_get_byte(f);
1725         s->id.ciw[i].command = qemu_get_byte(f);
1726         s->id.ciw[i].count = qemu_get_be16(f);
1727     }
1728     s->ccw_fmt_1 = qemu_get_byte(f);
1729     s->ccw_no_data_cnt = qemu_get_byte(f);
1730     /*
1731      * Hack alert. We don't migrate the channel subsystem status (no
1732      * device!), but we need to find out if the guest enabled mss/mcss-e.
1733      * If the subchannel is enabled, it certainly was able to access it,
1734      * so adjust the max_ssid/max_cssid values for relevant ssid/cssid
1735      * values. This is not watertight, but better than nothing.
1736      */
1737     if (s->curr_status.pmcw.flags & PMCW_FLAGS_MASK_ENA) {
1738         if (s->ssid) {
1739             channel_subsys.max_ssid = MAX_SSID;
1740         }
1741         if (s->cssid != channel_subsys.default_cssid) {
1742             channel_subsys.max_cssid = MAX_CSSID;
1743         }
1744     }
1745     return 0;
1746 }
1747 
1748 void css_reset_sch(SubchDev *sch)
1749 {
1750     PMCW *p = &sch->curr_status.pmcw;
1751 
1752     if ((p->flags & PMCW_FLAGS_MASK_ENA) != 0 && sch->disable_cb) {
1753         sch->disable_cb(sch);
1754     }
1755 
1756     p->intparm = 0;
1757     p->flags &= ~(PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA |
1758                   PMCW_FLAGS_MASK_LM | PMCW_FLAGS_MASK_MME |
1759                   PMCW_FLAGS_MASK_MP | PMCW_FLAGS_MASK_TF);
1760     p->flags |= PMCW_FLAGS_MASK_DNV;
1761     p->devno = sch->devno;
1762     p->pim = 0x80;
1763     p->lpm = p->pim;
1764     p->pnom = 0;
1765     p->lpum = 0;
1766     p->mbi = 0;
1767     p->pom = 0xff;
1768     p->pam = 0x80;
1769     p->chars &= ~(PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_XMWME |
1770                   PMCW_CHARS_MASK_CSENSE);
1771 
1772     memset(&sch->curr_status.scsw, 0, sizeof(sch->curr_status.scsw));
1773     sch->curr_status.mba = 0;
1774 
1775     sch->channel_prog = 0x0;
1776     sch->last_cmd_valid = false;
1777     sch->thinint_active = false;
1778 }
1779 
1780 void css_reset(void)
1781 {
1782     CrwContainer *crw_cont;
1783 
1784     /* Clean up monitoring. */
1785     channel_subsys.chnmon_active = false;
1786     channel_subsys.chnmon_area = 0;
1787 
1788     /* Clear pending CRWs. */
1789     while ((crw_cont = QTAILQ_FIRST(&channel_subsys.pending_crws))) {
1790         QTAILQ_REMOVE(&channel_subsys.pending_crws, crw_cont, sibling);
1791         g_free(crw_cont);
1792     }
1793     channel_subsys.sei_pending = false;
1794     channel_subsys.do_crw_mchk = true;
1795     channel_subsys.crws_lost = false;
1796 
1797     /* Reset maximum ids. */
1798     channel_subsys.max_cssid = 0;
1799     channel_subsys.max_ssid = 0;
1800 }
1801 
1802 static void get_css_devid(Object *obj, Visitor *v, const char *name,
1803                           void *opaque, Error **errp)
1804 {
1805     DeviceState *dev = DEVICE(obj);
1806     Property *prop = opaque;
1807     CssDevId *dev_id = qdev_get_prop_ptr(dev, prop);
1808     char buffer[] = "xx.x.xxxx";
1809     char *p = buffer;
1810     int r;
1811 
1812     if (dev_id->valid) {
1813 
1814         r = snprintf(buffer, sizeof(buffer), "%02x.%1x.%04x", dev_id->cssid,
1815                      dev_id->ssid, dev_id->devid);
1816         assert(r == sizeof(buffer) - 1);
1817 
1818         /* drop leading zero */
1819         if (dev_id->cssid <= 0xf) {
1820             p++;
1821         }
1822     } else {
1823         snprintf(buffer, sizeof(buffer), "<unset>");
1824     }
1825 
1826     visit_type_str(v, name, &p, errp);
1827 }
1828 
1829 /*
1830  * parse <cssid>.<ssid>.<devid> and assert valid range for cssid/ssid
1831  */
1832 static void set_css_devid(Object *obj, Visitor *v, const char *name,
1833                           void *opaque, Error **errp)
1834 {
1835     DeviceState *dev = DEVICE(obj);
1836     Property *prop = opaque;
1837     CssDevId *dev_id = qdev_get_prop_ptr(dev, prop);
1838     Error *local_err = NULL;
1839     char *str;
1840     int num, n1, n2;
1841     unsigned int cssid, ssid, devid;
1842 
1843     if (dev->realized) {
1844         qdev_prop_set_after_realize(dev, name, errp);
1845         return;
1846     }
1847 
1848     visit_type_str(v, name, &str, &local_err);
1849     if (local_err) {
1850         error_propagate(errp, local_err);
1851         return;
1852     }
1853 
1854     num = sscanf(str, "%2x.%1x%n.%4x%n", &cssid, &ssid, &n1, &devid, &n2);
1855     if (num != 3 || (n2 - n1) != 5 || strlen(str) != n2) {
1856         error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
1857         goto out;
1858     }
1859     if ((cssid > MAX_CSSID) || (ssid > MAX_SSID)) {
1860         error_setg(errp, "Invalid cssid or ssid: cssid %x, ssid %x",
1861                    cssid, ssid);
1862         goto out;
1863     }
1864 
1865     dev_id->cssid = cssid;
1866     dev_id->ssid = ssid;
1867     dev_id->devid = devid;
1868     dev_id->valid = true;
1869 
1870 out:
1871     g_free(str);
1872 }
1873 
1874 PropertyInfo css_devid_propinfo = {
1875     .name = "str",
1876     .description = "Identifier of an I/O device in the channel "
1877                    "subsystem, example: fe.1.23ab",
1878     .get = get_css_devid,
1879     .set = set_css_devid,
1880 };
1881 
1882 SubchDev *css_create_virtual_sch(CssDevId bus_id, Error **errp)
1883 {
1884     uint16_t schid = 0;
1885     SubchDev *sch;
1886 
1887     if (bus_id.valid) {
1888         /* Enforce use of virtual cssid. */
1889         if (bus_id.cssid != VIRTUAL_CSSID) {
1890             error_setg(errp, "cssid %hhx not valid for virtual devices",
1891                        bus_id.cssid);
1892             return NULL;
1893         }
1894         if (!css_find_free_subch_for_devno(bus_id.cssid, bus_id.ssid,
1895                                            bus_id.devid, &schid, errp)) {
1896             return NULL;
1897         }
1898     } else {
1899         bus_id.cssid = VIRTUAL_CSSID;
1900         if (!css_find_free_subch_and_devno(bus_id.cssid, &bus_id.ssid,
1901                                            &bus_id.devid, &schid, errp)) {
1902             return NULL;
1903         }
1904     }
1905 
1906     sch = g_malloc0(sizeof(*sch));
1907     sch->cssid = bus_id.cssid;
1908     sch->ssid = bus_id.ssid;
1909     sch->devno = bus_id.devid;
1910     sch->schid = schid;
1911     css_subch_assign(sch->cssid, sch->ssid, schid, sch->devno, sch);
1912     return sch;
1913 }
1914