diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-01 12:22:24 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-01 12:22:24 -0400 |
| commit | 32527bc0e4b4fa7711ad1c923cf64ae72a7ffd9d (patch) | |
| tree | 397c7ea179ebd3d2dacc0a2c8b165f8840137045 | |
| parent | e14a685dfabf3ceeb366f1db1a22471b8f98a08b (diff) | |
| parent | 99f6a570eedc885675b6aa36b7acdbdcc3a7f55b (diff) | |
Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6:
[S390] cio: online_store - trigger recognition for boxed devices
[S390] cio: disallow online setting of device in transient state
[S390] cio: introduce notifier for boxed state
[S390] cio: introduce ccw_device_schedule_sch_unregister
[S390] cio: wake up on failed recognition
[S390] fix hypfs build failure
[PATCH] sysrq: include interrupt.h instead of irq.h
| -rw-r--r-- | arch/s390/hypfs/hypfs_diag.c | 2 | ||||
| -rw-r--r-- | arch/s390/include/asm/cio.h | 2 | ||||
| -rw-r--r-- | drivers/char/sysrq.c | 2 | ||||
| -rw-r--r-- | drivers/s390/block/dasd.c | 1 | ||||
| -rw-r--r-- | drivers/s390/cio/device.c | 43 | ||||
| -rw-r--r-- | drivers/s390/cio/device.h | 1 | ||||
| -rw-r--r-- | drivers/s390/cio/device_fsm.c | 31 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_ccw.c | 5 |
8 files changed, 58 insertions, 29 deletions
diff --git a/arch/s390/hypfs/hypfs_diag.c b/arch/s390/hypfs/hypfs_diag.c index b1e892a43816..704dd396257b 100644 --- a/arch/s390/hypfs/hypfs_diag.c +++ b/arch/s390/hypfs/hypfs_diag.c | |||
| @@ -12,6 +12,8 @@ | |||
| 12 | 12 | ||
| 13 | #include <linux/types.h> | 13 | #include <linux/types.h> |
| 14 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
| 15 | #include <linux/gfp.h> | ||
| 16 | #include <linux/slab.h> | ||
| 15 | #include <linux/string.h> | 17 | #include <linux/string.h> |
| 16 | #include <linux/vmalloc.h> | 18 | #include <linux/vmalloc.h> |
| 17 | #include <asm/ebcdic.h> | 19 | #include <asm/ebcdic.h> |
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/char/sysrq.c b/drivers/char/sysrq.c index 5afe7316c72e..ebea9b2c30a5 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c | |||
| @@ -35,7 +35,7 @@ | |||
| 35 | #include <linux/vt_kern.h> | 35 | #include <linux/vt_kern.h> |
| 36 | #include <linux/workqueue.h> | 36 | #include <linux/workqueue.h> |
| 37 | #include <linux/kexec.h> | 37 | #include <linux/kexec.h> |
| 38 | #include <linux/irq.h> | 38 | #include <linux/interrupt.h> |
| 39 | #include <linux/hrtimer.h> | 39 | #include <linux/hrtimer.h> |
| 40 | #include <linux/oom.h> | 40 | #include <linux/oom.h> |
| 41 | 41 | ||
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 c4d2f667a2f6..35441fa16be1 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
| @@ -310,8 +310,6 @@ static void ccw_device_remove_orphan_cb(struct work_struct *work) | |||
| 310 | put_device(&cdev->dev); | 310 | put_device(&cdev->dev); |
| 311 | } | 311 | } |
| 312 | 312 | ||
| 313 | static void ccw_device_call_sch_unregister(struct work_struct *work); | ||
| 314 | |||
| 315 | static void | 313 | static void |
| 316 | ccw_device_remove_disconnected(struct ccw_device *cdev) | 314 | ccw_device_remove_disconnected(struct ccw_device *cdev) |
| 317 | { | 315 | { |
| @@ -335,11 +333,10 @@ ccw_device_remove_disconnected(struct ccw_device *cdev) | |||
| 335 | spin_unlock_irqrestore(cdev->ccwlock, flags); | 333 | spin_unlock_irqrestore(cdev->ccwlock, flags); |
| 336 | PREPARE_WORK(&cdev->private->kick_work, | 334 | PREPARE_WORK(&cdev->private->kick_work, |
| 337 | ccw_device_remove_orphan_cb); | 335 | ccw_device_remove_orphan_cb); |
| 336 | queue_work(slow_path_wq, &cdev->private->kick_work); | ||
| 338 | } else | 337 | } else |
| 339 | /* Deregister subchannel, which will kill the ccw device. */ | 338 | /* Deregister subchannel, which will kill the ccw device. */ |
| 340 | PREPARE_WORK(&cdev->private->kick_work, | 339 | ccw_device_schedule_sch_unregister(cdev); |
| 341 | ccw_device_call_sch_unregister); | ||
| 342 | queue_work(slow_path_wq, &cdev->private->kick_work); | ||
| 343 | } | 340 | } |
| 344 | 341 | ||
| 345 | /** | 342 | /** |
| @@ -471,7 +468,7 @@ static int online_store_recog_and_online(struct ccw_device *cdev) | |||
| 471 | int ret; | 468 | int ret; |
| 472 | 469 | ||
| 473 | /* Do device recognition, if needed. */ | 470 | /* Do device recognition, if needed. */ |
| 474 | if (cdev->id.cu_type == 0) { | 471 | if (cdev->private->state == DEV_STATE_BOXED) { |
| 475 | ret = ccw_device_recognition(cdev); | 472 | ret = ccw_device_recognition(cdev); |
| 476 | if (ret) { | 473 | if (ret) { |
| 477 | CIO_MSG_EVENT(0, "Couldn't start recognition " | 474 | CIO_MSG_EVENT(0, "Couldn't start recognition " |
| @@ -482,17 +479,21 @@ static int online_store_recog_and_online(struct ccw_device *cdev) | |||
| 482 | } | 479 | } |
| 483 | wait_event(cdev->private->wait_q, | 480 | wait_event(cdev->private->wait_q, |
| 484 | cdev->private->flags.recog_done); | 481 | cdev->private->flags.recog_done); |
| 482 | if (cdev->private->state != DEV_STATE_OFFLINE) | ||
| 483 | /* recognition failed */ | ||
| 484 | return -EAGAIN; | ||
| 485 | } | 485 | } |
| 486 | if (cdev->drv && cdev->drv->set_online) | 486 | if (cdev->drv && cdev->drv->set_online) |
| 487 | ccw_device_set_online(cdev); | 487 | ccw_device_set_online(cdev); |
| 488 | return 0; | 488 | return 0; |
| 489 | } | 489 | } |
| 490 | |||
| 490 | static int online_store_handle_online(struct ccw_device *cdev, int force) | 491 | static int online_store_handle_online(struct ccw_device *cdev, int force) |
| 491 | { | 492 | { |
| 492 | int ret; | 493 | int ret; |
| 493 | 494 | ||
| 494 | ret = online_store_recog_and_online(cdev); | 495 | ret = online_store_recog_and_online(cdev); |
| 495 | if (ret) | 496 | if (ret && !force) |
| 496 | return ret; | 497 | return ret; |
| 497 | if (force && cdev->private->state == DEV_STATE_BOXED) { | 498 | if (force && cdev->private->state == DEV_STATE_BOXED) { |
| 498 | ret = ccw_device_stlck(cdev); | 499 | ret = ccw_device_stlck(cdev); |
| @@ -500,7 +501,9 @@ static int online_store_handle_online(struct ccw_device *cdev, int force) | |||
| 500 | return ret; | 501 | return ret; |
| 501 | if (cdev->id.cu_type == 0) | 502 | if (cdev->id.cu_type == 0) |
| 502 | cdev->private->state = DEV_STATE_NOT_OPER; | 503 | cdev->private->state = DEV_STATE_NOT_OPER; |
| 503 | online_store_recog_and_online(cdev); | 504 | ret = online_store_recog_and_online(cdev); |
| 505 | if (ret) | ||
| 506 | return ret; | ||
| 504 | } | 507 | } |
| 505 | return 0; | 508 | return 0; |
| 506 | } | 509 | } |
| @@ -512,7 +515,11 @@ static ssize_t online_store (struct device *dev, struct device_attribute *attr, | |||
| 512 | int force, ret; | 515 | int force, ret; |
| 513 | unsigned long i; | 516 | unsigned long i; |
| 514 | 517 | ||
| 515 | if (atomic_cmpxchg(&cdev->private->onoff, 0, 1) != 0) | 518 | if ((cdev->private->state != DEV_STATE_OFFLINE && |
| 519 | cdev->private->state != DEV_STATE_ONLINE && | ||
| 520 | cdev->private->state != DEV_STATE_BOXED && | ||
| 521 | cdev->private->state != DEV_STATE_DISCONNECTED) || | ||
| 522 | atomic_cmpxchg(&cdev->private->onoff, 0, 1) != 0) | ||
| 516 | return -EAGAIN; | 523 | return -EAGAIN; |
| 517 | 524 | ||
| 518 | if (cdev->drv && !try_module_get(cdev->drv->owner)) { | 525 | if (cdev->drv && !try_module_get(cdev->drv->owner)) { |
| @@ -1014,6 +1021,13 @@ static void ccw_device_call_sch_unregister(struct work_struct *work) | |||
| 1014 | put_device(&sch->dev); | 1021 | put_device(&sch->dev); |
| 1015 | } | 1022 | } |
| 1016 | 1023 | ||
| 1024 | void ccw_device_schedule_sch_unregister(struct ccw_device *cdev) | ||
| 1025 | { | ||
| 1026 | PREPARE_WORK(&cdev->private->kick_work, | ||
| 1027 | ccw_device_call_sch_unregister); | ||
| 1028 | queue_work(slow_path_wq, &cdev->private->kick_work); | ||
| 1029 | } | ||
| 1030 | |||
| 1017 | /* | 1031 | /* |
| 1018 | * subchannel recognition done. Called from the state machine. | 1032 | * subchannel recognition done. Called from the state machine. |
| 1019 | */ | 1033 | */ |
| @@ -1025,19 +1039,17 @@ io_subchannel_recog_done(struct ccw_device *cdev) | |||
| 1025 | return; | 1039 | return; |
| 1026 | } | 1040 | } |
| 1027 | switch (cdev->private->state) { | 1041 | switch (cdev->private->state) { |
| 1042 | case DEV_STATE_BOXED: | ||
| 1043 | /* Device did not respond in time. */ | ||
| 1028 | case DEV_STATE_NOT_OPER: | 1044 | case DEV_STATE_NOT_OPER: |
| 1029 | cdev->private->flags.recog_done = 1; | 1045 | cdev->private->flags.recog_done = 1; |
| 1030 | /* Remove device found not operational. */ | 1046 | /* Remove device found not operational. */ |
| 1031 | if (!get_device(&cdev->dev)) | 1047 | if (!get_device(&cdev->dev)) |
| 1032 | break; | 1048 | break; |
| 1033 | PREPARE_WORK(&cdev->private->kick_work, | 1049 | ccw_device_schedule_sch_unregister(cdev); |
| 1034 | ccw_device_call_sch_unregister); | ||
| 1035 | queue_work(slow_path_wq, &cdev->private->kick_work); | ||
| 1036 | if (atomic_dec_and_test(&ccw_device_init_count)) | 1050 | if (atomic_dec_and_test(&ccw_device_init_count)) |
| 1037 | wake_up(&ccw_device_init_wq); | 1051 | wake_up(&ccw_device_init_wq); |
| 1038 | break; | 1052 | break; |
| 1039 | case DEV_STATE_BOXED: | ||
| 1040 | /* Device did not respond in time. */ | ||
| 1041 | case DEV_STATE_OFFLINE: | 1053 | case DEV_STATE_OFFLINE: |
| 1042 | /* | 1054 | /* |
| 1043 | * We can't register the device in interrupt context so | 1055 | * We can't register the device in interrupt context so |
| @@ -1551,8 +1563,7 @@ static int purge_fn(struct device *dev, void *data) | |||
| 1551 | goto out; | 1563 | goto out; |
| 1552 | CIO_MSG_EVENT(3, "ccw: purging 0.%x.%04x\n", priv->dev_id.ssid, | 1564 | CIO_MSG_EVENT(3, "ccw: purging 0.%x.%04x\n", priv->dev_id.ssid, |
| 1553 | priv->dev_id.devno); | 1565 | priv->dev_id.devno); |
| 1554 | PREPARE_WORK(&cdev->private->kick_work, ccw_device_call_sch_unregister); | 1566 | ccw_device_schedule_sch_unregister(cdev); |
| 1555 | queue_work(slow_path_wq, &cdev->private->kick_work); | ||
| 1556 | 1567 | ||
| 1557 | out: | 1568 | out: |
| 1558 | /* Abort loop in case of pending signal. */ | 1569 | /* Abort loop in case of pending signal. */ |
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h index 85e01846ca65..f1cbbd94ad4e 100644 --- a/drivers/s390/cio/device.h +++ b/drivers/s390/cio/device.h | |||
| @@ -87,6 +87,7 @@ int ccw_device_is_orphan(struct ccw_device *); | |||
| 87 | int ccw_device_recognition(struct ccw_device *); | 87 | int ccw_device_recognition(struct ccw_device *); |
| 88 | int ccw_device_online(struct ccw_device *); | 88 | int ccw_device_online(struct ccw_device *); |
| 89 | int ccw_device_offline(struct ccw_device *); | 89 | int ccw_device_offline(struct ccw_device *); |
| 90 | void ccw_device_schedule_sch_unregister(struct ccw_device *); | ||
| 90 | int ccw_purge_blacklisted(void); | 91 | int ccw_purge_blacklisted(void); |
| 91 | 92 | ||
| 92 | /* Function prototypes for device status and basic sense stuff. */ | 93 | /* Function prototypes for device status and basic sense stuff. */ |
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index 87b4bfca080f..e46049261561 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c | |||
| @@ -256,13 +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 | return; | 263 | wake_up(&cdev->private->wait_q); |
| 264 | } | 264 | return; |
| 265 | /* Boxed devices don't need extra treatment. */ | ||
| 266 | } | 265 | } |
| 267 | notify = 0; | 266 | notify = 0; |
| 268 | same_dev = 0; /* Keep the compiler quiet... */ | 267 | same_dev = 0; /* Keep the compiler quiet... */ |
| @@ -274,7 +273,7 @@ ccw_device_recog_done(struct ccw_device *cdev, int state) | |||
| 274 | sch->schid.ssid, sch->schid.sch_no); | 273 | sch->schid.ssid, sch->schid.sch_no); |
| 275 | break; | 274 | break; |
| 276 | case DEV_STATE_OFFLINE: | 275 | case DEV_STATE_OFFLINE: |
| 277 | if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) { | 276 | if (cdev->online) { |
| 278 | same_dev = ccw_device_handle_oper(cdev); | 277 | same_dev = ccw_device_handle_oper(cdev); |
| 279 | notify = 1; | 278 | notify = 1; |
| 280 | } | 279 | } |
| @@ -307,12 +306,17 @@ ccw_device_recog_done(struct ccw_device *cdev, int state) | |||
| 307 | " subchannel 0.%x.%04x\n", | 306 | " subchannel 0.%x.%04x\n", |
| 308 | cdev->private->dev_id.devno, | 307 | cdev->private->dev_id.devno, |
| 309 | 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 | } | ||
| 310 | break; | 315 | break; |
| 311 | } | 316 | } |
| 312 | cdev->private->state = state; | 317 | cdev->private->state = state; |
| 313 | io_subchannel_recog_done(cdev); | 318 | io_subchannel_recog_done(cdev); |
| 314 | if (state != DEV_STATE_NOT_OPER) | 319 | wake_up(&cdev->private->wait_q); |
| 315 | wake_up(&cdev->private->wait_q); | ||
| 316 | } | 320 | } |
| 317 | 321 | ||
| 318 | /* | 322 | /* |
| @@ -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 | } |
