summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSebastian Ott <sebott@linux.vnet.ibm.com>2009-03-31 19:16:05 +0200
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2009-03-31 19:17:06 +0200
commit47593bfa1056d306fde067b28dd8617009be4121 (patch)
tree3bbad2e48bb773ac4b6f8e0efb4214c75cede7f5 /drivers
parent[S390] cio: introduce ccw_device_schedule_sch_unregister (diff)
downloadlinux-47593bfa1056d306fde067b28dd8617009be4121.tar.xz
linux-47593bfa1056d306fde067b28dd8617009be4121.zip
[S390] cio: introduce notifier for boxed state
If a ccw device did not respond in time during internal io, we set it into boxed state. With this patch we have the following behaviour: * the ccw driver will get a notification if the device was online and goes into the boxed state * if the device was disconnected and got boxed nothing special is to be done (it will be handled in reprobing later) * if the device got boxed while initial sensing it will be unregistered Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/s390/block/dasd.c1
-rw-r--r--drivers/s390/cio/device.c4
-rw-r--r--drivers/s390/cio/device_fsm.c29
-rw-r--r--drivers/s390/scsi/zfcp_ccw.c5
4 files changed, 26 insertions, 13 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 2fd64e5a9ab2..0570794ccf1c 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -2363,6 +2363,7 @@ int dasd_generic_notify(struct ccw_device *cdev, int event)
ret = 0;
switch (event) {
case CIO_GONE:
+ case CIO_BOXED:
case CIO_NO_PATH:
/* First of all call extended error reporting. */
dasd_eer_write(device, NULL, DASD_EER_NOPATH);
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index cdbf664ed446..868f8c6b053a 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -1035,6 +1035,8 @@ io_subchannel_recog_done(struct ccw_device *cdev)
return;
}
switch (cdev->private->state) {
+ case DEV_STATE_BOXED:
+ /* Device did not respond in time. */
case DEV_STATE_NOT_OPER:
cdev->private->flags.recog_done = 1;
/* Remove device found not operational. */
@@ -1044,8 +1046,6 @@ io_subchannel_recog_done(struct ccw_device *cdev)
if (atomic_dec_and_test(&ccw_device_init_count))
wake_up(&ccw_device_init_wq);
break;
- case DEV_STATE_BOXED:
- /* Device did not respond in time. */
case DEV_STATE_OFFLINE:
/*
* We can't register the device in interrupt context so
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index ccd72f95765f..e46049261561 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -256,14 +256,12 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
old_lpm = 0;
if (sch->lpm != old_lpm)
__recover_lost_chpids(sch, old_lpm);
- if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) {
- if (state == DEV_STATE_NOT_OPER) {
- cdev->private->flags.recog_done = 1;
- cdev->private->state = DEV_STATE_DISCONNECTED;
- wake_up(&cdev->private->wait_q);
- return;
- }
- /* Boxed devices don't need extra treatment. */
+ if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID &&
+ (state == DEV_STATE_NOT_OPER || state == DEV_STATE_BOXED)) {
+ cdev->private->flags.recog_done = 1;
+ cdev->private->state = DEV_STATE_DISCONNECTED;
+ wake_up(&cdev->private->wait_q);
+ return;
}
notify = 0;
same_dev = 0; /* Keep the compiler quiet... */
@@ -275,7 +273,7 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
sch->schid.ssid, sch->schid.sch_no);
break;
case DEV_STATE_OFFLINE:
- if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) {
+ if (cdev->online) {
same_dev = ccw_device_handle_oper(cdev);
notify = 1;
}
@@ -308,6 +306,12 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
" subchannel 0.%x.%04x\n",
cdev->private->dev_id.devno,
sch->schid.ssid, sch->schid.sch_no);
+ if (cdev->id.cu_type != 0) { /* device was recognized before */
+ cdev->private->flags.recog_done = 1;
+ cdev->private->state = DEV_STATE_BOXED;
+ wake_up(&cdev->private->wait_q);
+ return;
+ }
break;
}
cdev->private->state = state;
@@ -390,10 +394,13 @@ ccw_device_done(struct ccw_device *cdev, int state)
cdev->private->state = state;
-
- if (state == DEV_STATE_BOXED)
+ if (state == DEV_STATE_BOXED) {
CIO_MSG_EVENT(0, "Boxed device %04x on subchannel %04x\n",
cdev->private->dev_id.devno, sch->schid.sch_no);
+ if (cdev->online && !ccw_device_notify(cdev, CIO_BOXED))
+ ccw_device_schedule_sch_unregister(cdev);
+ cdev->private->flags.donotify = 0;
+ }
if (cdev->private->flags.donotify) {
cdev->private->flags.donotify = 0;
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c
index 1fe1e2eda512..cfb0dcb6e3ff 100644
--- a/drivers/s390/scsi/zfcp_ccw.c
+++ b/drivers/s390/scsi/zfcp_ccw.c
@@ -176,6 +176,11 @@ static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event)
zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
"ccnoti4", NULL);
break;
+ case CIO_BOXED:
+ dev_warn(&adapter->ccw_device->dev,
+ "The ccw device did not respond in time.\n");
+ zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti5", NULL);
+ break;
}
return 1;
}