diff options
Diffstat (limited to 'hw/s390x')
-rw-r--r-- | hw/s390x/css.c | 84 | ||||
-rw-r--r-- | hw/s390x/s390-ccw.c | 11 |
2 files changed, 29 insertions, 66 deletions
diff --git a/hw/s390x/css.c b/hw/s390x/css.c index 4f964b7691..c87c1aecc0 100644 --- a/hw/s390x/css.c +++ b/hw/s390x/css.c @@ -1181,12 +1181,11 @@ static void sch_handle_start_func_virtual(SubchDev *sch) } -static int sch_handle_start_func_passthrough(SubchDev *sch) +static IOInstEnding sch_handle_start_func_passthrough(SubchDev *sch) { PMCW *p = &sch->curr_status.pmcw; SCSW *s = &sch->curr_status.scsw; - int ret; ORB *orb = &sch->orb; if (!(s->ctrl & SCSW_ACTL_SUSP)) { @@ -1200,31 +1199,12 @@ static int sch_handle_start_func_passthrough(SubchDev *sch) */ if (!(orb->ctrl0 & ORB_CTRL0_MASK_PFCH) || !(orb->ctrl0 & ORB_CTRL0_MASK_C64)) { - return -EINVAL; + warn_report("vfio-ccw requires PFCH and C64 flags set"); + sch_gen_unit_exception(sch); + css_inject_io_interrupt(sch); + return IOINST_CC_EXPECTED; } - - ret = s390_ccw_cmd_request(orb, s, sch->driver_data); - switch (ret) { - /* Currently we don't update control block and just return the cc code. */ - case 0: - break; - case -EBUSY: - break; - case -ENODEV: - break; - case -EACCES: - /* Let's reflect an inaccessible host device by cc 3. */ - ret = -ENODEV; - break; - default: - /* - * All other return codes will trigger a program check, - * or set cc to 1. - */ - break; - }; - - return ret; + return s390_ccw_cmd_request(sch); } /* @@ -1233,7 +1213,7 @@ static int sch_handle_start_func_passthrough(SubchDev *sch) * read/writes) asynchronous later on if we start supporting more than * our current very simple devices. */ -int do_subchannel_work_virtual(SubchDev *sch) +IOInstEnding do_subchannel_work_virtual(SubchDev *sch) { SCSW *s = &sch->curr_status.scsw; @@ -1247,12 +1227,12 @@ int do_subchannel_work_virtual(SubchDev *sch) sch_handle_start_func_virtual(sch); } css_inject_io_interrupt(sch); - return 0; + /* inst must succeed if this func is called */ + return IOINST_CC_EXPECTED; } -int do_subchannel_work_passthrough(SubchDev *sch) +IOInstEnding do_subchannel_work_passthrough(SubchDev *sch) { - int ret = 0; SCSW *s = &sch->curr_status.scsw; if (s->ctrl & SCSW_FCTL_CLEAR_FUNC) { @@ -1262,16 +1242,15 @@ int do_subchannel_work_passthrough(SubchDev *sch) /* TODO: Halt handling */ sch_handle_halt_func(sch); } else if (s->ctrl & SCSW_FCTL_START_FUNC) { - ret = sch_handle_start_func_passthrough(sch); + return sch_handle_start_func_passthrough(sch); } - - return ret; + return IOINST_CC_EXPECTED; } -static int do_subchannel_work(SubchDev *sch) +static IOInstEnding do_subchannel_work(SubchDev *sch) { if (!sch->do_subchannel_work) { - return -EINVAL; + return IOINST_CC_STATUS_PRESENT; } g_assert(sch->curr_status.scsw.ctrl & SCSW_CTRL_MASK_FCTL); return sch->do_subchannel_work(sch); @@ -1561,27 +1540,23 @@ static void css_update_chnmon(SubchDev *sch) } } -int css_do_ssch(SubchDev *sch, ORB *orb) +IOInstEnding css_do_ssch(SubchDev *sch, ORB *orb) { SCSW *s = &sch->curr_status.scsw; PMCW *p = &sch->curr_status.pmcw; - int ret; if (~(p->flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) { - ret = -ENODEV; - goto out; + return IOINST_CC_NOT_OPERATIONAL; } if (s->ctrl & SCSW_STCTL_STATUS_PEND) { - ret = -EINPROGRESS; - goto out; + return IOINST_CC_STATUS_PRESENT; } if (s->ctrl & (SCSW_FCTL_START_FUNC | SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) { - ret = -EBUSY; - goto out; + return IOINST_CC_BUSY; } /* If monitoring is active, update counter. */ @@ -1594,10 +1569,7 @@ int css_do_ssch(SubchDev *sch, ORB *orb) s->ctrl |= (SCSW_FCTL_START_FUNC | SCSW_ACTL_START_PEND); s->flags &= ~SCSW_FLAGS_MASK_PNO; - ret = do_subchannel_work(sch); - -out: - return ret; + return do_subchannel_work(sch); } static void copy_irb_to_guest(IRB *dest, const IRB *src, PMCW *pmcw, @@ -1844,27 +1816,23 @@ void css_do_schm(uint8_t mbk, int update, int dct, uint64_t mbo) } } -int css_do_rsch(SubchDev *sch) +IOInstEnding css_do_rsch(SubchDev *sch) { SCSW *s = &sch->curr_status.scsw; PMCW *p = &sch->curr_status.pmcw; - int ret; if (~(p->flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) { - ret = -ENODEV; - goto out; + return IOINST_CC_NOT_OPERATIONAL; } if (s->ctrl & SCSW_STCTL_STATUS_PEND) { - ret = -EINPROGRESS; - goto out; + 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))) { - ret = -EINVAL; - goto out; + return IOINST_CC_BUSY; } /* If monitoring is active, update counter. */ @@ -1873,11 +1841,7 @@ int css_do_rsch(SubchDev *sch) } s->ctrl |= SCSW_ACTL_RESUME_PEND; - do_subchannel_work(sch); - ret = 0; - -out: - return ret; + return do_subchannel_work(sch); } int css_do_rchp(uint8_t cssid, uint8_t chpid) diff --git a/hw/s390x/s390-ccw.c b/hw/s390x/s390-ccw.c index 8614dda6f8..0ef232ec27 100644 --- a/hw/s390x/s390-ccw.c +++ b/hw/s390x/s390-ccw.c @@ -18,15 +18,14 @@ #include "hw/s390x/css-bridge.h" #include "hw/s390x/s390-ccw.h" -int s390_ccw_cmd_request(ORB *orb, SCSW *scsw, void *data) +IOInstEnding s390_ccw_cmd_request(SubchDev *sch) { - S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(data); + S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(sch->driver_data); - if (cdc->handle_request) { - return cdc->handle_request(orb, scsw, data); - } else { - return -ENOSYS; + if (!cdc->handle_request) { + return IOINST_CC_STATUS_PRESENT; } + return cdc->handle_request(sch); } static void s390_ccw_get_dev_info(S390CCWDevice *cdev, |