diff options
author | Cornelia Huck <cornelia.huck@de.ibm.com> | 2006-12-04 09:41:04 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2006-12-04 09:41:04 -0500 |
commit | d23861ff1a4da1f4a5255eb4582f620191c6e1c0 (patch) | |
tree | fcf5cd0ce14600f2ace203bc71ae940db7fe6497 /drivers/s390/cio/device_pgid.c | |
parent | 24cb5b4846ebae5543869b5c596c2650f380df53 (diff) |
[S390] cio: Retry internal operations after vary off.
If I/O was running on a just varied off chpid, it will be terminated.
If this was a common I/O layer internal I/O, it needs to be retried.
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio/device_pgid.c')
-rw-r--r-- | drivers/s390/cio/device_pgid.c | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c index 2975ce888c19..cb1879a96818 100644 --- a/drivers/s390/cio/device_pgid.c +++ b/drivers/s390/cio/device_pgid.c | |||
@@ -71,6 +71,8 @@ __ccw_device_sense_pgid_start(struct ccw_device *cdev) | |||
71 | ccw->cda = (__u32) __pa (&cdev->private->pgid[i]); | 71 | ccw->cda = (__u32) __pa (&cdev->private->pgid[i]); |
72 | if (cdev->private->iretry > 0) { | 72 | if (cdev->private->iretry > 0) { |
73 | cdev->private->iretry--; | 73 | cdev->private->iretry--; |
74 | /* Reset internal retry indication. */ | ||
75 | cdev->private->flags.intretry = 0; | ||
74 | ret = cio_start (sch, cdev->private->iccws, | 76 | ret = cio_start (sch, cdev->private->iccws, |
75 | cdev->private->imask); | 77 | cdev->private->imask); |
76 | /* ret is 0, -EBUSY, -EACCES or -ENODEV */ | 78 | /* ret is 0, -EBUSY, -EACCES or -ENODEV */ |
@@ -122,8 +124,14 @@ __ccw_device_check_sense_pgid(struct ccw_device *cdev) | |||
122 | 124 | ||
123 | sch = to_subchannel(cdev->dev.parent); | 125 | sch = to_subchannel(cdev->dev.parent); |
124 | irb = &cdev->private->irb; | 126 | irb = &cdev->private->irb; |
125 | if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) | 127 | if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) { |
128 | /* Retry Sense PGID if requested. */ | ||
129 | if (cdev->private->flags.intretry) { | ||
130 | cdev->private->flags.intretry = 0; | ||
131 | return -EAGAIN; | ||
132 | } | ||
126 | return -ETIME; | 133 | return -ETIME; |
134 | } | ||
127 | if (irb->esw.esw0.erw.cons && | 135 | if (irb->esw.esw0.erw.cons && |
128 | (irb->ecw[0]&(SNS0_CMD_REJECT|SNS0_INTERVENTION_REQ))) { | 136 | (irb->ecw[0]&(SNS0_CMD_REJECT|SNS0_INTERVENTION_REQ))) { |
129 | /* | 137 | /* |
@@ -253,6 +261,8 @@ __ccw_device_do_pgid(struct ccw_device *cdev, __u8 func) | |||
253 | ret = -EACCES; | 261 | ret = -EACCES; |
254 | if (cdev->private->iretry > 0) { | 262 | if (cdev->private->iretry > 0) { |
255 | cdev->private->iretry--; | 263 | cdev->private->iretry--; |
264 | /* Reset internal retry indication. */ | ||
265 | cdev->private->flags.intretry = 0; | ||
256 | ret = cio_start (sch, cdev->private->iccws, | 266 | ret = cio_start (sch, cdev->private->iccws, |
257 | cdev->private->imask); | 267 | cdev->private->imask); |
258 | /* We expect an interrupt in case of success or busy | 268 | /* We expect an interrupt in case of success or busy |
@@ -293,6 +303,8 @@ static int __ccw_device_do_nop(struct ccw_device *cdev) | |||
293 | ret = -EACCES; | 303 | ret = -EACCES; |
294 | if (cdev->private->iretry > 0) { | 304 | if (cdev->private->iretry > 0) { |
295 | cdev->private->iretry--; | 305 | cdev->private->iretry--; |
306 | /* Reset internal retry indication. */ | ||
307 | cdev->private->flags.intretry = 0; | ||
296 | ret = cio_start (sch, cdev->private->iccws, | 308 | ret = cio_start (sch, cdev->private->iccws, |
297 | cdev->private->imask); | 309 | cdev->private->imask); |
298 | /* We expect an interrupt in case of success or busy | 310 | /* We expect an interrupt in case of success or busy |
@@ -321,8 +333,14 @@ __ccw_device_check_pgid(struct ccw_device *cdev) | |||
321 | 333 | ||
322 | sch = to_subchannel(cdev->dev.parent); | 334 | sch = to_subchannel(cdev->dev.parent); |
323 | irb = &cdev->private->irb; | 335 | irb = &cdev->private->irb; |
324 | if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) | 336 | if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) { |
337 | /* Retry Set PGID if requested. */ | ||
338 | if (cdev->private->flags.intretry) { | ||
339 | cdev->private->flags.intretry = 0; | ||
340 | return -EAGAIN; | ||
341 | } | ||
325 | return -ETIME; | 342 | return -ETIME; |
343 | } | ||
326 | if (irb->esw.esw0.erw.cons) { | 344 | if (irb->esw.esw0.erw.cons) { |
327 | if (irb->ecw[0] & SNS0_CMD_REJECT) | 345 | if (irb->ecw[0] & SNS0_CMD_REJECT) |
328 | return -EOPNOTSUPP; | 346 | return -EOPNOTSUPP; |
@@ -360,8 +378,14 @@ static int __ccw_device_check_nop(struct ccw_device *cdev) | |||
360 | 378 | ||
361 | sch = to_subchannel(cdev->dev.parent); | 379 | sch = to_subchannel(cdev->dev.parent); |
362 | irb = &cdev->private->irb; | 380 | irb = &cdev->private->irb; |
363 | if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) | 381 | if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) { |
382 | /* Retry NOP if requested. */ | ||
383 | if (cdev->private->flags.intretry) { | ||
384 | cdev->private->flags.intretry = 0; | ||
385 | return -EAGAIN; | ||
386 | } | ||
364 | return -ETIME; | 387 | return -ETIME; |
388 | } | ||
365 | if (irb->scsw.cc == 3) { | 389 | if (irb->scsw.cc == 3) { |
366 | CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel 0.%x.%04x," | 390 | CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel 0.%x.%04x," |
367 | " lpm %02X, became 'not operational'\n", | 391 | " lpm %02X, became 'not operational'\n", |