#include "css.h"
#include "device.h"
#include "ioasm.h"
+#include "io_sch.h"
/*
* Check for any kind of channel or interface control check but don't
cdev_irb = &cdev->private->irb;
+ /*
+ * If the clear function had been performed, all formerly pending
+ * status at the subchannel has been cleared and we must not pass
+ * intermediate accumulated status to the device driver.
+ */
+ if (irb->scsw.fctl & SCSW_FCTL_CLEAR_FUNC)
+ memset(&cdev->private->irb, 0, sizeof(struct irb));
+
/* Copy bits which are valid only for the start function. */
if (irb->scsw.fctl & SCSW_FCTL_START_FUNC) {
/* Copy key. */
cdev_irb->scsw.cpa = irb->scsw.cpa;
/* Accumulate device status, but not the device busy flag. */
cdev_irb->scsw.dstat &= ~DEV_STAT_BUSY;
- cdev_irb->scsw.dstat |= irb->scsw.dstat;
+ /* dstat is not always valid. */
+ if (irb->scsw.stctl &
+ (SCSW_STCTL_PRIM_STATUS | SCSW_STCTL_SEC_STATUS
+ | SCSW_STCTL_INTER_STATUS | SCSW_STCTL_ALERT_STATUS))
+ cdev_irb->scsw.dstat |= irb->scsw.dstat;
/* Accumulate subchannel status. */
cdev_irb->scsw.cstat |= irb->scsw.cstat;
/* Copy residual count if it is valid. */
ccw_device_do_sense(struct ccw_device *cdev, struct irb *irb)
{
struct subchannel *sch;
+ struct ccw1 *sense_ccw;
sch = to_subchannel(cdev->dev.parent);
/*
* We have ending status but no sense information. Do a basic sense.
*/
- sch->sense_ccw.cmd_code = CCW_CMD_BASIC_SENSE;
- sch->sense_ccw.cda = (__u32) __pa(cdev->private->irb.ecw);
- sch->sense_ccw.count = SENSE_MAX_COUNT;
- sch->sense_ccw.flags = CCW_FLAG_SLI;
+ sense_ccw = &to_io_private(sch)->sense_ccw;
+ sense_ccw->cmd_code = CCW_CMD_BASIC_SENSE;
+ sense_ccw->cda = (__u32) __pa(cdev->private->irb.ecw);
+ sense_ccw->count = SENSE_MAX_COUNT;
+ sense_ccw->flags = CCW_FLAG_SLI;
/* Reset internal retry indication. */
cdev->private->flags.intretry = 0;
- return cio_start (sch, &sch->sense_ccw, 0xff);
+ return cio_start(sch, sense_ccw, 0xff);
}
/*