diff options
-rw-r--r-- | arch/ia64/kernel/palinfo.c | 502 | ||||
-rw-r--r-- | arch/ia64/kernel/salinfo.c | 39 | ||||
-rw-r--r-- | arch/ia64/sn/kernel/sn2/prominfo_proc.c | 108 |
3 files changed, 301 insertions, 348 deletions
diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c index 79521d5499f9..b17129e3b7c8 100644 --- a/arch/ia64/kernel/palinfo.c +++ b/arch/ia64/kernel/palinfo.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/errno.h> | 22 | #include <linux/errno.h> |
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/proc_fs.h> | 24 | #include <linux/proc_fs.h> |
25 | #include <linux/seq_file.h> | ||
25 | #include <linux/mm.h> | 26 | #include <linux/mm.h> |
26 | #include <linux/module.h> | 27 | #include <linux/module.h> |
27 | #include <linux/efi.h> | 28 | #include <linux/efi.h> |
@@ -41,7 +42,7 @@ MODULE_LICENSE("GPL"); | |||
41 | 42 | ||
42 | #define PALINFO_VERSION "0.5" | 43 | #define PALINFO_VERSION "0.5" |
43 | 44 | ||
44 | typedef int (*palinfo_func_t)(char*); | 45 | typedef int (*palinfo_func_t)(struct seq_file *); |
45 | 46 | ||
46 | typedef struct { | 47 | typedef struct { |
47 | const char *name; /* name of the proc entry */ | 48 | const char *name; /* name of the proc entry */ |
@@ -54,7 +55,7 @@ typedef struct { | |||
54 | * A bunch of string array to get pretty printing | 55 | * A bunch of string array to get pretty printing |
55 | */ | 56 | */ |
56 | 57 | ||
57 | static char *cache_types[] = { | 58 | static const char *cache_types[] = { |
58 | "", /* not used */ | 59 | "", /* not used */ |
59 | "Instruction", | 60 | "Instruction", |
60 | "Data", | 61 | "Data", |
@@ -122,19 +123,16 @@ static const char *mem_attrib[]={ | |||
122 | * - a pointer to the end of the buffer | 123 | * - a pointer to the end of the buffer |
123 | * | 124 | * |
124 | */ | 125 | */ |
125 | static char * | 126 | static void bitvector_process(struct seq_file *m, u64 vector) |
126 | bitvector_process(char *p, u64 vector) | ||
127 | { | 127 | { |
128 | int i,j; | 128 | int i,j; |
129 | const char *units[]={ "", "K", "M", "G", "T" }; | 129 | static const char *units[]={ "", "K", "M", "G", "T" }; |
130 | 130 | ||
131 | for (i=0, j=0; i < 64; i++ , j=i/10) { | 131 | for (i=0, j=0; i < 64; i++ , j=i/10) { |
132 | if (vector & 0x1) { | 132 | if (vector & 0x1) |
133 | p += sprintf(p, "%d%s ", 1 << (i-j*10), units[j]); | 133 | seq_printf(m, "%d%s ", 1 << (i-j*10), units[j]); |
134 | } | ||
135 | vector >>= 1; | 134 | vector >>= 1; |
136 | } | 135 | } |
137 | return p; | ||
138 | } | 136 | } |
139 | 137 | ||
140 | /* | 138 | /* |
@@ -149,8 +147,7 @@ bitvector_process(char *p, u64 vector) | |||
149 | * - a pointer to the end of the buffer | 147 | * - a pointer to the end of the buffer |
150 | * | 148 | * |
151 | */ | 149 | */ |
152 | static char * | 150 | static void bitregister_process(struct seq_file *m, u64 *reg_info, int max) |
153 | bitregister_process(char *p, u64 *reg_info, int max) | ||
154 | { | 151 | { |
155 | int i, begin, skip = 0; | 152 | int i, begin, skip = 0; |
156 | u64 value = reg_info[0]; | 153 | u64 value = reg_info[0]; |
@@ -163,9 +160,9 @@ bitregister_process(char *p, u64 *reg_info, int max) | |||
163 | 160 | ||
164 | if ((value & 0x1) == 0 && skip == 0) { | 161 | if ((value & 0x1) == 0 && skip == 0) { |
165 | if (begin <= i - 2) | 162 | if (begin <= i - 2) |
166 | p += sprintf(p, "%d-%d ", begin, i-1); | 163 | seq_printf(m, "%d-%d ", begin, i-1); |
167 | else | 164 | else |
168 | p += sprintf(p, "%d ", i-1); | 165 | seq_printf(m, "%d ", i-1); |
169 | skip = 1; | 166 | skip = 1; |
170 | begin = -1; | 167 | begin = -1; |
171 | } else if ((value & 0x1) && skip == 1) { | 168 | } else if ((value & 0x1) && skip == 1) { |
@@ -176,19 +173,15 @@ bitregister_process(char *p, u64 *reg_info, int max) | |||
176 | } | 173 | } |
177 | if (begin > -1) { | 174 | if (begin > -1) { |
178 | if (begin < 127) | 175 | if (begin < 127) |
179 | p += sprintf(p, "%d-127", begin); | 176 | seq_printf(m, "%d-127", begin); |
180 | else | 177 | else |
181 | p += sprintf(p, "127"); | 178 | seq_puts(m, "127"); |
182 | } | 179 | } |
183 | |||
184 | return p; | ||
185 | } | 180 | } |
186 | 181 | ||
187 | static int | 182 | static int power_info(struct seq_file *m) |
188 | power_info(char *page) | ||
189 | { | 183 | { |
190 | s64 status; | 184 | s64 status; |
191 | char *p = page; | ||
192 | u64 halt_info_buffer[8]; | 185 | u64 halt_info_buffer[8]; |
193 | pal_power_mgmt_info_u_t *halt_info =(pal_power_mgmt_info_u_t *)halt_info_buffer; | 186 | pal_power_mgmt_info_u_t *halt_info =(pal_power_mgmt_info_u_t *)halt_info_buffer; |
194 | int i; | 187 | int i; |
@@ -198,26 +191,25 @@ power_info(char *page) | |||
198 | 191 | ||
199 | for (i=0; i < 8 ; i++ ) { | 192 | for (i=0; i < 8 ; i++ ) { |
200 | if (halt_info[i].pal_power_mgmt_info_s.im == 1) { | 193 | if (halt_info[i].pal_power_mgmt_info_s.im == 1) { |
201 | p += sprintf(p, "Power level %d:\n" | 194 | seq_printf(m, |
202 | "\tentry_latency : %d cycles\n" | 195 | "Power level %d:\n" |
203 | "\texit_latency : %d cycles\n" | 196 | "\tentry_latency : %d cycles\n" |
204 | "\tpower consumption : %d mW\n" | 197 | "\texit_latency : %d cycles\n" |
205 | "\tCache+TLB coherency : %s\n", i, | 198 | "\tpower consumption : %d mW\n" |
206 | halt_info[i].pal_power_mgmt_info_s.entry_latency, | 199 | "\tCache+TLB coherency : %s\n", i, |
207 | halt_info[i].pal_power_mgmt_info_s.exit_latency, | 200 | halt_info[i].pal_power_mgmt_info_s.entry_latency, |
208 | halt_info[i].pal_power_mgmt_info_s.power_consumption, | 201 | halt_info[i].pal_power_mgmt_info_s.exit_latency, |
209 | halt_info[i].pal_power_mgmt_info_s.co ? "Yes" : "No"); | 202 | halt_info[i].pal_power_mgmt_info_s.power_consumption, |
203 | halt_info[i].pal_power_mgmt_info_s.co ? "Yes" : "No"); | ||
210 | } else { | 204 | } else { |
211 | p += sprintf(p,"Power level %d: not implemented\n",i); | 205 | seq_printf(m,"Power level %d: not implemented\n", i); |
212 | } | 206 | } |
213 | } | 207 | } |
214 | return p - page; | 208 | return 0; |
215 | } | 209 | } |
216 | 210 | ||
217 | static int | 211 | static int cache_info(struct seq_file *m) |
218 | cache_info(char *page) | ||
219 | { | 212 | { |
220 | char *p = page; | ||
221 | unsigned long i, levels, unique_caches; | 213 | unsigned long i, levels, unique_caches; |
222 | pal_cache_config_info_t cci; | 214 | pal_cache_config_info_t cci; |
223 | int j, k; | 215 | int j, k; |
@@ -228,73 +220,74 @@ cache_info(char *page) | |||
228 | return 0; | 220 | return 0; |
229 | } | 221 | } |
230 | 222 | ||
231 | p += sprintf(p, "Cache levels : %ld\nUnique caches : %ld\n\n", levels, unique_caches); | 223 | seq_printf(m, "Cache levels : %ld\nUnique caches : %ld\n\n", |
224 | levels, unique_caches); | ||
232 | 225 | ||
233 | for (i=0; i < levels; i++) { | 226 | for (i=0; i < levels; i++) { |
234 | |||
235 | for (j=2; j >0 ; j--) { | 227 | for (j=2; j >0 ; j--) { |
236 | |||
237 | /* even without unification some level may not be present */ | 228 | /* even without unification some level may not be present */ |
238 | if ((status=ia64_pal_cache_config_info(i,j, &cci)) != 0) { | 229 | if ((status=ia64_pal_cache_config_info(i,j, &cci)) != 0) |
239 | continue; | 230 | continue; |
240 | } | 231 | |
241 | p += sprintf(p, | 232 | seq_printf(m, |
242 | "%s Cache level %lu:\n" | 233 | "%s Cache level %lu:\n" |
243 | "\tSize : %u bytes\n" | 234 | "\tSize : %u bytes\n" |
244 | "\tAttributes : ", | 235 | "\tAttributes : ", |
245 | cache_types[j+cci.pcci_unified], i+1, | 236 | cache_types[j+cci.pcci_unified], i+1, |
246 | cci.pcci_cache_size); | 237 | cci.pcci_cache_size); |
247 | 238 | ||
248 | if (cci.pcci_unified) p += sprintf(p, "Unified "); | 239 | if (cci.pcci_unified) |
249 | 240 | seq_puts(m, "Unified "); | |
250 | p += sprintf(p, "%s\n", cache_mattrib[cci.pcci_cache_attr]); | 241 | |
251 | 242 | seq_printf(m, "%s\n", cache_mattrib[cci.pcci_cache_attr]); | |
252 | p += sprintf(p, | 243 | |
253 | "\tAssociativity : %d\n" | 244 | seq_printf(m, |
254 | "\tLine size : %d bytes\n" | 245 | "\tAssociativity : %d\n" |
255 | "\tStride : %d bytes\n", | 246 | "\tLine size : %d bytes\n" |
256 | cci.pcci_assoc, 1<<cci.pcci_line_size, 1<<cci.pcci_stride); | 247 | "\tStride : %d bytes\n", |
248 | cci.pcci_assoc, | ||
249 | 1<<cci.pcci_line_size, | ||
250 | 1<<cci.pcci_stride); | ||
257 | if (j == 1) | 251 | if (j == 1) |
258 | p += sprintf(p, "\tStore latency : N/A\n"); | 252 | seq_puts(m, "\tStore latency : N/A\n"); |
259 | else | 253 | else |
260 | p += sprintf(p, "\tStore latency : %d cycle(s)\n", | 254 | seq_printf(m, "\tStore latency : %d cycle(s)\n", |
261 | cci.pcci_st_latency); | 255 | cci.pcci_st_latency); |
262 | 256 | ||
263 | p += sprintf(p, | 257 | seq_printf(m, |
264 | "\tLoad latency : %d cycle(s)\n" | 258 | "\tLoad latency : %d cycle(s)\n" |
265 | "\tStore hints : ", cci.pcci_ld_latency); | 259 | "\tStore hints : ", cci.pcci_ld_latency); |
266 | 260 | ||
267 | for(k=0; k < 8; k++ ) { | 261 | for(k=0; k < 8; k++ ) { |
268 | if ( cci.pcci_st_hints & 0x1) | 262 | if ( cci.pcci_st_hints & 0x1) |
269 | p += sprintf(p, "[%s]", cache_st_hints[k]); | 263 | seq_printf(m, "[%s]", cache_st_hints[k]); |
270 | cci.pcci_st_hints >>=1; | 264 | cci.pcci_st_hints >>=1; |
271 | } | 265 | } |
272 | p += sprintf(p, "\n\tLoad hints : "); | 266 | seq_puts(m, "\n\tLoad hints : "); |
273 | 267 | ||
274 | for(k=0; k < 8; k++ ) { | 268 | for(k=0; k < 8; k++ ) { |
275 | if (cci.pcci_ld_hints & 0x1) | 269 | if (cci.pcci_ld_hints & 0x1) |
276 | p += sprintf(p, "[%s]", cache_ld_hints[k]); | 270 | seq_printf(m, "[%s]", cache_ld_hints[k]); |
277 | cci.pcci_ld_hints >>=1; | 271 | cci.pcci_ld_hints >>=1; |
278 | } | 272 | } |
279 | p += sprintf(p, | 273 | seq_printf(m, |
280 | "\n\tAlias boundary : %d byte(s)\n" | 274 | "\n\tAlias boundary : %d byte(s)\n" |
281 | "\tTag LSB : %d\n" | 275 | "\tTag LSB : %d\n" |
282 | "\tTag MSB : %d\n", | 276 | "\tTag MSB : %d\n", |
283 | 1<<cci.pcci_alias_boundary, cci.pcci_tag_lsb, | 277 | 1<<cci.pcci_alias_boundary, cci.pcci_tag_lsb, |
284 | cci.pcci_tag_msb); | 278 | cci.pcci_tag_msb); |
285 | 279 | ||
286 | /* when unified, data(j=2) is enough */ | 280 | /* when unified, data(j=2) is enough */ |
287 | if (cci.pcci_unified) break; | 281 | if (cci.pcci_unified) |
282 | break; | ||
288 | } | 283 | } |
289 | } | 284 | } |
290 | return p - page; | 285 | return 0; |
291 | } | 286 | } |
292 | 287 | ||
293 | 288 | ||
294 | static int | 289 | static int vm_info(struct seq_file *m) |
295 | vm_info(char *page) | ||
296 | { | 290 | { |
297 | char *p = page; | ||
298 | u64 tr_pages =0, vw_pages=0, tc_pages; | 291 | u64 tr_pages =0, vw_pages=0, tc_pages; |
299 | u64 attrib; | 292 | u64 attrib; |
300 | pal_vm_info_1_u_t vm_info_1; | 293 | pal_vm_info_1_u_t vm_info_1; |
@@ -309,7 +302,7 @@ vm_info(char *page) | |||
309 | printk(KERN_ERR "ia64_pal_vm_summary=%ld\n", status); | 302 | printk(KERN_ERR "ia64_pal_vm_summary=%ld\n", status); |
310 | } else { | 303 | } else { |
311 | 304 | ||
312 | p += sprintf(p, | 305 | seq_printf(m, |
313 | "Physical Address Space : %d bits\n" | 306 | "Physical Address Space : %d bits\n" |
314 | "Virtual Address Space : %d bits\n" | 307 | "Virtual Address Space : %d bits\n" |
315 | "Protection Key Registers(PKR) : %d\n" | 308 | "Protection Key Registers(PKR) : %d\n" |
@@ -324,49 +317,49 @@ vm_info(char *page) | |||
324 | vm_info_1.pal_vm_info_1_s.hash_tag_id, | 317 | vm_info_1.pal_vm_info_1_s.hash_tag_id, |
325 | vm_info_2.pal_vm_info_2_s.rid_size); | 318 | vm_info_2.pal_vm_info_2_s.rid_size); |
326 | if (vm_info_2.pal_vm_info_2_s.max_purges == PAL_MAX_PURGES) | 319 | if (vm_info_2.pal_vm_info_2_s.max_purges == PAL_MAX_PURGES) |
327 | p += sprintf(p, "unlimited\n"); | 320 | seq_puts(m, "unlimited\n"); |
328 | else | 321 | else |
329 | p += sprintf(p, "%d\n", | 322 | seq_printf(m, "%d\n", |
330 | vm_info_2.pal_vm_info_2_s.max_purges ? | 323 | vm_info_2.pal_vm_info_2_s.max_purges ? |
331 | vm_info_2.pal_vm_info_2_s.max_purges : 1); | 324 | vm_info_2.pal_vm_info_2_s.max_purges : 1); |
332 | } | 325 | } |
333 | 326 | ||
334 | if (ia64_pal_mem_attrib(&attrib) == 0) { | 327 | if (ia64_pal_mem_attrib(&attrib) == 0) { |
335 | p += sprintf(p, "Supported memory attributes : "); | 328 | seq_puts(m, "Supported memory attributes : "); |
336 | sep = ""; | 329 | sep = ""; |
337 | for (i = 0; i < 8; i++) { | 330 | for (i = 0; i < 8; i++) { |
338 | if (attrib & (1 << i)) { | 331 | if (attrib & (1 << i)) { |
339 | p += sprintf(p, "%s%s", sep, mem_attrib[i]); | 332 | seq_printf(m, "%s%s", sep, mem_attrib[i]); |
340 | sep = ", "; | 333 | sep = ", "; |
341 | } | 334 | } |
342 | } | 335 | } |
343 | p += sprintf(p, "\n"); | 336 | seq_putc(m, '\n'); |
344 | } | 337 | } |
345 | 338 | ||
346 | if ((status = ia64_pal_vm_page_size(&tr_pages, &vw_pages)) !=0) { | 339 | if ((status = ia64_pal_vm_page_size(&tr_pages, &vw_pages)) !=0) { |
347 | printk(KERN_ERR "ia64_pal_vm_page_size=%ld\n", status); | 340 | printk(KERN_ERR "ia64_pal_vm_page_size=%ld\n", status); |
348 | } else { | 341 | } else { |
349 | 342 | ||
350 | p += sprintf(p, | 343 | seq_printf(m, |
351 | "\nTLB walker : %simplemented\n" | 344 | "\nTLB walker : %simplemented\n" |
352 | "Number of DTR : %d\n" | 345 | "Number of DTR : %d\n" |
353 | "Number of ITR : %d\n" | 346 | "Number of ITR : %d\n" |
354 | "TLB insertable page sizes : ", | 347 | "TLB insertable page sizes : ", |
355 | vm_info_1.pal_vm_info_1_s.vw ? "" : "not ", | 348 | vm_info_1.pal_vm_info_1_s.vw ? "" : "not ", |
356 | vm_info_1.pal_vm_info_1_s.max_dtr_entry+1, | 349 | vm_info_1.pal_vm_info_1_s.max_dtr_entry+1, |
357 | vm_info_1.pal_vm_info_1_s.max_itr_entry+1); | 350 | vm_info_1.pal_vm_info_1_s.max_itr_entry+1); |
358 | |||
359 | 351 | ||
360 | p = bitvector_process(p, tr_pages); | 352 | bitvector_process(m, tr_pages); |
361 | 353 | ||
362 | p += sprintf(p, "\nTLB purgeable page sizes : "); | 354 | seq_puts(m, "\nTLB purgeable page sizes : "); |
363 | 355 | ||
364 | p = bitvector_process(p, vw_pages); | 356 | bitvector_process(m, vw_pages); |
365 | } | 357 | } |
366 | if ((status=ia64_get_ptce(&ptce)) != 0) { | 358 | |
359 | if ((status = ia64_get_ptce(&ptce)) != 0) { | ||
367 | printk(KERN_ERR "ia64_get_ptce=%ld\n", status); | 360 | printk(KERN_ERR "ia64_get_ptce=%ld\n", status); |
368 | } else { | 361 | } else { |
369 | p += sprintf(p, | 362 | seq_printf(m, |
370 | "\nPurge base address : 0x%016lx\n" | 363 | "\nPurge base address : 0x%016lx\n" |
371 | "Purge outer loop count : %d\n" | 364 | "Purge outer loop count : %d\n" |
372 | "Purge inner loop count : %d\n" | 365 | "Purge inner loop count : %d\n" |
@@ -375,7 +368,7 @@ vm_info(char *page) | |||
375 | ptce.base, ptce.count[0], ptce.count[1], | 368 | ptce.base, ptce.count[0], ptce.count[1], |
376 | ptce.stride[0], ptce.stride[1]); | 369 | ptce.stride[0], ptce.stride[1]); |
377 | 370 | ||
378 | p += sprintf(p, | 371 | seq_printf(m, |
379 | "TC Levels : %d\n" | 372 | "TC Levels : %d\n" |
380 | "Unique TC(s) : %d\n", | 373 | "Unique TC(s) : %d\n", |
381 | vm_info_1.pal_vm_info_1_s.num_tc_levels, | 374 | vm_info_1.pal_vm_info_1_s.num_tc_levels, |
@@ -385,13 +378,11 @@ vm_info(char *page) | |||
385 | for (j=2; j>0 ; j--) { | 378 | for (j=2; j>0 ; j--) { |
386 | tc_pages = 0; /* just in case */ | 379 | tc_pages = 0; /* just in case */ |
387 | 380 | ||
388 | |||
389 | /* even without unification, some levels may not be present */ | 381 | /* even without unification, some levels may not be present */ |
390 | if ((status=ia64_pal_vm_info(i,j, &tc_info, &tc_pages)) != 0) { | 382 | if ((status=ia64_pal_vm_info(i,j, &tc_info, &tc_pages)) != 0) |
391 | continue; | 383 | continue; |
392 | } | ||
393 | 384 | ||
394 | p += sprintf(p, | 385 | seq_printf(m, |
395 | "\n%s Translation Cache Level %d:\n" | 386 | "\n%s Translation Cache Level %d:\n" |
396 | "\tHash sets : %d\n" | 387 | "\tHash sets : %d\n" |
397 | "\tAssociativity : %d\n" | 388 | "\tAssociativity : %d\n" |
@@ -403,15 +394,15 @@ vm_info(char *page) | |||
403 | tc_info.tc_num_entries); | 394 | tc_info.tc_num_entries); |
404 | 395 | ||
405 | if (tc_info.tc_pf) | 396 | if (tc_info.tc_pf) |
406 | p += sprintf(p, "PreferredPageSizeOptimized "); | 397 | seq_puts(m, "PreferredPageSizeOptimized "); |
407 | if (tc_info.tc_unified) | 398 | if (tc_info.tc_unified) |
408 | p += sprintf(p, "Unified "); | 399 | seq_puts(m, "Unified "); |
409 | if (tc_info.tc_reduce_tr) | 400 | if (tc_info.tc_reduce_tr) |
410 | p += sprintf(p, "TCReduction"); | 401 | seq_puts(m, "TCReduction"); |
411 | 402 | ||
412 | p += sprintf(p, "\n\tSupported page sizes: "); | 403 | seq_puts(m, "\n\tSupported page sizes: "); |
413 | 404 | ||
414 | p = bitvector_process(p, tc_pages); | 405 | bitvector_process(m, tc_pages); |
415 | 406 | ||
416 | /* when unified date (j=2) is enough */ | 407 | /* when unified date (j=2) is enough */ |
417 | if (tc_info.tc_unified) | 408 | if (tc_info.tc_unified) |
@@ -419,16 +410,14 @@ vm_info(char *page) | |||
419 | } | 410 | } |
420 | } | 411 | } |
421 | } | 412 | } |
422 | p += sprintf(p, "\n"); | ||
423 | 413 | ||
424 | return p - page; | 414 | seq_putc(m, '\n'); |
415 | return 0; | ||
425 | } | 416 | } |
426 | 417 | ||
427 | 418 | ||
428 | static int | 419 | static int register_info(struct seq_file *m) |
429 | register_info(char *page) | ||
430 | { | 420 | { |
431 | char *p = page; | ||
432 | u64 reg_info[2]; | 421 | u64 reg_info[2]; |
433 | u64 info; | 422 | u64 info; |
434 | unsigned long phys_stacked; | 423 | unsigned long phys_stacked; |
@@ -442,35 +431,31 @@ register_info(char *page) | |||
442 | }; | 431 | }; |
443 | 432 | ||
444 | for(info=0; info < 4; info++) { | 433 | for(info=0; info < 4; info++) { |
445 | 434 | if (ia64_pal_register_info(info, ®_info[0], ®_info[1]) != 0) | |
446 | if (ia64_pal_register_info(info, ®_info[0], ®_info[1]) != 0) return 0; | 435 | return 0; |
447 | 436 | seq_printf(m, "%-32s : ", info_type[info]); | |
448 | p += sprintf(p, "%-32s : ", info_type[info]); | 437 | bitregister_process(m, reg_info, 128); |
449 | 438 | seq_putc(m, '\n'); | |
450 | p = bitregister_process(p, reg_info, 128); | ||
451 | |||
452 | p += sprintf(p, "\n"); | ||
453 | } | 439 | } |
454 | 440 | ||
455 | if (ia64_pal_rse_info(&phys_stacked, &hints) == 0) { | 441 | if (ia64_pal_rse_info(&phys_stacked, &hints) == 0) |
442 | seq_printf(m, | ||
443 | "RSE stacked physical registers : %ld\n" | ||
444 | "RSE load/store hints : %ld (%s)\n", | ||
445 | phys_stacked, hints.ph_data, | ||
446 | hints.ph_data < RSE_HINTS_COUNT ? rse_hints[hints.ph_data]: "(??)"); | ||
456 | 447 | ||
457 | p += sprintf(p, | ||
458 | "RSE stacked physical registers : %ld\n" | ||
459 | "RSE load/store hints : %ld (%s)\n", | ||
460 | phys_stacked, hints.ph_data, | ||
461 | hints.ph_data < RSE_HINTS_COUNT ? rse_hints[hints.ph_data]: "(??)"); | ||
462 | } | ||
463 | if (ia64_pal_debug_info(&iregs, &dregs)) | 448 | if (ia64_pal_debug_info(&iregs, &dregs)) |
464 | return 0; | 449 | return 0; |
465 | 450 | ||
466 | p += sprintf(p, | 451 | seq_printf(m, |
467 | "Instruction debug register pairs : %ld\n" | 452 | "Instruction debug register pairs : %ld\n" |
468 | "Data debug register pairs : %ld\n", iregs, dregs); | 453 | "Data debug register pairs : %ld\n", iregs, dregs); |
469 | 454 | ||
470 | return p - page; | 455 | return 0; |
471 | } | 456 | } |
472 | 457 | ||
473 | static char *proc_features_0[]={ /* Feature set 0 */ | 458 | static const char *const proc_features_0[]={ /* Feature set 0 */ |
474 | NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, | 459 | NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, |
475 | NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL, | 460 | NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL, |
476 | NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, | 461 | NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, |
@@ -502,7 +487,7 @@ static char *proc_features_0[]={ /* Feature set 0 */ | |||
502 | "Enable BERR promotion" | 487 | "Enable BERR promotion" |
503 | }; | 488 | }; |
504 | 489 | ||
505 | static char *proc_features_16[]={ /* Feature set 16 */ | 490 | static const char *const proc_features_16[]={ /* Feature set 16 */ |
506 | "Disable ETM", | 491 | "Disable ETM", |
507 | "Enable ETM", | 492 | "Enable ETM", |
508 | "Enable MCA on half-way timer", | 493 | "Enable MCA on half-way timer", |
@@ -522,7 +507,7 @@ static char *proc_features_16[]={ /* Feature set 16 */ | |||
522 | NULL, NULL, NULL, NULL, NULL | 507 | NULL, NULL, NULL, NULL, NULL |
523 | }; | 508 | }; |
524 | 509 | ||
525 | static char **proc_features[]={ | 510 | static const char *const *const proc_features[]={ |
526 | proc_features_0, | 511 | proc_features_0, |
527 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 512 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
528 | NULL, NULL, NULL, NULL, | 513 | NULL, NULL, NULL, NULL, |
@@ -530,11 +515,10 @@ static char **proc_features[]={ | |||
530 | NULL, NULL, NULL, NULL, | 515 | NULL, NULL, NULL, NULL, |
531 | }; | 516 | }; |
532 | 517 | ||
533 | static char * feature_set_info(char *page, u64 avail, u64 status, u64 control, | 518 | static void feature_set_info(struct seq_file *m, u64 avail, u64 status, u64 control, |
534 | unsigned long set) | 519 | unsigned long set) |
535 | { | 520 | { |
536 | char *p = page; | 521 | const char *const *vf, *const *v; |
537 | char **vf, **v; | ||
538 | int i; | 522 | int i; |
539 | 523 | ||
540 | vf = v = proc_features[set]; | 524 | vf = v = proc_features[set]; |
@@ -547,13 +531,13 @@ static char * feature_set_info(char *page, u64 avail, u64 status, u64 control, | |||
547 | if (vf) | 531 | if (vf) |
548 | v = vf + i; | 532 | v = vf + i; |
549 | if ( v && *v ) { | 533 | if ( v && *v ) { |
550 | p += sprintf(p, "%-40s : %s %s\n", *v, | 534 | seq_printf(m, "%-40s : %s %s\n", *v, |
551 | avail & 0x1 ? (status & 0x1 ? | 535 | avail & 0x1 ? (status & 0x1 ? |
552 | "On " : "Off"): "", | 536 | "On " : "Off"): "", |
553 | avail & 0x1 ? (control & 0x1 ? | 537 | avail & 0x1 ? (control & 0x1 ? |
554 | "Ctrl" : "NoCtrl"): ""); | 538 | "Ctrl" : "NoCtrl"): ""); |
555 | } else { | 539 | } else { |
556 | p += sprintf(p, "Feature set %2ld bit %2d\t\t\t" | 540 | seq_printf(m, "Feature set %2ld bit %2d\t\t\t" |
557 | " : %s %s\n", | 541 | " : %s %s\n", |
558 | set, i, | 542 | set, i, |
559 | avail & 0x1 ? (status & 0x1 ? | 543 | avail & 0x1 ? (status & 0x1 ? |
@@ -562,36 +546,32 @@ static char * feature_set_info(char *page, u64 avail, u64 status, u64 control, | |||
562 | "Ctrl" : "NoCtrl"): ""); | 546 | "Ctrl" : "NoCtrl"): ""); |
563 | } | 547 | } |
564 | } | 548 | } |
565 | return p; | ||
566 | } | 549 | } |
567 | 550 | ||
568 | static int | 551 | static int processor_info(struct seq_file *m) |
569 | processor_info(char *page) | ||
570 | { | 552 | { |
571 | char *p = page; | ||
572 | u64 avail=1, status=1, control=1, feature_set=0; | 553 | u64 avail=1, status=1, control=1, feature_set=0; |
573 | s64 ret; | 554 | s64 ret; |
574 | 555 | ||
575 | do { | 556 | do { |
576 | ret = ia64_pal_proc_get_features(&avail, &status, &control, | 557 | ret = ia64_pal_proc_get_features(&avail, &status, &control, |
577 | feature_set); | 558 | feature_set); |
578 | if (ret < 0) { | 559 | if (ret < 0) |
579 | return p - page; | 560 | return 0; |
580 | } | 561 | |
581 | if (ret == 1) { | 562 | if (ret == 1) { |
582 | feature_set++; | 563 | feature_set++; |
583 | continue; | 564 | continue; |
584 | } | 565 | } |
585 | 566 | ||
586 | p = feature_set_info(p, avail, status, control, feature_set); | 567 | feature_set_info(m, avail, status, control, feature_set); |
587 | |||
588 | feature_set++; | 568 | feature_set++; |
589 | } while(1); | 569 | } while(1); |
590 | 570 | ||
591 | return p - page; | 571 | return 0; |
592 | } | 572 | } |
593 | 573 | ||
594 | static const char *bus_features[]={ | 574 | static const char *const bus_features[]={ |
595 | NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, | 575 | NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, |
596 | NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL, | 576 | NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL, |
597 | NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, | 577 | NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, |
@@ -617,125 +597,118 @@ static const char *bus_features[]={ | |||
617 | }; | 597 | }; |
618 | 598 | ||
619 | 599 | ||
620 | static int | 600 | static int bus_info(struct seq_file *m) |
621 | bus_info(char *page) | ||
622 | { | 601 | { |
623 | char *p = page; | 602 | const char *const *v = bus_features; |
624 | const char **v = bus_features; | ||
625 | pal_bus_features_u_t av, st, ct; | 603 | pal_bus_features_u_t av, st, ct; |
626 | u64 avail, status, control; | 604 | u64 avail, status, control; |
627 | int i; | 605 | int i; |
628 | s64 ret; | 606 | s64 ret; |
629 | 607 | ||
630 | if ((ret=ia64_pal_bus_get_features(&av, &st, &ct)) != 0) return 0; | 608 | if ((ret=ia64_pal_bus_get_features(&av, &st, &ct)) != 0) |
609 | return 0; | ||
631 | 610 | ||
632 | avail = av.pal_bus_features_val; | 611 | avail = av.pal_bus_features_val; |
633 | status = st.pal_bus_features_val; | 612 | status = st.pal_bus_features_val; |
634 | control = ct.pal_bus_features_val; | 613 | control = ct.pal_bus_features_val; |
635 | 614 | ||
636 | for(i=0; i < 64; i++, v++, avail >>=1, status >>=1, control >>=1) { | 615 | for(i=0; i < 64; i++, v++, avail >>=1, status >>=1, control >>=1) { |
637 | if ( ! *v ) continue; | 616 | if ( ! *v ) |
638 | p += sprintf(p, "%-48s : %s%s %s\n", *v, | 617 | continue; |
639 | avail & 0x1 ? "" : "NotImpl", | 618 | seq_printf(m, "%-48s : %s%s %s\n", *v, |
640 | avail & 0x1 ? (status & 0x1 ? "On" : "Off"): "", | 619 | avail & 0x1 ? "" : "NotImpl", |
641 | avail & 0x1 ? (control & 0x1 ? "Ctrl" : "NoCtrl"): ""); | 620 | avail & 0x1 ? (status & 0x1 ? "On" : "Off"): "", |
621 | avail & 0x1 ? (control & 0x1 ? "Ctrl" : "NoCtrl"): ""); | ||
642 | } | 622 | } |
643 | return p - page; | 623 | return 0; |
644 | } | 624 | } |
645 | 625 | ||
646 | static int | 626 | static int version_info(struct seq_file *m) |
647 | version_info(char *page) | ||
648 | { | 627 | { |
649 | pal_version_u_t min_ver, cur_ver; | 628 | pal_version_u_t min_ver, cur_ver; |
650 | char *p = page; | ||
651 | 629 | ||
652 | if (ia64_pal_version(&min_ver, &cur_ver) != 0) | 630 | if (ia64_pal_version(&min_ver, &cur_ver) != 0) |
653 | return 0; | 631 | return 0; |
654 | 632 | ||
655 | p += sprintf(p, | 633 | seq_printf(m, |
656 | "PAL_vendor : 0x%02x (min=0x%02x)\n" | 634 | "PAL_vendor : 0x%02x (min=0x%02x)\n" |
657 | "PAL_A : %02x.%02x (min=%02x.%02x)\n" | 635 | "PAL_A : %02x.%02x (min=%02x.%02x)\n" |
658 | "PAL_B : %02x.%02x (min=%02x.%02x)\n", | 636 | "PAL_B : %02x.%02x (min=%02x.%02x)\n", |
659 | cur_ver.pal_version_s.pv_pal_vendor, | 637 | cur_ver.pal_version_s.pv_pal_vendor, |
660 | min_ver.pal_version_s.pv_pal_vendor, | 638 | min_ver.pal_version_s.pv_pal_vendor, |
661 | cur_ver.pal_version_s.pv_pal_a_model, | 639 | cur_ver.pal_version_s.pv_pal_a_model, |
662 | cur_ver.pal_version_s.pv_pal_a_rev, | 640 | cur_ver.pal_version_s.pv_pal_a_rev, |
663 | min_ver.pal_version_s.pv_pal_a_model, | 641 | min_ver.pal_version_s.pv_pal_a_model, |
664 | min_ver.pal_version_s.pv_pal_a_rev, | 642 | min_ver.pal_version_s.pv_pal_a_rev, |
665 | cur_ver.pal_version_s.pv_pal_b_model, | 643 | cur_ver.pal_version_s.pv_pal_b_model, |
666 | cur_ver.pal_version_s.pv_pal_b_rev, | 644 | cur_ver.pal_version_s.pv_pal_b_rev, |
667 | min_ver.pal_version_s.pv_pal_b_model, | 645 | min_ver.pal_version_s.pv_pal_b_model, |
668 | min_ver.pal_version_s.pv_pal_b_rev); | 646 | min_ver.pal_version_s.pv_pal_b_rev); |
669 | return p - page; | 647 | return 0; |
670 | } | 648 | } |
671 | 649 | ||
672 | static int | 650 | static int perfmon_info(struct seq_file *m) |
673 | perfmon_info(char *page) | ||
674 | { | 651 | { |
675 | char *p = page; | ||
676 | u64 pm_buffer[16]; | 652 | u64 pm_buffer[16]; |
677 | pal_perf_mon_info_u_t pm_info; | 653 | pal_perf_mon_info_u_t pm_info; |
678 | 654 | ||
679 | if (ia64_pal_perf_mon_info(pm_buffer, &pm_info) != 0) return 0; | 655 | if (ia64_pal_perf_mon_info(pm_buffer, &pm_info) != 0) |
680 | 656 | return 0; | |
681 | p += sprintf(p, | ||
682 | "PMC/PMD pairs : %d\n" | ||
683 | "Counter width : %d bits\n" | ||
684 | "Cycle event number : %d\n" | ||
685 | "Retired event number : %d\n" | ||
686 | "Implemented PMC : ", | ||
687 | pm_info.pal_perf_mon_info_s.generic, pm_info.pal_perf_mon_info_s.width, | ||
688 | pm_info.pal_perf_mon_info_s.cycles, pm_info.pal_perf_mon_info_s.retired); | ||
689 | 657 | ||
690 | p = bitregister_process(p, pm_buffer, 256); | 658 | seq_printf(m, |
691 | p += sprintf(p, "\nImplemented PMD : "); | 659 | "PMC/PMD pairs : %d\n" |
692 | p = bitregister_process(p, pm_buffer+4, 256); | 660 | "Counter width : %d bits\n" |
693 | p += sprintf(p, "\nCycles count capable : "); | 661 | "Cycle event number : %d\n" |
694 | p = bitregister_process(p, pm_buffer+8, 256); | 662 | "Retired event number : %d\n" |
695 | p += sprintf(p, "\nRetired bundles count capable : "); | 663 | "Implemented PMC : ", |
664 | pm_info.pal_perf_mon_info_s.generic, | ||
665 | pm_info.pal_perf_mon_info_s.width, | ||
666 | pm_info.pal_perf_mon_info_s.cycles, | ||
667 | pm_info.pal_perf_mon_info_s.retired); | ||
668 | |||
669 | bitregister_process(m, pm_buffer, 256); | ||
670 | seq_puts(m, "\nImplemented PMD : "); | ||
671 | bitregister_process(m, pm_buffer+4, 256); | ||
672 | seq_puts(m, "\nCycles count capable : "); | ||
673 | bitregister_process(m, pm_buffer+8, 256); | ||
674 | seq_puts(m, "\nRetired bundles count capable : "); | ||
696 | 675 | ||
697 | #ifdef CONFIG_ITANIUM | 676 | #ifdef CONFIG_ITANIUM |
698 | /* | 677 | /* |
699 | * PAL_PERF_MON_INFO reports that only PMC4 can be used to count CPU_CYCLES | 678 | * PAL_PERF_MON_INFO reports that only PMC4 can be used to count CPU_CYCLES |
700 | * which is wrong, both PMC4 and PMD5 support it. | 679 | * which is wrong, both PMC4 and PMD5 support it. |
701 | */ | 680 | */ |
702 | if (pm_buffer[12] == 0x10) pm_buffer[12]=0x30; | 681 | if (pm_buffer[12] == 0x10) |
682 | pm_buffer[12]=0x30; | ||
703 | #endif | 683 | #endif |
704 | 684 | ||
705 | p = bitregister_process(p, pm_buffer+12, 256); | 685 | bitregister_process(m, pm_buffer+12, 256); |
706 | 686 | seq_putc(m, '\n'); | |
707 | p += sprintf(p, "\n"); | 687 | return 0; |
708 | |||
709 | return p - page; | ||
710 | } | 688 | } |
711 | 689 | ||
712 | static int | 690 | static int frequency_info(struct seq_file *m) |
713 | frequency_info(char *page) | ||
714 | { | 691 | { |
715 | char *p = page; | ||
716 | struct pal_freq_ratio proc, itc, bus; | 692 | struct pal_freq_ratio proc, itc, bus; |
717 | unsigned long base; | 693 | unsigned long base; |
718 | 694 | ||
719 | if (ia64_pal_freq_base(&base) == -1) | 695 | if (ia64_pal_freq_base(&base) == -1) |
720 | p += sprintf(p, "Output clock : not implemented\n"); | 696 | seq_puts(m, "Output clock : not implemented\n"); |
721 | else | 697 | else |
722 | p += sprintf(p, "Output clock : %ld ticks/s\n", base); | 698 | seq_printf(m, "Output clock : %ld ticks/s\n", base); |
723 | 699 | ||
724 | if (ia64_pal_freq_ratios(&proc, &bus, &itc) != 0) return 0; | 700 | if (ia64_pal_freq_ratios(&proc, &bus, &itc) != 0) return 0; |
725 | 701 | ||
726 | p += sprintf(p, | 702 | seq_printf(m, |
727 | "Processor/Clock ratio : %d/%d\n" | 703 | "Processor/Clock ratio : %d/%d\n" |
728 | "Bus/Clock ratio : %d/%d\n" | 704 | "Bus/Clock ratio : %d/%d\n" |
729 | "ITC/Clock ratio : %d/%d\n", | 705 | "ITC/Clock ratio : %d/%d\n", |
730 | proc.num, proc.den, bus.num, bus.den, itc.num, itc.den); | 706 | proc.num, proc.den, bus.num, bus.den, itc.num, itc.den); |
731 | 707 | return 0; | |
732 | return p - page; | ||
733 | } | 708 | } |
734 | 709 | ||
735 | static int | 710 | static int tr_info(struct seq_file *m) |
736 | tr_info(char *page) | ||
737 | { | 711 | { |
738 | char *p = page; | ||
739 | long status; | 712 | long status; |
740 | pal_tr_valid_u_t tr_valid; | 713 | pal_tr_valid_u_t tr_valid; |
741 | u64 tr_buffer[4]; | 714 | u64 tr_buffer[4]; |
@@ -794,39 +767,40 @@ tr_info(char *page) | |||
794 | 767 | ||
795 | ifa_reg = (struct ifa_reg *)&tr_buffer[2]; | 768 | ifa_reg = (struct ifa_reg *)&tr_buffer[2]; |
796 | 769 | ||
797 | if (ifa_reg->valid == 0) continue; | 770 | if (ifa_reg->valid == 0) |
771 | continue; | ||
798 | 772 | ||
799 | gr_reg = (struct gr_reg *)tr_buffer; | 773 | gr_reg = (struct gr_reg *)tr_buffer; |
800 | itir_reg = (struct itir_reg *)&tr_buffer[1]; | 774 | itir_reg = (struct itir_reg *)&tr_buffer[1]; |
801 | rid_reg = (struct rid_reg *)&tr_buffer[3]; | 775 | rid_reg = (struct rid_reg *)&tr_buffer[3]; |
802 | 776 | ||
803 | pgm = -1 << (itir_reg->ps - 12); | 777 | pgm = -1 << (itir_reg->ps - 12); |
804 | p += sprintf(p, | 778 | seq_printf(m, |
805 | "%cTR%lu: av=%d pv=%d dv=%d mv=%d\n" | 779 | "%cTR%lu: av=%d pv=%d dv=%d mv=%d\n" |
806 | "\tppn : 0x%lx\n" | 780 | "\tppn : 0x%lx\n" |
807 | "\tvpn : 0x%lx\n" | 781 | "\tvpn : 0x%lx\n" |
808 | "\tps : ", | 782 | "\tps : ", |
809 | "ID"[i], j, | 783 | "ID"[i], j, |
810 | tr_valid.pal_tr_valid_s.access_rights_valid, | 784 | tr_valid.pal_tr_valid_s.access_rights_valid, |
811 | tr_valid.pal_tr_valid_s.priv_level_valid, | 785 | tr_valid.pal_tr_valid_s.priv_level_valid, |
812 | tr_valid.pal_tr_valid_s.dirty_bit_valid, | 786 | tr_valid.pal_tr_valid_s.dirty_bit_valid, |
813 | tr_valid.pal_tr_valid_s.mem_attr_valid, | 787 | tr_valid.pal_tr_valid_s.mem_attr_valid, |
814 | (gr_reg->ppn & pgm)<< 12, (ifa_reg->vpn & pgm)<< 12); | 788 | (gr_reg->ppn & pgm)<< 12, (ifa_reg->vpn & pgm)<< 12); |
815 | 789 | ||
816 | p = bitvector_process(p, 1<< itir_reg->ps); | 790 | bitvector_process(m, 1<< itir_reg->ps); |
817 | 791 | ||
818 | p += sprintf(p, | 792 | seq_printf(m, |
819 | "\n\tpl : %d\n" | 793 | "\n\tpl : %d\n" |
820 | "\tar : %d\n" | 794 | "\tar : %d\n" |
821 | "\trid : %x\n" | 795 | "\trid : %x\n" |
822 | "\tp : %d\n" | 796 | "\tp : %d\n" |
823 | "\tma : %d\n" | 797 | "\tma : %d\n" |
824 | "\td : %d\n", | 798 | "\td : %d\n", |
825 | gr_reg->pl, gr_reg->ar, rid_reg->rid, gr_reg->p, gr_reg->ma, | 799 | gr_reg->pl, gr_reg->ar, rid_reg->rid, gr_reg->p, gr_reg->ma, |
826 | gr_reg->d); | 800 | gr_reg->d); |
827 | } | 801 | } |
828 | } | 802 | } |
829 | return p - page; | 803 | return 0; |
830 | } | 804 | } |
831 | 805 | ||
832 | 806 | ||
@@ -834,7 +808,7 @@ tr_info(char *page) | |||
834 | /* | 808 | /* |
835 | * List {name,function} pairs for every entry in /proc/palinfo/cpu* | 809 | * List {name,function} pairs for every entry in /proc/palinfo/cpu* |
836 | */ | 810 | */ |
837 | static palinfo_entry_t palinfo_entries[]={ | 811 | static const palinfo_entry_t palinfo_entries[]={ |
838 | { "version_info", version_info, }, | 812 | { "version_info", version_info, }, |
839 | { "vm_info", vm_info, }, | 813 | { "vm_info", vm_info, }, |
840 | { "cache_info", cache_info, }, | 814 | { "cache_info", cache_info, }, |
@@ -876,7 +850,7 @@ typedef union { | |||
876 | */ | 850 | */ |
877 | typedef struct { | 851 | typedef struct { |
878 | palinfo_func_t func; /* pointer to function to call */ | 852 | palinfo_func_t func; /* pointer to function to call */ |
879 | char *page; /* buffer to store results */ | 853 | struct seq_file *m; /* buffer to store results */ |
880 | int ret; /* return value from call */ | 854 | int ret; /* return value from call */ |
881 | } palinfo_smp_data_t; | 855 | } palinfo_smp_data_t; |
882 | 856 | ||
@@ -889,7 +863,7 @@ static void | |||
889 | palinfo_smp_call(void *info) | 863 | palinfo_smp_call(void *info) |
890 | { | 864 | { |
891 | palinfo_smp_data_t *data = (palinfo_smp_data_t *)info; | 865 | palinfo_smp_data_t *data = (palinfo_smp_data_t *)info; |
892 | data->ret = (*data->func)(data->page); | 866 | data->ret = (*data->func)(data->m); |
893 | } | 867 | } |
894 | 868 | ||
895 | /* | 869 | /* |
@@ -899,13 +873,13 @@ palinfo_smp_call(void *info) | |||
899 | * otherwise how many bytes in the "page" buffer were written | 873 | * otherwise how many bytes in the "page" buffer were written |
900 | */ | 874 | */ |
901 | static | 875 | static |
902 | int palinfo_handle_smp(pal_func_cpu_u_t *f, char *page) | 876 | int palinfo_handle_smp(struct seq_file *m, pal_func_cpu_u_t *f) |
903 | { | 877 | { |
904 | palinfo_smp_data_t ptr; | 878 | palinfo_smp_data_t ptr; |
905 | int ret; | 879 | int ret; |
906 | 880 | ||
907 | ptr.func = palinfo_entries[f->func_id].proc_read; | 881 | ptr.func = palinfo_entries[f->func_id].proc_read; |
908 | ptr.page = page; | 882 | ptr.m = m; |
909 | ptr.ret = 0; /* just in case */ | 883 | ptr.ret = 0; /* just in case */ |
910 | 884 | ||
911 | 885 | ||
@@ -919,7 +893,7 @@ int palinfo_handle_smp(pal_func_cpu_u_t *f, char *page) | |||
919 | } | 893 | } |
920 | #else /* ! CONFIG_SMP */ | 894 | #else /* ! CONFIG_SMP */ |
921 | static | 895 | static |
922 | int palinfo_handle_smp(pal_func_cpu_u_t *f, char *page) | 896 | int palinfo_handle_smp(struct seq_file *m, pal_func_cpu_u_t *f) |
923 | { | 897 | { |
924 | printk(KERN_ERR "palinfo: should not be called with non SMP kernel\n"); | 898 | printk(KERN_ERR "palinfo: should not be called with non SMP kernel\n"); |
925 | return 0; | 899 | return 0; |
@@ -929,34 +903,35 @@ int palinfo_handle_smp(pal_func_cpu_u_t *f, char *page) | |||
929 | /* | 903 | /* |
930 | * Entry point routine: all calls go through this function | 904 | * Entry point routine: all calls go through this function |
931 | */ | 905 | */ |
932 | static int | 906 | static int proc_palinfo_show(struct seq_file *m, void *v) |
933 | palinfo_read_entry(char *page, char **start, off_t off, int count, int *eof, void *data) | ||
934 | { | 907 | { |
935 | int len=0; | 908 | pal_func_cpu_u_t *f = (pal_func_cpu_u_t *)&m->private; |
936 | pal_func_cpu_u_t *f = (pal_func_cpu_u_t *)&data; | ||
937 | 909 | ||
938 | /* | 910 | /* |
939 | * in SMP mode, we may need to call another CPU to get correct | 911 | * in SMP mode, we may need to call another CPU to get correct |
940 | * information. PAL, by definition, is processor specific | 912 | * information. PAL, by definition, is processor specific |
941 | */ | 913 | */ |
942 | if (f->req_cpu == get_cpu()) | 914 | if (f->req_cpu == get_cpu()) |
943 | len = (*palinfo_entries[f->func_id].proc_read)(page); | 915 | (*palinfo_entries[f->func_id].proc_read)(m); |
944 | else | 916 | else |
945 | len = palinfo_handle_smp(f, page); | 917 | palinfo_handle_smp(m, f); |
946 | 918 | ||
947 | put_cpu(); | 919 | put_cpu(); |
920 | return 0; | ||
921 | } | ||
948 | 922 | ||
949 | if (len <= off+count) *eof = 1; | 923 | static int proc_palinfo_open(struct inode *inode, struct file *file) |
950 | 924 | { | |
951 | *start = page + off; | 925 | return single_open(file, proc_palinfo_show, PDE_DATA(inode)); |
952 | len -= off; | ||
953 | |||
954 | if (len>count) len = count; | ||
955 | if (len<0) len = 0; | ||
956 | |||
957 | return len; | ||
958 | } | 926 | } |
959 | 927 | ||
928 | static const struct file_operations proc_palinfo_fops = { | ||
929 | .open = proc_palinfo_open, | ||
930 | .read = seq_read, | ||
931 | .llseek = seq_lseek, | ||
932 | .release = seq_release, | ||
933 | }; | ||
934 | |||
960 | static void __cpuinit | 935 | static void __cpuinit |
961 | create_palinfo_proc_entries(unsigned int cpu) | 936 | create_palinfo_proc_entries(unsigned int cpu) |
962 | { | 937 | { |
@@ -974,9 +949,8 @@ create_palinfo_proc_entries(unsigned int cpu) | |||
974 | 949 | ||
975 | for (j=0; j < NR_PALINFO_ENTRIES; j++) { | 950 | for (j=0; j < NR_PALINFO_ENTRIES; j++) { |
976 | f.func_id = j; | 951 | f.func_id = j; |
977 | create_proc_read_entry( | 952 | proc_create_data(palinfo_entries[j].name, 0, cpu_dir, |
978 | palinfo_entries[j].name, 0, cpu_dir, | 953 | &proc_palinfo_fops, (void *)f.value); |
979 | palinfo_read_entry, (void *)f.value); | ||
980 | } | 954 | } |
981 | } | 955 | } |
982 | 956 | ||
diff --git a/arch/ia64/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c index a97d75b9c5ec..5035245cb258 100644 --- a/arch/ia64/kernel/salinfo.c +++ b/arch/ia64/kernel/salinfo.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/cpu.h> | 40 | #include <linux/cpu.h> |
41 | #include <linux/types.h> | 41 | #include <linux/types.h> |
42 | #include <linux/proc_fs.h> | 42 | #include <linux/proc_fs.h> |
43 | #include <linux/seq_file.h> | ||
43 | #include <linux/module.h> | 44 | #include <linux/module.h> |
44 | #include <linux/smp.h> | 45 | #include <linux/smp.h> |
45 | #include <linux/timer.h> | 46 | #include <linux/timer.h> |
@@ -53,7 +54,7 @@ MODULE_AUTHOR("Jesse Barnes <jbarnes@sgi.com>"); | |||
53 | MODULE_DESCRIPTION("/proc interface to IA-64 SAL features"); | 54 | MODULE_DESCRIPTION("/proc interface to IA-64 SAL features"); |
54 | MODULE_LICENSE("GPL"); | 55 | MODULE_LICENSE("GPL"); |
55 | 56 | ||
56 | static int salinfo_read(char *page, char **start, off_t off, int count, int *eof, void *data); | 57 | static const struct file_operations proc_salinfo_fops; |
57 | 58 | ||
58 | typedef struct { | 59 | typedef struct { |
59 | const char *name; /* name of the proc entry */ | 60 | const char *name; /* name of the proc entry */ |
@@ -65,7 +66,7 @@ typedef struct { | |||
65 | * List {name,feature} pairs for every entry in /proc/sal/<feature> | 66 | * List {name,feature} pairs for every entry in /proc/sal/<feature> |
66 | * that this module exports | 67 | * that this module exports |
67 | */ | 68 | */ |
68 | static salinfo_entry_t salinfo_entries[]={ | 69 | static const salinfo_entry_t salinfo_entries[]={ |
69 | { "bus_lock", IA64_SAL_PLATFORM_FEATURE_BUS_LOCK, }, | 70 | { "bus_lock", IA64_SAL_PLATFORM_FEATURE_BUS_LOCK, }, |
70 | { "irq_redirection", IA64_SAL_PLATFORM_FEATURE_IRQ_REDIR_HINT, }, | 71 | { "irq_redirection", IA64_SAL_PLATFORM_FEATURE_IRQ_REDIR_HINT, }, |
71 | { "ipi_redirection", IA64_SAL_PLATFORM_FEATURE_IPI_REDIR_HINT, }, | 72 | { "ipi_redirection", IA64_SAL_PLATFORM_FEATURE_IPI_REDIR_HINT, }, |
@@ -629,8 +630,9 @@ salinfo_init(void) | |||
629 | 630 | ||
630 | for (i=0; i < NR_SALINFO_ENTRIES; i++) { | 631 | for (i=0; i < NR_SALINFO_ENTRIES; i++) { |
631 | /* pass the feature bit in question as misc data */ | 632 | /* pass the feature bit in question as misc data */ |
632 | *sdir++ = create_proc_read_entry (salinfo_entries[i].name, 0, salinfo_dir, | 633 | *sdir++ = proc_create_data(salinfo_entries[i].name, 0, salinfo_dir, |
633 | salinfo_read, (void *)salinfo_entries[i].feature); | 634 | &proc_salinfo_fops, |
635 | (void *)salinfo_entries[i].feature); | ||
634 | } | 636 | } |
635 | 637 | ||
636 | for (i = 0; i < ARRAY_SIZE(salinfo_log_name); i++) { | 638 | for (i = 0; i < ARRAY_SIZE(salinfo_log_name); i++) { |
@@ -676,22 +678,23 @@ salinfo_init(void) | |||
676 | * 'data' contains an integer that corresponds to the feature we're | 678 | * 'data' contains an integer that corresponds to the feature we're |
677 | * testing | 679 | * testing |
678 | */ | 680 | */ |
679 | static int | 681 | static int proc_salinfo_show(struct seq_file *m, void *v) |
680 | salinfo_read(char *page, char **start, off_t off, int count, int *eof, void *data) | ||
681 | { | 682 | { |
682 | int len = 0; | 683 | unsigned long data = (unsigned long)v; |
683 | 684 | seq_puts(m, (sal_platform_features & data) ? "1\n" : "0\n"); | |
684 | len = sprintf(page, (sal_platform_features & (unsigned long)data) ? "1\n" : "0\n"); | 685 | return 0; |
685 | 686 | } | |
686 | if (len <= off+count) *eof = 1; | ||
687 | |||
688 | *start = page + off; | ||
689 | len -= off; | ||
690 | |||
691 | if (len>count) len = count; | ||
692 | if (len<0) len = 0; | ||
693 | 687 | ||
694 | return len; | 688 | static int proc_salinfo_open(struct inode *inode, struct file *file) |
689 | { | ||
690 | return single_open(file, proc_salinfo_show, PDE_DATA(inode)); | ||
695 | } | 691 | } |
696 | 692 | ||
693 | static const struct file_operations proc_salinfo_fops = { | ||
694 | .open = proc_salinfo_open, | ||
695 | .read = seq_read, | ||
696 | .llseek = seq_lseek, | ||
697 | .release = seq_release, | ||
698 | }; | ||
699 | |||
697 | module_init(salinfo_init); | 700 | module_init(salinfo_init); |
diff --git a/arch/ia64/sn/kernel/sn2/prominfo_proc.c b/arch/ia64/sn/kernel/sn2/prominfo_proc.c index 90298bda936a..daa8d6badb16 100644 --- a/arch/ia64/sn/kernel/sn2/prominfo_proc.c +++ b/arch/ia64/sn/kernel/sn2/prominfo_proc.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
13 | #include <linux/proc_fs.h> | 13 | #include <linux/proc_fs.h> |
14 | #include <linux/seq_file.h> | ||
14 | #include <linux/nodemask.h> | 15 | #include <linux/nodemask.h> |
15 | #include <asm/io.h> | 16 | #include <asm/io.h> |
16 | #include <asm/sn/sn_sal.h> | 17 | #include <asm/sn/sn_sal.h> |
@@ -101,18 +102,18 @@ get_fit_entry(unsigned long nasid, int index, unsigned long *fentry, | |||
101 | /* | 102 | /* |
102 | * These two routines display the FIT table for each node. | 103 | * These two routines display the FIT table for each node. |
103 | */ | 104 | */ |
104 | static int dump_fit_entry(char *page, unsigned long *fentry) | 105 | static void dump_fit_entry(struct seq_file *m, unsigned long *fentry) |
105 | { | 106 | { |
106 | unsigned type; | 107 | unsigned type; |
107 | 108 | ||
108 | type = FIT_TYPE(fentry[1]); | 109 | type = FIT_TYPE(fentry[1]); |
109 | return sprintf(page, "%02x %-25s %x.%02x %016lx %u\n", | 110 | seq_printf(m, "%02x %-25s %x.%02x %016lx %u\n", |
110 | type, | 111 | type, |
111 | fit_type_name(type), | 112 | fit_type_name(type), |
112 | FIT_MAJOR(fentry[1]), FIT_MINOR(fentry[1]), | 113 | FIT_MAJOR(fentry[1]), FIT_MINOR(fentry[1]), |
113 | fentry[0], | 114 | fentry[0], |
114 | /* mult by sixteen to get size in bytes */ | 115 | /* mult by sixteen to get size in bytes */ |
115 | (unsigned)(fentry[1] & 0xffffff) * 16); | 116 | (unsigned)(fentry[1] & 0xffffff) * 16); |
116 | } | 117 | } |
117 | 118 | ||
118 | 119 | ||
@@ -124,31 +125,39 @@ static int dump_fit_entry(char *page, unsigned long *fentry) | |||
124 | * OK except for 4kB pages (and no one is going to do that on SN | 125 | * OK except for 4kB pages (and no one is going to do that on SN |
125 | * anyway). | 126 | * anyway). |
126 | */ | 127 | */ |
127 | static int | 128 | static int proc_fit_show(struct seq_file *m, void *v) |
128 | dump_fit(char *page, unsigned long nasid) | ||
129 | { | 129 | { |
130 | unsigned long nasid = (unsigned long)m->private; | ||
130 | unsigned long fentry[2]; | 131 | unsigned long fentry[2]; |
131 | int index; | 132 | int index; |
132 | char *p; | ||
133 | 133 | ||
134 | p = page; | ||
135 | for (index=0;;index++) { | 134 | for (index=0;;index++) { |
136 | BUG_ON(index * 60 > PAGE_SIZE); | 135 | BUG_ON(index * 60 > PAGE_SIZE); |
137 | if (get_fit_entry(nasid, index, fentry, NULL, 0)) | 136 | if (get_fit_entry(nasid, index, fentry, NULL, 0)) |
138 | break; | 137 | break; |
139 | p += dump_fit_entry(p, fentry); | 138 | dump_fit_entry(m, fentry); |
140 | } | 139 | } |
140 | return 0; | ||
141 | } | ||
141 | 142 | ||
142 | return p - page; | 143 | static int proc_fit_open(struct inode *inode, struct file *file) |
144 | { | ||
145 | return single_open(file, proc_fit_show, PDE_DATA(inode)); | ||
143 | } | 146 | } |
144 | 147 | ||
145 | static int | 148 | static const struct file_operations proc_fit_fops = { |
146 | dump_version(char *page, unsigned long nasid) | 149 | .open = proc_fit_open, |
150 | .read = seq_read, | ||
151 | .llseek = seq_lseek, | ||
152 | .release = seq_release, | ||
153 | }; | ||
154 | |||
155 | static int proc_version_show(struct seq_file *m, void *v) | ||
147 | { | 156 | { |
157 | unsigned long nasid = (unsigned long)m->private; | ||
148 | unsigned long fentry[2]; | 158 | unsigned long fentry[2]; |
149 | char banner[128]; | 159 | char banner[128]; |
150 | int index; | 160 | int index; |
151 | int len; | ||
152 | 161 | ||
153 | for (index = 0; ; index++) { | 162 | for (index = 0; ; index++) { |
154 | if (get_fit_entry(nasid, index, fentry, banner, | 163 | if (get_fit_entry(nasid, index, fentry, banner, |
@@ -158,56 +167,24 @@ dump_version(char *page, unsigned long nasid) | |||
158 | break; | 167 | break; |
159 | } | 168 | } |
160 | 169 | ||
161 | len = sprintf(page, "%x.%02x\n", FIT_MAJOR(fentry[1]), | 170 | seq_printf(m, "%x.%02x\n", FIT_MAJOR(fentry[1]), FIT_MINOR(fentry[1])); |
162 | FIT_MINOR(fentry[1])); | ||
163 | page += len; | ||
164 | 171 | ||
165 | if (banner[0]) | 172 | if (banner[0]) |
166 | len += snprintf(page, PAGE_SIZE-len, "%s\n", banner); | 173 | seq_printf(m, "%s\n", banner); |
167 | 174 | return 0; | |
168 | return len; | ||
169 | } | ||
170 | |||
171 | /* same as in proc_misc.c */ | ||
172 | static int | ||
173 | proc_calc_metrics(char *page, char **start, off_t off, int count, int *eof, | ||
174 | int len) | ||
175 | { | ||
176 | if (len <= off + count) | ||
177 | *eof = 1; | ||
178 | *start = page + off; | ||
179 | len -= off; | ||
180 | if (len > count) | ||
181 | len = count; | ||
182 | if (len < 0) | ||
183 | len = 0; | ||
184 | return len; | ||
185 | } | 175 | } |
186 | 176 | ||
187 | static int | 177 | static int proc_version_open(struct inode *inode, struct file *file) |
188 | read_version_entry(char *page, char **start, off_t off, int count, int *eof, | ||
189 | void *data) | ||
190 | { | 178 | { |
191 | int len; | 179 | return single_open(file, proc_version_show, PDE_DATA(inode)); |
192 | |||
193 | /* data holds the NASID of the node */ | ||
194 | len = dump_version(page, (unsigned long)data); | ||
195 | len = proc_calc_metrics(page, start, off, count, eof, len); | ||
196 | return len; | ||
197 | } | 180 | } |
198 | 181 | ||
199 | static int | 182 | static const struct file_operations proc_version_fops = { |
200 | read_fit_entry(char *page, char **start, off_t off, int count, int *eof, | 183 | .open = proc_version_open, |
201 | void *data) | 184 | .read = seq_read, |
202 | { | 185 | .llseek = seq_lseek, |
203 | int len; | 186 | .release = seq_release, |
204 | 187 | }; | |
205 | /* data holds the NASID of the node */ | ||
206 | len = dump_fit(page, (unsigned long)data); | ||
207 | len = proc_calc_metrics(page, start, off, count, eof, len); | ||
208 | |||
209 | return len; | ||
210 | } | ||
211 | 188 | ||
212 | /* module entry points */ | 189 | /* module entry points */ |
213 | int __init prominfo_init(void); | 190 | int __init prominfo_init(void); |
@@ -216,12 +193,11 @@ void __exit prominfo_exit(void); | |||
216 | module_init(prominfo_init); | 193 | module_init(prominfo_init); |
217 | module_exit(prominfo_exit); | 194 | module_exit(prominfo_exit); |
218 | 195 | ||
219 | static struct proc_dir_entry *sgi_prominfo_entry; | ||
220 | |||
221 | #define NODE_NAME_LEN 11 | 196 | #define NODE_NAME_LEN 11 |
222 | 197 | ||
223 | int __init prominfo_init(void) | 198 | int __init prominfo_init(void) |
224 | { | 199 | { |
200 | struct proc_dir_entry *sgi_prominfo_entry; | ||
225 | cnodeid_t cnodeid; | 201 | cnodeid_t cnodeid; |
226 | 202 | ||
227 | if (!ia64_platform_is("sn2")) | 203 | if (!ia64_platform_is("sn2")) |
@@ -241,10 +217,10 @@ int __init prominfo_init(void) | |||
241 | if (!dir) | 217 | if (!dir) |
242 | continue; | 218 | continue; |
243 | nasid = cnodeid_to_nasid(cnodeid); | 219 | nasid = cnodeid_to_nasid(cnodeid); |
244 | create_proc_read_entry("fit", 0, dir, read_fit_entry, | 220 | proc_create_data("fit", 0, dir, |
245 | (void *)nasid); | 221 | &proc_fit_fops, (void *)nasid); |
246 | create_proc_read_entry("version", 0, dir, | 222 | proc_create_data("version", 0, dir, |
247 | read_version_entry, (void *)nasid); | 223 | &proc_version_fops, (void *)nasid); |
248 | } | 224 | } |
249 | return 0; | 225 | return 0; |
250 | } | 226 | } |