]> rtime.felk.cvut.cz Git - socketcan-devel.git/blob - kernel/2.6/drivers/net/can/sja1000/proc.c
changed indentation to 8, other white space changes.
[socketcan-devel.git] / kernel / 2.6 / drivers / net / can / sja1000 / proc.c
1 /*
2  * $Id$
3  *
4  * proc.c -  proc file system functions for SJA1000 CAN driver.
5  *
6  * Copyright (c) 2002-2005 Volkswagen Group Electronic Research
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions, the following disclaimer and
14  *    the referenced file 'COPYING'.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of Volkswagen nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * Alternatively, provided that this notice is retained in full, this
23  * software may be distributed under the terms of the GNU General
24  * Public License ("GPL") version 2 as distributed in the 'COPYING'
25  * file from the main directory of the linux kernel source.
26  *
27  * The provided data structures and external interfaces from this code
28  * are not restricted to be used by modules with a GPL compatible license.
29  *
30  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
34  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
36  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
40  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
41  * DAMAGE.
42  *
43  * Send feedback to <llcf@volkswagen.de>
44  *
45  */
46
47 #include <linux/module.h>
48
49 #include <linux/slab.h>
50 #include <linux/proc_fs.h>
51 #include <linux/netdevice.h>
52
53 #include <linux/can/can.h>
54 #include <linux/can/can_ioctl.h>
55 #include "sja1000.h"
56
57 static struct proc_dir_entry *pde       = NULL;
58 static struct proc_dir_entry *pde_regs  = NULL;
59 static struct proc_dir_entry *pde_reset = NULL;
60
61 static struct net_device **can_dev;
62 static int max_devices;
63
64 static int sja1000_proc_read(char *page, char **start, off_t off,
65                              int count, int *eof, void *data)
66 {
67         int len = 0;
68         struct net_device *dev;
69         int i;
70         struct can_priv *priv;
71         unsigned char stat;
72
73         len += snprintf(page + len, PAGE_SIZE - len, "CAN bus device statistics:\n");
74         len += snprintf(page + len, PAGE_SIZE - len, "       errwarn  overrun   wakeup   buserr   errpass  arbitr   restarts clock        baud\n");
75         for (i = 0; (i < max_devices) && (len < PAGE_SIZE - 200); i++) {
76                 if (can_dev[i]) {
77                         dev = can_dev[i];
78                         stat = REG_READ(REG_SR);
79                         priv = netdev_priv(can_dev[i]);
80                         len += snprintf(page + len, PAGE_SIZE - len, "can%d: %8d %8d %8d %8d %8d %8d %8d %10d %8d\n", i,
81                                         priv->can_stats.error_warning,
82                                         priv->can_stats.data_overrun,
83                                         priv->can_stats.wakeup,
84                                         priv->can_stats.bus_error,
85                                         priv->can_stats.error_passive,
86                                         priv->can_stats.arbitration_lost,
87                                         priv->can_stats.restarts,
88                                         priv->clock,
89                                         priv->speed
90                                 );
91                         if (stat & 0x80) {
92                                 len += snprintf(page + len, PAGE_SIZE - len,
93                                         "can%d: bus status: BUS OFF, ", i);
94                         } else if (stat & 0x40) {
95                                 len += snprintf(page + len, PAGE_SIZE - len,
96                                         "can%d: bus status: ERROR PASSIVE, ", i);
97                         } else {
98                                 len += snprintf(page + len, PAGE_SIZE - len,
99                                         "can%d: bus status: OK, ", i);
100                         }
101                         len += snprintf(page + len, PAGE_SIZE - len,
102                                         "RXERR: %d, TXERR: %d\n",
103                                         REG_READ(REG_RXERR),
104                                         REG_READ(REG_TXERR));
105                 }
106         }
107
108         *eof = 1;
109         return len;
110 }
111
112 static int sja1000_proc_read_regs(char *page, char **start, off_t off,
113                                   int count, int *eof, void *data)
114 {
115         int len = 0;
116         struct net_device *dev;
117         int i;
118         struct can_priv   *priv;
119
120         len = sprintf(page, "SJA1000 registers:\n");
121         for (i = 0; (i < max_devices) && (len < PAGE_SIZE - 200); i++) {
122                 if (can_dev[i]) {
123                         dev = can_dev[i];
124                         len += snprintf(page + len, PAGE_SIZE - len,
125                                         "can%d SJA1000 registers:\n", i);
126
127                         priv = netdev_priv(can_dev[i]);
128                         len += snprintf(page + len, PAGE_SIZE - len, "00: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
129                                         REG_READ(0x00),
130                                         REG_READ(0x01),
131                                         REG_READ(0x02),
132                                         REG_READ(0x03),
133                                         REG_READ(0x04),
134                                         REG_READ(0x05),
135                                         REG_READ(0x06),
136                                         REG_READ(0x07),
137                                         REG_READ(0x08),
138                                         REG_READ(0x09),
139                                         REG_READ(0x0a),
140                                         REG_READ(0x0b),
141                                         REG_READ(0x0c),
142                                         REG_READ(0x0d),
143                                         REG_READ(0x0e),
144                                         REG_READ(0x0f)
145                                 );
146                         len += snprintf(page + len, PAGE_SIZE - len, "10: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
147                                         REG_READ(0x10),
148                                         REG_READ(0x11),
149                                         REG_READ(0x12),
150                                         REG_READ(0x13),
151                                         REG_READ(0x14),
152                                         REG_READ(0x15),
153                                         REG_READ(0x16),
154                                         REG_READ(0x17),
155                                         REG_READ(0x18),
156                                         REG_READ(0x19),
157                                         REG_READ(0x1a),
158                                         REG_READ(0x1b),
159                                         REG_READ(0x1c),
160                                         REG_READ(0x1d),
161                                         REG_READ(0x1e),
162                                         REG_READ(0x1f)
163                                 );
164                 }
165         }
166
167         *eof = 1;
168         return len;
169 }
170
171 static int sja1000_proc_read_reset(char *page, char **start, off_t off,
172                                    int count, int *eof, void *data)
173 {
174         int len = 0;
175         struct net_device *dev;
176         int i;
177         struct can_priv   *priv;
178
179         len += snprintf(page + len, PAGE_SIZE - len, "resetting ");
180         for (i = 0; (i < max_devices) && (len < PAGE_SIZE - 200); i++) {
181                 if (can_dev[i]) {
182                         dev = can_dev[i];
183                         priv = netdev_priv(can_dev[i]);
184                         if ((priv->state != STATE_UNINITIALIZED)
185                             && (priv->state != STATE_RESET_MODE)) {
186                                 len += snprintf(page + len, PAGE_SIZE - len,
187                                                 "%s ", dev->name);
188                                 dev->stop(dev);
189                                 dev->open(dev);
190                                 /* count number of restarts */
191                                 priv->can_stats.restarts++;
192
193                         } else {
194                                 len += snprintf(page + len, PAGE_SIZE - len,
195                                                 "(%s|%d) ", dev->name,
196                                                 priv->state);
197                         }
198                 }
199         }
200
201         len += snprintf(page + len, PAGE_SIZE - len, "done\n");
202
203         *eof = 1;
204         return len;
205 }
206
207 void sja1000_proc_init(const char *drv_name, struct net_device **dev, int max)
208 {
209         char fname[256];
210
211         can_dev     = dev;
212         max_devices = max;
213
214         if (pde == NULL) {
215                 sprintf(fname, PROCBASE "/%s", drv_name);
216                 pde = create_proc_read_entry(fname, 0644, NULL,
217                                              sja1000_proc_read, NULL);
218         }
219         if (pde_regs == NULL) {
220                 sprintf(fname, PROCBASE "/%s_regs", drv_name);
221                 pde_regs = create_proc_read_entry(fname, 0644, NULL,
222                                                 sja1000_proc_read_regs, NULL);
223         }
224         if (pde_reset == NULL) {
225                 sprintf(fname, PROCBASE "/%s_reset", drv_name);
226                 pde_reset = create_proc_read_entry(fname, 0644, NULL,
227                                                 sja1000_proc_read_reset, NULL);
228         }
229 }
230
231 void sja1000_proc_delete(const char *drv_name)
232 {
233         char fname[256];
234
235         if (pde) {
236                 sprintf(fname, PROCBASE "/%s", drv_name);
237                 remove_proc_entry(fname, NULL);
238         }
239         if (pde_regs) {
240                 sprintf(fname, PROCBASE "/%s_regs", drv_name);
241                 remove_proc_entry(fname, NULL);
242         }
243         if (pde_reset) {
244                 sprintf(fname, PROCBASE "/%s_reset", drv_name);
245                 remove_proc_entry(fname, NULL);
246         }
247 }