diff options
Diffstat (limited to 'drivers/s390/s390mach.c')
-rw-r--r-- | drivers/s390/s390mach.c | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c index e088b5e28711..806bb1a921eb 100644 --- a/drivers/s390/s390mach.c +++ b/drivers/s390/s390mach.c | |||
@@ -13,22 +13,18 @@ | |||
13 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
14 | #include <linux/workqueue.h> | 14 | #include <linux/workqueue.h> |
15 | #include <linux/time.h> | 15 | #include <linux/time.h> |
16 | #include <linux/device.h> | ||
16 | #include <linux/kthread.h> | 17 | #include <linux/kthread.h> |
17 | 18 | #include <asm/etr.h> | |
18 | #include <asm/lowcore.h> | 19 | #include <asm/lowcore.h> |
19 | 20 | #include <asm/cio.h> | |
21 | #include "cio/cio.h" | ||
22 | #include "cio/chsc.h" | ||
23 | #include "cio/css.h" | ||
20 | #include "s390mach.h" | 24 | #include "s390mach.h" |
21 | 25 | ||
22 | static struct semaphore m_sem; | 26 | static struct semaphore m_sem; |
23 | 27 | ||
24 | extern int css_process_crw(int, int); | ||
25 | extern int chsc_process_crw(void); | ||
26 | extern int chp_process_crw(int, int); | ||
27 | extern void css_reiterate_subchannels(void); | ||
28 | |||
29 | extern struct workqueue_struct *slow_path_wq; | ||
30 | extern struct work_struct slow_path_work; | ||
31 | |||
32 | static NORET_TYPE void | 28 | static NORET_TYPE void |
33 | s390_handle_damage(char *msg) | 29 | s390_handle_damage(char *msg) |
34 | { | 30 | { |
@@ -470,6 +466,19 @@ s390_do_machine_check(struct pt_regs *regs) | |||
470 | s390_handle_damage("unable to revalidate registers."); | 466 | s390_handle_damage("unable to revalidate registers."); |
471 | } | 467 | } |
472 | 468 | ||
469 | if (mci->cd) { | ||
470 | /* Timing facility damage */ | ||
471 | s390_handle_damage("TOD clock damaged"); | ||
472 | } | ||
473 | |||
474 | if (mci->ed && mci->ec) { | ||
475 | /* External damage */ | ||
476 | if (S390_lowcore.external_damage_code & (1U << ED_ETR_SYNC)) | ||
477 | etr_sync_check(); | ||
478 | if (S390_lowcore.external_damage_code & (1U << ED_ETR_SWITCH)) | ||
479 | etr_switch_to_local(); | ||
480 | } | ||
481 | |||
473 | if (mci->se) | 482 | if (mci->se) |
474 | /* Storage error uncorrected */ | 483 | /* Storage error uncorrected */ |
475 | s390_handle_damage("received storage error uncorrected " | 484 | s390_handle_damage("received storage error uncorrected " |
@@ -508,7 +517,7 @@ static int | |||
508 | machine_check_init(void) | 517 | machine_check_init(void) |
509 | { | 518 | { |
510 | init_MUTEX_LOCKED(&m_sem); | 519 | init_MUTEX_LOCKED(&m_sem); |
511 | ctl_clear_bit(14, 25); /* disable external damage MCH */ | 520 | ctl_set_bit(14, 25); /* enable external damage MCH */ |
512 | ctl_set_bit(14, 27); /* enable system recovery MCH */ | 521 | ctl_set_bit(14, 27); /* enable system recovery MCH */ |
513 | #ifdef CONFIG_MACHCHK_WARNING | 522 | #ifdef CONFIG_MACHCHK_WARNING |
514 | ctl_set_bit(14, 24); /* enable warning MCH */ | 523 | ctl_set_bit(14, 24); /* enable warning MCH */ |
@@ -529,7 +538,11 @@ arch_initcall(machine_check_init); | |||
529 | static int __init | 538 | static int __init |
530 | machine_check_crw_init (void) | 539 | machine_check_crw_init (void) |
531 | { | 540 | { |
532 | kthread_run(s390_collect_crw_info, &m_sem, "kmcheck"); | 541 | struct task_struct *task; |
542 | |||
543 | task = kthread_run(s390_collect_crw_info, &m_sem, "kmcheck"); | ||
544 | if (IS_ERR(task)) | ||
545 | return PTR_ERR(task); | ||
533 | ctl_set_bit(14, 28); /* enable channel report MCH */ | 546 | ctl_set_bit(14, 28); /* enable channel report MCH */ |
534 | return 0; | 547 | return 0; |
535 | } | 548 | } |