diff options
| -rw-r--r-- | drivers/s390/cio/device_pgid.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c index 32610fd8868e..1693a102dcfe 100644 --- a/drivers/s390/cio/device_pgid.c +++ b/drivers/s390/cio/device_pgid.c | |||
| @@ -24,6 +24,21 @@ | |||
| 24 | #include "ioasm.h" | 24 | #include "ioasm.h" |
| 25 | 25 | ||
| 26 | /* | 26 | /* |
| 27 | * Helper function called from interrupt context to decide whether an | ||
| 28 | * operation should be tried again. | ||
| 29 | */ | ||
| 30 | static int __ccw_device_should_retry(struct scsw *scsw) | ||
| 31 | { | ||
| 32 | /* CC is only valid if start function bit is set. */ | ||
| 33 | if ((scsw->fctl & SCSW_FCTL_START_FUNC) && scsw->cc == 1) | ||
| 34 | return 1; | ||
| 35 | /* No more activity. For sense and set PGID we stubbornly try again. */ | ||
| 36 | if (!scsw->actl) | ||
| 37 | return 1; | ||
| 38 | return 0; | ||
| 39 | } | ||
| 40 | |||
| 41 | /* | ||
| 27 | * Start Sense Path Group ID helper function. Used in ccw_device_recog | 42 | * Start Sense Path Group ID helper function. Used in ccw_device_recog |
| 28 | * and ccw_device_sense_pgid. | 43 | * and ccw_device_sense_pgid. |
| 29 | */ | 44 | */ |
| @@ -155,10 +170,10 @@ ccw_device_sense_pgid_irq(struct ccw_device *cdev, enum dev_event dev_event) | |||
| 155 | int ret; | 170 | int ret; |
| 156 | 171 | ||
| 157 | irb = (struct irb *) __LC_IRB; | 172 | irb = (struct irb *) __LC_IRB; |
| 158 | /* Retry sense pgid for cc=1. */ | 173 | |
| 159 | if (irb->scsw.stctl == | 174 | if (irb->scsw.stctl == |
| 160 | (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) { | 175 | (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) { |
| 161 | if (irb->scsw.cc == 1) { | 176 | if (__ccw_device_should_retry(&irb->scsw)) { |
| 162 | ret = __ccw_device_sense_pgid_start(cdev); | 177 | ret = __ccw_device_sense_pgid_start(cdev); |
| 163 | if (ret && ret != -EBUSY) | 178 | if (ret && ret != -EBUSY) |
| 164 | ccw_device_sense_pgid_done(cdev, ret); | 179 | ccw_device_sense_pgid_done(cdev, ret); |
| @@ -391,10 +406,10 @@ ccw_device_verify_irq(struct ccw_device *cdev, enum dev_event dev_event) | |||
| 391 | int ret; | 406 | int ret; |
| 392 | 407 | ||
| 393 | irb = (struct irb *) __LC_IRB; | 408 | irb = (struct irb *) __LC_IRB; |
| 394 | /* Retry set pgid for cc=1. */ | 409 | |
| 395 | if (irb->scsw.stctl == | 410 | if (irb->scsw.stctl == |
| 396 | (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) { | 411 | (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) { |
| 397 | if (irb->scsw.cc == 1) | 412 | if (__ccw_device_should_retry(&irb->scsw)) |
| 398 | __ccw_device_verify_start(cdev); | 413 | __ccw_device_verify_start(cdev); |
| 399 | return; | 414 | return; |
| 400 | } | 415 | } |
| @@ -494,10 +509,10 @@ ccw_device_disband_irq(struct ccw_device *cdev, enum dev_event dev_event) | |||
| 494 | int ret; | 509 | int ret; |
| 495 | 510 | ||
| 496 | irb = (struct irb *) __LC_IRB; | 511 | irb = (struct irb *) __LC_IRB; |
| 497 | /* Retry set pgid for cc=1. */ | 512 | |
| 498 | if (irb->scsw.stctl == | 513 | if (irb->scsw.stctl == |
| 499 | (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) { | 514 | (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) { |
| 500 | if (irb->scsw.cc == 1) | 515 | if (__ccw_device_should_retry(&irb->scsw)) |
| 501 | __ccw_device_disband_start(cdev); | 516 | __ccw_device_disband_start(cdev); |
| 502 | return; | 517 | return; |
| 503 | } | 518 | } |
