When testing I/O transaction with bad addresses we need to check the result of the error when the I/O completed with an alert status. The resulting status is reported in the subchannel and device status of the IRB SCSW. Let's provide the tests the possibility to check if the device and the subchannel status of the IRB SCSW are set as expected. Signed-off-by: Pierre Morel <pmorel@xxxxxxxxxxxxx> --- lib/s390x/css.h | 6 ++++-- lib/s390x/css_lib.c | 24 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/lib/s390x/css.h b/lib/s390x/css.h index 1603781..a5a8427 100644 --- a/lib/s390x/css.h +++ b/lib/s390x/css.h @@ -95,8 +95,9 @@ struct scsw { #define SCSW_DEVS_DEV_END 0x04 #define SCSW_DEVS_SCH_END 0x08 uint8_t dev_stat; -#define SCSW_SCHS_PCI 0x80 -#define SCSW_SCHS_IL 0x40 +#define SCSW_SCHS_PCI 0x80 +#define SCSW_SCHS_IL 0x40 +#define SCSW_SCHS_PRG_CHK 0x20 uint8_t sch_stat; uint16_t count; }; @@ -318,6 +319,7 @@ int css_residual_count(unsigned int schid); void enable_io_isc(uint8_t isc); int wait_and_check_io_completion(int schid, uint32_t ctrl); int check_io_completion(int schid, uint32_t ctrl); +bool check_io_errors(int schid, uint8_t dev_stat, uint8_t sch_stat); /* * CHSC definitions diff --git a/lib/s390x/css_lib.c b/lib/s390x/css_lib.c index 97bf032..65159aa 100644 --- a/lib/s390x/css_lib.c +++ b/lib/s390x/css_lib.c @@ -552,6 +552,30 @@ end: return ret; } +/* check_io_errors: + * @schid: the subchannel ID + * @dev_stat : expected device stat flags + * @sch_stat : expected subchannel stat flags + * + * This routine must be called when an error occurs on CSS I/O + * Only report failures information and returns if we found + * the expected status flags. + */ +bool check_io_errors(int schid, uint8_t dev_stat, uint8_t sch_stat) +{ + if (!(irb.scsw.ctrl & SCSW_SC_ALERT)) { + report_info("No alert in SCSW Ctrl: %s", dump_scsw_flags(irb.scsw.ctrl)); + report_info("schid %08x : dev_stat: %02x sch_stat: %02x", schid, irb.scsw.dev_stat, irb.scsw.sch_stat); + return false; + } + + if ((dev_stat != irb.scsw.dev_stat) || (sch_stat != irb.scsw.sch_stat)) { + report_info("schid %08x : dev_stat: %02x sch_stat: %02x", schid, irb.scsw.dev_stat, irb.scsw.sch_stat); + return false; + } + return true; +} + /* * css_residual_count * Return the residual count, if it is valid. -- 2.17.1