sbeproc.c 11 KB

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