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 ***/