blob: 750e50c30c67b6e27737cfeedec53a1be766fe14 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
/*
* arch/s390/kernel/s390mach.c
* S/390 machine check handler,
* currently only channel-reports are supported
*
* S390 version
* Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Author(s): Ingo Adlung (adlung@de.ibm.com)
*/
#include <linux/init.h>
#include <asm/irq.h>
#include <asm/lowcore.h>
#include <asm/semaphore.h>
#include <asm/s390io.h>
#include <asm/s390dyn.h>
#include <asm/s390mach.h>
#define S390_MACHCHK_DEBUG
static mchchk_queue_element_t *mchchk_queue_head = NULL;
static mchchk_queue_element_t *mchchk_queue_tail = NULL;
static mchchk_queue_element_t *mchchk_queue_free = NULL;
static spinlock_t mchchk_queue_lock;
static struct semaphore s_sem[2];
//
// initialize machine check handling
//
void s390_init_machine_check( void )
{
init_MUTEX_LOCKED( &s_sem[0] );
init_MUTEX_LOCKED( &s_sem[1] );
#if 0
//
// fix me ! initialize a machine check queue with 100 elements
//
#ifdef S390_MACHCHK_DEBUG
printk( "init_mach : starting kernel thread\n");
#endif
kernel_thread( s390_machine_check_handler, s_sem, 0);
//
// wait for the machine check handler to be ready
//
#ifdef S390_MACHCHK_DEBUG
printk( "init_mach : waiting for kernel thread\n");
#endif
down( &sem[0]);
#ifdef S390_MACHCHK_DEBUG
printk( "init_mach : kernel thread ready\n");
#endif
//
// fix me ! we have to initialize CR14 to allow for CRW pending
// conditions
//
// fix me ! enable machine checks in the PSW
//
#endif
return;
}
//
// machine check pre-processor
//
void __init s390_do_machine_check( void )
{
// fix me ! we have to check for machine check and
// post the handler eventually
return;
}
//
// machine check handler
//
static void __init s390_machine_check_handler( struct semaphore *sem )
{
#ifdef S390_MACHCHK_DEBUG
printk( "mach_handler : kernel thread up\n");
#endif
up( &sem[0] );
#ifdef S390_MACHCHK_DEBUG
printk( "mach_handler : kernel thread ready\n");
#endif
do {
#ifdef S390_MACHCHK_DEBUG
printk( "mach_handler : waiting for wakeup\n");
#endif
down_interruptible( &sem[1] );
#ifdef S390_MACHCHK_DEBUG
printk( "mach_handler : wakeup\n");
#endif
break; // fix me ! unconditional surrender ...
// fix me ! check for machine checks and
// call do_crw_pending() eventually
} while (1);
return;
}
mchchk_queue_element_t *s390_get_mchchk( void )
{
unsigned long flags;
mchchk_queue_element_t *qe;
spin_lock_irqsave( &mchchk_queue_lock, flags );
// fix me ! dequeue first element if available
qe = NULL;
spin_unlock_irqrestore( &mchchk_queue_lock, flags );
return qe;
}
void s390_free_mchchk( mchchk_queue_element_t *mchchk )
{
unsigned long flags;
if ( mchchk != NULL)
{
spin_lock_irqsave( &mchchk_queue_lock, flags );
mchchk->next = mchchk_queue_free;
if ( mchchk_queue_free != NULL )
{
mchchk_queue_free->prev = mchchk;
} /* endif */
mchchk->prev = NULL;
mchchk_queue_free = mchchk;
spin_unlock_irqrestore( &mchchk_queue_lock, flags );
} /* endif */
return;
}
|