[S390] cio chpid offline.
authorCornelia Huck <cornelia.huck@de.ibm.com>
Thu, 29 Jun 2006 13:03:35 +0000 (15:03 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Thu, 29 Jun 2006 13:03:35 +0000 (15:03 +0200)
After setting a path to a dasd offline at the SE, I/O hangs on that
dasd for 5 minutes, then continues.
I/O for which an interrupt will not be reported after the channel
path has been disabled was not terminated by the common I/O layer,
causing the dasd MIH to hit after 5 minutes.

Be more aggressive in terminating I/O after setting a channel path
offline. Also make sure to generate a fake irb if the device
driver issues an I/O request after being notified of the killed
I/O and clear residual information from the irb before trying to
start the delayed verification.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
drivers/s390/cio/chsc.c
drivers/s390/cio/device_fsm.c
drivers/s390/cio/device_ops.c

index 4a9da5b..b00f3ed 100644 (file)
@@ -244,8 +244,7 @@ s390_subchannel_remove_chpid(struct device *dev, void *data)
 
        if ((sch->schib.scsw.actl & SCSW_ACTL_DEVACT) &&
            (sch->schib.scsw.actl & SCSW_ACTL_SCHACT) &&
-           (sch->schib.pmcw.lpum == mask) &&
-           (sch->vpm == 0)) {
+           (sch->schib.pmcw.lpum == mask)) {
                int cc;
 
                cc = cio_clear(sch);
index 49ec562..5ec8ef1 100644 (file)
@@ -861,6 +861,8 @@ ccw_device_clear_verify(struct ccw_device *cdev, enum dev_event dev_event)
        irb = (struct irb *) __LC_IRB;
        /* Accumulate status. We don't do basic sense. */
        ccw_device_accumulate_irb(cdev, irb);
+       /* Remember to clear irb to avoid residuals. */
+       memset(&cdev->private->irb, 0, sizeof(struct irb));
        /* Try to start delayed device verification. */
        ccw_device_online_verify(cdev, 0);
        /* Note: Don't call handler for cio initiated clear! */
index 5c9904b..b266ad8 100644 (file)
@@ -78,7 +78,8 @@ ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa,
                return -ENODEV;
        if (cdev->private->state == DEV_STATE_NOT_OPER)
                return -ENODEV;
-       if (cdev->private->state == DEV_STATE_VERIFY) {
+       if (cdev->private->state == DEV_STATE_VERIFY ||
+           cdev->private->state == DEV_STATE_CLEAR_VERIFY) {
                /* Remember to fake irb when finished. */
                if (!cdev->private->flags.fake_irb) {
                        cdev->private->flags.fake_irb = 1;