vserver 1.9.3
[linux-2.6.git] / arch / ia64 / sn / kernel / sn2 / sn_proc_fs.c
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 2000-2004 Silicon Graphics, Inc. All rights reserved.
7  */
8 #include <linux/config.h>
9 #include <asm/uaccess.h>
10
11 #ifdef CONFIG_PROC_FS
12 #include <linux/proc_fs.h>
13 #include <linux/seq_file.h>
14 #include <asm/sn/sgi.h>
15 #include <asm/sn/sn_sal.h>
16
17 static int partition_id_show(struct seq_file *s, void *p)
18 {
19         seq_printf(s, "%d\n", sn_local_partid());
20         return 0;
21 }
22
23 static int partition_id_open(struct inode *inode, struct file *file)
24 {
25         return single_open(file, partition_id_show, NULL);
26 }
27
28 static int system_serial_number_show(struct seq_file *s, void *p)
29 {
30         seq_printf(s, "%s\n", sn_system_serial_number());
31         return 0;
32 }
33
34 static int system_serial_number_open(struct inode *inode, struct file *file)
35 {
36         return single_open(file, system_serial_number_show, NULL);
37 }
38
39 static int licenseID_show(struct seq_file *s, void *p)
40 {
41         seq_printf(s, "0x%lx\n", sn_partition_serial_number_val());
42         return 0;
43 }
44
45 static int licenseID_open(struct inode *inode, struct file *file)
46 {
47         return single_open(file, licenseID_show, NULL);
48 }
49
50 /*
51  * Enable forced interrupt by default.
52  * When set, the sn interrupt handler writes the force interrupt register on
53  * the bridge chip.  The hardware will then send an interrupt message if the
54  * interrupt line is active.  This mimics a level sensitive interrupt.
55  */
56 int sn_force_interrupt_flag = 1;
57
58 static int sn_force_interrupt_show(struct seq_file *s, void *p)
59 {
60         seq_printf(s, "Force interrupt is %s\n",
61                 sn_force_interrupt_flag ? "enabled" : "disabled");
62         return 0;
63 }
64
65 static ssize_t sn_force_interrupt_write_proc(struct file *file,
66                 const __user char *buffer, size_t count, loff_t *data)
67 {
68         sn_force_interrupt_flag = (*buffer == '0') ? 0 : 1;
69         return count;
70 }
71
72 static int sn_force_interrupt_open(struct inode *inode, struct file *file)
73 {
74         return single_open(file, sn_force_interrupt_show, NULL);
75 }
76
77 static int coherence_id_show(struct seq_file *s, void *p)
78 {
79         seq_printf(s, "%d\n", cpuid_to_coherence_id(smp_processor_id()));
80         return 0;
81 }
82
83 static int coherence_id_open(struct inode *inode, struct file *file)
84 {
85         return single_open(file, coherence_id_show, NULL);
86 }
87
88 static struct proc_dir_entry *sn_procfs_create_entry(
89         const char *name, struct proc_dir_entry *parent,
90         int (*openfunc)(struct inode *, struct file *),
91         int (*releasefunc)(struct inode *, struct file *))
92 {
93         struct proc_dir_entry *e = create_proc_entry(name, 0444, parent);
94
95         if (e) {
96                 e->proc_fops = (struct file_operations *)kmalloc(
97                         sizeof(struct file_operations), GFP_KERNEL);
98                 if (e->proc_fops) {
99                         memset(e->proc_fops, 0, sizeof(struct file_operations));
100                         e->proc_fops->open = openfunc;
101                         e->proc_fops->read = seq_read;
102                         e->proc_fops->llseek = seq_lseek;
103                         e->proc_fops->release = releasefunc;
104                 }
105         }
106
107         return e;
108 }
109
110 /* /proc/sgi_sn/sn_topology uses seq_file, see sn_hwperf.c */
111 extern int sn_topology_open(struct inode *, struct file *);
112 extern int sn_topology_release(struct inode *, struct file *);
113
114 void register_sn_procfs(void)
115 {
116         static struct proc_dir_entry *sgi_proc_dir = NULL;
117         struct proc_dir_entry *e;
118
119         BUG_ON(sgi_proc_dir != NULL);
120         if (!(sgi_proc_dir = proc_mkdir("sgi_sn", 0)))
121                 return;
122
123         sn_procfs_create_entry("partition_id", sgi_proc_dir,
124                 partition_id_open, single_release);
125
126         sn_procfs_create_entry("system_serial_number", sgi_proc_dir,
127                 system_serial_number_open, single_release);
128
129         sn_procfs_create_entry("licenseID", sgi_proc_dir, 
130                 licenseID_open, single_release);
131
132         e = sn_procfs_create_entry("sn_force_interrupt", sgi_proc_dir, 
133                 sn_force_interrupt_open, single_release);
134         if (e) 
135                 e->proc_fops->write = sn_force_interrupt_write_proc;
136
137         sn_procfs_create_entry("coherence_id", sgi_proc_dir, 
138                 coherence_id_open, single_release);
139         
140         sn_procfs_create_entry("sn_topology", sgi_proc_dir,
141                 sn_topology_open, sn_topology_release);
142 }
143
144 #endif /* CONFIG_PROC_FS */