]> err.no Git - linux-2.6/blobdiff - drivers/s390/cio/device_ops.c
[S390] cio: always query all paths on path verification.
[linux-2.6] / drivers / s390 / cio / device_ops.c
index b266ad8e14ff2623fc6e5cea70e04d9a4160435b..93a897eebfff769c4aaddac3738d9c363291d03d 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>
@@ -97,6 +96,12 @@ ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa,
        ret = cio_set_options (sch, flags);
        if (ret)
                return ret;
+       /* Adjust requested path mask to excluded varied off paths. */
+       if (lpm) {
+               lpm &= sch->opm;
+               if (lpm == 0)
+                       return -EACCES;
+       }
        ret = cio_start_key (sch, cpa, lpm, key);
        if (ret == 0)
                cdev->private->intparm = intparm;
@@ -251,7 +256,7 @@ ccw_device_get_path_mask(struct ccw_device *cdev)
        if (!sch)
                return 0;
        else
-               return sch->vpm;
+               return sch->lpm;
 }
 
 static void
@@ -264,6 +269,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)) {
@@ -302,7 +310,7 @@ __ccw_device_retry_loop(struct ccw_device *cdev, struct ccw1 *ccw, long magic, _
        sch = to_subchannel(cdev->dev.parent);
        do {
                ret = cio_start (sch, ccw, lpm);
-               if ((ret == -EBUSY) || (ret == -EACCES)) {
+               if (ret == -EBUSY) {
                        /* Try again later. */
                        spin_unlock_irq(&sch->lock);
                        msleep(10);
@@ -431,6 +439,13 @@ read_conf_data_lpm (struct ccw_device *cdev, void **buffer, int *length, __u8 lp
        if (!ciw || ciw->cmd == 0)
                return -EOPNOTSUPP;
 
+       /* Adjust requested path mask to excluded varied off paths. */
+       if (lpm) {
+               lpm &= sch->opm;
+               if (lpm == 0)
+                       return -EACCES;
+       }
+
        rcd_ccw = kzalloc(sizeof(struct ccw1), GFP_KERNEL | GFP_DMA);
        if (!rcd_ccw)
                return -ENOMEM;