summaryrefslogtreecommitdiff
path: root/drivers/s390
diff options
context:
space:
mode:
authorPeter Oberparleiter <peter.oberparleiter@de.ibm.com>2006-09-20 13:59:57 (GMT)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2006-09-20 13:59:57 (GMT)
commite0e32c8eba86fd5ea79eefad6f2c0b4988dfd02a (patch)
tree2337ed7ce0e1c392c31a67da6c534c6d681649aa /drivers/s390
parentdd9963f9dd0985e16e878fd3632ecadfc54d3fbb (diff)
downloadlinux-e0e32c8eba86fd5ea79eefad6f2c0b4988dfd02a.tar.xz
[S390] cio: update path groups on logical CHPID changes.
CHPIDs that are logically varied off will not be removed from a CCW device's path group because resign-from-pathgroup command is issued with invalid path mask of 0 because internal CCW operations are masked by the logical path mask after the relevant bits are cleared by the vary operation. Do not apply logical path mask to internal operations. Signed-off-by: Peter Oberparleiter <peter.oberparleiter@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/cio/cio.c2
-rw-r--r--drivers/s390/cio/device_ops.c15
2 files changed, 15 insertions, 2 deletions
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 61eb7ca..54cce54 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -191,7 +191,7 @@ cio_start_key (struct subchannel *sch, /* subchannel structure */
sch->orb.pfch = sch->options.prefetch == 0;
sch->orb.spnd = sch->options.suspend;
sch->orb.ssic = sch->options.suspend && sch->options.inter;
- sch->orb.lpm = (lpm != 0) ? (lpm & sch->opm) : sch->lpm;
+ sch->orb.lpm = (lpm != 0) ? lpm : sch->lpm;
#ifdef CONFIG_64BIT
/*
* for 64 bit we always support 64 bit IDAWs with 4k page size only
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index 9e3de0bd..acad8f8 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -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;
@@ -304,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);
@@ -433,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;