diff options
author | Peter Oberparleiter <peter.oberparleiter@de.ibm.com> | 2006-04-27 21:40:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-04-28 11:33:47 -0400 |
commit | 329b785bcee5d001f97a33bdb80de014bb5020b0 (patch) | |
tree | 795cbbba999f83c3e61a87135dde088b574c7406 /drivers/s390 | |
parent | bcff5cd667da6eb3df9173626497e3e69b004e42 (diff) |
[PATCH] s390: fix I/O termination race in cio
Fix a race condition in the I/O termination logic. The race can cause I/O to
a dasd device to fail with no retry left after turning one channel path to the
device off and on multiple times.
Signed-off-by: Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/cio/chsc.c | 26 |
1 files changed, 4 insertions, 22 deletions
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 6412b2c3edd3..daedb00a4346 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c | |||
@@ -242,28 +242,10 @@ s390_subchannel_remove_chpid(struct device *dev, void *data) | |||
242 | if (sch->vpm == mask) | 242 | if (sch->vpm == mask) |
243 | goto out_unreg; | 243 | goto out_unreg; |
244 | 244 | ||
245 | if ((sch->schib.scsw.actl & (SCSW_ACTL_CLEAR_PEND | | 245 | if ((sch->schib.scsw.actl & SCSW_ACTL_DEVACT) && |
246 | SCSW_ACTL_HALT_PEND | | 246 | (sch->schib.scsw.actl & SCSW_ACTL_SCHACT) && |
247 | SCSW_ACTL_START_PEND | | 247 | (sch->schib.pmcw.lpum == mask) && |
248 | SCSW_ACTL_RESUME_PEND)) && | 248 | (sch->vpm == 0)) { |
249 | (sch->schib.pmcw.lpum == mask)) { | ||
250 | int cc = cio_cancel(sch); | ||
251 | |||
252 | if (cc == -ENODEV) | ||
253 | goto out_unreg; | ||
254 | |||
255 | if (cc == -EINVAL) { | ||
256 | cc = cio_clear(sch); | ||
257 | if (cc == -ENODEV) | ||
258 | goto out_unreg; | ||
259 | /* Call handler. */ | ||
260 | if (sch->driver && sch->driver->termination) | ||
261 | sch->driver->termination(&sch->dev); | ||
262 | goto out_unlock; | ||
263 | } | ||
264 | } else if ((sch->schib.scsw.actl & SCSW_ACTL_DEVACT) && | ||
265 | (sch->schib.scsw.actl & SCSW_ACTL_SCHACT) && | ||
266 | (sch->schib.pmcw.lpum == mask)) { | ||
267 | int cc; | 249 | int cc; |
268 | 250 | ||
269 | cc = cio_clear(sch); | 251 | cc = cio_clear(sch); |