summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Oberparleiter <peter.oberparleiter@de.ibm.com>2009-10-06 10:34:02 +0200
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2009-10-06 10:35:07 +0200
commit6afcc775d9d66fe550fad6c579f78b3c3da895b8 (patch)
treefcbd29835c31ed0174025bc6991309fd6b6a0e76
parent9a332116948955bd25d122efd91feed103f0e3e4 (diff)
[S390] cio: make not operational handling consistent
When a ccw device appears not operational, inform the associated device driver and act according to the response: if the driver wants to keep the device, put it into the disconnected state. If not, or if there is no driver or if the device is not online, unregister it. This approach is consistent with no-path event handling. Signed-off-by: Peter Oberparleiter <peter.oberparleiter@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--drivers/s390/cio/device.c4
-rw-r--r--drivers/s390/cio/device.h1
-rw-r--r--drivers/s390/cio/device_fsm.c11
3 files changed, 9 insertions, 7 deletions
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index f780bdd3a04e..2ee093ec86e4 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -1609,7 +1609,7 @@ int ccw_purge_blacklisted(void)
return 0;
}
-static void device_set_disconnected(struct ccw_device *cdev)
+void ccw_device_set_disconnected(struct ccw_device *cdev)
{
if (!cdev)
return;
@@ -1705,7 +1705,7 @@ static int io_subchannel_sch_event(struct subchannel *sch, int slow)
ccw_device_trigger_reprobe(cdev);
break;
case DISC:
- device_set_disconnected(cdev);
+ ccw_device_set_disconnected(cdev);
break;
default:
break;
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h
index ed39a2caaf47..246c6482842c 100644
--- a/drivers/s390/cio/device.h
+++ b/drivers/s390/cio/device.h
@@ -125,6 +125,7 @@ int ccw_device_stlck(struct ccw_device *);
void ccw_device_trigger_reprobe(struct ccw_device *);
void ccw_device_kill_io(struct ccw_device *);
int ccw_device_notify(struct ccw_device *, int);
+void ccw_device_set_disconnected(struct ccw_device *cdev);
void ccw_device_set_notoper(struct ccw_device *cdev);
/* qdio needs this. */
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index 3db3847ee137..3b0f408a896c 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -400,6 +400,8 @@ ccw_device_done(struct ccw_device *cdev, int state)
cdev->private->dev_id.devno, sch->schid.sch_no);
if (!ccw_device_notify(cdev, CIO_GONE))
ccw_device_schedule_sch_unregister(cdev);
+ else
+ ccw_device_set_disconnected(cdev);
cdev->private->flags.donotify = 0;
break;
case DEV_STATE_DISCONNECTED:
@@ -744,11 +746,10 @@ ccw_device_recog_notoper(struct ccw_device *cdev, enum dev_event dev_event)
static void ccw_device_generic_notoper(struct ccw_device *cdev,
enum dev_event dev_event)
{
- struct subchannel *sch;
-
- ccw_device_set_notoper(cdev);
- sch = to_subchannel(cdev->dev.parent);
- css_schedule_eval(sch->schid);
+ if (!ccw_device_notify(cdev, CIO_GONE))
+ ccw_device_schedule_sch_unregister(cdev);
+ else
+ ccw_device_set_disconnected(cdev);
}
/*