4ec8d5192374cb74a87b84659d4db6cd19e28190
[linux-flexiantxendom0-3.2.10.git] / arch / ia64 / kernel / salinfo.c
1 /*
2  * salinfo.c
3  *
4  * Creates entries in /proc/sal for various system features.
5  *
6  * Copyright (c) 2001 Silicon Graphics, Inc.  All rights reserved.
7  *
8  * 10/30/2001   jbarnes@sgi.com         copied much of Stephane's palinfo
9  *                                      code to create this file
10  */
11
12 #include <linux/types.h>
13 #include <linux/proc_fs.h>
14 #include <linux/module.h>
15
16 #include <asm/sal.h>
17
18 MODULE_AUTHOR("Jesse Barnes <jbarnes@sgi.com>");
19 MODULE_DESCRIPTION("/proc interface to IA-64 SAL features");
20 MODULE_LICENSE("GPL");
21
22 static int salinfo_read(char *page, char **start, off_t off, int count, int *eof, void *data);
23
24 typedef struct {
25         const char              *name;          /* name of the proc entry */
26         unsigned long           feature;        /* feature bit */
27         struct proc_dir_entry   *entry;         /* registered entry (removal) */
28 } salinfo_entry_t;
29
30 /*
31  * List {name,feature} pairs for every entry in /proc/sal/<feature>
32  * that this module exports
33  */
34 static salinfo_entry_t salinfo_entries[]={
35         { "bus_lock",           IA64_SAL_PLATFORM_FEATURE_BUS_LOCK, },
36         { "irq_redirection",    IA64_SAL_PLATFORM_FEATURE_IRQ_REDIR_HINT, },
37         { "ipi_redirection",    IA64_SAL_PLATFORM_FEATURE_IPI_REDIR_HINT, },
38         { "itc_drift",          IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT, },
39 };
40
41 #define NR_SALINFO_ENTRIES (sizeof(salinfo_entries)/sizeof(salinfo_entry_t))
42
43 /*
44  * One for each feature and one more for the directory entry...
45  */
46 static struct proc_dir_entry *salinfo_proc_entries[NR_SALINFO_ENTRIES + 1];
47
48 static int __init
49 salinfo_init(void)
50 {
51         struct proc_dir_entry *salinfo_dir; /* /proc/sal dir entry */
52         struct proc_dir_entry **sdir = salinfo_proc_entries; /* keeps track of every entry */
53         int i;
54
55         salinfo_dir = proc_mkdir("sal", NULL);
56
57         for (i=0; i < NR_SALINFO_ENTRIES; i++) {
58                 /* pass the feature bit in question as misc data */
59                 *sdir = create_proc_read_entry (salinfo_entries[i].name, 0, salinfo_dir,
60                                                   salinfo_read, (void *)salinfo_entries[i].feature);
61                 if (*sdir)
62                         *sdir->owner = THIS_MODULE;
63                 sdir++;
64         }
65         *sdir++ = salinfo_dir;
66
67         return 0;
68 }
69
70 static void __exit
71 salinfo_exit(void)
72 {
73         int i = 0;
74
75         for (i = 0; i < NR_SALINFO_ENTRIES ; i++) {
76                 if (salinfo_proc_entries[i])
77                         remove_proc_entry (salinfo_proc_entries[i]->name, NULL);
78         }
79 }
80
81 /*
82  * 'data' contains an integer that corresponds to the feature we're
83  * testing
84  */
85 static int
86 salinfo_read(char *page, char **start, off_t off, int count, int *eof, void *data)
87 {
88         int len = 0;
89
90         len = sprintf(page, (sal_platform_features & (unsigned long)data) ? "1\n" : "0\n");
91
92         if (len <= off+count) *eof = 1;
93
94         *start = page + off;
95         len   -= off;
96
97         if (len>count) len = count;
98         if (len<0) len = 0;
99
100         return len;
101 }
102
103 module_init(salinfo_init);
104 module_exit(salinfo_exit);