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/kernel.h>
10 #include <linux/proc_fs.h>
11 #include <linux/init.h>
12 #include <asm/ebcdic.h>
17 char manufacturer
[16];
31 unsigned short cpu_address
;
37 unsigned int capability
;
38 unsigned short cpus_total
;
39 unsigned short cpus_configured
;
40 unsigned short cpus_standby
;
41 unsigned short cpus_reserved
;
42 unsigned short adjustment
[0];
50 unsigned short cpu_id
;
51 unsigned short cpu_address
;
57 unsigned short lpar_number
;
59 unsigned char characteristics
;
60 #define LPAR_CHAR_DEDICATED (1 << 7)
61 #define LPAR_CHAR_SHARED (1 << 6)
62 #define LPAR_CHAR_LIMITED (1 << 5)
63 unsigned short cpus_total
;
64 unsigned short cpus_configured
;
65 unsigned short cpus_standby
;
66 unsigned short cpus_reserved
;
70 unsigned short cpus_dedicated
;
71 unsigned short cpus_shared
;
81 unsigned short cpus_total
;
82 unsigned short cpus_configured
;
83 unsigned short cpus_standby
;
84 unsigned short cpus_reserved
;
95 struct sysinfo_1_1_1 sysinfo_1_1_1
;
96 struct sysinfo_1_2_1 sysinfo_1_2_1
;
97 struct sysinfo_1_2_2 sysinfo_1_2_2
;
98 struct sysinfo_2_2_1 sysinfo_2_2_1
;
99 struct sysinfo_2_2_2 sysinfo_2_2_2
;
100 struct sysinfo_3_2_2 sysinfo_3_2_2
;
103 static inline int stsi (void *sysinfo
,
104 int fc
, int sel1
, int sel2
)
109 __asm__
__volatile__ ( "lr\t0,%2\n"
115 ".section .fixup,\"ax\"\n"
122 ".section __ex_table,\"a\"\n"
126 : "=d" (cc
), "=d" (retv
)
127 : "d" ((fc
<< 28) | sel1
), "d" (sel2
), "a" (sysinfo
)
128 : "cc", "memory", "0", "1" );
130 __asm__
__volatile__ ( "lr\t0,%2\n"
136 ".section .fixup,\"ax\"\n"
140 ".section __ex_table,\"a\"\n"
144 : "=d" (cc
), "=d" (retv
)
145 : "d" ((fc
<< 28) | sel1
), "d" (sel2
), "a" (sysinfo
)
146 : "cc", "memory", "0", "1" );
149 return cc
? -1 : retv
;
152 static inline int stsi_0 (void)
154 int rc
= stsi (NULL
, 0, 0, 0);
155 return rc
== -1 ? rc
: (((unsigned int)rc
) >> 28);
158 static inline int stsi_1_1_1 (struct sysinfo_1_1_1
*info
)
160 int rc
= stsi (info
, 1, 1, 1);
163 EBCASC (info
->manufacturer
, sizeof(info
->manufacturer
));
164 EBCASC (info
->type
, sizeof(info
->type
));
165 EBCASC (info
->model
, sizeof(info
->model
));
166 EBCASC (info
->sequence
, sizeof(info
->sequence
));
167 EBCASC (info
->plant
, sizeof(info
->plant
));
169 return rc
== -1 ? rc
: 0;
172 static inline int stsi_1_2_1 (struct sysinfo_1_2_1
*info
)
174 int rc
= stsi (info
, 1, 2, 1);
177 EBCASC (info
->sequence
, sizeof(info
->sequence
));
178 EBCASC (info
->plant
, sizeof(info
->plant
));
180 return rc
== -1 ? rc
: 0;
183 static inline int stsi_1_2_2 (struct sysinfo_1_2_2
*info
)
185 int rc
= stsi (info
, 1, 2, 2);
186 return rc
== -1 ? rc
: 0;
189 static inline int stsi_2_2_1 (struct sysinfo_2_2_1
*info
)
191 int rc
= stsi (info
, 2, 2, 1);
194 EBCASC (info
->sequence
, sizeof(info
->sequence
));
195 EBCASC (info
->plant
, sizeof(info
->plant
));
197 return rc
== -1 ? rc
: 0;
200 static inline int stsi_2_2_2 (struct sysinfo_2_2_2
*info
)
202 int rc
= stsi (info
, 2, 2, 2);
205 EBCASC (info
->name
, sizeof(info
->name
));
207 return rc
== -1 ? rc
: 0;
210 static inline int stsi_3_2_2 (struct sysinfo_3_2_2
*info
)
212 int rc
= stsi (info
, 3, 2, 2);
216 for (i
= 0; i
< info
->count
; i
++)
218 EBCASC (info
->vm
[i
].name
, sizeof(info
->vm
[i
].name
));
219 EBCASC (info
->vm
[i
].cpi
, sizeof(info
->vm
[i
].cpi
));
222 return rc
== -1 ? rc
: 0;
226 static int proc_read_sysinfo(char *page
, char **start
,
227 off_t off
, int count
,
228 int *eof
, void *data
)
230 unsigned long info_page
= get_zeroed_page (GFP_KERNEL
);
231 union s390_sysinfo
*info
= (union s390_sysinfo
*) info_page
;
241 if (level
>= 1 && stsi_1_1_1 (&info
->sysinfo_1_1_1
) == 0)
243 len
+= sprintf (page
+len
, "Manufacturer: %-16.16s\n",
244 info
->sysinfo_1_1_1
.manufacturer
);
245 len
+= sprintf (page
+len
, "Type: %-4.4s\n",
246 info
->sysinfo_1_1_1
.type
);
247 len
+= sprintf (page
+len
, "Model: %-16.16s\n",
248 info
->sysinfo_1_1_1
.model
);
249 len
+= sprintf (page
+len
, "Sequence Code: %-16.16s\n",
250 info
->sysinfo_1_1_1
.sequence
);
251 len
+= sprintf (page
+len
, "Plant: %-4.4s\n",
252 info
->sysinfo_1_1_1
.plant
);
255 if (level
>= 1 && stsi_1_2_2 (&info
->sysinfo_1_2_2
) == 0)
257 len
+= sprintf (page
+len
, "\n");
258 len
+= sprintf (page
+len
, "CPUs Total: %d\n",
259 info
->sysinfo_1_2_2
.cpus_total
);
260 len
+= sprintf (page
+len
, "CPUs Configured: %d\n",
261 info
->sysinfo_1_2_2
.cpus_configured
);
262 len
+= sprintf (page
+len
, "CPUs Standby: %d\n",
263 info
->sysinfo_1_2_2
.cpus_standby
);
264 len
+= sprintf (page
+len
, "CPUs Reserved: %d\n",
265 info
->sysinfo_1_2_2
.cpus_reserved
);
267 len
+= sprintf (page
+len
, "Capability: %d\n",
268 info
->sysinfo_1_2_2
.capability
);
270 for (i
= 2; i
<= info
->sysinfo_1_2_2
.cpus_total
; i
++)
271 len
+= sprintf (page
+len
, "Adjustment %02d-way: %d\n",
272 i
, info
->sysinfo_1_2_2
.adjustment
[i
-2]);
275 if (level
>= 2 && stsi_2_2_2 (&info
->sysinfo_2_2_2
) == 0)
277 len
+= sprintf (page
+len
, "\n");
278 len
+= sprintf (page
+len
, "LPAR Number: %d\n",
279 info
->sysinfo_2_2_2
.lpar_number
);
281 len
+= sprintf (page
+len
, "LPAR Characteristics: ");
282 if (info
->sysinfo_2_2_2
.characteristics
& LPAR_CHAR_DEDICATED
)
283 len
+= sprintf (page
+len
, "Dedicated ");
284 if (info
->sysinfo_2_2_2
.characteristics
& LPAR_CHAR_SHARED
)
285 len
+= sprintf (page
+len
, "Shared ");
286 if (info
->sysinfo_2_2_2
.characteristics
& LPAR_CHAR_LIMITED
)
287 len
+= sprintf (page
+len
, "Limited ");
288 len
+= sprintf (page
+len
, "\n");
290 len
+= sprintf (page
+len
, "LPAR Name: %-8.8s\n",
291 info
->sysinfo_2_2_2
.name
);
293 len
+= sprintf (page
+len
, "LPAR Adjustment: %d\n",
294 info
->sysinfo_2_2_2
.caf
);
296 len
+= sprintf (page
+len
, "LPAR CPUs Total: %d\n",
297 info
->sysinfo_2_2_2
.cpus_total
);
298 len
+= sprintf (page
+len
, "LPAR CPUs Configured: %d\n",
299 info
->sysinfo_2_2_2
.cpus_configured
);
300 len
+= sprintf (page
+len
, "LPAR CPUs Standby: %d\n",
301 info
->sysinfo_2_2_2
.cpus_standby
);
302 len
+= sprintf (page
+len
, "LPAR CPUs Reserved: %d\n",
303 info
->sysinfo_2_2_2
.cpus_reserved
);
304 len
+= sprintf (page
+len
, "LPAR CPUs Dedicated: %d\n",
305 info
->sysinfo_2_2_2
.cpus_dedicated
);
306 len
+= sprintf (page
+len
, "LPAR CPUs Shared: %d\n",
307 info
->sysinfo_2_2_2
.cpus_shared
);
310 if (level
>= 3 && stsi_3_2_2 (&info
->sysinfo_3_2_2
) == 0)
312 for (i
= 0; i
< info
->sysinfo_3_2_2
.count
; i
++)
314 len
+= sprintf (page
+len
, "\n");
315 len
+= sprintf (page
+len
, "VM%02d Name: %-8.8s\n",
316 i
, info
->sysinfo_3_2_2
.vm
[i
].name
);
317 len
+= sprintf (page
+len
, "VM%02d Control Program: %-16.16s\n",
318 i
, info
->sysinfo_3_2_2
.vm
[i
].cpi
);
320 len
+= sprintf (page
+len
, "VM%02d Adjustment: %d\n",
321 i
, info
->sysinfo_3_2_2
.vm
[i
].caf
);
323 len
+= sprintf (page
+len
, "VM%02d CPUs Total: %d\n",
324 i
, info
->sysinfo_3_2_2
.vm
[i
].cpus_total
);
325 len
+= sprintf (page
+len
, "VM%02d CPUs Configured: %d\n",
326 i
, info
->sysinfo_3_2_2
.vm
[i
].cpus_configured
);
327 len
+= sprintf (page
+len
, "VM%02d CPUs Standby: %d\n",
328 i
, info
->sysinfo_3_2_2
.vm
[i
].cpus_standby
);
329 len
+= sprintf (page
+len
, "VM%02d CPUs Reserved: %d\n",
330 i
, info
->sysinfo_3_2_2
.vm
[i
].cpus_reserved
);
334 free_page (info_page
);
338 static __init
int create_proc_sysinfo(void)
340 create_proc_read_entry ("sysinfo", 0444, NULL
,
341 proc_read_sysinfo
, NULL
);
345 __initcall(create_proc_sysinfo
);