diff options
| author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2009-03-31 13:16:05 -0400 |
|---|---|---|
| committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2009-03-31 13:17:06 -0400 |
| commit | 47593bfa1056d306fde067b28dd8617009be4121 (patch) | |
| tree | 3bbad2e48bb773ac4b6f8e0efb4214c75cede7f5 | |
| parent | c4621a62649a56f155a96dfc5de479be226f0768 (diff) | |
[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>
| -rw-r--r-- | arch/s390/include/asm/cio.h | 2 | ||||
| -rw-r--r-- | drivers/s390/block/dasd.c | 1 | ||||
| -rw-r--r-- | drivers/s390/cio/device.c | 4 | ||||
| -rw-r--r-- | drivers/s390/cio/device_fsm.c | 29 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_ccw.c | 5 |
5 files changed, 28 insertions, 13 deletions
diff --git a/arch/s390/include/asm/cio.h b/arch/s390/include/asm/cio.h index 6dccb071aec3..619bf94b11f1 100644 --- a/arch/s390/include/asm/cio.h +++ b/arch/s390/include/asm/cio.h | |||
| @@ -456,6 +456,8 @@ struct ciw { | |||
| 456 | #define CIO_OPER 0x0004 | 456 | #define CIO_OPER 0x0004 |
| 457 | /* Sick revalidation of device. */ | 457 | /* Sick revalidation of device. */ |
| 458 | #define CIO_REVALIDATE 0x0008 | 458 | #define CIO_REVALIDATE 0x0008 |
| 459 | /* Device did not respond in time. */ | ||
| 460 | #define CIO_BOXED 0x0010 | ||
| 459 | 461 | ||
| 460 | /** | 462 | /** |
| 461 | * struct ccw_dev_id - unique identifier for ccw devices | 463 | * struct ccw_dev_id - unique identifier for ccw devices |
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) | |||
| 2363 | ret = 0; | 2363 | ret = 0; |
| 2364 | switch (event) { | 2364 | switch (event) { |
| 2365 | case CIO_GONE: | 2365 | case CIO_GONE: |
| 2366 | case CIO_BOXED: | ||
| 2366 | case CIO_NO_PATH: | 2367 | case CIO_NO_PATH: |
| 2367 | /* First of all call extended error reporting. */ | 2368 | /* First of all call extended error reporting. */ |
| 2368 | dasd_eer_write(device, NULL, DASD_EER_NOPATH); | 2369 | 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) | |||
| 1035 | return; | 1035 | return; |
| 1036 | } | 1036 | } |
| 1037 | switch (cdev->private->state) { | 1037 | switch (cdev->private->state) { |
| 1038 | case DEV_STATE_BOXED: | ||
| 1039 | /* Device did not respond in time. */ | ||
| 1038 | case DEV_STATE_NOT_OPER: | 1040 | case DEV_STATE_NOT_OPER: |
| 1039 | cdev->private->flags.recog_done = 1; | 1041 | cdev->private->flags.recog_done = 1; |
| 1040 | /* Remove device found not operational. */ | 1042 | /* Remove device found not operational. */ |
| @@ -1044,8 +1046,6 @@ io_subchannel_recog_done(struct ccw_device *cdev) | |||
| 1044 | if (atomic_dec_and_test(&ccw_device_init_count)) | 1046 | if (atomic_dec_and_test(&ccw_device_init_count)) |
| 1045 | wake_up(&ccw_device_init_wq); | 1047 | wake_up(&ccw_device_init_wq); |
| 1046 | break; | 1048 | break; |
| 1047 | case DEV_STATE_BOXED: | ||
| 1048 | /* Device did not respond in time. */ | ||
| 1049 | case DEV_STATE_OFFLINE: | 1049 | case DEV_STATE_OFFLINE: |
| 1050 | /* | 1050 | /* |
| 1051 | * We can't register the device in interrupt context so | 1051 | * 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) | |||
| 256 | old_lpm = 0; | 256 | old_lpm = 0; |
| 257 | if (sch->lpm != old_lpm) | 257 | if (sch->lpm != old_lpm) |
| 258 | __recover_lost_chpids(sch, old_lpm); | 258 | __recover_lost_chpids(sch, old_lpm); |
| 259 | if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) { | 259 | if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID && |
| 260 | if (state == DEV_STATE_NOT_OPER) { | 260 | (state == DEV_STATE_NOT_OPER || state == DEV_STATE_BOXED)) { |
| 261 | cdev->private->flags.recog_done = 1; | 261 | cdev->private->flags.recog_done = 1; |
| 262 | cdev->private->state = DEV_STATE_DISCONNECTED; | 262 | cdev->private->state = DEV_STATE_DISCONNECTED; |
| 263 | wake_up(&cdev->private->wait_q); | 263 | wake_up(&cdev->private->wait_q); |
| 264 | return; | 264 | return; |
| 265 | } | ||
| 266 | /* Boxed devices don't need extra treatment. */ | ||
| 267 | } | 265 | } |
| 268 | notify = 0; | 266 | notify = 0; |
| 269 | same_dev = 0; /* Keep the compiler quiet... */ | 267 | same_dev = 0; /* Keep the compiler quiet... */ |
| @@ -275,7 +273,7 @@ ccw_device_recog_done(struct ccw_device *cdev, int state) | |||
| 275 | sch->schid.ssid, sch->schid.sch_no); | 273 | sch->schid.ssid, sch->schid.sch_no); |
| 276 | break; | 274 | break; |
| 277 | case DEV_STATE_OFFLINE: | 275 | case DEV_STATE_OFFLINE: |
| 278 | if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) { | 276 | if (cdev->online) { |
| 279 | same_dev = ccw_device_handle_oper(cdev); | 277 | same_dev = ccw_device_handle_oper(cdev); |
| 280 | notify = 1; | 278 | notify = 1; |
| 281 | } | 279 | } |
| @@ -308,6 +306,12 @@ ccw_device_recog_done(struct ccw_device *cdev, int state) | |||
| 308 | " subchannel 0.%x.%04x\n", | 306 | " subchannel 0.%x.%04x\n", |
| 309 | cdev->private->dev_id.devno, | 307 | cdev->private->dev_id.devno, |
| 310 | sch->schid.ssid, sch->schid.sch_no); | 308 | sch->schid.ssid, sch->schid.sch_no); |
| 309 | if (cdev->id.cu_type != 0) { /* device was recognized before */ | ||
| 310 | cdev->private->flags.recog_done = 1; | ||
| 311 | cdev->private->state = DEV_STATE_BOXED; | ||
| 312 | wake_up(&cdev->private->wait_q); | ||
| 313 | return; | ||
| 314 | } | ||
| 311 | break; | 315 | break; |
| 312 | } | 316 | } |
| 313 | cdev->private->state = state; | 317 | cdev->private->state = state; |
| @@ -390,10 +394,13 @@ ccw_device_done(struct ccw_device *cdev, int state) | |||
| 390 | 394 | ||
| 391 | cdev->private->state = state; | 395 | cdev->private->state = state; |
| 392 | 396 | ||
| 393 | 397 | if (state == DEV_STATE_BOXED) { | |
| 394 | if (state == DEV_STATE_BOXED) | ||
| 395 | CIO_MSG_EVENT(0, "Boxed device %04x on subchannel %04x\n", | 398 | CIO_MSG_EVENT(0, "Boxed device %04x on subchannel %04x\n", |
| 396 | cdev->private->dev_id.devno, sch->schid.sch_no); | 399 | cdev->private->dev_id.devno, sch->schid.sch_no); |
| 400 | if (cdev->online && !ccw_device_notify(cdev, CIO_BOXED)) | ||
| 401 | ccw_device_schedule_sch_unregister(cdev); | ||
| 402 | cdev->private->flags.donotify = 0; | ||
| 403 | } | ||
| 397 | 404 | ||
| 398 | if (cdev->private->flags.donotify) { | 405 | if (cdev->private->flags.donotify) { |
| 399 | cdev->private->flags.donotify = 0; | 406 | 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) | |||
| 176 | zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, | 176 | zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, |
| 177 | "ccnoti4", NULL); | 177 | "ccnoti4", NULL); |
| 178 | break; | 178 | break; |
| 179 | case CIO_BOXED: | ||
| 180 | dev_warn(&adapter->ccw_device->dev, | ||
| 181 | "The ccw device did not respond in time.\n"); | ||
| 182 | zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti5", NULL); | ||
| 183 | break; | ||
| 179 | } | 184 | } |
| 180 | return 1; | 185 | return 1; |
| 181 | } | 186 | } |
