Fix taking address of fields in packed structs warnings

by gcc 9
 -----BEGIN PGP SIGNATURE-----
 
 iQJGBAABCAAwFiEEw9DWbcNiT/aowBjO3s9rk8bwL68FAlykg9ISHGNvaHVja0By
 ZWRoYXQuY29tAAoJEN7Pa5PG8C+vQnkQAJ+1E7/dSkWnfJ9Vu2V9dmlZl7RFFwwh
 SEbzaow0m6TARAdPua8FuSyGiZSEZ3ZgjahaemnCOtMJkpsftDTKY0PXM+eeHNLJ
 59Oh1ZQWel6vUHbJv+EcZF2DdkGBKdhjuTQHqpFgZ0u5ahFNGdOy1rOdDzuagJ03
 gSOyC+v5KEPT0e8uucfoNppFFYhvbT1dVLYl+S6E1h86UueU2WigroHGZZt3Z18p
 CVdm8Kjb8/tuJ09gzEt3gO/9TJUAvattCqK3FFV3FCqfYgSRT2oIUll+6KVuJ+q2
 ktdGhMNSjhdDbROKlbesGImSbROHLjAUPh6f/yZO0msysQsbd8d7Aj0nDRBqH+fy
 wMK0rCUKChuhQhbrm/lOs2kxGzv/JZV8xnLfxP5O5TVhA+2pTFj07Pzc0sJuZBZ7
 gfa6ZsoEO5z/2CKiJH3vJVCN3gwI5UnsH3AmuATfcX2GH7bhar3Zj2oR9J5NprXl
 IPWV0mbBgumZxd9RG38a8tnwkcGHCRqd0x2q8cpD05XWvrl13GamVNwBYvyTvb5L
 MbBGIevDfj0cNgZZ0SKXW4YLgEGMMA4x4hEOi8cvW2pJLnm/YGF2atz1u6Tf4E1V
 /Gcptv/6Qf9cAXrwfTm4lCXWQtSbQRHKa2AynQijR6NpNUvZ4ItMlavsuSkTu+4a
 PMWNL88bUMAr
 =vFLX
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20190403' into staging

Fix taking address of fields in packed structs warnings
by gcc 9

# gpg: Signature made Wed 03 Apr 2019 10:58:42 BST
# gpg:                using RSA key C3D0D66DC3624FF6A8C018CEDECF6B93C6F02FAF
# gpg:                issuer "cohuck@redhat.com"
# gpg: Good signature from "Cornelia Huck <conny@cornelia-huck.de>" [unknown]
# gpg:                 aka "Cornelia Huck <huckc@linux.vnet.ibm.com>" [full]
# gpg:                 aka "Cornelia Huck <cornelia.huck@de.ibm.com>" [full]
# gpg:                 aka "Cornelia Huck <cohuck@kernel.org>" [unknown]
# gpg:                 aka "Cornelia Huck <cohuck@redhat.com>" [unknown]
# Primary key fingerprint: C3D0 D66D C362 4FF6 A8C0  18CE DECF 6B93 C6F0 2FAF

* remotes/cohuck/tags/s390x-20190403:
  hw/s390x/3270-ccw: avoid taking address of fields in packed struct
  hw/s390x/ipl: avoid taking address of fields in packed struct
  hw/s390/css: avoid taking address members in packed structs
  hw/vfio/ccw: avoid taking address members in packed structs

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2019-04-03 13:13:30 +01:00
commit f4b3717137
4 changed files with 218 additions and 232 deletions

View File

@ -78,13 +78,13 @@ static int emulated_ccw_3270_cb(SubchDev *sch, CCW1 ccw)
if (rc == -EIO) { if (rc == -EIO) {
/* I/O error, specific devices generate specific conditions */ /* 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->curr_status.scsw.dstat = SCSW_DSTAT_UNIT_CHECK;
sch->sense_data[0] = 0x40; /* intervention-req */ sch->sense_data[0] = 0x40; /* intervention-req */
s->ctrl &= ~SCSW_ACTL_START_PEND; schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
s->ctrl &= ~SCSW_CTRL_MASK_STCTL; schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY | schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND; SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
} }

View File

@ -695,35 +695,32 @@ void css_adapter_interrupt(CssIoAdapterType type, uint8_t isc)
static void sch_handle_clear_func(SubchDev *sch) static void sch_handle_clear_func(SubchDev *sch)
{ {
PMCW *p = &sch->curr_status.pmcw; SCHIB *schib = &sch->curr_status;
SCSW *s = &sch->curr_status.scsw;
int path; int path;
/* Path management: In our simple css, we always choose the only path. */ /* Path management: In our simple css, we always choose the only path. */
path = 0x80; path = 0x80;
/* Reset values prior to 'issuing the clear signal'. */ /* Reset values prior to 'issuing the clear signal'. */
p->lpum = 0; schib->pmcw.lpum = 0;
p->pom = 0xff; schib->pmcw.pom = 0xff;
s->flags &= ~SCSW_FLAGS_MASK_PNO; schib->scsw.flags &= ~SCSW_FLAGS_MASK_PNO;
/* We always 'attempt to issue the clear signal', and we always succeed. */ /* We always 'attempt to issue the clear signal', and we always succeed. */
sch->channel_prog = 0x0; sch->channel_prog = 0x0;
sch->last_cmd_valid = false; sch->last_cmd_valid = false;
s->ctrl &= ~SCSW_ACTL_CLEAR_PEND; schib->scsw.ctrl &= ~SCSW_ACTL_CLEAR_PEND;
s->ctrl |= SCSW_STCTL_STATUS_PEND; schib->scsw.ctrl |= SCSW_STCTL_STATUS_PEND;
s->dstat = 0; schib->scsw.dstat = 0;
s->cstat = 0; schib->scsw.cstat = 0;
p->lpum = path; schib->pmcw.lpum = path;
} }
static void sch_handle_halt_func(SubchDev *sch) static void sch_handle_halt_func(SubchDev *sch)
{ {
SCHIB *schib = &sch->curr_status;
PMCW *p = &sch->curr_status.pmcw;
SCSW *s = &sch->curr_status.scsw;
hwaddr curr_ccw = sch->channel_prog; hwaddr curr_ccw = sch->channel_prog;
int path; 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. */ /* We always 'attempt to issue the halt signal', and we always succeed. */
sch->channel_prog = 0x0; sch->channel_prog = 0x0;
sch->last_cmd_valid = false; sch->last_cmd_valid = false;
s->ctrl &= ~SCSW_ACTL_HALT_PEND; schib->scsw.ctrl &= ~SCSW_ACTL_HALT_PEND;
s->ctrl |= SCSW_STCTL_STATUS_PEND; schib->scsw.ctrl |= SCSW_STCTL_STATUS_PEND;
if ((s->ctrl & (SCSW_ACTL_SUBCH_ACTIVE | SCSW_ACTL_DEVICE_ACTIVE)) || if ((schib->scsw.ctrl & (SCSW_ACTL_SUBCH_ACTIVE |
!((s->ctrl & SCSW_ACTL_START_PEND) || SCSW_ACTL_DEVICE_ACTIVE)) ||
(s->ctrl & SCSW_ACTL_SUSP))) { !((schib->scsw.ctrl & SCSW_ACTL_START_PEND) ||
s->dstat = SCSW_DSTAT_DEVICE_END; (schib->scsw.ctrl & SCSW_ACTL_SUSP))) {
schib->scsw.dstat = SCSW_DSTAT_DEVICE_END;
} }
if ((s->ctrl & (SCSW_ACTL_SUBCH_ACTIVE | SCSW_ACTL_DEVICE_ACTIVE)) || if ((schib->scsw.ctrl & (SCSW_ACTL_SUBCH_ACTIVE |
(s->ctrl & SCSW_ACTL_SUSP)) { SCSW_ACTL_DEVICE_ACTIVE)) ||
s->cpa = curr_ccw + 8; (schib->scsw.ctrl & SCSW_ACTL_SUSP)) {
schib->scsw.cpa = curr_ccw + 8;
} }
s->cstat = 0; schib->scsw.cstat = 0;
p->lpum = path; 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) static void sch_handle_start_func_virtual(SubchDev *sch)
{ {
SCHIB *schib = &sch->curr_status;
PMCW *p = &sch->curr_status.pmcw;
SCSW *s = &sch->curr_status.scsw;
int path; int path;
int ret; int ret;
bool suspend_allowed; 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 management: In our simple css, we always choose the only path. */
path = 0x80; 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 */ /* Start Function triggered via ssch, i.e. we have an ORB */
ORB *orb = &sch->orb; ORB *orb = &sch->orb;
s->cstat = 0; schib->scsw.cstat = 0;
s->dstat = 0; schib->scsw.dstat = 0;
/* Look at the orb and try to execute the channel program. */ /* Look at the orb and try to execute the channel program. */
p->intparm = orb->intparm; schib->pmcw.intparm = orb->intparm;
if (!(orb->lpm & path)) { if (!(orb->lpm & path)) {
/* Generate a deferred cc 3 condition. */ /* Generate a deferred cc 3 condition. */
s->flags |= SCSW_FLAGS_MASK_CC; schib->scsw.flags |= SCSW_FLAGS_MASK_CC;
s->ctrl &= ~SCSW_CTRL_MASK_STCTL; schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
s->ctrl |= (SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND); schib->scsw.ctrl |= (SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND);
return; return;
} }
sch->ccw_fmt_1 = !!(orb->ctrl0 & ORB_CTRL0_MASK_FMT); 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; sch->ccw_no_data_cnt = 0;
suspend_allowed = !!(orb->ctrl0 & ORB_CTRL0_MASK_SPND); suspend_allowed = !!(orb->ctrl0 & ORB_CTRL0_MASK_SPND);
} else { } else {
/* Start Function resumed via rsch */ /* 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. */ /* The channel program had been suspended before. */
suspend_allowed = true; suspend_allowed = true;
} }
@ -1154,40 +1151,40 @@ static void sch_handle_start_func_virtual(SubchDev *sch)
break; break;
case 0: case 0:
/* success */ /* success */
s->ctrl &= ~SCSW_ACTL_START_PEND; schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
s->ctrl &= ~SCSW_CTRL_MASK_STCTL; schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY | schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
SCSW_STCTL_STATUS_PEND; SCSW_STCTL_STATUS_PEND;
s->dstat = SCSW_DSTAT_CHANNEL_END | SCSW_DSTAT_DEVICE_END; schib->scsw.dstat = SCSW_DSTAT_CHANNEL_END | SCSW_DSTAT_DEVICE_END;
s->cpa = sch->channel_prog + 8; schib->scsw.cpa = sch->channel_prog + 8;
break; break;
case -EIO: case -EIO:
/* I/O errors, status depends on specific devices */ /* I/O errors, status depends on specific devices */
break; break;
case -ENOSYS: case -ENOSYS:
/* unsupported command, generate unit check (command reject) */ /* unsupported command, generate unit check (command reject) */
s->ctrl &= ~SCSW_ACTL_START_PEND; schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
s->dstat = SCSW_DSTAT_UNIT_CHECK; schib->scsw.dstat = SCSW_DSTAT_UNIT_CHECK;
/* Set sense bit 0 in ecw0. */ /* Set sense bit 0 in ecw0. */
sch->sense_data[0] = 0x80; sch->sense_data[0] = 0x80;
s->ctrl &= ~SCSW_CTRL_MASK_STCTL; schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY | schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND; SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
s->cpa = sch->channel_prog + 8; schib->scsw.cpa = sch->channel_prog + 8;
break; break;
case -EINPROGRESS: case -EINPROGRESS:
/* channel program has been suspended */ /* channel program has been suspended */
s->ctrl &= ~SCSW_ACTL_START_PEND; schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
s->ctrl |= SCSW_ACTL_SUSP; schib->scsw.ctrl |= SCSW_ACTL_SUSP;
break; break;
default: default:
/* error, generate channel program check */ /* error, generate channel program check */
s->ctrl &= ~SCSW_ACTL_START_PEND; schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
s->cstat = SCSW_CSTAT_PROG_CHECK; schib->scsw.cstat = SCSW_CSTAT_PROG_CHECK;
s->ctrl &= ~SCSW_CTRL_MASK_STCTL; schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY | schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND; SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
s->cpa = sch->channel_prog + 8; schib->scsw.cpa = sch->channel_prog + 8;
break; break;
} }
} while (ret == -EAGAIN); } 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) static IOInstEnding sch_handle_start_func_passthrough(SubchDev *sch)
{ {
SCHIB *schib = &sch->curr_status;
PMCW *p = &sch->curr_status.pmcw;
SCSW *s = &sch->curr_status.scsw;
ORB *orb = &sch->orb; ORB *orb = &sch->orb;
if (!(s->ctrl & SCSW_ACTL_SUSP)) { if (!(schib->scsw.ctrl & SCSW_ACTL_SUSP)) {
assert(orb != NULL); assert(orb != NULL);
p->intparm = orb->intparm; schib->pmcw.intparm = orb->intparm;
} }
return s390_ccw_cmd_request(sch); 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) IOInstEnding do_subchannel_work_virtual(SubchDev *sch)
{ {
SCHIB *schib = &sch->curr_status;
SCSW *s = &sch->curr_status.scsw; if (schib->scsw.ctrl & SCSW_FCTL_CLEAR_FUNC) {
if (s->ctrl & SCSW_FCTL_CLEAR_FUNC) {
sch_handle_clear_func(sch); 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); 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. */ /* Triggered by both ssch and rsch. */
sch_handle_start_func_virtual(sch); sch_handle_start_func_virtual(sch);
} }
@ -1234,15 +1227,15 @@ IOInstEnding do_subchannel_work_virtual(SubchDev *sch)
IOInstEnding do_subchannel_work_passthrough(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 */ /* TODO: Clear handling */
sch_handle_clear_func(sch); 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 */ /* TODO: Halt handling */
sch_handle_halt_func(sch); 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 sch_handle_start_func_passthrough(sch);
} }
return IOINST_CC_EXPECTED; 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) IOInstEnding css_do_msch(SubchDev *sch, const SCHIB *orig_schib)
{ {
SCSW *s = &sch->curr_status.scsw; SCHIB *schib = &sch->curr_status;
PMCW *p = &sch->curr_status.pmcw;
uint16_t oldflags; 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; return IOINST_CC_EXPECTED;
} }
if (s->ctrl & SCSW_STCTL_STATUS_PEND) { if (schib->scsw.ctrl & SCSW_STCTL_STATUS_PEND) {
return IOINST_CC_STATUS_PRESENT; return IOINST_CC_STATUS_PRESENT;
} }
if (s->ctrl & if (schib->scsw.ctrl &
(SCSW_FCTL_START_FUNC|SCSW_FCTL_HALT_FUNC|SCSW_FCTL_CLEAR_FUNC)) { (SCSW_FCTL_START_FUNC|SCSW_FCTL_HALT_FUNC|SCSW_FCTL_CLEAR_FUNC)) {
return IOINST_CC_BUSY; 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. */ /* Only update the program-modifiable fields. */
p->intparm = schib.pmcw.intparm; schib->pmcw.intparm = schib_copy.pmcw.intparm;
oldflags = p->flags; oldflags = schib->pmcw.flags;
p->flags &= ~(PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA | schib->pmcw.flags &= ~(PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA |
PMCW_FLAGS_MASK_LM | PMCW_FLAGS_MASK_MME | PMCW_FLAGS_MASK_LM | PMCW_FLAGS_MASK_MME |
PMCW_FLAGS_MASK_MP); 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_ISC | PMCW_FLAGS_MASK_ENA |
PMCW_FLAGS_MASK_LM | PMCW_FLAGS_MASK_MME | PMCW_FLAGS_MASK_LM | PMCW_FLAGS_MASK_MME |
PMCW_FLAGS_MASK_MP); PMCW_FLAGS_MASK_MP);
p->lpm = schib.pmcw.lpm; schib->pmcw.lpm = schib_copy.pmcw.lpm;
p->mbi = schib.pmcw.mbi; schib->pmcw.mbi = schib_copy.pmcw.mbi;
p->pom = schib.pmcw.pom; schib->pmcw.pom = schib_copy.pmcw.pom;
p->chars &= ~(PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_CSENSE); schib->pmcw.chars &= ~(PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_CSENSE);
p->chars |= schib.pmcw.chars & schib->pmcw.chars |= schib_copy.pmcw.chars &
(PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_CSENSE); (PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_CSENSE);
sch->curr_status.mba = schib.mba; schib->mba = schib_copy.mba;
/* Has the channel been disabled? */ /* Has the channel been disabled? */
if (sch->disable_cb && (oldflags & PMCW_FLAGS_MASK_ENA) != 0 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); sch->disable_cb(sch);
} }
return IOINST_CC_EXPECTED; return IOINST_CC_EXPECTED;
@ -1417,82 +1409,80 @@ IOInstEnding css_do_msch(SubchDev *sch, const SCHIB *orig_schib)
IOInstEnding css_do_xsch(SubchDev *sch) IOInstEnding css_do_xsch(SubchDev *sch)
{ {
SCSW *s = &sch->curr_status.scsw; SCHIB *schib = &sch->curr_status;
PMCW *p = &sch->curr_status.pmcw;
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; 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; return IOINST_CC_STATUS_PRESENT;
} }
if (!(s->ctrl & SCSW_CTRL_MASK_FCTL) || if (!(schib->scsw.ctrl & SCSW_CTRL_MASK_FCTL) ||
((s->ctrl & SCSW_CTRL_MASK_FCTL) != SCSW_FCTL_START_FUNC) || ((schib->scsw.ctrl & SCSW_CTRL_MASK_FCTL) != SCSW_FCTL_START_FUNC) ||
(!(s->ctrl & (!(schib->scsw.ctrl &
(SCSW_ACTL_RESUME_PEND | SCSW_ACTL_START_PEND | SCSW_ACTL_SUSP))) || (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; return IOINST_CC_BUSY;
} }
/* Cancel the current operation. */ /* Cancel the current operation. */
s->ctrl &= ~(SCSW_FCTL_START_FUNC | schib->scsw.ctrl &= ~(SCSW_FCTL_START_FUNC |
SCSW_ACTL_RESUME_PEND | SCSW_ACTL_RESUME_PEND |
SCSW_ACTL_START_PEND | SCSW_ACTL_START_PEND |
SCSW_ACTL_SUSP); SCSW_ACTL_SUSP);
sch->channel_prog = 0x0; sch->channel_prog = 0x0;
sch->last_cmd_valid = false; sch->last_cmd_valid = false;
s->dstat = 0; schib->scsw.dstat = 0;
s->cstat = 0; schib->scsw.cstat = 0;
return IOINST_CC_EXPECTED; return IOINST_CC_EXPECTED;
} }
IOInstEnding css_do_csch(SubchDev *sch) IOInstEnding css_do_csch(SubchDev *sch)
{ {
SCSW *s = &sch->curr_status.scsw; SCHIB *schib = &sch->curr_status;
PMCW *p = &sch->curr_status.pmcw;
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; return IOINST_CC_NOT_OPERATIONAL;
} }
/* Trigger the clear function. */ /* Trigger the clear function. */
s->ctrl &= ~(SCSW_CTRL_MASK_FCTL | SCSW_CTRL_MASK_ACTL); schib->scsw.ctrl &= ~(SCSW_CTRL_MASK_FCTL | SCSW_CTRL_MASK_ACTL);
s->ctrl |= SCSW_FCTL_CLEAR_FUNC | SCSW_ACTL_CLEAR_PEND; schib->scsw.ctrl |= SCSW_FCTL_CLEAR_FUNC | SCSW_ACTL_CLEAR_PEND;
return do_subchannel_work(sch); return do_subchannel_work(sch);
} }
IOInstEnding css_do_hsch(SubchDev *sch) IOInstEnding css_do_hsch(SubchDev *sch)
{ {
SCSW *s = &sch->curr_status.scsw; SCHIB *schib = &sch->curr_status;
PMCW *p = &sch->curr_status.pmcw;
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; return IOINST_CC_NOT_OPERATIONAL;
} }
if (((s->ctrl & SCSW_CTRL_MASK_STCTL) == SCSW_STCTL_STATUS_PEND) || if (((schib->scsw.ctrl & SCSW_CTRL_MASK_STCTL) == SCSW_STCTL_STATUS_PEND) ||
(s->ctrl & (SCSW_STCTL_PRIMARY | (schib->scsw.ctrl & (SCSW_STCTL_PRIMARY |
SCSW_STCTL_SECONDARY | SCSW_STCTL_SECONDARY |
SCSW_STCTL_ALERT))) { SCSW_STCTL_ALERT))) {
return IOINST_CC_STATUS_PRESENT; 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; return IOINST_CC_BUSY;
} }
/* Trigger the halt function. */ /* Trigger the halt function. */
s->ctrl |= SCSW_FCTL_HALT_FUNC; schib->scsw.ctrl |= SCSW_FCTL_HALT_FUNC;
s->ctrl &= ~SCSW_FCTL_START_FUNC; schib->scsw.ctrl &= ~SCSW_FCTL_START_FUNC;
if (((s->ctrl & SCSW_CTRL_MASK_ACTL) == if (((schib->scsw.ctrl & SCSW_CTRL_MASK_ACTL) ==
(SCSW_ACTL_SUBCH_ACTIVE | SCSW_ACTL_DEVICE_ACTIVE)) && (SCSW_ACTL_SUBCH_ACTIVE | SCSW_ACTL_DEVICE_ACTIVE)) &&
((s->ctrl & SCSW_CTRL_MASK_STCTL) == SCSW_STCTL_INTERMEDIATE)) { ((schib->scsw.ctrl & SCSW_CTRL_MASK_STCTL) ==
s->ctrl &= ~SCSW_STCTL_STATUS_PEND; 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); return do_subchannel_work(sch);
} }
@ -1534,18 +1524,17 @@ static void css_update_chnmon(SubchDev *sch)
IOInstEnding css_do_ssch(SubchDev *sch, ORB *orb) IOInstEnding css_do_ssch(SubchDev *sch, ORB *orb)
{ {
SCSW *s = &sch->curr_status.scsw; SCHIB *schib = &sch->curr_status;
PMCW *p = &sch->curr_status.pmcw;
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; 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; 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_HALT_FUNC |
SCSW_FCTL_CLEAR_FUNC)) { SCSW_FCTL_CLEAR_FUNC)) {
return IOINST_CC_BUSY; return IOINST_CC_BUSY;
@ -1558,13 +1547,13 @@ IOInstEnding css_do_ssch(SubchDev *sch, ORB *orb)
sch->orb = *orb; sch->orb = *orb;
sch->channel_prog = orb->cpa; sch->channel_prog = orb->cpa;
/* Trigger the start function. */ /* Trigger the start function. */
s->ctrl |= (SCSW_FCTL_START_FUNC | SCSW_ACTL_START_PEND); schib->scsw.ctrl |= (SCSW_FCTL_START_FUNC | SCSW_ACTL_START_PEND);
s->flags &= ~SCSW_FLAGS_MASK_PNO; schib->scsw.flags &= ~SCSW_FLAGS_MASK_PNO;
return do_subchannel_work(sch); 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 *irb_len)
{ {
int i; 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) int css_do_tsch_get_irb(SubchDev *sch, IRB *target_irb, int *irb_len)
{ {
SCSW *s = &sch->curr_status.scsw; SCHIB *schib = &sch->curr_status;
PMCW *p = &sch->curr_status.pmcw; PMCW p;
uint16_t stctl; uint16_t stctl;
IRB irb; 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; return 3;
} }
stctl = s->ctrl & SCSW_CTRL_MASK_STCTL; stctl = schib->scsw.ctrl & SCSW_CTRL_MASK_STCTL;
/* Prepare the irb for the guest. */ /* Prepare the irb for the guest. */
memset(&irb, 0, sizeof(IRB)); memset(&irb, 0, sizeof(IRB));
/* Copy scsw from current status. */ /* Copy scsw from current status. */
memcpy(&irb.scsw, s, sizeof(SCSW)); irb.scsw = schib->scsw;
if (stctl & SCSW_STCTL_STATUS_PEND) { 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_CHN_CTRL_CHK |
SCSW_CSTAT_INTF_CTRL_CHK)) { SCSW_CSTAT_INTF_CTRL_CHK)) {
irb.scsw.flags |= SCSW_FLAGS_MASK_ESWF; 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; irb.esw[0] = 0x00800000;
} }
/* If a unit check is pending, copy sense data. */ /* If a unit check is pending, copy sense data. */
if ((s->dstat & SCSW_DSTAT_UNIT_CHECK) && if ((schib->scsw.dstat & SCSW_DSTAT_UNIT_CHECK) &&
(p->chars & PMCW_CHARS_MASK_CSENSE)) { (schib->pmcw.chars & PMCW_CHARS_MASK_CSENSE)) {
int i; int i;
irb.scsw.flags |= SCSW_FLAGS_MASK_ESWF | SCSW_FLAGS_MASK_ECTL; 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. */ /* 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); return ((stctl & SCSW_STCTL_STATUS_PEND) == 0);
} }
void css_do_tsch_update_subch(SubchDev *sch) void css_do_tsch_update_subch(SubchDev *sch)
{ {
SCSW *s = &sch->curr_status.scsw; SCHIB *schib = &sch->curr_status;
PMCW *p = &sch->curr_status.pmcw;
uint16_t stctl; uint16_t stctl;
uint16_t fctl; uint16_t fctl;
uint16_t actl; uint16_t actl;
stctl = s->ctrl & SCSW_CTRL_MASK_STCTL; stctl = schib->scsw.ctrl & SCSW_CTRL_MASK_STCTL;
fctl = s->ctrl & SCSW_CTRL_MASK_FCTL; fctl = schib->scsw.ctrl & SCSW_CTRL_MASK_FCTL;
actl = s->ctrl & SCSW_CTRL_MASK_ACTL; actl = schib->scsw.ctrl & SCSW_CTRL_MASK_ACTL;
/* Clear conditions on subchannel, if applicable. */ /* Clear conditions on subchannel, if applicable. */
if (stctl & SCSW_STCTL_STATUS_PEND) { 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)) || if ((stctl != (SCSW_STCTL_INTERMEDIATE | SCSW_STCTL_STATUS_PEND)) ||
((fctl & SCSW_FCTL_HALT_FUNC) && ((fctl & SCSW_FCTL_HALT_FUNC) &&
(actl & SCSW_ACTL_SUSP))) { (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)) { if (stctl != (SCSW_STCTL_INTERMEDIATE | SCSW_STCTL_STATUS_PEND)) {
s->flags &= ~SCSW_FLAGS_MASK_PNO; schib->scsw.flags &= ~SCSW_FLAGS_MASK_PNO;
s->ctrl &= ~(SCSW_ACTL_RESUME_PEND | schib->scsw.ctrl &= ~(SCSW_ACTL_RESUME_PEND |
SCSW_ACTL_START_PEND | SCSW_ACTL_START_PEND |
SCSW_ACTL_HALT_PEND | SCSW_ACTL_HALT_PEND |
SCSW_ACTL_CLEAR_PEND | SCSW_ACTL_CLEAR_PEND |
@ -1678,20 +1667,20 @@ void css_do_tsch_update_subch(SubchDev *sch)
} else { } else {
if ((actl & SCSW_ACTL_SUSP) && if ((actl & SCSW_ACTL_SUSP) &&
(fctl & SCSW_FCTL_START_FUNC)) { (fctl & SCSW_FCTL_START_FUNC)) {
s->flags &= ~SCSW_FLAGS_MASK_PNO; schib->scsw.flags &= ~SCSW_FLAGS_MASK_PNO;
if (fctl & SCSW_FCTL_HALT_FUNC) { 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_START_PEND |
SCSW_ACTL_HALT_PEND | SCSW_ACTL_HALT_PEND |
SCSW_ACTL_CLEAR_PEND | SCSW_ACTL_CLEAR_PEND |
SCSW_ACTL_SUSP); SCSW_ACTL_SUSP);
} else { } else {
s->ctrl &= ~SCSW_ACTL_RESUME_PEND; schib->scsw.ctrl &= ~SCSW_ACTL_RESUME_PEND;
} }
} }
} }
/* Clear pending sense data. */ /* 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)); 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) IOInstEnding css_do_rsch(SubchDev *sch)
{ {
SCSW *s = &sch->curr_status.scsw; SCHIB *schib = &sch->curr_status;
PMCW *p = &sch->curr_status.pmcw;
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; 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; return IOINST_CC_STATUS_PRESENT;
} }
if (((s->ctrl & SCSW_CTRL_MASK_FCTL) != SCSW_FCTL_START_FUNC) || if (((schib->scsw.ctrl & SCSW_CTRL_MASK_FCTL) != SCSW_FCTL_START_FUNC) ||
(s->ctrl & SCSW_ACTL_RESUME_PEND) || (schib->scsw.ctrl & SCSW_ACTL_RESUME_PEND) ||
(!(s->ctrl & SCSW_ACTL_SUSP))) { (!(schib->scsw.ctrl & SCSW_ACTL_SUSP))) {
return IOINST_CC_BUSY; return IOINST_CC_BUSY;
} }
@ -1826,7 +1814,7 @@ IOInstEnding css_do_rsch(SubchDev *sch)
css_update_chnmon(sch); css_update_chnmon(sch);
} }
s->ctrl |= SCSW_ACTL_RESUME_PEND; schib->scsw.ctrl |= SCSW_ACTL_RESUME_PEND;
return do_subchannel_work(sch); 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) void css_sch_build_virtual_schib(SubchDev *sch, uint8_t chpid, uint8_t type)
{ {
PMCW *p = &sch->curr_status.pmcw; SCHIB *schib = &sch->curr_status;
SCSW *s = &sch->curr_status.scsw;
int i; int i;
CssImage *css = channel_subsys.css[sch->cssid]; CssImage *css = channel_subsys.css[sch->cssid];
assert(css != NULL); assert(css != NULL);
memset(p, 0, sizeof(PMCW)); memset(&schib->pmcw, 0, sizeof(PMCW));
p->flags |= PMCW_FLAGS_MASK_DNV; schib->pmcw.flags |= PMCW_FLAGS_MASK_DNV;
p->devno = sch->devno; schib->pmcw.devno = sch->devno;
/* single path */ /* single path */
p->pim = 0x80; schib->pmcw.pim = 0x80;
p->pom = 0xff; schib->pmcw.pom = 0xff;
p->pam = 0x80; schib->pmcw.pam = 0x80;
p->chpid[0] = chpid; schib->pmcw.chpid[0] = chpid;
if (!css->chpids[chpid].in_use) { if (!css->chpids[chpid].in_use) {
css_add_chpid(sch->cssid, chpid, type, true); css_add_chpid(sch->cssid, chpid, type, true);
} }
memset(s, 0, sizeof(SCSW)); memset(&schib->scsw, 0, sizeof(SCSW));
sch->curr_status.mba = 0; schib->mba = 0;
for (i = 0; i < ARRAY_SIZE(sch->curr_status.mda); i++) { for (i = 0; i < ARRAY_SIZE(schib->mda); i++) {
sch->curr_status.mda[i] = 0; schib->mda[i] = 0;
} }
} }
@ -2246,30 +2233,30 @@ int css_enable_mss(void)
void css_reset_sch(SubchDev *sch) 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); sch->disable_cb(sch);
} }
p->intparm = 0; schib->pmcw.intparm = 0;
p->flags &= ~(PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA | schib->pmcw.flags &= ~(PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA |
PMCW_FLAGS_MASK_LM | PMCW_FLAGS_MASK_MME | PMCW_FLAGS_MASK_LM | PMCW_FLAGS_MASK_MME |
PMCW_FLAGS_MASK_MP | PMCW_FLAGS_MASK_TF); PMCW_FLAGS_MASK_MP | PMCW_FLAGS_MASK_TF);
p->flags |= PMCW_FLAGS_MASK_DNV; schib->pmcw.flags |= PMCW_FLAGS_MASK_DNV;
p->devno = sch->devno; schib->pmcw.devno = sch->devno;
p->pim = 0x80; schib->pmcw.pim = 0x80;
p->lpm = p->pim; schib->pmcw.lpm = schib->pmcw.pim;
p->pnom = 0; schib->pmcw.pnom = 0;
p->lpum = 0; schib->pmcw.lpum = 0;
p->mbi = 0; schib->pmcw.mbi = 0;
p->pom = 0xff; schib->pmcw.pom = 0xff;
p->pam = 0x80; schib->pmcw.pam = 0x80;
p->chars &= ~(PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_XMWME | schib->pmcw.chars &= ~(PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_XMWME |
PMCW_CHARS_MASK_CSENSE); PMCW_CHARS_MASK_CSENSE);
memset(&sch->curr_status.scsw, 0, sizeof(sch->curr_status.scsw)); memset(&schib->scsw, 0, sizeof(schib->scsw));
sch->curr_status.mba = 0; schib->mba = 0;
sch->channel_prog = 0x0; sch->channel_prog = 0x0;
sch->last_cmd_valid = false; sch->last_cmd_valid = false;
@ -2433,7 +2420,7 @@ static int css_sch_get_chpids(SubchDev *sch, CssDevId *dev_id)
FILE *fd; FILE *fd;
uint32_t chpid[8]; uint32_t chpid[8];
int i; 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", fid_path = g_strdup_printf("/sys/bus/css/devices/%x.%x.%04x/chpids",
dev_id->cssid, dev_id->ssid, dev_id->devid); 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; return -EINVAL;
} }
for (i = 0; i < ARRAY_SIZE(p->chpid); i++) { for (i = 0; i < ARRAY_SIZE(schib->pmcw.chpid); i++) {
p->chpid[i] = chpid[i]; schib->pmcw.chpid[i] = chpid[i];
} }
fclose(fd); fclose(fd);
@ -2467,7 +2454,7 @@ static int css_sch_get_path_masks(SubchDev *sch, CssDevId *dev_id)
char *fid_path; char *fid_path;
FILE *fd; FILE *fd;
uint32_t pim, pam, pom; 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", fid_path = g_strdup_printf("/sys/bus/css/devices/%x.%x.%04x/pimpampom",
dev_id->cssid, dev_id->ssid, dev_id->devid); 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; return -EINVAL;
} }
p->pim = pim; schib->pmcw.pim = pim;
p->pam = pam; schib->pmcw.pam = pam;
p->pom = pom; schib->pmcw.pom = pom;
fclose(fd); fclose(fd);
g_free(fid_path); 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) int css_sch_build_schib(SubchDev *sch, CssDevId *dev_id)
{ {
CssImage *css = channel_subsys.css[sch->cssid]; CssImage *css = channel_subsys.css[sch->cssid];
PMCW *p = &sch->curr_status.pmcw; SCHIB *schib = &sch->curr_status;
SCSW *s = &sch->curr_status.scsw;
uint32_t type; uint32_t type;
int i, ret; int i, ret;
assert(css != NULL); assert(css != NULL);
memset(p, 0, sizeof(PMCW)); memset(&schib->pmcw, 0, sizeof(PMCW));
p->flags |= PMCW_FLAGS_MASK_DNV; schib->pmcw.flags |= PMCW_FLAGS_MASK_DNV;
/* We are dealing with I/O subchannels only. */ /* We are dealing with I/O subchannels only. */
p->devno = sch->devno; schib->pmcw.devno = sch->devno;
/* Grab path mask from sysfs. */ /* Grab path mask from sysfs. */
ret = css_sch_get_path_masks(sch, dev_id); 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. */ /* Build chpid type. */
for (i = 0; i < ARRAY_SIZE(p->chpid); i++) { for (i = 0; i < ARRAY_SIZE(schib->pmcw.chpid); i++) {
if (p->chpid[i] && !css->chpids[p->chpid[i]].in_use) { if (schib->pmcw.chpid[i] && !css->chpids[schib->pmcw.chpid[i]].in_use) {
ret = css_sch_get_chpid_type(p->chpid[i], &type, dev_id); ret = css_sch_get_chpid_type(schib->pmcw.chpid[i], &type, dev_id);
if (ret) { if (ret) {
return 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)); memset(&schib->scsw, 0, sizeof(SCSW));
sch->curr_status.mba = 0; schib->mba = 0;
for (i = 0; i < ARRAY_SIZE(sch->curr_status.mda); i++) { for (i = 0; i < ARRAY_SIZE(schib->mda); i++) {
sch->curr_status.mda[i] = 0; schib->mda[i] = 0;
} }
return 0; return 0;

View File

@ -252,8 +252,6 @@ static void s390_ipl_set_boot_menu(S390IPLState *ipl)
{ {
QemuOptsList *plist = qemu_find_opts("boot-opts"); QemuOptsList *plist = qemu_find_opts("boot-opts");
QemuOpts *opts = QTAILQ_FIRST(&plist->head); QemuOpts *opts = QTAILQ_FIRST(&plist->head);
uint8_t *flags = &ipl->qipl.qipl_flags;
uint32_t *timeout = &ipl->qipl.boot_menu_timeout;
const char *tmp; const char *tmp;
unsigned long splash_time = 0; unsigned long splash_time = 0;
@ -269,7 +267,7 @@ static void s390_ipl_set_boot_menu(S390IPLState *ipl)
case S390_IPL_TYPE_CCW: case S390_IPL_TYPE_CCW:
/* In the absence of -boot menu, use zipl parameters */ /* In the absence of -boot menu, use zipl parameters */
if (!qemu_opt_get(opts, "menu")) { if (!qemu_opt_get(opts, "menu")) {
*flags |= QIPL_FLAG_BM_OPTS_ZIPL; ipl->qipl.qipl_flags |= QIPL_FLAG_BM_OPTS_ZIPL;
return; return;
} }
break; break;
@ -286,23 +284,23 @@ static void s390_ipl_set_boot_menu(S390IPLState *ipl)
return; return;
} }
*flags |= QIPL_FLAG_BM_OPTS_CMD; ipl->qipl.qipl_flags |= QIPL_FLAG_BM_OPTS_CMD;
tmp = qemu_opt_get(opts, "splash-time"); tmp = qemu_opt_get(opts, "splash-time");
if (tmp && qemu_strtoul(tmp, NULL, 10, &splash_time)) { if (tmp && qemu_strtoul(tmp, NULL, 10, &splash_time)) {
error_report("splash-time is invalid, forcing it to 0"); error_report("splash-time is invalid, forcing it to 0");
*timeout = 0; ipl->qipl.boot_menu_timeout = 0;
return; return;
} }
if (splash_time > 0xffffffff) { if (splash_time > 0xffffffff) {
error_report("splash-time is too large, forcing it to max value"); error_report("splash-time is too large, forcing it to max value");
*timeout = 0xffffffff; ipl->qipl.boot_menu_timeout = 0xffffffff;
return; 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) static CcwDevice *s390_get_ccw_device(DeviceState *dev_st)

View File

@ -130,8 +130,8 @@ static void vfio_ccw_io_notifier_handler(void *opaque)
S390CCWDevice *cdev = S390_CCW_DEVICE(vcdev); S390CCWDevice *cdev = S390_CCW_DEVICE(vcdev);
CcwDevice *ccw_dev = CCW_DEVICE(cdev); CcwDevice *ccw_dev = CCW_DEVICE(cdev);
SubchDev *sch = ccw_dev->sch; SubchDev *sch = ccw_dev->sch;
SCSW *s = &sch->curr_status.scsw; SCHIB *schib = &sch->curr_status;
PMCW *p = &sch->curr_status.pmcw; SCSW s;
IRB irb; IRB irb;
int size; int size;
@ -145,33 +145,33 @@ static void vfio_ccw_io_notifier_handler(void *opaque)
switch (errno) { switch (errno) {
case ENODEV: case ENODEV:
/* Generate a deferred cc 3 condition. */ /* Generate a deferred cc 3 condition. */
s->flags |= SCSW_FLAGS_MASK_CC; schib->scsw.flags |= SCSW_FLAGS_MASK_CC;
s->ctrl &= ~SCSW_CTRL_MASK_STCTL; schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
s->ctrl |= (SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND); schib->scsw.ctrl |= (SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND);
goto read_err; goto read_err;
case EFAULT: case EFAULT:
/* Memory problem, generate channel data check. */ /* Memory problem, generate channel data check. */
s->ctrl &= ~SCSW_ACTL_START_PEND; schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
s->cstat = SCSW_CSTAT_DATA_CHECK; schib->scsw.cstat = SCSW_CSTAT_DATA_CHECK;
s->ctrl &= ~SCSW_CTRL_MASK_STCTL; schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY | schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND; SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
goto read_err; goto read_err;
default: default:
/* Error, generate channel program check. */ /* Error, generate channel program check. */
s->ctrl &= ~SCSW_ACTL_START_PEND; schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
s->cstat = SCSW_CSTAT_PROG_CHECK; schib->scsw.cstat = SCSW_CSTAT_PROG_CHECK;
s->ctrl &= ~SCSW_CTRL_MASK_STCTL; schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY | schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND; SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
goto read_err; goto read_err;
} }
} else if (size != vcdev->io_region_size) { } else if (size != vcdev->io_region_size) {
/* Information transfer error, generate channel-control check. */ /* Information transfer error, generate channel-control check. */
s->ctrl &= ~SCSW_ACTL_START_PEND; schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
s->cstat = SCSW_CSTAT_CHN_CTRL_CHK; schib->scsw.cstat = SCSW_CSTAT_CHN_CTRL_CHK;
s->ctrl &= ~SCSW_CTRL_MASK_STCTL; schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY | schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND; SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
goto read_err; goto read_err;
} }
@ -179,11 +179,13 @@ static void vfio_ccw_io_notifier_handler(void *opaque)
memcpy(&irb, region->irb_area, sizeof(IRB)); memcpy(&irb, region->irb_area, sizeof(IRB));
/* Update control block via 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 a uint check is pending, copy sense data. */
if ((s->dstat & SCSW_DSTAT_UNIT_CHECK) && if ((schib->scsw.dstat & SCSW_DSTAT_UNIT_CHECK) &&
(p->chars & PMCW_CHARS_MASK_CSENSE)) { (schib->pmcw.chars & PMCW_CHARS_MASK_CSENSE)) {
memcpy(sch->sense_data, irb.ecw, sizeof(irb.ecw)); memcpy(sch->sense_data, irb.ecw, sizeof(irb.ecw));
} }