]> err.no Git - linux-2.6/blobdiff - drivers/s390/cio/device_ops.c
[S390] cio: update path groups on logical CHPID changes.
[linux-2.6] / drivers / s390 / cio / device_ops.c
index a60124264beec97583a150973f07550eb4845193..acad8f852eda5ffdcde02b761d6c164b473f7fb2 100644 (file)
@@ -96,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;
@@ -263,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)) {
@@ -301,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);
@@ -430,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;