Skip to content

Commit

Permalink
[S390] cio: unsolicited interrupts during sense pgid.
Browse files Browse the repository at this point in the history
Calls to set a device online with path grouping may get stuck in
some cases because certain device conditions where discarded after
unsolicited interrupts.
Check subchannel activity after unsolicited interrupts and retry
the operation if the subchannel is idle.

Signed-off-by: Stefan Bader <shbader@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
  • Loading branch information
Stefan Bader authored and Martin Schwidefsky committed Aug 30, 2006
1 parent 3b88508 commit 7b7db1b
Showing 1 changed file with 21 additions and 6 deletions.
27 changes: 21 additions & 6 deletions drivers/s390/cio/device_pgid.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,21 @@
#include "device.h"
#include "ioasm.h"

/*
* Helper function called from interrupt context to decide whether an
* operation should be tried again.
*/
static int __ccw_device_should_retry(struct scsw *scsw)
{
/* CC is only valid if start function bit is set. */
if ((scsw->fctl & SCSW_FCTL_START_FUNC) && scsw->cc == 1)
return 1;
/* No more activity. For sense and set PGID we stubbornly try again. */
if (!scsw->actl)
return 1;
return 0;
}

/*
* Start Sense Path Group ID helper function. Used in ccw_device_recog
* and ccw_device_sense_pgid.
Expand Down Expand Up @@ -155,10 +170,10 @@ ccw_device_sense_pgid_irq(struct ccw_device *cdev, enum dev_event dev_event)
int ret;

irb = (struct irb *) __LC_IRB;
/* Retry sense pgid for cc=1. */

if (irb->scsw.stctl ==
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
if (irb->scsw.cc == 1) {
if (__ccw_device_should_retry(&irb->scsw)) {
ret = __ccw_device_sense_pgid_start(cdev);
if (ret && ret != -EBUSY)
ccw_device_sense_pgid_done(cdev, ret);
Expand Down Expand Up @@ -391,10 +406,10 @@ ccw_device_verify_irq(struct ccw_device *cdev, enum dev_event dev_event)
int ret;

irb = (struct irb *) __LC_IRB;
/* Retry set pgid for cc=1. */

if (irb->scsw.stctl ==
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
if (irb->scsw.cc == 1)
if (__ccw_device_should_retry(&irb->scsw))
__ccw_device_verify_start(cdev);
return;
}
Expand Down Expand Up @@ -494,10 +509,10 @@ ccw_device_disband_irq(struct ccw_device *cdev, enum dev_event dev_event)
int ret;

irb = (struct irb *) __LC_IRB;
/* Retry set pgid for cc=1. */

if (irb->scsw.stctl ==
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
if (irb->scsw.cc == 1)
if (__ccw_device_should_retry(&irb->scsw))
__ccw_device_disband_start(cdev);
return;
}
Expand Down

0 comments on commit 7b7db1b

Please sign in to comment.