1
/* Copyright (C) 2004-2005 SBE, Inc.
3
* This program is free software; you can redistribute it and/or modify
4
* it under the terms of the GNU General Public License as published by
5
* the Free Software Foundation; either version 2 of the License, or
6
* (at your option) any later version.
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU General Public License for more details.
14
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
16
#include <linux/types.h>
17
#include <linux/module.h>
18
#include <linux/errno.h>
19
#include <linux/kernel.h>
20
#include <linux/init.h>
21
#include <linux/proc_fs.h>
22
#include <linux/sched.h>
23
#include <asm/uaccess.h>
24
#include "pmcc4_sysdep.h"
25
#include "sbecom_inline_linux.h"
26
#include "pmcc4_private.h"
30
void sbecom_get_brdinfo (ci_t *, struct sbe_brd_info *, u_int8_t *);
31
extern struct s_hdw_info hdw_info[MAX_BOARDS];
35
/********************************************************************/
37
/********************************************************************/
41
sbecom_proc_brd_cleanup (ci_t * ci)
45
char dir[7 + SBE_IFACETMPL_SIZE + 1];
46
snprintf(dir, sizeof(dir), "driver/%s", ci->devname);
47
remove_proc_entry("info", ci->dir_dev);
48
remove_proc_entry(dir, NULL);
55
sbecom_proc_get_sbe_info (char *buffer, char **start, off_t offset,
56
int length, int *eof, void *priv)
58
ci_t *ci = (ci_t *) priv;
61
struct sbe_brd_info *bip;
63
if (!(bip = OS_kmalloc (sizeof (struct sbe_brd_info))))
69
pr_info(">> sbecom_proc_get_sbe_info: entered, offset %d. length %d.\n",
70
(int) offset, (int) length);
74
hdw_info_t *hi = &hdw_info[ci->brdno];
80
case PROM_FORMAT_TYPE1:
81
bsn = (u_int8_t *) hi->mfg_info.pft1.Serial;
83
case PROM_FORMAT_TYPE2:
84
bsn = (u_int8_t *) hi->mfg_info.pft2.Serial;
88
sbecom_get_brdinfo (ci, bip, bsn);
93
pr_info(">> sbecom_get_brdinfo: returned, first_if %p <%s> last_if %p <%s>\n",
94
(char *) &bip->first_iname, (char *) &bip->first_iname,
95
(char *) &bip->last_iname, (char *) &bip->last_iname);
97
len += sprintf (buffer + len, "Board Type: ");
100
case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T3):
101
len += sprintf (buffer + len, "wanPMC-C1T3");
103
case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1):
104
len += sprintf (buffer + len, "wanPTMC-256T3 <E1>");
106
case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1):
107
len += sprintf (buffer + len, "wanPTMC-256T3 <T1>");
109
case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_C24TE1):
110
len += sprintf (buffer + len, "wanPTMC-C24TE1");
113
case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1):
114
case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1_L):
115
len += sprintf (buffer + len, "wanPMC-C4T1E1");
117
case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1):
118
case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1_L):
119
len += sprintf (buffer + len, "wanPMC-C2T1E1");
121
case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1):
122
case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1_L):
123
len += sprintf (buffer + len, "wanPMC-C1T1E1");
126
case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1):
127
len += sprintf (buffer + len, "wanPCI-C4T1E1");
129
case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1):
130
len += sprintf (buffer + len, "wanPCI-C2T1E1");
132
case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1):
133
len += sprintf (buffer + len, "wanPCI-C1T1E1");
137
len += sprintf (buffer + len, "unknown");
140
len += sprintf (buffer + len, " [%08X]\n", bip->brd_id);
142
len += sprintf (buffer + len, "Board Number: %d\n", bip->brdno);
143
len += sprintf (buffer + len, "Hardware ID: 0x%02X\n", ci->hdw_bid);
144
len += sprintf (buffer + len, "Board SN: %06X\n", bip->brd_sn);
145
len += sprintf(buffer + len, "Board MAC: %pMF\n",
147
len += sprintf (buffer + len, "Ports: %d\n", ci->max_port);
148
len += sprintf (buffer + len, "Channels: %d\n", bip->brd_chan_cnt);
150
len += sprintf (buffer + len, "Interface: %s -> %s\n",
151
(char *) &bip->first_iname, (char *) &bip->last_iname);
153
len += sprintf (buffer + len, "Interface: <not available> 1st %p lst %p\n",
154
(char *) &bip->first_iname, (char *) &bip->last_iname);
157
switch (bip->brd_pci_speed)
159
case BINFO_PCI_SPEED_33:
162
case BINFO_PCI_SPEED_66:
166
spd = "<not available>";
169
len += sprintf (buffer + len, "PCI Bus Speed: %s\n", spd);
170
len += sprintf (buffer + len, "Release: %s\n", ci->release);
172
#ifdef SBE_PMCC4_ENABLE
174
extern int cxt1e1_max_mru;
176
extern int max_chans_used;
177
extern int cxt1e1_max_mtu;
179
extern int max_rxdesc_used, max_txdesc_used;
181
len += sprintf (buffer + len, "\ncxt1e1_max_mru: %d\n", cxt1e1_max_mru);
183
len += sprintf (buffer + len, "\nmax_chans_used: %d\n", max_chans_used);
184
len += sprintf (buffer + len, "cxt1e1_max_mtu: %d\n", cxt1e1_max_mtu);
186
len += sprintf (buffer + len, "max_rxdesc_used: %d\n", max_rxdesc_used);
187
len += sprintf (buffer + len, "max_txdesc_used: %d\n", max_txdesc_used);
191
OS_kfree (bip); /* cleanup */
194
* How to be a proc read function
195
* ------------------------------
197
* int f(char *buffer, char **start, off_t offset,
198
* int count, int *peof, void *dat)
200
* Assume that the buffer is "count" bytes in size.
202
* If you know you have supplied all the data you
205
* You have three ways to return data:
206
* 0) Leave *start = NULL. (This is the default.)
207
* Put the data of the requested offset at that
208
* offset within the buffer. Return the number (n)
209
* of bytes there are from the beginning of the
210
* buffer up to the last byte of data. If the
211
* number of supplied bytes (= n - offset) is
212
* greater than zero and you didn't signal eof
213
* and the reader is prepared to take more data
214
* you will be called again with the requested
215
* offset advanced by the number of bytes
216
* absorbed. This interface is useful for files
217
* no larger than the buffer.
218
* 1) Set *start = an unsigned long value less than
219
* the buffer address but greater than zero.
220
* Put the data of the requested offset at the
221
* beginning of the buffer. Return the number of
222
* bytes of data placed there. If this number is
223
* greater than zero and you didn't signal eof
224
* and the reader is prepared to take more data
225
* you will be called again with the requested
226
* offset advanced by *start. This interface is
227
* useful when you have a large file consisting
228
* of a series of blocks which you want to count
229
* and return as wholes.
230
* (Hack by Paul.Russell@rustcorp.com.au)
231
* 2) Set *start = an address within the buffer.
232
* Put the data of the requested offset at *start.
233
* Return the number of bytes of data placed there.
234
* If this number is greater than zero and you
235
* didn't signal eof and the reader is prepared to
236
* take more data you will be called again with the
237
* requested offset advanced by the number of bytes
242
/* #4 - interpretation of above = set EOF, return len */
248
* #1 - from net/wireless/atmel.c RLD NOTE -there's something wrong with
249
* this plagarized code which results in this routine being called TWICE.
250
* The second call returns ZERO, resulting in hidden failure, but at
251
* least only a single message set is being displayed.
253
if (len <= offset + length)
255
*start = buffer + offset;
263
#if 0 /* #2 from net/tokenring/olympic.c +
277
*start = buffer + (offset - begin); /* Start of wanted data */
278
len -= (offset - begin); /* Start slop */
280
len = length; /* Ending slop */
285
* char/ftape/lowlevel/ftape-proc.c */
286
len = strlen (buffer);
288
if (offset + length >= len)
295
pr_info(">> proc_fs: returned len = %d., start %p\n", len, start); /* RLD DEBUG */
299
using NONE: returns = 314.314.314.
300
using #1 : returns = 314, 0.
301
using #2 : returns = 314, 0, 0.
302
using #3 : returns = 314, 314.
303
using #4 : returns = 314, 314.
309
/* initialize the /proc subsystem for the specific SBE driver */
312
sbecom_proc_brd_init (ci_t * ci)
314
struct proc_dir_entry *e;
315
char dir[7 + SBE_IFACETMPL_SIZE + 1];
317
/* create a directory in the root procfs */
318
snprintf(dir, sizeof(dir), "driver/%s", ci->devname);
319
ci->dir_dev = proc_mkdir(dir, NULL);
322
pr_err("Unable to create directory /proc/driver/%s\n", ci->devname);
325
e = create_proc_read_entry ("info", S_IFREG | S_IRUGO,
326
ci->dir_dev, sbecom_proc_get_sbe_info, ci);
329
pr_err("Unable to create entry /proc/driver/%s/info\n", ci->devname);
335
sbecom_proc_brd_cleanup (ci);
339
#else /*** ! CONFIG_PROC_FS ***/
341
/* stubbed off dummy routines */
344
sbecom_proc_brd_cleanup (ci_t * ci)
349
sbecom_proc_brd_init (ci_t * ci)
354
#endif /*** CONFIG_PROC_FS ***/
357
/*** End-of-File ***/