Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
[pandora-kernel.git] / drivers / s390 / cio / device_ops.c
index 795abb5..9e3de0b 100644 (file)
@@ -6,7 +6,6 @@
  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
  *               Cornelia Huck (cornelia.huck@de.ibm.com)
  */
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/errno.h>
@@ -78,7 +77,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;
@@ -263,6 +263,9 @@ ccw_device_wake_up(struct ccw_device *cdev, unsigned long ip, struct irb *irb)
        /* Abuse intparm for error reporting. */
        if (IS_ERR(irb))
                cdev->private->intparm = -EIO;
+       else if (irb->scsw.cc == 1)
+               /* Retry for deferred condition code. */
+               cdev->private->intparm = -EAGAIN;
        else if ((irb->scsw.dstat !=
                  (DEV_STAT_CHN_END|DEV_STAT_DEV_END)) ||
                 (irb->scsw.cstat != 0)) {
@@ -270,7 +273,8 @@ ccw_device_wake_up(struct ccw_device *cdev, unsigned long ip, struct irb *irb)
                 * We didn't get channel end / device end. Check if path
                 * verification has been started; we can retry after it has
                 * finished. We also retry unit checks except for command reject
-                * or intervention required.
+                * or intervention required. Also check for long busy
+                * conditions.
                 */
                 if (cdev->private->flags.doverify ||
                         cdev->private->state == DEV_STATE_VERIFY)
@@ -279,6 +283,10 @@ ccw_device_wake_up(struct ccw_device *cdev, unsigned long ip, struct irb *irb)
                     !(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))
+                       cdev->private->intparm = -EAGAIN;
                 else
                         cdev->private->intparm = -EIO;