diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/s390/sysinfo.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/s390/sysinfo.c')
-rw-r--r-- | drivers/s390/sysinfo.c | 347 |
1 files changed, 347 insertions, 0 deletions
diff --git a/drivers/s390/sysinfo.c b/drivers/s390/sysinfo.c new file mode 100644 index 000000000000..87c2db1bd4f5 --- /dev/null +++ b/drivers/s390/sysinfo.c | |||
@@ -0,0 +1,347 @@ | |||
1 | /* | ||
2 | * drivers/s390/sysinfo.c | ||
3 | * | ||
4 | * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
5 | * Author(s): Ulrich Weigand (Ulrich.Weigand@de.ibm.com) | ||
6 | */ | ||
7 | |||
8 | #include <linux/config.h> | ||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/mm.h> | ||
11 | #include <linux/proc_fs.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <asm/ebcdic.h> | ||
14 | |||
15 | struct sysinfo_1_1_1 | ||
16 | { | ||
17 | char reserved_0[32]; | ||
18 | char manufacturer[16]; | ||
19 | char type[4]; | ||
20 | char reserved_1[12]; | ||
21 | char model[16]; | ||
22 | char sequence[16]; | ||
23 | char plant[4]; | ||
24 | }; | ||
25 | |||
26 | struct sysinfo_1_2_1 | ||
27 | { | ||
28 | char reserved_0[80]; | ||
29 | char sequence[16]; | ||
30 | char plant[4]; | ||
31 | char reserved_1[2]; | ||
32 | unsigned short cpu_address; | ||
33 | }; | ||
34 | |||
35 | struct sysinfo_1_2_2 | ||
36 | { | ||
37 | char reserved_0[32]; | ||
38 | unsigned int capability; | ||
39 | unsigned short cpus_total; | ||
40 | unsigned short cpus_configured; | ||
41 | unsigned short cpus_standby; | ||
42 | unsigned short cpus_reserved; | ||
43 | unsigned short adjustment[0]; | ||
44 | }; | ||
45 | |||
46 | struct sysinfo_2_2_1 | ||
47 | { | ||
48 | char reserved_0[80]; | ||
49 | char sequence[16]; | ||
50 | char plant[4]; | ||
51 | unsigned short cpu_id; | ||
52 | unsigned short cpu_address; | ||
53 | }; | ||
54 | |||
55 | struct sysinfo_2_2_2 | ||
56 | { | ||
57 | char reserved_0[32]; | ||
58 | unsigned short lpar_number; | ||
59 | char reserved_1; | ||
60 | unsigned char characteristics; | ||
61 | #define LPAR_CHAR_DEDICATED (1 << 7) | ||
62 | #define LPAR_CHAR_SHARED (1 << 6) | ||
63 | #define LPAR_CHAR_LIMITED (1 << 5) | ||
64 | unsigned short cpus_total; | ||
65 | unsigned short cpus_configured; | ||
66 | unsigned short cpus_standby; | ||
67 | unsigned short cpus_reserved; | ||
68 | char name[8]; | ||
69 | unsigned int caf; | ||
70 | char reserved_2[16]; | ||
71 | unsigned short cpus_dedicated; | ||
72 | unsigned short cpus_shared; | ||
73 | }; | ||
74 | |||
75 | struct sysinfo_3_2_2 | ||
76 | { | ||
77 | char reserved_0[31]; | ||
78 | unsigned char count; | ||
79 | struct | ||
80 | { | ||
81 | char reserved_0[4]; | ||
82 | unsigned short cpus_total; | ||
83 | unsigned short cpus_configured; | ||
84 | unsigned short cpus_standby; | ||
85 | unsigned short cpus_reserved; | ||
86 | char name[8]; | ||
87 | unsigned int caf; | ||
88 | char cpi[16]; | ||
89 | char reserved_1[24]; | ||
90 | |||
91 | } vm[8]; | ||
92 | }; | ||
93 | |||
94 | union s390_sysinfo | ||
95 | { | ||
96 | struct sysinfo_1_1_1 sysinfo_1_1_1; | ||
97 | struct sysinfo_1_2_1 sysinfo_1_2_1; | ||
98 | struct sysinfo_1_2_2 sysinfo_1_2_2; | ||
99 | struct sysinfo_2_2_1 sysinfo_2_2_1; | ||
100 | struct sysinfo_2_2_2 sysinfo_2_2_2; | ||
101 | struct sysinfo_3_2_2 sysinfo_3_2_2; | ||
102 | }; | ||
103 | |||
104 | static inline int stsi (void *sysinfo, | ||
105 | int fc, int sel1, int sel2) | ||
106 | { | ||
107 | int cc, retv; | ||
108 | |||
109 | #ifndef CONFIG_ARCH_S390X | ||
110 | __asm__ __volatile__ ( "lr\t0,%2\n" | ||
111 | "\tlr\t1,%3\n" | ||
112 | "\tstsi\t0(%4)\n" | ||
113 | "0:\tipm\t%0\n" | ||
114 | "\tsrl\t%0,28\n" | ||
115 | "1:lr\t%1,0\n" | ||
116 | ".section .fixup,\"ax\"\n" | ||
117 | "2:\tlhi\t%0,3\n" | ||
118 | "\tbras\t1,3f\n" | ||
119 | "\t.long 1b\n" | ||
120 | "3:\tl\t1,0(1)\n" | ||
121 | "\tbr\t1\n" | ||
122 | ".previous\n" | ||
123 | ".section __ex_table,\"a\"\n" | ||
124 | "\t.align 4\n" | ||
125 | "\t.long 0b,2b\n" | ||
126 | ".previous\n" | ||
127 | : "=d" (cc), "=d" (retv) | ||
128 | : "d" ((fc << 28) | sel1), "d" (sel2), "a" (sysinfo) | ||
129 | : "cc", "memory", "0", "1" ); | ||
130 | #else | ||
131 | __asm__ __volatile__ ( "lr\t0,%2\n" | ||
132 | "lr\t1,%3\n" | ||
133 | "\tstsi\t0(%4)\n" | ||
134 | "0:\tipm\t%0\n" | ||
135 | "\tsrl\t%0,28\n" | ||
136 | "1:lr\t%1,0\n" | ||
137 | ".section .fixup,\"ax\"\n" | ||
138 | "2:\tlhi\t%0,3\n" | ||
139 | "\tjg\t1b\n" | ||
140 | ".previous\n" | ||
141 | ".section __ex_table,\"a\"\n" | ||
142 | "\t.align 8\n" | ||
143 | "\t.quad 0b,2b\n" | ||
144 | ".previous\n" | ||
145 | : "=d" (cc), "=d" (retv) | ||
146 | : "d" ((fc << 28) | sel1), "d" (sel2), "a" (sysinfo) | ||
147 | : "cc", "memory", "0", "1" ); | ||
148 | #endif | ||
149 | |||
150 | return cc? -1 : retv; | ||
151 | } | ||
152 | |||
153 | static inline int stsi_0 (void) | ||
154 | { | ||
155 | int rc = stsi (NULL, 0, 0, 0); | ||
156 | return rc == -1 ? rc : (((unsigned int)rc) >> 28); | ||
157 | } | ||
158 | |||
159 | static inline int stsi_1_1_1 (struct sysinfo_1_1_1 *info) | ||
160 | { | ||
161 | int rc = stsi (info, 1, 1, 1); | ||
162 | if (rc != -1) | ||
163 | { | ||
164 | EBCASC (info->manufacturer, sizeof(info->manufacturer)); | ||
165 | EBCASC (info->type, sizeof(info->type)); | ||
166 | EBCASC (info->model, sizeof(info->model)); | ||
167 | EBCASC (info->sequence, sizeof(info->sequence)); | ||
168 | EBCASC (info->plant, sizeof(info->plant)); | ||
169 | } | ||
170 | return rc == -1 ? rc : 0; | ||
171 | } | ||
172 | |||
173 | static inline int stsi_1_2_1 (struct sysinfo_1_2_1 *info) | ||
174 | { | ||
175 | int rc = stsi (info, 1, 2, 1); | ||
176 | if (rc != -1) | ||
177 | { | ||
178 | EBCASC (info->sequence, sizeof(info->sequence)); | ||
179 | EBCASC (info->plant, sizeof(info->plant)); | ||
180 | } | ||
181 | return rc == -1 ? rc : 0; | ||
182 | } | ||
183 | |||
184 | static inline int stsi_1_2_2 (struct sysinfo_1_2_2 *info) | ||
185 | { | ||
186 | int rc = stsi (info, 1, 2, 2); | ||
187 | return rc == -1 ? rc : 0; | ||
188 | } | ||
189 | |||
190 | static inline int stsi_2_2_1 (struct sysinfo_2_2_1 *info) | ||
191 | { | ||
192 | int rc = stsi (info, 2, 2, 1); | ||
193 | if (rc != -1) | ||
194 | { | ||
195 | EBCASC (info->sequence, sizeof(info->sequence)); | ||
196 | EBCASC (info->plant, sizeof(info->plant)); | ||
197 | } | ||
198 | return rc == -1 ? rc : 0; | ||
199 | } | ||
200 | |||
201 | static inline int stsi_2_2_2 (struct sysinfo_2_2_2 *info) | ||
202 | { | ||
203 | int rc = stsi (info, 2, 2, 2); | ||
204 | if (rc != -1) | ||
205 | { | ||
206 | EBCASC (info->name, sizeof(info->name)); | ||
207 | } | ||
208 | return rc == -1 ? rc : 0; | ||
209 | } | ||
210 | |||
211 | static inline int stsi_3_2_2 (struct sysinfo_3_2_2 *info) | ||
212 | { | ||
213 | int rc = stsi (info, 3, 2, 2); | ||
214 | if (rc != -1) | ||
215 | { | ||
216 | int i; | ||
217 | for (i = 0; i < info->count; i++) | ||
218 | { | ||
219 | EBCASC (info->vm[i].name, sizeof(info->vm[i].name)); | ||
220 | EBCASC (info->vm[i].cpi, sizeof(info->vm[i].cpi)); | ||
221 | } | ||
222 | } | ||
223 | return rc == -1 ? rc : 0; | ||
224 | } | ||
225 | |||
226 | |||
227 | static int proc_read_sysinfo(char *page, char **start, | ||
228 | off_t off, int count, | ||
229 | int *eof, void *data) | ||
230 | { | ||
231 | unsigned long info_page = get_zeroed_page (GFP_KERNEL); | ||
232 | union s390_sysinfo *info = (union s390_sysinfo *) info_page; | ||
233 | int len = 0; | ||
234 | int level; | ||
235 | int i; | ||
236 | |||
237 | if (!info) | ||
238 | return 0; | ||
239 | |||
240 | level = stsi_0 (); | ||
241 | |||
242 | if (level >= 1 && stsi_1_1_1 (&info->sysinfo_1_1_1) == 0) | ||
243 | { | ||
244 | len += sprintf (page+len, "Manufacturer: %-16.16s\n", | ||
245 | info->sysinfo_1_1_1.manufacturer); | ||
246 | len += sprintf (page+len, "Type: %-4.4s\n", | ||
247 | info->sysinfo_1_1_1.type); | ||
248 | len += sprintf (page+len, "Model: %-16.16s\n", | ||
249 | info->sysinfo_1_1_1.model); | ||
250 | len += sprintf (page+len, "Sequence Code: %-16.16s\n", | ||
251 | info->sysinfo_1_1_1.sequence); | ||
252 | len += sprintf (page+len, "Plant: %-4.4s\n", | ||
253 | info->sysinfo_1_1_1.plant); | ||
254 | } | ||
255 | |||
256 | if (level >= 1 && stsi_1_2_2 (&info->sysinfo_1_2_2) == 0) | ||
257 | { | ||
258 | len += sprintf (page+len, "\n"); | ||
259 | len += sprintf (page+len, "CPUs Total: %d\n", | ||
260 | info->sysinfo_1_2_2.cpus_total); | ||
261 | len += sprintf (page+len, "CPUs Configured: %d\n", | ||
262 | info->sysinfo_1_2_2.cpus_configured); | ||
263 | len += sprintf (page+len, "CPUs Standby: %d\n", | ||
264 | info->sysinfo_1_2_2.cpus_standby); | ||
265 | len += sprintf (page+len, "CPUs Reserved: %d\n", | ||
266 | info->sysinfo_1_2_2.cpus_reserved); | ||
267 | |||
268 | len += sprintf (page+len, "Capability: %d\n", | ||
269 | info->sysinfo_1_2_2.capability); | ||
270 | |||
271 | for (i = 2; i <= info->sysinfo_1_2_2.cpus_total; i++) | ||
272 | len += sprintf (page+len, "Adjustment %02d-way: %d\n", | ||
273 | i, info->sysinfo_1_2_2.adjustment[i-2]); | ||
274 | } | ||
275 | |||
276 | if (level >= 2 && stsi_2_2_2 (&info->sysinfo_2_2_2) == 0) | ||
277 | { | ||
278 | len += sprintf (page+len, "\n"); | ||
279 | len += sprintf (page+len, "LPAR Number: %d\n", | ||
280 | info->sysinfo_2_2_2.lpar_number); | ||
281 | |||
282 | len += sprintf (page+len, "LPAR Characteristics: "); | ||
283 | if (info->sysinfo_2_2_2.characteristics & LPAR_CHAR_DEDICATED) | ||
284 | len += sprintf (page+len, "Dedicated "); | ||
285 | if (info->sysinfo_2_2_2.characteristics & LPAR_CHAR_SHARED) | ||
286 | len += sprintf (page+len, "Shared "); | ||
287 | if (info->sysinfo_2_2_2.characteristics & LPAR_CHAR_LIMITED) | ||
288 | len += sprintf (page+len, "Limited "); | ||
289 | len += sprintf (page+len, "\n"); | ||
290 | |||
291 | len += sprintf (page+len, "LPAR Name: %-8.8s\n", | ||
292 | info->sysinfo_2_2_2.name); | ||
293 | |||
294 | len += sprintf (page+len, "LPAR Adjustment: %d\n", | ||
295 | info->sysinfo_2_2_2.caf); | ||
296 | |||
297 | len += sprintf (page+len, "LPAR CPUs Total: %d\n", | ||
298 | info->sysinfo_2_2_2.cpus_total); | ||
299 | len += sprintf (page+len, "LPAR CPUs Configured: %d\n", | ||
300 | info->sysinfo_2_2_2.cpus_configured); | ||
301 | len += sprintf (page+len, "LPAR CPUs Standby: %d\n", | ||
302 | info->sysinfo_2_2_2.cpus_standby); | ||
303 | len += sprintf (page+len, "LPAR CPUs Reserved: %d\n", | ||
304 | info->sysinfo_2_2_2.cpus_reserved); | ||
305 | len += sprintf (page+len, "LPAR CPUs Dedicated: %d\n", | ||
306 | info->sysinfo_2_2_2.cpus_dedicated); | ||
307 | len += sprintf (page+len, "LPAR CPUs Shared: %d\n", | ||
308 | info->sysinfo_2_2_2.cpus_shared); | ||
309 | } | ||
310 | |||
311 | if (level >= 3 && stsi_3_2_2 (&info->sysinfo_3_2_2) == 0) | ||
312 | { | ||
313 | for (i = 0; i < info->sysinfo_3_2_2.count; i++) | ||
314 | { | ||
315 | len += sprintf (page+len, "\n"); | ||
316 | len += sprintf (page+len, "VM%02d Name: %-8.8s\n", | ||
317 | i, info->sysinfo_3_2_2.vm[i].name); | ||
318 | len += sprintf (page+len, "VM%02d Control Program: %-16.16s\n", | ||
319 | i, info->sysinfo_3_2_2.vm[i].cpi); | ||
320 | |||
321 | len += sprintf (page+len, "VM%02d Adjustment: %d\n", | ||
322 | i, info->sysinfo_3_2_2.vm[i].caf); | ||
323 | |||
324 | len += sprintf (page+len, "VM%02d CPUs Total: %d\n", | ||
325 | i, info->sysinfo_3_2_2.vm[i].cpus_total); | ||
326 | len += sprintf (page+len, "VM%02d CPUs Configured: %d\n", | ||
327 | i, info->sysinfo_3_2_2.vm[i].cpus_configured); | ||
328 | len += sprintf (page+len, "VM%02d CPUs Standby: %d\n", | ||
329 | i, info->sysinfo_3_2_2.vm[i].cpus_standby); | ||
330 | len += sprintf (page+len, "VM%02d CPUs Reserved: %d\n", | ||
331 | i, info->sysinfo_3_2_2.vm[i].cpus_reserved); | ||
332 | } | ||
333 | } | ||
334 | |||
335 | free_page (info_page); | ||
336 | return len; | ||
337 | } | ||
338 | |||
339 | static __init int create_proc_sysinfo(void) | ||
340 | { | ||
341 | create_proc_read_entry ("sysinfo", 0444, NULL, | ||
342 | proc_read_sysinfo, NULL); | ||
343 | return 0; | ||
344 | } | ||
345 | |||
346 | __initcall(create_proc_sysinfo); | ||
347 | |||