[S390] cio: improve unit check handling for internal operations
[linux-block.git] / drivers / s390 / cio / device_ops.c
index 93a897eebfff769c4aaddac3738d9c363291d03d..84b9b18eabc25159d752ea1f78a0792263e97bd3 100644 (file)
@@ -216,6 +216,9 @@ ccw_device_call_handler(struct ccw_device *cdev)
              (stctl & SCSW_STCTL_PRIM_STATUS)))
                return 0;
 
+       /* Clear pending timers for device driver initiated I/O. */
+       if (ending_status)
+               ccw_device_set_timeout(cdev, 0);
        /*
         * Now we are ready to call the device driver interrupt handler.
         */
@@ -285,10 +288,10 @@ ccw_device_wake_up(struct ccw_device *cdev, unsigned long ip, struct irb *irb)
                 if (cdev->private->flags.doverify ||
                         cdev->private->state == DEV_STATE_VERIFY)
                         cdev->private->intparm = -EAGAIN;
-                if ((irb->scsw.dstat & DEV_STAT_UNIT_CHECK) &&
-                    !(irb->ecw[0] &
-                      (SNS0_CMD_REJECT | SNS0_INTERVENTION_REQ)))
-                        cdev->private->intparm = -EAGAIN;
+               else if ((irb->scsw.dstat & DEV_STAT_UNIT_CHECK) &&
+                        !(irb->ecw[0] &
+                          (SNS0_CMD_REJECT | SNS0_INTERVENTION_REQ)))
+                       cdev->private->intparm = -EAGAIN;
                else if ((irb->scsw.dstat & DEV_STAT_ATTENTION) &&
                         (irb->scsw.dstat & DEV_STAT_DEV_END) &&
                         (irb->scsw.dstat & DEV_STAT_UNIT_EXCEP))
@@ -309,7 +312,10 @@ __ccw_device_retry_loop(struct ccw_device *cdev, struct ccw1 *ccw, long magic, _
 
        sch = to_subchannel(cdev->dev.parent);
        do {
+               ccw_device_set_timeout(cdev, 60 * HZ);
                ret = cio_start (sch, ccw, lpm);
+               if (ret != 0)
+                       ccw_device_set_timeout(cdev, 0);
                if (ret == -EBUSY) {
                        /* Try again later. */
                        spin_unlock_irq(&sch->lock);