aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/sibyte/sb1250/bus_watcher.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/sibyte/sb1250/bus_watcher.c')
-rw-r--r--arch/mips/sibyte/sb1250/bus_watcher.c81
1 files changed, 37 insertions, 44 deletions
diff --git a/arch/mips/sibyte/sb1250/bus_watcher.c b/arch/mips/sibyte/sb1250/bus_watcher.c
index e651105b3f0b..cb1e3cb37d70 100644
--- a/arch/mips/sibyte/sb1250/bus_watcher.c
+++ b/arch/mips/sibyte/sb1250/bus_watcher.c
@@ -30,6 +30,7 @@
30#include <linux/interrupt.h> 30#include <linux/interrupt.h>
31#include <linux/sched.h> 31#include <linux/sched.h>
32#include <linux/proc_fs.h> 32#include <linux/proc_fs.h>
33#include <linux/seq_file.h>
33#include <asm/io.h> 34#include <asm/io.h>
34 35
35#include <asm/sibyte/sb1250.h> 36#include <asm/sibyte/sb1250.h>
@@ -99,63 +100,60 @@ void check_bus_watcher(void)
99 printk("Bus watcher indicates no error\n"); 100 printk("Bus watcher indicates no error\n");
100} 101}
101 102
102static int bw_print_buffer(char *page, struct bw_stats_struct *stats) 103#ifdef CONFIG_PROC_FS
104
105/* For simplicity, I want to assume a single read is required each
106 time */
107static int bw_proc_show(struct seq_file *m, void *v)
103{ 108{
104 int len; 109 struct bw_stats_struct *stats = m->private;
105 110
106 len = sprintf(page, "SiByte Bus Watcher statistics\n"); 111 seq_puts(m, "SiByte Bus Watcher statistics\n");
107 len += sprintf(page+len, "-----------------------------\n"); 112 seq_puts(m, "-----------------------------\n");
108 len += sprintf(page+len, "L2-d-cor %8ld\nL2-d-bad %8ld\n", 113 seq_printf(m, "L2-d-cor %8ld\nL2-d-bad %8ld\n",
109 stats->l2_cor_d, stats->l2_bad_d); 114 stats->l2_cor_d, stats->l2_bad_d);
110 len += sprintf(page+len, "L2-t-cor %8ld\nL2-t-bad %8ld\n", 115 seq_printf(m, "L2-t-cor %8ld\nL2-t-bad %8ld\n",
111 stats->l2_cor_t, stats->l2_bad_t); 116 stats->l2_cor_t, stats->l2_bad_t);
112 len += sprintf(page+len, "MC-d-cor %8ld\nMC-d-bad %8ld\n", 117 seq_printf(m, "MC-d-cor %8ld\nMC-d-bad %8ld\n",
113 stats->mem_cor_d, stats->mem_bad_d); 118 stats->mem_cor_d, stats->mem_bad_d);
114 len += sprintf(page+len, "IO-err %8ld\n", stats->bus_error); 119 seq_printf(m, "IO-err %8ld\n", stats->bus_error);
115 len += sprintf(page+len, "\nLast recorded signature:\n"); 120 seq_puts(m, "\nLast recorded signature:\n");
116 len += sprintf(page+len, "Request %02x from %d, answered by %d with Dcode %d\n", 121 seq_printf(m, "Request %02x from %d, answered by %d with Dcode %d\n",
117 (unsigned int)(G_SCD_BERR_TID(stats->status) & 0x3f), 122 (unsigned int)(G_SCD_BERR_TID(stats->status) & 0x3f),
118 (int)(G_SCD_BERR_TID(stats->status) >> 6), 123 (int)(G_SCD_BERR_TID(stats->status) >> 6),
119 (int)G_SCD_BERR_RID(stats->status), 124 (int)G_SCD_BERR_RID(stats->status),
120 (int)G_SCD_BERR_DCODE(stats->status)); 125 (int)G_SCD_BERR_DCODE(stats->status));
121 /* XXXKW indicate multiple errors between printings, or stats 126 /* XXXKW indicate multiple errors between printings, or stats
122 collection (or both)? */ 127 collection (or both)? */
123 if (stats->status & M_SCD_BERR_MULTERRS) 128 if (stats->status & M_SCD_BERR_MULTERRS)
124 len += sprintf(page+len, "Multiple errors observed since last check.\n"); 129 seq_puts(m, "Multiple errors observed since last check.\n");
125 if (stats->status_printed) { 130 if (stats->status_printed) {
126 len += sprintf(page+len, "(no change since last printing)\n"); 131 seq_puts(m, "(no change since last printing)\n");
127 } else { 132 } else {
128 stats->status_printed = 1; 133 stats->status_printed = 1;
129 } 134 }
130 135
131 return len; 136 return 0;
132} 137}
133 138
134#ifdef CONFIG_PROC_FS 139static int bw_proc_open(struct inode *inode, struct file *file)
135
136/* For simplicity, I want to assume a single read is required each
137 time */
138static int bw_read_proc(char *page, char **start, off_t off,
139 int count, int *eof, void *data)
140{ 140{
141 int len; 141 return single_open(file, bw_proc_show, PDE_DATA(inode));
142
143 if (off == 0) {
144 len = bw_print_buffer(page, data);
145 *start = page;
146 } else {
147 len = 0;
148 *eof = 1;
149 }
150 return len;
151} 142}
152 143
144static const struct file_operations bw_proc_fops = {
145 .open = bw_proc_open,
146 .read = seq_read,
147 .llseek = seq_lseek,
148 .release = seq_release,
149};
150
153static void create_proc_decoder(struct bw_stats_struct *stats) 151static void create_proc_decoder(struct bw_stats_struct *stats)
154{ 152{
155 struct proc_dir_entry *ent; 153 struct proc_dir_entry *ent;
156 154
157 ent = create_proc_read_entry("bus_watcher", S_IWUSR | S_IRUGO, NULL, 155 ent = proc_create_data("bus_watcher", S_IWUSR | S_IRUGO, NULL,
158 bw_read_proc, stats); 156 &bw_proc_fops, stats);
159 if (!ent) { 157 if (!ent) {
160 printk(KERN_INFO "Unable to initialize bus_watcher /proc entry\n"); 158 printk(KERN_INFO "Unable to initialize bus_watcher /proc entry\n");
161 return; 159 return;
@@ -210,11 +208,6 @@ static irqreturn_t sibyte_bw_int(int irq, void *data)
210 stats->bus_error += G_SCD_MEM_BUSERR(cntr); 208 stats->bus_error += G_SCD_MEM_BUSERR(cntr);
211 csr_out32(0, IOADDR(A_BUS_MEM_IO_ERRORS)); 209 csr_out32(0, IOADDR(A_BUS_MEM_IO_ERRORS));
212 210
213#ifndef CONFIG_PROC_FS
214 bw_print_buffer(bw_buf, stats);
215 printk(bw_buf);
216#endif
217
218 return IRQ_HANDLED; 211 return IRQ_HANDLED;
219} 212}
220 213