4 * proc.c - proc file system functions for SJA1000 CAN driver.
6 * Copyright (c) 2002-2005 Volkswagen Group Electronic Research
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
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.
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.
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
43 * Send feedback to <llcf@volkswagen.de>
47 #include <linux/module.h>
49 #include <linux/slab.h>
50 #include <linux/proc_fs.h>
51 #include <linux/netdevice.h>
53 #include <linux/can/can.h>
54 #include <linux/can/can_ioctl.h>
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;
61 static struct net_device **can_dev;
62 static int max_devices;
64 static int sja1000_proc_read(char *page, char **start, off_t off,
65 int count, int *eof, void *data)
68 struct net_device *dev;
70 struct can_priv *priv;
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++) {
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,
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);
98 len += snprintf(page + len, PAGE_SIZE - len,
99 "can%d: bus status: OK, ", i);
101 len += snprintf(page + len, PAGE_SIZE - len,
102 "RXERR: %d, TXERR: %d\n",
104 REG_READ(REG_TXERR));
112 static int sja1000_proc_read_regs(char *page, char **start, off_t off,
113 int count, int *eof, void *data)
116 struct net_device *dev;
118 struct can_priv *priv;
120 len = sprintf(page, "SJA1000 registers:\n");
121 for (i = 0; (i < max_devices) && (len < PAGE_SIZE - 200); i++) {
124 len += snprintf(page + len, PAGE_SIZE - len,
125 "can%d SJA1000 registers:\n", i);
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",
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",
171 static int sja1000_proc_read_reset(char *page, char **start, off_t off,
172 int count, int *eof, void *data)
175 struct net_device *dev;
177 struct can_priv *priv;
179 len += snprintf(page + len, PAGE_SIZE - len, "resetting ");
180 for (i = 0; (i < max_devices) && (len < PAGE_SIZE - 200); 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,
190 /* count number of restarts */
191 priv->can_stats.restarts++;
194 len += snprintf(page + len, PAGE_SIZE - len,
195 "(%s|%d) ", dev->name,
201 len += snprintf(page + len, PAGE_SIZE - len, "done\n");
207 void sja1000_proc_init(const char *drv_name, struct net_device **dev, int max)
215 sprintf(fname, PROCBASE "/%s", drv_name);
216 pde = create_proc_read_entry(fname, 0644, NULL,
217 sja1000_proc_read, NULL);
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);
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);
231 void sja1000_proc_delete(const char *drv_name)
236 sprintf(fname, PROCBASE "/%s", drv_name);
237 remove_proc_entry(fname, NULL);
240 sprintf(fname, PROCBASE "/%s_regs", drv_name);
241 remove_proc_entry(fname, NULL);
244 sprintf(fname, PROCBASE "/%s_reset", drv_name);
245 remove_proc_entry(fname, NULL);