2 * drivers/s390/sysinfo.c
4 * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
5 * Author(s): Ulrich Weigand (Ulrich.Weigand@de.ibm.com)
8 #include <linux/config.h>
9 #include <linux/kernel.h>
11 #include <linux/proc_fs.h>
12 #include <linux/init.h>
13 #include <asm/ebcdic.h>
18 char manufacturer
[16];
32 unsigned short cpu_address
;
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];
51 unsigned short cpu_id
;
52 unsigned short cpu_address
;
58 unsigned short lpar_number
;
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
;
71 unsigned short cpus_dedicated
;
72 unsigned short cpus_shared
;
82 unsigned short cpus_total
;
83 unsigned short cpus_configured
;
84 unsigned short cpus_standby
;
85 unsigned short cpus_reserved
;
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
;
104 static inline int stsi (void *sysinfo
,
105 int fc
, int sel1
, int sel2
)
109 #ifndef CONFIG_ARCH_S390X
110 __asm__
__volatile__ ( "lr\t0,%2\n"
116 ".section .fixup,\"ax\"\n"
123 ".section __ex_table,\"a\"\n"
127 : "=d" (cc
), "=d" (retv
)
128 : "d" ((fc
<< 28) | sel1
), "d" (sel2
), "a" (sysinfo
)
129 : "cc", "memory", "0", "1" );
131 __asm__
__volatile__ ( "lr\t0,%2\n"
137 ".section .fixup,\"ax\"\n"
141 ".section __ex_table,\"a\"\n"
145 : "=d" (cc
), "=d" (retv
)
146 : "d" ((fc
<< 28) | sel1
), "d" (sel2
), "a" (sysinfo
)
147 : "cc", "memory", "0", "1" );
150 return cc
? -1 : retv
;
153 static inline int stsi_0 (void)
155 int rc
= stsi (NULL
, 0, 0, 0);
156 return rc
== -1 ? rc
: (((unsigned int)rc
) >> 28);
159 static inline int stsi_1_1_1 (struct sysinfo_1_1_1
*info
)
161 int rc
= stsi (info
, 1, 1, 1);
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
));
170 return rc
== -1 ? rc
: 0;
173 static inline int stsi_1_2_1 (struct sysinfo_1_2_1
*info
)
175 int rc
= stsi (info
, 1, 2, 1);
178 EBCASC (info
->sequence
, sizeof(info
->sequence
));
179 EBCASC (info
->plant
, sizeof(info
->plant
));
181 return rc
== -1 ? rc
: 0;
184 static inline int stsi_1_2_2 (struct sysinfo_1_2_2
*info
)
186 int rc
= stsi (info
, 1, 2, 2);
187 return rc
== -1 ? rc
: 0;
190 static inline int stsi_2_2_1 (struct sysinfo_2_2_1
*info
)
192 int rc
= stsi (info
, 2, 2, 1);
195 EBCASC (info
->sequence
, sizeof(info
->sequence
));
196 EBCASC (info
->plant
, sizeof(info
->plant
));
198 return rc
== -1 ? rc
: 0;
201 static inline int stsi_2_2_2 (struct sysinfo_2_2_2
*info
)
203 int rc
= stsi (info
, 2, 2, 2);
206 EBCASC (info
->name
, sizeof(info
->name
));
208 return rc
== -1 ? rc
: 0;
211 static inline int stsi_3_2_2 (struct sysinfo_3_2_2
*info
)
213 int rc
= stsi (info
, 3, 2, 2);
217 for (i
= 0; i
< info
->count
; i
++)
219 EBCASC (info
->vm
[i
].name
, sizeof(info
->vm
[i
].name
));
220 EBCASC (info
->vm
[i
].cpi
, sizeof(info
->vm
[i
].cpi
));
223 return rc
== -1 ? rc
: 0;
227 static int proc_read_sysinfo(char *page
, char **start
,
228 off_t off
, int count
,
229 int *eof
, void *data
)
231 unsigned long info_page
= get_zeroed_page (GFP_KERNEL
);
232 union s390_sysinfo
*info
= (union s390_sysinfo
*) info_page
;
242 if (level
>= 1 && stsi_1_1_1 (&info
->sysinfo_1_1_1
) == 0)
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
);
256 if (level
>= 1 && stsi_1_2_2 (&info
->sysinfo_1_2_2
) == 0)
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
);
268 len
+= sprintf (page
+len
, "Capability: %d\n",
269 info
->sysinfo_1_2_2
.capability
);
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]);
276 if (level
>= 2 && stsi_2_2_2 (&info
->sysinfo_2_2_2
) == 0)
278 len
+= sprintf (page
+len
, "\n");
279 len
+= sprintf (page
+len
, "LPAR Number: %d\n",
280 info
->sysinfo_2_2_2
.lpar_number
);
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");
291 len
+= sprintf (page
+len
, "LPAR Name: %-8.8s\n",
292 info
->sysinfo_2_2_2
.name
);
294 len
+= sprintf (page
+len
, "LPAR Adjustment: %d\n",
295 info
->sysinfo_2_2_2
.caf
);
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
);
311 if (level
>= 3 && stsi_3_2_2 (&info
->sysinfo_3_2_2
) == 0)
313 for (i
= 0; i
< info
->sysinfo_3_2_2
.count
; i
++)
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
);
321 len
+= sprintf (page
+len
, "VM%02d Adjustment: %d\n",
322 i
, info
->sysinfo_3_2_2
.vm
[i
].caf
);
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
);
335 free_page (info_page
);
339 static __init
int create_proc_sysinfo(void)
341 create_proc_read_entry ("sysinfo", 0444, NULL
,
342 proc_read_sysinfo
, NULL
);
346 __initcall(create_proc_sysinfo
);