aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/block/dataplane/xen-block.c28
-rw-r--r--hw/block/xen-block.c22
-rw-r--r--hw/block/xen_blkif.h2
-rw-r--r--hw/s390x/3270-ccw.c8
-rw-r--r--hw/s390x/css.c388
-rw-r--r--hw/s390x/ipl.c12
-rw-r--r--hw/vfio/ccw.c42
7 files changed, 250 insertions, 252 deletions
diff --git a/hw/block/dataplane/xen-block.c b/hw/block/dataplane/xen-block.c
index f1523c5b45..bb8f1186e4 100644
--- a/hw/block/dataplane/xen-block.c
+++ b/hw/block/dataplane/xen-block.c
@@ -49,7 +49,6 @@ struct XenBlockDataPlane {
unsigned int *ring_ref;
unsigned int nr_ring_ref;
void *sring;
- int64_t file_blk;
int protocol;
blkif_back_rings_t rings;
int more_work;
@@ -168,7 +167,7 @@ static int xen_block_parse_request(XenBlockRequest *request)
goto err;
}
- request->start = request->req.sector_number * dataplane->file_blk;
+ request->start = request->req.sector_number * XEN_BLKIF_SECTOR_SIZE;
for (i = 0; i < request->req.nr_segments; i++) {
if (i == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
error_report("error: nr_segments too big");
@@ -178,14 +177,14 @@ static int xen_block_parse_request(XenBlockRequest *request)
error_report("error: first > last sector");
goto err;
}
- if (request->req.seg[i].last_sect * dataplane->file_blk >=
+ if (request->req.seg[i].last_sect * XEN_BLKIF_SECTOR_SIZE >=
XC_PAGE_SIZE) {
error_report("error: page crossing");
goto err;
}
len = (request->req.seg[i].last_sect -
- request->req.seg[i].first_sect + 1) * dataplane->file_blk;
+ request->req.seg[i].first_sect + 1) * XEN_BLKIF_SECTOR_SIZE;
request->size += len;
}
if (request->start + request->size > blk_getlength(dataplane->blk)) {
@@ -205,7 +204,6 @@ static int xen_block_copy_request(XenBlockRequest *request)
XenDevice *xendev = dataplane->xendev;
XenDeviceGrantCopySegment segs[BLKIF_MAX_SEGMENTS_PER_REQUEST];
int i, count;
- int64_t file_blk = dataplane->file_blk;
bool to_domain = (request->req.operation == BLKIF_OP_READ);
void *virt = request->buf;
Error *local_err = NULL;
@@ -220,16 +218,17 @@ static int xen_block_copy_request(XenBlockRequest *request)
if (to_domain) {
segs[i].dest.foreign.ref = request->req.seg[i].gref;
segs[i].dest.foreign.offset = request->req.seg[i].first_sect *
- file_blk;
+ XEN_BLKIF_SECTOR_SIZE;
segs[i].source.virt = virt;
} else {
segs[i].source.foreign.ref = request->req.seg[i].gref;
segs[i].source.foreign.offset = request->req.seg[i].first_sect *
- file_blk;
+ XEN_BLKIF_SECTOR_SIZE;
segs[i].dest.virt = virt;
}
segs[i].len = (request->req.seg[i].last_sect -
- request->req.seg[i].first_sect + 1) * file_blk;
+ request->req.seg[i].first_sect + 1) *
+ XEN_BLKIF_SECTOR_SIZE;
virt += segs[i].len;
}
@@ -331,22 +330,22 @@ static bool xen_block_split_discard(XenBlockRequest *request,
XenBlockDataPlane *dataplane = request->dataplane;
int64_t byte_offset;
int byte_chunk;
- uint64_t byte_remaining, limit;
+ uint64_t byte_remaining;
uint64_t sec_start = sector_number;
uint64_t sec_count = nr_sectors;
/* Wrap around, or overflowing byte limit? */
if (sec_start + sec_count < sec_count ||
- sec_start + sec_count > INT64_MAX / dataplane->file_blk) {
+ sec_start + sec_count > INT64_MAX / XEN_BLKIF_SECTOR_SIZE) {
return false;
}
- limit = BDRV_REQUEST_MAX_SECTORS * dataplane->file_blk;
- byte_offset = sec_start * dataplane->file_blk;
- byte_remaining = sec_count * dataplane->file_blk;
+ byte_offset = sec_start * XEN_BLKIF_SECTOR_SIZE;
+ byte_remaining = sec_count * XEN_BLKIF_SECTOR_SIZE;
do {
- byte_chunk = byte_remaining > limit ? limit : byte_remaining;
+ byte_chunk = byte_remaining > BDRV_REQUEST_MAX_BYTES ?
+ BDRV_REQUEST_MAX_BYTES : byte_remaining;
request->aio_inflight++;
blk_aio_pdiscard(dataplane->blk, byte_offset, byte_chunk,
xen_block_complete_aio, request);
@@ -632,7 +631,6 @@ XenBlockDataPlane *xen_block_dataplane_create(XenDevice *xendev,
XenBlockDataPlane *dataplane = g_new0(XenBlockDataPlane, 1);
dataplane->xendev = xendev;
- dataplane->file_blk = conf->logical_block_size;
dataplane->blk = conf->blk;
QLIST_INIT(&dataplane->inflight);
diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
index 9c722b9b95..ef635be4c2 100644
--- a/hw/block/xen-block.c
+++ b/hw/block/xen-block.c
@@ -149,7 +149,7 @@ static void xen_block_set_size(XenBlockDevice *blockdev)
const char *type = object_get_typename(OBJECT(blockdev));
XenBlockVdev *vdev = &blockdev->props.vdev;
BlockConf *conf = &blockdev->props.conf;
- int64_t sectors = blk_getlength(conf->blk) / conf->logical_block_size;
+ int64_t sectors = blk_getlength(conf->blk) / XEN_BLKIF_SECTOR_SIZE;
XenDevice *xendev = XEN_DEVICE(blockdev);
trace_xen_block_size(type, vdev->disk, vdev->partition, sectors);
@@ -223,6 +223,12 @@ static void xen_block_realize(XenDevice *xendev, Error **errp)
blkconf_blocksizes(conf);
+ if (conf->logical_block_size != XEN_BLKIF_SECTOR_SIZE) {
+ error_setg(errp, "logical_block_size != %u not supported",
+ XEN_BLKIF_SECTOR_SIZE);
+ return;
+ }
+
if (conf->logical_block_size > conf->physical_block_size) {
error_setg(
errp, "logical_block_size > physical_block_size not supported");
@@ -232,8 +238,14 @@ static void xen_block_realize(XenDevice *xendev, Error **errp)
blk_set_dev_ops(conf->blk, &xen_block_dev_ops, blockdev);
blk_set_guest_block_size(conf->blk, conf->logical_block_size);
- if (conf->discard_granularity > 0) {
+ if (conf->discard_granularity == -1) {
+ conf->discard_granularity = conf->physical_block_size;
+ }
+
+ if (blk_get_flags(conf->blk) & BDRV_O_UNMAP) {
xen_device_backend_printf(xendev, "feature-discard", "%u", 1);
+ xen_device_backend_printf(xendev, "discard-granularity", "%u",
+ conf->discard_granularity);
}
xen_device_backend_printf(xendev, "feature-flush-cache", "%u", 1);
@@ -247,7 +259,7 @@ static void xen_block_realize(XenDevice *xendev, Error **errp)
blockdev->device_type);
xen_device_backend_printf(xendev, "sector-size", "%u",
- conf->logical_block_size);
+ XEN_BLKIF_SECTOR_SIZE);
xen_block_set_size(blockdev);
@@ -755,6 +767,7 @@ static XenBlockDrive *xen_block_drive_create(const char *id,
drive->id = g_strdup(id);
file_layer = qdict_new();
+ driver_layer = qdict_new();
qdict_put_str(file_layer, "driver", "file");
qdict_put_str(file_layer, "filename", filename);
@@ -782,6 +795,7 @@ static XenBlockDrive *xen_block_drive_create(const char *id,
if (!qemu_strtoul(discard_enable, NULL, 2, &value) && !!value) {
qdict_put_str(file_layer, "discard", "unmap");
+ qdict_put_str(driver_layer, "discard", "unmap");
}
}
@@ -791,8 +805,6 @@ static XenBlockDrive *xen_block_drive_create(const char *id,
*/
qdict_put_str(file_layer, "locking", "off");
- driver_layer = qdict_new();
-
qdict_put_str(driver_layer, "driver", driver);
g_free(driver);
diff --git a/hw/block/xen_blkif.h b/hw/block/xen_blkif.h
index 3e6e1ea365..a353693ea0 100644
--- a/hw/block/xen_blkif.h
+++ b/hw/block/xen_blkif.h
@@ -143,4 +143,6 @@ static inline void blkif_get_x86_64_req(blkif_request_t *dst,
}
}
+#define XEN_BLKIF_SECTOR_SIZE 512
+
#endif /* XEN_BLKIF_H */
diff --git a/hw/s390x/3270-ccw.c b/hw/s390x/3270-ccw.c
index 2c8d16ccf7..14882242c3 100644
--- a/hw/s390x/3270-ccw.c
+++ b/hw/s390x/3270-ccw.c
@@ -78,13 +78,13 @@ static int emulated_ccw_3270_cb(SubchDev *sch, CCW1 ccw)
if (rc == -EIO) {
/* I/O error, specific devices generate specific conditions */
- SCSW *s = &sch->curr_status.scsw;
+ SCHIB *schib = &sch->curr_status;
sch->curr_status.scsw.dstat = SCSW_DSTAT_UNIT_CHECK;
sch->sense_data[0] = 0x40; /* intervention-req */
- s->ctrl &= ~SCSW_ACTL_START_PEND;
- s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
- s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
+ schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
+ schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
+ schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
}
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index f92b046cd3..8fc9e35ba5 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -695,35 +695,32 @@ void css_adapter_interrupt(CssIoAdapterType type, uint8_t isc)
static void sch_handle_clear_func(SubchDev *sch)
{
- PMCW *p = &sch->curr_status.pmcw;
- SCSW *s = &sch->curr_status.scsw;
+ SCHIB *schib = &sch->curr_status;
int path;
/* Path management: In our simple css, we always choose the only path. */
path = 0x80;
/* Reset values prior to 'issuing the clear signal'. */
- p->lpum = 0;
- p->pom = 0xff;
- s->flags &= ~SCSW_FLAGS_MASK_PNO;
+ schib->pmcw.lpum = 0;
+ schib->pmcw.pom = 0xff;
+ schib->scsw.flags &= ~SCSW_FLAGS_MASK_PNO;
/* We always 'attempt to issue the clear signal', and we always succeed. */
sch->channel_prog = 0x0;
sch->last_cmd_valid = false;
- s->ctrl &= ~SCSW_ACTL_CLEAR_PEND;
- s->ctrl |= SCSW_STCTL_STATUS_PEND;
+ schib->scsw.ctrl &= ~SCSW_ACTL_CLEAR_PEND;
+ schib->scsw.ctrl |= SCSW_STCTL_STATUS_PEND;
- s->dstat = 0;
- s->cstat = 0;
- p->lpum = path;
+ schib->scsw.dstat = 0;
+ schib->scsw.cstat = 0;
+ schib->pmcw.lpum = path;
}
static void sch_handle_halt_func(SubchDev *sch)
{
-
- PMCW *p = &sch->curr_status.pmcw;
- SCSW *s = &sch->curr_status.scsw;
+ SCHIB *schib = &sch->curr_status;
hwaddr curr_ccw = sch->channel_prog;
int path;
@@ -733,20 +730,22 @@ static void sch_handle_halt_func(SubchDev *sch)
/* We always 'attempt to issue the halt signal', and we always succeed. */
sch->channel_prog = 0x0;
sch->last_cmd_valid = false;
- s->ctrl &= ~SCSW_ACTL_HALT_PEND;
- s->ctrl |= SCSW_STCTL_STATUS_PEND;
+ schib->scsw.ctrl &= ~SCSW_ACTL_HALT_PEND;
+ schib->scsw.ctrl |= SCSW_STCTL_STATUS_PEND;
- if ((s->ctrl & (SCSW_ACTL_SUBCH_ACTIVE | SCSW_ACTL_DEVICE_ACTIVE)) ||
- !((s->ctrl & SCSW_ACTL_START_PEND) ||
- (s->ctrl & SCSW_ACTL_SUSP))) {
- s->dstat = SCSW_DSTAT_DEVICE_END;
+ if ((schib->scsw.ctrl & (SCSW_ACTL_SUBCH_ACTIVE |
+ SCSW_ACTL_DEVICE_ACTIVE)) ||
+ !((schib->scsw.ctrl & SCSW_ACTL_START_PEND) ||
+ (schib->scsw.ctrl & SCSW_ACTL_SUSP))) {
+ schib->scsw.dstat = SCSW_DSTAT_DEVICE_END;
}
- if ((s->ctrl & (SCSW_ACTL_SUBCH_ACTIVE | SCSW_ACTL_DEVICE_ACTIVE)) ||
- (s->ctrl & SCSW_ACTL_SUSP)) {
- s->cpa = curr_ccw + 8;
+ if ((schib->scsw.ctrl & (SCSW_ACTL_SUBCH_ACTIVE |
+ SCSW_ACTL_DEVICE_ACTIVE)) ||
+ (schib->scsw.ctrl & SCSW_ACTL_SUSP)) {
+ schib->scsw.cpa = curr_ccw + 8;
}
- s->cstat = 0;
- p->lpum = path;
+ schib->scsw.cstat = 0;
+ schib->pmcw.lpum = path;
}
@@ -1111,9 +1110,7 @@ static int css_interpret_ccw(SubchDev *sch, hwaddr ccw_addr,
static void sch_handle_start_func_virtual(SubchDev *sch)
{
-
- PMCW *p = &sch->curr_status.pmcw;
- SCSW *s = &sch->curr_status.scsw;
+ SCHIB *schib = &sch->curr_status;
int path;
int ret;
bool suspend_allowed;
@@ -1121,27 +1118,27 @@ static void sch_handle_start_func_virtual(SubchDev *sch)
/* Path management: In our simple css, we always choose the only path. */
path = 0x80;
- if (!(s->ctrl & SCSW_ACTL_SUSP)) {
+ if (!(schib->scsw.ctrl & SCSW_ACTL_SUSP)) {
/* Start Function triggered via ssch, i.e. we have an ORB */
ORB *orb = &sch->orb;
- s->cstat = 0;
- s->dstat = 0;
+ schib->scsw.cstat = 0;
+ schib->scsw.dstat = 0;
/* Look at the orb and try to execute the channel program. */
- p->intparm = orb->intparm;
+ schib->pmcw.intparm = orb->intparm;
if (!(orb->lpm & path)) {
/* Generate a deferred cc 3 condition. */
- s->flags |= SCSW_FLAGS_MASK_CC;
- s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
- s->ctrl |= (SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND);
+ schib->scsw.flags |= SCSW_FLAGS_MASK_CC;
+ schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
+ schib->scsw.ctrl |= (SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND);
return;
}
sch->ccw_fmt_1 = !!(orb->ctrl0 & ORB_CTRL0_MASK_FMT);
- s->flags |= (sch->ccw_fmt_1) ? SCSW_FLAGS_MASK_FMT : 0;
+ schib->scsw.flags |= (sch->ccw_fmt_1) ? SCSW_FLAGS_MASK_FMT : 0;
sch->ccw_no_data_cnt = 0;
suspend_allowed = !!(orb->ctrl0 & ORB_CTRL0_MASK_SPND);
} else {
/* Start Function resumed via rsch */
- s->ctrl &= ~(SCSW_ACTL_SUSP | SCSW_ACTL_RESUME_PEND);
+ schib->scsw.ctrl &= ~(SCSW_ACTL_SUSP | SCSW_ACTL_RESUME_PEND);
/* The channel program had been suspended before. */
suspend_allowed = true;
}
@@ -1154,40 +1151,40 @@ static void sch_handle_start_func_virtual(SubchDev *sch)
break;
case 0:
/* success */
- s->ctrl &= ~SCSW_ACTL_START_PEND;
- s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
- s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
+ schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
+ schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
+ schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
SCSW_STCTL_STATUS_PEND;
- s->dstat = SCSW_DSTAT_CHANNEL_END | SCSW_DSTAT_DEVICE_END;
- s->cpa = sch->channel_prog + 8;
+ schib->scsw.dstat = SCSW_DSTAT_CHANNEL_END | SCSW_DSTAT_DEVICE_END;
+ schib->scsw.cpa = sch->channel_prog + 8;
break;
case -EIO:
/* I/O errors, status depends on specific devices */
break;
case -ENOSYS:
/* unsupported command, generate unit check (command reject) */
- s->ctrl &= ~SCSW_ACTL_START_PEND;
- s->dstat = SCSW_DSTAT_UNIT_CHECK;
+ schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
+ schib->scsw.dstat = SCSW_DSTAT_UNIT_CHECK;
/* Set sense bit 0 in ecw0. */
sch->sense_data[0] = 0x80;
- s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
- s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
+ schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
+ schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
- s->cpa = sch->channel_prog + 8;
+ schib->scsw.cpa = sch->channel_prog + 8;
break;
case -EINPROGRESS:
/* channel program has been suspended */
- s->ctrl &= ~SCSW_ACTL_START_PEND;
- s->ctrl |= SCSW_ACTL_SUSP;
+ schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
+ schib->scsw.ctrl |= SCSW_ACTL_SUSP;
break;
default:
/* error, generate channel program check */
- s->ctrl &= ~SCSW_ACTL_START_PEND;
- s->cstat = SCSW_CSTAT_PROG_CHECK;
- s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
- s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
+ schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
+ schib->scsw.cstat = SCSW_CSTAT_PROG_CHECK;
+ schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
+ schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
- s->cpa = sch->channel_prog + 8;
+ schib->scsw.cpa = sch->channel_prog + 8;
break;
}
} while (ret == -EAGAIN);
@@ -1196,14 +1193,11 @@ static void sch_handle_start_func_virtual(SubchDev *sch)
static IOInstEnding sch_handle_start_func_passthrough(SubchDev *sch)
{
-
- PMCW *p = &sch->curr_status.pmcw;
- SCSW *s = &sch->curr_status.scsw;
-
+ SCHIB *schib = &sch->curr_status;
ORB *orb = &sch->orb;
- if (!(s->ctrl & SCSW_ACTL_SUSP)) {
+ if (!(schib->scsw.ctrl & SCSW_ACTL_SUSP)) {
assert(orb != NULL);
- p->intparm = orb->intparm;
+ schib->pmcw.intparm = orb->intparm;
}
return s390_ccw_cmd_request(sch);
}
@@ -1216,14 +1210,13 @@ static IOInstEnding sch_handle_start_func_passthrough(SubchDev *sch)
*/
IOInstEnding do_subchannel_work_virtual(SubchDev *sch)
{
+ SCHIB *schib = &sch->curr_status;
- SCSW *s = &sch->curr_status.scsw;
-
- if (s->ctrl & SCSW_FCTL_CLEAR_FUNC) {
+ if (schib->scsw.ctrl & SCSW_FCTL_CLEAR_FUNC) {
sch_handle_clear_func(sch);
- } else if (s->ctrl & SCSW_FCTL_HALT_FUNC) {
+ } else if (schib->scsw.ctrl & SCSW_FCTL_HALT_FUNC) {
sch_handle_halt_func(sch);
- } else if (s->ctrl & SCSW_FCTL_START_FUNC) {
+ } else if (schib->scsw.ctrl & SCSW_FCTL_START_FUNC) {
/* Triggered by both ssch and rsch. */
sch_handle_start_func_virtual(sch);
}
@@ -1234,15 +1227,15 @@ IOInstEnding do_subchannel_work_virtual(SubchDev *sch)
IOInstEnding do_subchannel_work_passthrough(SubchDev *sch)
{
- SCSW *s = &sch->curr_status.scsw;
+ SCHIB *schib = &sch->curr_status;
- if (s->ctrl & SCSW_FCTL_CLEAR_FUNC) {
+ if (schib->scsw.ctrl & SCSW_FCTL_CLEAR_FUNC) {
/* TODO: Clear handling */
sch_handle_clear_func(sch);
- } else if (s->ctrl & SCSW_FCTL_HALT_FUNC) {
+ } else if (schib->scsw.ctrl & SCSW_FCTL_HALT_FUNC) {
/* TODO: Halt handling */
sch_handle_halt_func(sch);
- } else if (s->ctrl & SCSW_FCTL_START_FUNC) {
+ } else if (schib->scsw.ctrl & SCSW_FCTL_START_FUNC) {
return sch_handle_start_func_passthrough(sch);
}
return IOINST_CC_EXPECTED;
@@ -1370,46 +1363,45 @@ static void copy_schib_from_guest(SCHIB *dest, const SCHIB *src)
IOInstEnding css_do_msch(SubchDev *sch, const SCHIB *orig_schib)
{
- SCSW *s = &sch->curr_status.scsw;
- PMCW *p = &sch->curr_status.pmcw;
+ SCHIB *schib = &sch->curr_status;
uint16_t oldflags;
- SCHIB schib;
+ SCHIB schib_copy;
- if (!(sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_DNV)) {
+ if (!(schib->pmcw.flags & PMCW_FLAGS_MASK_DNV)) {
return IOINST_CC_EXPECTED;
}
- if (s->ctrl & SCSW_STCTL_STATUS_PEND) {
+ if (schib->scsw.ctrl & SCSW_STCTL_STATUS_PEND) {
return IOINST_CC_STATUS_PRESENT;
}
- if (s->ctrl &
+ if (schib->scsw.ctrl &
(SCSW_FCTL_START_FUNC|SCSW_FCTL_HALT_FUNC|SCSW_FCTL_CLEAR_FUNC)) {
return IOINST_CC_BUSY;
}
- copy_schib_from_guest(&schib, orig_schib);
+ copy_schib_from_guest(&schib_copy, orig_schib);
/* Only update the program-modifiable fields. */
- p->intparm = schib.pmcw.intparm;
- oldflags = p->flags;
- p->flags &= ~(PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA |
+ schib->pmcw.intparm = schib_copy.pmcw.intparm;
+ oldflags = schib->pmcw.flags;
+ schib->pmcw.flags &= ~(PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA |
PMCW_FLAGS_MASK_LM | PMCW_FLAGS_MASK_MME |
PMCW_FLAGS_MASK_MP);
- p->flags |= schib.pmcw.flags &
+ schib->pmcw.flags |= schib_copy.pmcw.flags &
(PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA |
PMCW_FLAGS_MASK_LM | PMCW_FLAGS_MASK_MME |
PMCW_FLAGS_MASK_MP);
- p->lpm = schib.pmcw.lpm;
- p->mbi = schib.pmcw.mbi;
- p->pom = schib.pmcw.pom;
- p->chars &= ~(PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_CSENSE);
- p->chars |= schib.pmcw.chars &
+ schib->pmcw.lpm = schib_copy.pmcw.lpm;
+ schib->pmcw.mbi = schib_copy.pmcw.mbi;
+ schib->pmcw.pom = schib_copy.pmcw.pom;
+ schib->pmcw.chars &= ~(PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_CSENSE);
+ schib->pmcw.chars |= schib_copy.pmcw.chars &
(PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_CSENSE);
- sch->curr_status.mba = schib.mba;
+ schib->mba = schib_copy.mba;
/* Has the channel been disabled? */
if (sch->disable_cb && (oldflags & PMCW_FLAGS_MASK_ENA) != 0
- && (p->flags & PMCW_FLAGS_MASK_ENA) == 0) {
+ && (schib->pmcw.flags & PMCW_FLAGS_MASK_ENA) == 0) {
sch->disable_cb(sch);
}
return IOINST_CC_EXPECTED;
@@ -1417,82 +1409,80 @@ IOInstEnding css_do_msch(SubchDev *sch, const SCHIB *orig_schib)
IOInstEnding css_do_xsch(SubchDev *sch)
{
- SCSW *s = &sch->curr_status.scsw;
- PMCW *p = &sch->curr_status.pmcw;
+ SCHIB *schib = &sch->curr_status;
- if (~(p->flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
+ if (~(schib->pmcw.flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
return IOINST_CC_NOT_OPERATIONAL;
}
- if (s->ctrl & SCSW_CTRL_MASK_STCTL) {
+ if (schib->scsw.ctrl & SCSW_CTRL_MASK_STCTL) {
return IOINST_CC_STATUS_PRESENT;
}
- if (!(s->ctrl & SCSW_CTRL_MASK_FCTL) ||
- ((s->ctrl & SCSW_CTRL_MASK_FCTL) != SCSW_FCTL_START_FUNC) ||
- (!(s->ctrl &
+ if (!(schib->scsw.ctrl & SCSW_CTRL_MASK_FCTL) ||
+ ((schib->scsw.ctrl & SCSW_CTRL_MASK_FCTL) != SCSW_FCTL_START_FUNC) ||
+ (!(schib->scsw.ctrl &
(SCSW_ACTL_RESUME_PEND | SCSW_ACTL_START_PEND | SCSW_ACTL_SUSP))) ||
- (s->ctrl & SCSW_ACTL_SUBCH_ACTIVE)) {
+ (schib->scsw.ctrl & SCSW_ACTL_SUBCH_ACTIVE)) {
return IOINST_CC_BUSY;
}
/* Cancel the current operation. */
- s->ctrl &= ~(SCSW_FCTL_START_FUNC |
+ schib->scsw.ctrl &= ~(SCSW_FCTL_START_FUNC |
SCSW_ACTL_RESUME_PEND |
SCSW_ACTL_START_PEND |
SCSW_ACTL_SUSP);
sch->channel_prog = 0x0;
sch->last_cmd_valid = false;
- s->dstat = 0;
- s->cstat = 0;
+ schib->scsw.dstat = 0;
+ schib->scsw.cstat = 0;
return IOINST_CC_EXPECTED;
}
IOInstEnding css_do_csch(SubchDev *sch)
{
- SCSW *s = &sch->curr_status.scsw;
- PMCW *p = &sch->curr_status.pmcw;
+ SCHIB *schib = &sch->curr_status;
- if (~(p->flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
+ if (~(schib->pmcw.flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
return IOINST_CC_NOT_OPERATIONAL;
}
/* Trigger the clear function. */
- s->ctrl &= ~(SCSW_CTRL_MASK_FCTL | SCSW_CTRL_MASK_ACTL);
- s->ctrl |= SCSW_FCTL_CLEAR_FUNC | SCSW_ACTL_CLEAR_PEND;
+ schib->scsw.ctrl &= ~(SCSW_CTRL_MASK_FCTL | SCSW_CTRL_MASK_ACTL);
+ schib->scsw.ctrl |= SCSW_FCTL_CLEAR_FUNC | SCSW_ACTL_CLEAR_PEND;
return do_subchannel_work(sch);
}
IOInstEnding css_do_hsch(SubchDev *sch)
{
- SCSW *s = &sch->curr_status.scsw;
- PMCW *p = &sch->curr_status.pmcw;
+ SCHIB *schib = &sch->curr_status;
- if (~(p->flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
+ if (~(schib->pmcw.flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
return IOINST_CC_NOT_OPERATIONAL;
}
- if (((s->ctrl & SCSW_CTRL_MASK_STCTL) == SCSW_STCTL_STATUS_PEND) ||
- (s->ctrl & (SCSW_STCTL_PRIMARY |
+ if (((schib->scsw.ctrl & SCSW_CTRL_MASK_STCTL) == SCSW_STCTL_STATUS_PEND) ||
+ (schib->scsw.ctrl & (SCSW_STCTL_PRIMARY |
SCSW_STCTL_SECONDARY |
SCSW_STCTL_ALERT))) {
return IOINST_CC_STATUS_PRESENT;
}
- if (s->ctrl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
+ if (schib->scsw.ctrl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
return IOINST_CC_BUSY;
}
/* Trigger the halt function. */
- s->ctrl |= SCSW_FCTL_HALT_FUNC;
- s->ctrl &= ~SCSW_FCTL_START_FUNC;
- if (((s->ctrl & SCSW_CTRL_MASK_ACTL) ==
+ schib->scsw.ctrl |= SCSW_FCTL_HALT_FUNC;
+ schib->scsw.ctrl &= ~SCSW_FCTL_START_FUNC;
+ if (((schib->scsw.ctrl & SCSW_CTRL_MASK_ACTL) ==
(SCSW_ACTL_SUBCH_ACTIVE | SCSW_ACTL_DEVICE_ACTIVE)) &&
- ((s->ctrl & SCSW_CTRL_MASK_STCTL) == SCSW_STCTL_INTERMEDIATE)) {
- s->ctrl &= ~SCSW_STCTL_STATUS_PEND;
+ ((schib->scsw.ctrl & SCSW_CTRL_MASK_STCTL) ==
+ SCSW_STCTL_INTERMEDIATE)) {
+ schib->scsw.ctrl &= ~SCSW_STCTL_STATUS_PEND;
}
- s->ctrl |= SCSW_ACTL_HALT_PEND;
+ schib->scsw.ctrl |= SCSW_ACTL_HALT_PEND;
return do_subchannel_work(sch);
}
@@ -1534,18 +1524,17 @@ static void css_update_chnmon(SubchDev *sch)
IOInstEnding css_do_ssch(SubchDev *sch, ORB *orb)
{
- SCSW *s = &sch->curr_status.scsw;
- PMCW *p = &sch->curr_status.pmcw;
+ SCHIB *schib = &sch->curr_status;
- if (~(p->flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
+ if (~(schib->pmcw.flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
return IOINST_CC_NOT_OPERATIONAL;
}
- if (s->ctrl & SCSW_STCTL_STATUS_PEND) {
+ if (schib->scsw.ctrl & SCSW_STCTL_STATUS_PEND) {
return IOINST_CC_STATUS_PRESENT;
}
- if (s->ctrl & (SCSW_FCTL_START_FUNC |
+ if (schib->scsw.ctrl & (SCSW_FCTL_START_FUNC |
SCSW_FCTL_HALT_FUNC |
SCSW_FCTL_CLEAR_FUNC)) {
return IOINST_CC_BUSY;
@@ -1558,13 +1547,13 @@ IOInstEnding css_do_ssch(SubchDev *sch, ORB *orb)
sch->orb = *orb;
sch->channel_prog = orb->cpa;
/* Trigger the start function. */
- s->ctrl |= (SCSW_FCTL_START_FUNC | SCSW_ACTL_START_PEND);
- s->flags &= ~SCSW_FLAGS_MASK_PNO;
+ schib->scsw.ctrl |= (SCSW_FCTL_START_FUNC | SCSW_ACTL_START_PEND);
+ schib->scsw.flags &= ~SCSW_FLAGS_MASK_PNO;
return do_subchannel_work(sch);
}
-static void copy_irb_to_guest(IRB *dest, const IRB *src, PMCW *pmcw,
+static void copy_irb_to_guest(IRB *dest, const IRB *src, const PMCW *pmcw,
int *irb_len)
{
int i;
@@ -1603,24 +1592,24 @@ static void copy_irb_to_guest(IRB *dest, const IRB *src, PMCW *pmcw,
int css_do_tsch_get_irb(SubchDev *sch, IRB *target_irb, int *irb_len)
{
- SCSW *s = &sch->curr_status.scsw;
- PMCW *p = &sch->curr_status.pmcw;
+ SCHIB *schib = &sch->curr_status;
+ PMCW p;
uint16_t stctl;
IRB irb;
- if (~(p->flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
+ if (~(schib->pmcw.flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
return 3;
}
- stctl = s->ctrl & SCSW_CTRL_MASK_STCTL;
+ stctl = schib->scsw.ctrl & SCSW_CTRL_MASK_STCTL;
/* Prepare the irb for the guest. */
memset(&irb, 0, sizeof(IRB));
/* Copy scsw from current status. */
- memcpy(&irb.scsw, s, sizeof(SCSW));
+ irb.scsw = schib->scsw;
if (stctl & SCSW_STCTL_STATUS_PEND) {
- if (s->cstat & (SCSW_CSTAT_DATA_CHECK |
+ if (schib->scsw.cstat & (SCSW_CSTAT_DATA_CHECK |
SCSW_CSTAT_CHN_CTRL_CHK |
SCSW_CSTAT_INTF_CTRL_CHK)) {
irb.scsw.flags |= SCSW_FLAGS_MASK_ESWF;
@@ -1629,8 +1618,8 @@ int css_do_tsch_get_irb(SubchDev *sch, IRB *target_irb, int *irb_len)
irb.esw[0] = 0x00800000;
}
/* If a unit check is pending, copy sense data. */
- if ((s->dstat & SCSW_DSTAT_UNIT_CHECK) &&
- (p->chars & PMCW_CHARS_MASK_CSENSE)) {
+ if ((schib->scsw.dstat & SCSW_DSTAT_UNIT_CHECK) &&
+ (schib->pmcw.chars & PMCW_CHARS_MASK_CSENSE)) {
int i;
irb.scsw.flags |= SCSW_FLAGS_MASK_ESWF | SCSW_FLAGS_MASK_ECTL;
@@ -1643,34 +1632,34 @@ int css_do_tsch_get_irb(SubchDev *sch, IRB *target_irb, int *irb_len)
}
}
/* Store the irb to the guest. */
- copy_irb_to_guest(target_irb, &irb, p, irb_len);
+ p = schib->pmcw;
+ copy_irb_to_guest(target_irb, &irb, &p, irb_len);
return ((stctl & SCSW_STCTL_STATUS_PEND) == 0);
}
void css_do_tsch_update_subch(SubchDev *sch)
{
- SCSW *s = &sch->curr_status.scsw;
- PMCW *p = &sch->curr_status.pmcw;
+ SCHIB *schib = &sch->curr_status;
uint16_t stctl;
uint16_t fctl;
uint16_t actl;
- stctl = s->ctrl & SCSW_CTRL_MASK_STCTL;
- fctl = s->ctrl & SCSW_CTRL_MASK_FCTL;
- actl = s->ctrl & SCSW_CTRL_MASK_ACTL;
+ stctl = schib->scsw.ctrl & SCSW_CTRL_MASK_STCTL;
+ fctl = schib->scsw.ctrl & SCSW_CTRL_MASK_FCTL;
+ actl = schib->scsw.ctrl & SCSW_CTRL_MASK_ACTL;
/* Clear conditions on subchannel, if applicable. */
if (stctl & SCSW_STCTL_STATUS_PEND) {
- s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
+ schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
if ((stctl != (SCSW_STCTL_INTERMEDIATE | SCSW_STCTL_STATUS_PEND)) ||
((fctl & SCSW_FCTL_HALT_FUNC) &&
(actl & SCSW_ACTL_SUSP))) {
- s->ctrl &= ~SCSW_CTRL_MASK_FCTL;
+ schib->scsw.ctrl &= ~SCSW_CTRL_MASK_FCTL;
}
if (stctl != (SCSW_STCTL_INTERMEDIATE | SCSW_STCTL_STATUS_PEND)) {
- s->flags &= ~SCSW_FLAGS_MASK_PNO;
- s->ctrl &= ~(SCSW_ACTL_RESUME_PEND |
+ schib->scsw.flags &= ~SCSW_FLAGS_MASK_PNO;
+ schib->scsw.ctrl &= ~(SCSW_ACTL_RESUME_PEND |
SCSW_ACTL_START_PEND |
SCSW_ACTL_HALT_PEND |
SCSW_ACTL_CLEAR_PEND |
@@ -1678,20 +1667,20 @@ void css_do_tsch_update_subch(SubchDev *sch)
} else {
if ((actl & SCSW_ACTL_SUSP) &&
(fctl & SCSW_FCTL_START_FUNC)) {
- s->flags &= ~SCSW_FLAGS_MASK_PNO;
+ schib->scsw.flags &= ~SCSW_FLAGS_MASK_PNO;
if (fctl & SCSW_FCTL_HALT_FUNC) {
- s->ctrl &= ~(SCSW_ACTL_RESUME_PEND |
+ schib->scsw.ctrl &= ~(SCSW_ACTL_RESUME_PEND |
SCSW_ACTL_START_PEND |
SCSW_ACTL_HALT_PEND |
SCSW_ACTL_CLEAR_PEND |
SCSW_ACTL_SUSP);
} else {
- s->ctrl &= ~SCSW_ACTL_RESUME_PEND;
+ schib->scsw.ctrl &= ~SCSW_ACTL_RESUME_PEND;
}
}
}
/* Clear pending sense data. */
- if (p->chars & PMCW_CHARS_MASK_CSENSE) {
+ if (schib->pmcw.chars & PMCW_CHARS_MASK_CSENSE) {
memset(sch->sense_data, 0 , sizeof(sch->sense_data));
}
}
@@ -1804,20 +1793,19 @@ void css_do_schm(uint8_t mbk, int update, int dct, uint64_t mbo)
IOInstEnding css_do_rsch(SubchDev *sch)
{
- SCSW *s = &sch->curr_status.scsw;
- PMCW *p = &sch->curr_status.pmcw;
+ SCHIB *schib = &sch->curr_status;
- if (~(p->flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
+ if (~(schib->pmcw.flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
return IOINST_CC_NOT_OPERATIONAL;
}
- if (s->ctrl & SCSW_STCTL_STATUS_PEND) {
+ if (schib->scsw.ctrl & SCSW_STCTL_STATUS_PEND) {
return IOINST_CC_STATUS_PRESENT;
}
- if (((s->ctrl & SCSW_CTRL_MASK_FCTL) != SCSW_FCTL_START_FUNC) ||
- (s->ctrl & SCSW_ACTL_RESUME_PEND) ||
- (!(s->ctrl & SCSW_ACTL_SUSP))) {
+ if (((schib->scsw.ctrl & SCSW_CTRL_MASK_FCTL) != SCSW_FCTL_START_FUNC) ||
+ (schib->scsw.ctrl & SCSW_ACTL_RESUME_PEND) ||
+ (!(schib->scsw.ctrl & SCSW_ACTL_SUSP))) {
return IOINST_CC_BUSY;
}
@@ -1826,7 +1814,7 @@ IOInstEnding css_do_rsch(SubchDev *sch)
css_update_chnmon(sch);
}
- s->ctrl |= SCSW_ACTL_RESUME_PEND;
+ schib->scsw.ctrl |= SCSW_ACTL_RESUME_PEND;
return do_subchannel_work(sch);
}
@@ -1927,28 +1915,27 @@ static int css_add_chpid(uint8_t cssid, uint8_t chpid, uint8_t type,
void css_sch_build_virtual_schib(SubchDev *sch, uint8_t chpid, uint8_t type)
{
- PMCW *p = &sch->curr_status.pmcw;
- SCSW *s = &sch->curr_status.scsw;
+ SCHIB *schib = &sch->curr_status;
int i;
CssImage *css = channel_subsys.css[sch->cssid];
assert(css != NULL);
- memset(p, 0, sizeof(PMCW));
- p->flags |= PMCW_FLAGS_MASK_DNV;
- p->devno = sch->devno;
+ memset(&schib->pmcw, 0, sizeof(PMCW));
+ schib->pmcw.flags |= PMCW_FLAGS_MASK_DNV;
+ schib->pmcw.devno = sch->devno;
/* single path */
- p->pim = 0x80;
- p->pom = 0xff;
- p->pam = 0x80;
- p->chpid[0] = chpid;
+ schib->pmcw.pim = 0x80;
+ schib->pmcw.pom = 0xff;
+ schib->pmcw.pam = 0x80;
+ schib->pmcw.chpid[0] = chpid;
if (!css->chpids[chpid].in_use) {
css_add_chpid(sch->cssid, chpid, type, true);
}
- memset(s, 0, sizeof(SCSW));
- sch->curr_status.mba = 0;
- for (i = 0; i < ARRAY_SIZE(sch->curr_status.mda); i++) {
- sch->curr_status.mda[i] = 0;
+ memset(&schib->scsw, 0, sizeof(SCSW));
+ schib->mba = 0;
+ for (i = 0; i < ARRAY_SIZE(schib->mda); i++) {
+ schib->mda[i] = 0;
}
}
@@ -2246,30 +2233,30 @@ int css_enable_mss(void)
void css_reset_sch(SubchDev *sch)
{
- PMCW *p = &sch->curr_status.pmcw;
+ SCHIB *schib = &sch->curr_status;
- if ((p->flags & PMCW_FLAGS_MASK_ENA) != 0 && sch->disable_cb) {
+ if ((schib->pmcw.flags & PMCW_FLAGS_MASK_ENA) != 0 && sch->disable_cb) {
sch->disable_cb(sch);
}
- p->intparm = 0;
- p->flags &= ~(PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA |
+ schib->pmcw.intparm = 0;
+ schib->pmcw.flags &= ~(PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA |
PMCW_FLAGS_MASK_LM | PMCW_FLAGS_MASK_MME |
PMCW_FLAGS_MASK_MP | PMCW_FLAGS_MASK_TF);
- p->flags |= PMCW_FLAGS_MASK_DNV;
- p->devno = sch->devno;
- p->pim = 0x80;
- p->lpm = p->pim;
- p->pnom = 0;
- p->lpum = 0;
- p->mbi = 0;
- p->pom = 0xff;
- p->pam = 0x80;
- p->chars &= ~(PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_XMWME |
+ schib->pmcw.flags |= PMCW_FLAGS_MASK_DNV;
+ schib->pmcw.devno = sch->devno;
+ schib->pmcw.pim = 0x80;
+ schib->pmcw.lpm = schib->pmcw.pim;
+ schib->pmcw.pnom = 0;
+ schib->pmcw.lpum = 0;
+ schib->pmcw.mbi = 0;
+ schib->pmcw.pom = 0xff;
+ schib->pmcw.pam = 0x80;
+ schib->pmcw.chars &= ~(PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_XMWME |
PMCW_CHARS_MASK_CSENSE);
- memset(&sch->curr_status.scsw, 0, sizeof(sch->curr_status.scsw));
- sch->curr_status.mba = 0;
+ memset(&schib->scsw, 0, sizeof(schib->scsw));
+ schib->mba = 0;
sch->channel_prog = 0x0;
sch->last_cmd_valid = false;
@@ -2433,7 +2420,7 @@ static int css_sch_get_chpids(SubchDev *sch, CssDevId *dev_id)
FILE *fd;
uint32_t chpid[8];
int i;
- PMCW *p = &sch->curr_status.pmcw;
+ SCHIB *schib = &sch->curr_status;
fid_path = g_strdup_printf("/sys/bus/css/devices/%x.%x.%04x/chpids",
dev_id->cssid, dev_id->ssid, dev_id->devid);
@@ -2452,8 +2439,8 @@ static int css_sch_get_chpids(SubchDev *sch, CssDevId *dev_id)
return -EINVAL;
}
- for (i = 0; i < ARRAY_SIZE(p->chpid); i++) {
- p->chpid[i] = chpid[i];
+ for (i = 0; i < ARRAY_SIZE(schib->pmcw.chpid); i++) {
+ schib->pmcw.chpid[i] = chpid[i];
}
fclose(fd);
@@ -2467,7 +2454,7 @@ static int css_sch_get_path_masks(SubchDev *sch, CssDevId *dev_id)
char *fid_path;
FILE *fd;
uint32_t pim, pam, pom;
- PMCW *p = &sch->curr_status.pmcw;
+ SCHIB *schib = &sch->curr_status;
fid_path = g_strdup_printf("/sys/bus/css/devices/%x.%x.%04x/pimpampom",
dev_id->cssid, dev_id->ssid, dev_id->devid);
@@ -2484,9 +2471,9 @@ static int css_sch_get_path_masks(SubchDev *sch, CssDevId *dev_id)
return -EINVAL;
}
- p->pim = pim;
- p->pam = pam;
- p->pom = pom;
+ schib->pmcw.pim = pim;
+ schib->pmcw.pam = pam;
+ schib->pmcw.pom = pom;
fclose(fd);
g_free(fid_path);
@@ -2528,16 +2515,15 @@ static int css_sch_get_chpid_type(uint8_t chpid, uint32_t *type,
int css_sch_build_schib(SubchDev *sch, CssDevId *dev_id)
{
CssImage *css = channel_subsys.css[sch->cssid];
- PMCW *p = &sch->curr_status.pmcw;
- SCSW *s = &sch->curr_status.scsw;
+ SCHIB *schib = &sch->curr_status;
uint32_t type;
int i, ret;
assert(css != NULL);
- memset(p, 0, sizeof(PMCW));
- p->flags |= PMCW_FLAGS_MASK_DNV;
+ memset(&schib->pmcw, 0, sizeof(PMCW));
+ schib->pmcw.flags |= PMCW_FLAGS_MASK_DNV;
/* We are dealing with I/O subchannels only. */
- p->devno = sch->devno;
+ schib->pmcw.devno = sch->devno;
/* Grab path mask from sysfs. */
ret = css_sch_get_path_masks(sch, dev_id);
@@ -2552,20 +2538,20 @@ int css_sch_build_schib(SubchDev *sch, CssDevId *dev_id)
}
/* Build chpid type. */
- for (i = 0; i < ARRAY_SIZE(p->chpid); i++) {
- if (p->chpid[i] && !css->chpids[p->chpid[i]].in_use) {
- ret = css_sch_get_chpid_type(p->chpid[i], &type, dev_id);
+ for (i = 0; i < ARRAY_SIZE(schib->pmcw.chpid); i++) {
+ if (schib->pmcw.chpid[i] && !css->chpids[schib->pmcw.chpid[i]].in_use) {
+ ret = css_sch_get_chpid_type(schib->pmcw.chpid[i], &type, dev_id);
if (ret) {
return ret;
}
- css_add_chpid(sch->cssid, p->chpid[i], type, false);
+ css_add_chpid(sch->cssid, schib->pmcw.chpid[i], type, false);
}
}
- memset(s, 0, sizeof(SCSW));
- sch->curr_status.mba = 0;
- for (i = 0; i < ARRAY_SIZE(sch->curr_status.mda); i++) {
- sch->curr_status.mda[i] = 0;
+ memset(&schib->scsw, 0, sizeof(SCSW));
+ schib->mba = 0;
+ for (i = 0; i < ARRAY_SIZE(schib->mda); i++) {
+ schib->mda[i] = 0;
}
return 0;
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index 896888bf8f..51b272e190 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -252,8 +252,6 @@ static void s390_ipl_set_boot_menu(S390IPLState *ipl)
{
QemuOptsList *plist = qemu_find_opts("boot-opts");
QemuOpts *opts = QTAILQ_FIRST(&plist->head);
- uint8_t *flags = &ipl->qipl.qipl_flags;
- uint32_t *timeout = &ipl->qipl.boot_menu_timeout;
const char *tmp;
unsigned long splash_time = 0;
@@ -269,7 +267,7 @@ static void s390_ipl_set_boot_menu(S390IPLState *ipl)
case S390_IPL_TYPE_CCW:
/* In the absence of -boot menu, use zipl parameters */
if (!qemu_opt_get(opts, "menu")) {
- *flags |= QIPL_FLAG_BM_OPTS_ZIPL;
+ ipl->qipl.qipl_flags |= QIPL_FLAG_BM_OPTS_ZIPL;
return;
}
break;
@@ -286,23 +284,23 @@ static void s390_ipl_set_boot_menu(S390IPLState *ipl)
return;
}
- *flags |= QIPL_FLAG_BM_OPTS_CMD;
+ ipl->qipl.qipl_flags |= QIPL_FLAG_BM_OPTS_CMD;
tmp = qemu_opt_get(opts, "splash-time");
if (tmp && qemu_strtoul(tmp, NULL, 10, &splash_time)) {
error_report("splash-time is invalid, forcing it to 0");
- *timeout = 0;
+ ipl->qipl.boot_menu_timeout = 0;
return;
}
if (splash_time > 0xffffffff) {
error_report("splash-time is too large, forcing it to max value");
- *timeout = 0xffffffff;
+ ipl->qipl.boot_menu_timeout = 0xffffffff;
return;
}
- *timeout = cpu_to_be32(splash_time);
+ ipl->qipl.boot_menu_timeout = cpu_to_be32(splash_time);
}
static CcwDevice *s390_get_ccw_device(DeviceState *dev_st)
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 9246729a75..c44d13cc50 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -130,8 +130,8 @@ static void vfio_ccw_io_notifier_handler(void *opaque)
S390CCWDevice *cdev = S390_CCW_DEVICE(vcdev);
CcwDevice *ccw_dev = CCW_DEVICE(cdev);
SubchDev *sch = ccw_dev->sch;
- SCSW *s = &sch->curr_status.scsw;
- PMCW *p = &sch->curr_status.pmcw;
+ SCHIB *schib = &sch->curr_status;
+ SCSW s;
IRB irb;
int size;
@@ -145,33 +145,33 @@ static void vfio_ccw_io_notifier_handler(void *opaque)
switch (errno) {
case ENODEV:
/* Generate a deferred cc 3 condition. */
- s->flags |= SCSW_FLAGS_MASK_CC;
- s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
- s->ctrl |= (SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND);
+ schib->scsw.flags |= SCSW_FLAGS_MASK_CC;
+ schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
+ schib->scsw.ctrl |= (SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND);
goto read_err;
case EFAULT:
/* Memory problem, generate channel data check. */
- s->ctrl &= ~SCSW_ACTL_START_PEND;
- s->cstat = SCSW_CSTAT_DATA_CHECK;
- s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
- s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
+ schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
+ schib->scsw.cstat = SCSW_CSTAT_DATA_CHECK;
+ schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
+ schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
goto read_err;
default:
/* Error, generate channel program check. */
- s->ctrl &= ~SCSW_ACTL_START_PEND;
- s->cstat = SCSW_CSTAT_PROG_CHECK;
- s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
- s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
+ schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
+ schib->scsw.cstat = SCSW_CSTAT_PROG_CHECK;
+ schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
+ schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
goto read_err;
}
} else if (size != vcdev->io_region_size) {
/* Information transfer error, generate channel-control check. */
- s->ctrl &= ~SCSW_ACTL_START_PEND;
- s->cstat = SCSW_CSTAT_CHN_CTRL_CHK;
- s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
- s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
+ schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
+ schib->scsw.cstat = SCSW_CSTAT_CHN_CTRL_CHK;
+ schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
+ schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
goto read_err;
}
@@ -179,11 +179,13 @@ static void vfio_ccw_io_notifier_handler(void *opaque)
memcpy(&irb, region->irb_area, sizeof(IRB));
/* Update control block via irb. */
- copy_scsw_to_guest(s, &irb.scsw);
+ s = schib->scsw;
+ copy_scsw_to_guest(&s, &irb.scsw);
+ schib->scsw = s;
/* If a uint check is pending, copy sense data. */
- if ((s->dstat & SCSW_DSTAT_UNIT_CHECK) &&
- (p->chars & PMCW_CHARS_MASK_CSENSE)) {
+ if ((schib->scsw.dstat & SCSW_DSTAT_UNIT_CHECK) &&
+ (schib->pmcw.chars & PMCW_CHARS_MASK_CSENSE)) {
memcpy(sch->sense_data, irb.ecw, sizeof(irb.ecw));
}