Staging: staging/cxt1e1: Convert bare printks to pr_<level>
[safe/jmp/linux-2.6] / drivers / staging / cxt1e1 / sbeproc.c
1 /* Copyright (C) 2004-2005  SBE, Inc.
2  *
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.
7  *
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.
12  */
13
14 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
15
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"
27 #include "sbeproc.h"
28
29 /* forwards */
30 void        sbecom_get_brdinfo (ci_t *, struct sbe_brd_info *, u_int8_t *);
31 extern struct s_hdw_info hdw_info[MAX_BOARDS];
32
33 #ifdef CONFIG_PROC_FS
34
35 /********************************************************************/
36 /* procfs stuff                                                     */
37 /********************************************************************/
38
39
40 void
41 sbecom_proc_brd_cleanup (ci_t * ci)
42 {
43     if (ci->dir_dev)
44     {
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);
49         ci->dir_dev = NULL;
50     }
51 }
52
53
54 static int
55 sbecom_proc_get_sbe_info (char *buffer, char **start, off_t offset,
56                           int length, int *eof, void *priv)
57 {
58     ci_t       *ci = (ci_t *) priv;
59     int         len = 0;
60     char       *spd;
61     struct sbe_brd_info *bip;
62
63     if (!(bip = OS_kmalloc (sizeof (struct sbe_brd_info))))
64     {
65         return -ENOMEM;
66     }
67 #if 0
68     /** RLD DEBUG **/
69     pr_info(">> sbecom_proc_get_sbe_info: entered, offset %d. length %d.\n",
70             (int) offset, (int) length);
71 #endif
72
73     {
74         hdw_info_t *hi = &hdw_info[ci->brdno];
75
76         u_int8_t *bsn = 0;
77
78         switch (hi->promfmt)
79         {
80         case PROM_FORMAT_TYPE1:
81             bsn = (u_int8_t *) hi->mfg_info.pft1.Serial;
82             break;
83         case PROM_FORMAT_TYPE2:
84             bsn = (u_int8_t *) hi->mfg_info.pft2.Serial;
85             break;
86         }
87
88         sbecom_get_brdinfo (ci, bip, bsn);
89     }
90
91 #if 0
92     /** RLD DEBUG **/
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);
96 #endif
97     len += sprintf (buffer + len, "Board Type:    ");
98     switch (bip->brd_id)
99     {
100     case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T3):
101         len += sprintf (buffer + len, "wanPMC-C1T3");
102         break;
103     case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1):
104         len += sprintf (buffer + len, "wanPTMC-256T3 <E1>");
105         break;
106     case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1):
107         len += sprintf (buffer + len, "wanPTMC-256T3 <T1>");
108         break;
109     case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_C24TE1):
110         len += sprintf (buffer + len, "wanPTMC-C24TE1");
111         break;
112
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");
116         break;
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");
120         break;
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");
124         break;
125
126     case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1):
127         len += sprintf (buffer + len, "wanPCI-C4T1E1");
128         break;
129     case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1):
130         len += sprintf (buffer + len, "wanPCI-C2T1E1");
131         break;
132     case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1):
133         len += sprintf (buffer + len, "wanPCI-C1T1E1");
134         break;
135
136     default:
137         len += sprintf (buffer + len, "unknown");
138         break;
139     }
140     len += sprintf (buffer + len, "  [%08X]\n", bip->brd_id);
141
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:     %02X-%02X-%02X-%02X-%02X-%02X\n",
146            bip->brd_mac_addr[0], bip->brd_mac_addr[1], bip->brd_mac_addr[2],
147           bip->brd_mac_addr[3], bip->brd_mac_addr[4], bip->brd_mac_addr[5]);
148     len += sprintf (buffer + len, "Ports:         %d\n", ci->max_port);
149     len += sprintf (buffer + len, "Channels:      %d\n", bip->brd_chan_cnt);
150 #if 1
151     len += sprintf (buffer + len, "Interface:     %s -> %s\n",
152                     (char *) &bip->first_iname, (char *) &bip->last_iname);
153 #else
154     len += sprintf (buffer + len, "Interface:     <not available> 1st %p lst %p\n",
155                     (char *) &bip->first_iname, (char *) &bip->last_iname);
156 #endif
157
158     switch (bip->brd_pci_speed)
159     {
160     case BINFO_PCI_SPEED_33:
161         spd = "33Mhz";
162         break;
163     case BINFO_PCI_SPEED_66:
164         spd = "66Mhz";
165         break;
166     default:
167         spd = "<not available>";
168         break;
169     }
170     len += sprintf (buffer + len, "PCI Bus Speed: %s\n", spd);
171     len += sprintf (buffer + len, "Release:       %s\n", ci->release);
172
173 #ifdef SBE_PMCC4_ENABLE
174     {
175         extern int max_mru;
176 #if 0
177         extern int max_chans_used;
178         extern int max_mtu;
179 #endif
180         extern int max_rxdesc_used, max_txdesc_used;
181
182         len += sprintf (buffer + len, "\nmax_mru:         %d\n", max_mru);
183 #if 0
184         len += sprintf (buffer + len, "\nmax_chans_used:  %d\n", max_chans_used);
185         len += sprintf (buffer + len, "max_mtu:         %d\n", max_mtu);
186 #endif
187         len += sprintf (buffer + len, "max_rxdesc_used: %d\n", max_rxdesc_used);
188         len += sprintf (buffer + len, "max_txdesc_used: %d\n", max_txdesc_used);
189     }
190 #endif
191
192     OS_kfree (bip);                 /* cleanup */
193
194     /***
195      * How to be a proc read function
196      * ------------------------------
197      * Prototype:
198      *    int f(char *buffer, char **start, off_t offset,
199      *          int count, int *peof, void *dat)
200      *
201      * Assume that the buffer is "count" bytes in size.
202      *
203      * If you know you have supplied all the data you
204      * have, set *peof.
205      *
206      * You have three ways to return data:
207      * 0) Leave *start = NULL.  (This is the default.)
208      *    Put the data of the requested offset at that
209      *    offset within the buffer.  Return the number (n)
210      *    of bytes there are from the beginning of the
211      *    buffer up to the last byte of data.  If the
212      *    number of supplied bytes (= n - offset) is
213      *    greater than zero and you didn't signal eof
214      *    and the reader is prepared to take more data
215      *    you will be called again with the requested
216      *    offset advanced by the number of bytes
217      *    absorbed.  This interface is useful for files
218      *    no larger than the buffer.
219      * 1) Set *start = an unsigned long value less than
220      *    the buffer address but greater than zero.
221      *    Put the data of the requested offset at the
222      *    beginning of the buffer.  Return the number of
223      *    bytes of data placed there.  If this number is
224      *    greater than zero and you didn't signal eof
225      *    and the reader is prepared to take more data
226      *    you will be called again with the requested
227      *    offset advanced by *start.  This interface is
228      *    useful when you have a large file consisting
229      *    of a series of blocks which you want to count
230      *    and return as wholes.
231      *    (Hack by Paul.Russell@rustcorp.com.au)
232      * 2) Set *start = an address within the buffer.
233      *    Put the data of the requested offset at *start.
234      *    Return the number of bytes of data placed there.
235      *    If this number is greater than zero and you
236      *    didn't signal eof and the reader is prepared to
237      *    take more data you will be called again with the
238      *    requested offset advanced by the number of bytes
239      *    absorbed.
240      */
241
242 #if 1
243     /* #4 - intepretation of above = set EOF, return len */
244     *eof = 1;
245 #endif
246
247 #if 0
248     /*
249      * #1 - from net/wireless/atmel.c RLD NOTE -there's something wrong with
250      * this plagarized code which results in this routine being called TWICE.
251      * The second call returns ZERO, resulting in hidden failure, but at
252      * least only a single message set is being displayed.
253      */
254     if (len <= offset + length)
255         *eof = 1;
256     *start = buffer + offset;
257     len -= offset;
258     if (len > length)
259         len = length;
260     if (len < 0)
261         len = 0;
262 #endif
263
264 #if 0                               /* #2 from net/tokenring/olympic.c +
265                                      * lanstreamer.c */
266     {
267         off_t       begin = 0;
268         int         size = 0;
269         off_t       pos = 0;
270
271         size = len;
272         pos = begin + size;
273         if (pos < offset)
274         {
275             len = 0;
276             begin = pos;
277         }
278         *start = buffer + (offset - begin);     /* Start of wanted data */
279         len -= (offset - begin);    /* Start slop */
280         if (len > length)
281             len = length;           /* Ending slop */
282     }
283 #endif
284
285 #if 0                               /* #3 from
286                                      * char/ftape/lowlevel/ftape-proc.c */
287     len = strlen (buffer);
288     *start = NULL;
289     if (offset + length >= len)
290         *eof = 1;
291     else
292         *eof = 0;
293 #endif
294
295 #if 0
296     pr_info(">> proc_fs: returned len = %d., start %p\n", len, start);  /* RLD DEBUG */
297 #endif
298
299 /***
300    using NONE: returns = 314.314.314.
301    using #1  : returns = 314, 0.
302    using #2  : returns = 314, 0, 0.
303    using #3  : returns = 314, 314.
304    using #4  : returns = 314, 314.
305 ***/
306
307     return len;
308 }
309
310 /* initialize the /proc subsystem for the specific SBE driver */
311
312 int         __init
313 sbecom_proc_brd_init (ci_t * ci)
314 {
315     struct proc_dir_entry *e;
316     char dir[7 + SBE_IFACETMPL_SIZE + 1];
317
318     /* create a directory in the root procfs */
319     snprintf(dir, sizeof(dir), "driver/%s", ci->devname);
320     ci->dir_dev = proc_mkdir(dir, NULL);
321     if (!ci->dir_dev)
322     {
323         pr_err("Unable to create directory /proc/driver/%s\n", ci->devname);
324         goto fail;
325     }
326     e = create_proc_read_entry ("info", S_IFREG | S_IRUGO,
327                                 ci->dir_dev, sbecom_proc_get_sbe_info, ci);
328     if (!e)
329     {
330         pr_err("Unable to create entry /proc/driver/%s/info\n", ci->devname);
331         goto fail;
332     }
333     return 0;
334
335 fail:
336     sbecom_proc_brd_cleanup (ci);
337     return 1;
338 }
339
340 #else                           /*** ! CONFIG_PROC_FS ***/
341
342 /* stubbed off dummy routines */
343
344 void
345 sbecom_proc_brd_cleanup (ci_t * ci)
346 {
347 }
348
349 int         __init
350 sbecom_proc_brd_init (ci_t * ci)
351 {
352     return 0;
353 }
354
355 #endif                          /*** CONFIG_PROC_FS ***/
356
357
358 /*** End-of-File ***/