diff options
author | Cornelia Huck <cornelia.huck@de.ibm.com> | 2008-04-30 15:38:39 +0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2008-04-30 15:38:45 +0400 |
commit | edf2209692769d3e461c0351553098bc017c2caf (patch) | |
tree | 833d40fbff5e35a06fcd3c55736d20e4e82901f6 /drivers/s390 | |
parent | 47494f6a84cdae2740b62e1d86a1860df85d9bbb (diff) | |
download | linux-edf2209692769d3e461c0351553098bc017c2caf.tar.xz |
[S390] cio: Make isc handling more robust.
Introduce an ->isc field in the subchannel to store the desired
interruption subclass, since sch->schib.pmcw.isc may be overwritten
by the hardware on stsch() after machine checks.
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/cio/cio.c | 9 | ||||
-rw-r--r-- | drivers/s390/cio/cio.h | 3 | ||||
-rw-r--r-- | drivers/s390/cio/device_fsm.c | 10 | ||||
-rw-r--r-- | drivers/s390/cio/device_ops.c | 2 |
4 files changed, 10 insertions, 14 deletions
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 23ffcc4768a7..08a578161306 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -407,8 +407,7 @@ cio_modify (struct subchannel *sch) /* * Enable subchannel. */ -int cio_enable_subchannel(struct subchannel *sch, unsigned int isc, - u32 intparm) +int cio_enable_subchannel(struct subchannel *sch, u32 intparm) { char dbf_txt[15]; int ccode; @@ -426,7 +425,7 @@ int cio_enable_subchannel(struct subchannel *sch, unsigned int isc, for (retry = 5, ret = 0; retry > 0; retry--) { sch->schib.pmcw.ena = 1; - sch->schib.pmcw.isc = isc; + sch->schib.pmcw.isc = sch->isc; sch->schib.pmcw.intparm = intparm; ret = cio_modify(sch); if (ret == -ENODEV) @@ -600,6 +599,7 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid) else sch->opm = chp_get_sch_opm(sch); sch->lpm = sch->schib.pmcw.pam & sch->opm; + sch->isc = 3; CIO_DEBUG(KERN_INFO, 0, "Detected device %04x on subchannel 0.%x.%04X" @@ -610,13 +610,11 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid) /* * We now have to initially ... - * ... set "interruption subclass" * ... enable "concurrent sense" * ... enable "multipath mode" if more than one * CHPID is available. This is done regardless * whether multiple paths are available for us. */ - sch->schib.pmcw.isc = 3; /* could be smth. else */ sch->schib.pmcw.csense = 1; /* concurrent sense */ sch->schib.pmcw.ena = 0; if ((sch->lpm & (sch->lpm - 1)) != 0) @@ -812,6 +810,7 @@ cio_probe_console(void) * enable console I/O-interrupt subclass 7 */ ctl_set_bit(6, 24); + console_subchannel.isc = 7; console_subchannel.schib.pmcw.isc = 7; console_subchannel.schib.pmcw.intparm = (u32)(addr_t)&console_subchannel; diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h index 08f2235c5a6f..3c75412904dc 100644 --- a/drivers/s390/cio/cio.h +++ b/drivers/s390/cio/cio.h @@ -74,6 +74,7 @@ struct subchannel { __u8 lpm; /* logical path mask */ __u8 opm; /* operational path mask */ struct schib schib; /* subchannel information block */ + int isc; /* desired interruption subclass */ struct chsc_ssd_info ssd_info; /* subchannel description */ struct device dev; /* entry in device tree */ struct css_driver *driver; @@ -85,7 +86,7 @@ struct subchannel { #define to_subchannel(n) container_of(n, struct subchannel, dev) extern int cio_validate_subchannel (struct subchannel *, struct subchannel_id); -extern int cio_enable_subchannel(struct subchannel *, unsigned int, u32); +extern int cio_enable_subchannel(struct subchannel *, u32); extern int cio_disable_subchannel (struct subchannel *); extern int cio_cancel (struct subchannel *); extern int cio_clear (struct subchannel *); diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index 4b92c84fb438..99403b0a97a7 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c @@ -555,8 +555,7 @@ ccw_device_recognition(struct ccw_device *cdev) (cdev->private->state != DEV_STATE_BOXED)) return -EINVAL; sch = to_subchannel(cdev->dev.parent); - ret = cio_enable_subchannel(sch, sch->schib.pmcw.isc, - (u32)(addr_t)sch); + ret = cio_enable_subchannel(sch, (u32)(addr_t)sch); if (ret != 0) /* Couldn't enable the subchannel for i/o. Sick device. */ return ret; @@ -667,8 +666,7 @@ ccw_device_online(struct ccw_device *cdev) sch = to_subchannel(cdev->dev.parent); if (css_init_done && !get_device(&cdev->dev)) return -ENODEV; - ret = cio_enable_subchannel(sch, sch->schib.pmcw.isc, - (u32)(addr_t)sch); + ret = cio_enable_subchannel(sch, (u32)(addr_t)sch); if (ret != 0) { /* Couldn't enable the subchannel for i/o. Sick device. */ if (ret == -ENODEV) @@ -1048,8 +1046,7 @@ ccw_device_start_id(struct ccw_device *cdev, enum dev_event dev_event) struct subchannel *sch; sch = to_subchannel(cdev->dev.parent); - if (cio_enable_subchannel(sch, sch->schib.pmcw.isc, - (u32)(addr_t)sch) != 0) + if (cio_enable_subchannel(sch, (u32)(addr_t)sch) != 0) /* Couldn't enable the subchannel for i/o. Sick device. */ return; @@ -1082,7 +1079,6 @@ device_trigger_reprobe(struct subchannel *sch) */ sch->lpm = sch->schib.pmcw.pam & sch->opm; /* Re-set some bits in the pmcw that were lost. */ - sch->schib.pmcw.isc = 3; sch->schib.pmcw.csense = 1; sch->schib.pmcw.ena = 0; if ((sch->lpm & (sch->lpm - 1)) != 0) diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c index a1718a0aa539..f308ad55a6d5 100644 --- a/drivers/s390/cio/device_ops.c +++ b/drivers/s390/cio/device_ops.c @@ -508,7 +508,7 @@ ccw_device_stlck(struct ccw_device *cdev) return -ENOMEM; } spin_lock_irqsave(sch->lock, flags); - ret = cio_enable_subchannel(sch, 3, (u32)(addr_t)sch); + ret = cio_enable_subchannel(sch, (u32)(addr_t)sch); if (ret) goto out_unlock; /* |