Commit 47593bfa authored by Sebastian Ott's avatar Sebastian Ott Committed by Martin Schwidefsky

[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: default avatarSebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent c4621a62
...@@ -456,6 +456,8 @@ struct ciw { ...@@ -456,6 +456,8 @@ struct ciw {
#define CIO_OPER 0x0004 #define CIO_OPER 0x0004
/* Sick revalidation of device. */ /* Sick revalidation of device. */
#define CIO_REVALIDATE 0x0008 #define CIO_REVALIDATE 0x0008
/* Device did not respond in time. */
#define CIO_BOXED 0x0010
/** /**
* struct ccw_dev_id - unique identifier for ccw devices * struct ccw_dev_id - unique identifier for ccw devices
......
...@@ -2363,6 +2363,7 @@ int dasd_generic_notify(struct ccw_device *cdev, int event) ...@@ -2363,6 +2363,7 @@ int dasd_generic_notify(struct ccw_device *cdev, int event)
ret = 0; ret = 0;
switch (event) { switch (event) {
case CIO_GONE: case CIO_GONE:
case CIO_BOXED:
case CIO_NO_PATH: case CIO_NO_PATH:
/* First of all call extended error reporting. */ /* First of all call extended error reporting. */
dasd_eer_write(device, NULL, DASD_EER_NOPATH); dasd_eer_write(device, NULL, DASD_EER_NOPATH);
......
...@@ -1035,6 +1035,8 @@ io_subchannel_recog_done(struct ccw_device *cdev) ...@@ -1035,6 +1035,8 @@ io_subchannel_recog_done(struct ccw_device *cdev)
return; return;
} }
switch (cdev->private->state) { switch (cdev->private->state) {
case DEV_STATE_BOXED:
/* Device did not respond in time. */
case DEV_STATE_NOT_OPER: case DEV_STATE_NOT_OPER:
cdev->private->flags.recog_done = 1; cdev->private->flags.recog_done = 1;
/* Remove device found not operational. */ /* Remove device found not operational. */
...@@ -1044,8 +1046,6 @@ io_subchannel_recog_done(struct ccw_device *cdev) ...@@ -1044,8 +1046,6 @@ io_subchannel_recog_done(struct ccw_device *cdev)
if (atomic_dec_and_test(&ccw_device_init_count)) if (atomic_dec_and_test(&ccw_device_init_count))
wake_up(&ccw_device_init_wq); wake_up(&ccw_device_init_wq);
break; break;
case DEV_STATE_BOXED:
/* Device did not respond in time. */
case DEV_STATE_OFFLINE: case DEV_STATE_OFFLINE:
/* /*
* We can't register the device in interrupt context so * We can't register the device in interrupt context so
......
...@@ -256,14 +256,12 @@ ccw_device_recog_done(struct ccw_device *cdev, int state) ...@@ -256,14 +256,12 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
old_lpm = 0; old_lpm = 0;
if (sch->lpm != old_lpm) if (sch->lpm != old_lpm)
__recover_lost_chpids(sch, old_lpm); __recover_lost_chpids(sch, old_lpm);
if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) { if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID &&
if (state == DEV_STATE_NOT_OPER) { (state == DEV_STATE_NOT_OPER || state == DEV_STATE_BOXED)) {
cdev->private->flags.recog_done = 1; cdev->private->flags.recog_done = 1;
cdev->private->state = DEV_STATE_DISCONNECTED; cdev->private->state = DEV_STATE_DISCONNECTED;
wake_up(&cdev->private->wait_q); wake_up(&cdev->private->wait_q);
return; return;
}
/* Boxed devices don't need extra treatment. */
} }
notify = 0; notify = 0;
same_dev = 0; /* Keep the compiler quiet... */ same_dev = 0; /* Keep the compiler quiet... */
...@@ -275,7 +273,7 @@ ccw_device_recog_done(struct ccw_device *cdev, int state) ...@@ -275,7 +273,7 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
sch->schid.ssid, sch->schid.sch_no); sch->schid.ssid, sch->schid.sch_no);
break; break;
case DEV_STATE_OFFLINE: case DEV_STATE_OFFLINE:
if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) { if (cdev->online) {
same_dev = ccw_device_handle_oper(cdev); same_dev = ccw_device_handle_oper(cdev);
notify = 1; notify = 1;
} }
...@@ -308,6 +306,12 @@ ccw_device_recog_done(struct ccw_device *cdev, int state) ...@@ -308,6 +306,12 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
" subchannel 0.%x.%04x\n", " subchannel 0.%x.%04x\n",
cdev->private->dev_id.devno, cdev->private->dev_id.devno,
sch->schid.ssid, sch->schid.sch_no); 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; break;
} }
cdev->private->state = state; cdev->private->state = state;
...@@ -390,10 +394,13 @@ ccw_device_done(struct ccw_device *cdev, int state) ...@@ -390,10 +394,13 @@ ccw_device_done(struct ccw_device *cdev, int state)
cdev->private->state = 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", CIO_MSG_EVENT(0, "Boxed device %04x on subchannel %04x\n",
cdev->private->dev_id.devno, sch->schid.sch_no); 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) { if (cdev->private->flags.donotify) {
cdev->private->flags.donotify = 0; cdev->private->flags.donotify = 0;
......
...@@ -176,6 +176,11 @@ static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event) ...@@ -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, zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
"ccnoti4", NULL); "ccnoti4", NULL);
break; 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; return 1;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment