1 /*****************************************************************************
2 * wanproc.c WAN Router Module. /proc filesystem interface.
4 * This module is completely hardware-independent and provides
5 * access to the router using Linux /proc filesystem.
9 * Copyright: (c) 1995-1999 Sangoma Technologies Inc.
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version
14 * 2 of the License, or (at your option) any later version.
15 * ============================================================================
16 * Jun 02, 1999 Gideon Hack Updates for Linux 2.2.X kernels.
17 * Jun 29, 1997 Alan Cox Merged with 1.0.3 vendor code
18 * Jan 29, 1997 Gene Kozin v1.0.1. Implemented /proc read routines
19 * Jan 30, 1997 Alan Cox Hacked around for 2.1
20 * Dec 13, 1996 Gene Kozin Initial version (based on Sangoma's WANPIPE)
21 *****************************************************************************/
23 #include <linux/version.h>
24 #include <linux/config.h>
25 #include <linux/stddef.h> /* offsetof(), etc. */
26 #include <linux/errno.h> /* return codes */
27 #include <linux/kernel.h>
28 #include <linux/slab.h> /* kmalloc(), kfree() */
29 #include <linux/mm.h> /* verify_area(), etc. */
30 #include <linux/string.h> /* inline mem*, str* functions */
31 #include <asm/byteorder.h> /* htons(), etc. */
33 #include <linux/wanrouter.h> /* WAN router API definitions */
37 #if defined(LINUX_2_1) || defined(LINUX_2_4)
38 #include <linux/init.h> /* __initfunc et al. */
39 #include <asm/uaccess.h> /* copy_to_user */
40 #define PROC_STATS_FORMAT "%30s: %12lu\n"
42 #define PROC_STATS_FORMAT "%30s: %12u\n"
43 #include <asm/segment.h> /* kernel <-> user copy */
47 /****** Defines and Macros **************************************************/
49 #define PROC_BUFSZ 4000 /* buffer size for printing proc info */
51 #define PROT_DECODE(prot) ((prot == WANCONFIG_FR) ? " FR" :\
52 (prot == WANCONFIG_X25) ? " X25" : \
53 (prot == WANCONFIG_PPP) ? " PPP" : \
54 (prot == WANCONFIG_CHDLC) ? " CHDLC": \
55 (prot == WANCONFIG_MPPP) ? " MPPP" : \
58 /****** Data Types **********************************************************/
60 typedef struct wan_stat_entry
62 struct wan_stat_entry *next;
63 char *description; /* description string */
64 void *data; /* -> data */
65 unsigned data_type; /* data type */
68 /****** Function Prototypes *************************************************/
73 #ifdef LINUX_2_4 /* Start of LINUX 2.4.X code */
76 /* Proc filesystem interface */
77 static int router_proc_perms(struct inode *, int);
78 static ssize_t router_proc_read(struct file* file, char* buf, size_t count, loff_t *ppos);
80 /* Methods for preparing data for reading proc entries */
82 static int config_get_info(char* buf, char** start, off_t offs, int len);
83 static int status_get_info(char* buf, char** start, off_t offs, int len);
84 static int wandev_get_info(char* buf, char** start, off_t offs, int len);
89 * Structures for interfacing with the /proc filesystem.
90 * Router creates its own directory /proc/net/router with the folowing
92 * config device configuration
93 * status global device statistics
94 * <device> entry for each WAN device
98 * Generic /proc/net/router/<file> file and inode operations
100 static struct file_operations router_fops =
102 read: router_proc_read,
105 static struct inode_operations router_inode =
107 permission: router_proc_perms,
111 * /proc/net/router/<device> file operations
114 static struct file_operations wandev_fops =
116 read: router_proc_read,
117 ioctl: wanrouter_ioctl,
124 static struct proc_dir_entry *proc_router;
127 static char conf_hdr[] =
128 "Device name | port |IRQ|DMA| mem.addr |mem.size|"
129 "option1|option2|option3|option4\n";
131 static char stat_hdr[] =
132 "Device name |protocol|station|interface|clocking|baud rate"
133 "| MTU |ndev|link state\n";
137 * Interface functions
141 * Initialize router proc interface.
144 int __init wanrouter_proc_init (void)
146 struct proc_dir_entry *p;
147 proc_router = proc_mkdir(ROUTER_NAME, proc_net);
151 p = create_proc_entry("config",0,proc_router);
154 p->proc_fops = &router_fops;
155 p->proc_iops = &router_inode;
156 p->get_info = config_get_info;
157 p = create_proc_entry("status",0,proc_router);
160 p->proc_fops = &router_fops;
161 p->proc_iops = &router_inode;
162 p->get_info = status_get_info;
165 remove_proc_entry("config", proc_router);
167 remove_proc_entry(ROUTER_NAME, proc_net);
173 * Clean up router proc interface.
176 void wanrouter_proc_cleanup (void)
178 remove_proc_entry("config", proc_router);
179 remove_proc_entry("status", proc_router);
180 remove_proc_entry(ROUTER_NAME,proc_net);
184 * Add directory entry for WAN device.
187 int wanrouter_proc_add (wan_device_t* wandev)
189 if (wandev->magic != ROUTER_MAGIC)
192 wandev->dent = create_proc_entry(wandev->name, 0, proc_router);
195 wandev->dent->proc_fops = &wandev_fops;
196 wandev->dent->proc_iops = &router_inode;
197 wandev->dent->get_info = wandev_get_info;
198 wandev->dent->data = wandev;
203 * Delete directory entry for WAN device.
206 int wanrouter_proc_delete(wan_device_t* wandev)
208 if (wandev->magic != ROUTER_MAGIC)
210 remove_proc_entry(wandev->name, proc_router);
214 /****** Proc filesystem entry points ****************************************/
217 * Verify access rights.
220 static int router_proc_perms (struct inode* inode, int op)
226 * Read router proc directory entry.
227 * This is universal routine for reading all entries in /proc/net/wanrouter
228 * directory. Each directory entry contains a pointer to the 'method' for
229 * preparing data for that entry.
231 * o allocate kernel buffer
232 * o call get_info() to prepare data
233 * o copy data to user space
234 * o release kernel buffer
236 * Return: number of bytes copied to user space (0, if no data)
240 static ssize_t router_proc_read(struct file* file, char* buf, size_t count,
243 struct inode *inode = file->f_dentry->d_inode;
244 struct proc_dir_entry* dent;
253 dent = inode->u.generic_ip;
254 if ((dent == NULL) || (dent->get_info == NULL))
257 page = kmalloc(PROC_BUFSZ, GFP_KERNEL);
261 pos = dent->get_info(page, dent->data, 0, 0);
262 if (offs == n && offs < pos) {
263 len = min_t(unsigned int, pos - offs, count);
264 if (copy_to_user(buf, (page + offs), len)) {
277 * Prepare data for reading 'Config' entry.
278 * Return length of data.
281 static int config_get_info(char* buf, char** start, off_t offs, int len)
283 int cnt = sizeof(conf_hdr) - 1;
284 wan_device_t* wandev;
285 strcpy(buf, conf_hdr);
286 for (wandev = router_devlist;
287 wandev && (cnt < (PROC_BUFSZ - 120));
288 wandev = wandev->next) {
289 if (wandev->state) cnt += sprintf(&buf[cnt],
290 "%-15s|0x%-4X|%3u|%3u| 0x%-8lX |0x%-6X|%7u|%7u|%7u|%7u\n",
307 * Prepare data for reading 'Status' entry.
308 * Return length of data.
311 static int status_get_info(char* buf, char** start, off_t offs, int len)
314 wan_device_t* wandev;
316 //cnt += sprintf(&buf[cnt], "\nSTATUS:\n\n");
317 strcpy(&buf[cnt], stat_hdr);
318 cnt += sizeof(stat_hdr) - 1;
320 for (wandev = router_devlist;
321 wandev && (cnt < (PROC_BUFSZ - 80));
322 wandev = wandev->next) {
323 if (!wandev->state) continue;
324 cnt += sprintf(&buf[cnt],
325 "%-15s|%-8s|%-7s|%-9s|%-8s|%9u|%5u|%3u |",
327 PROT_DECODE(wandev->config_id),
328 wandev->config_id == WANCONFIG_FR ?
329 (wandev->station ? " Node" : " CPE") :
330 (wandev->config_id == WANCONFIG_X25 ?
331 (wandev->station ? " DCE" : " DTE") :
333 wandev->interface ? " V.35" : " RS-232",
334 wandev->clocking ? "internal" : "external",
339 switch (wandev->state) {
341 case WAN_UNCONFIGURED:
342 cnt += sprintf(&buf[cnt], "%-12s\n", "unconfigured");
345 case WAN_DISCONNECTED:
346 cnt += sprintf(&buf[cnt], "%-12s\n", "disconnected");
350 cnt += sprintf(&buf[cnt], "%-12s\n", "connecting");
354 cnt += sprintf(&buf[cnt], "%-12s\n", "connected");
358 cnt += sprintf(&buf[cnt], "%-12s\n", "invalid");
366 * Prepare data for reading <device> entry.
367 * Return length of data.
369 * On entry, the 'start' argument will contain a pointer to WAN device
373 static int wandev_get_info(char* buf, char** start, off_t offs, int len)
375 wan_device_t* wandev = (void*)start;
379 if ((wandev == NULL) || (wandev->magic != ROUTER_MAGIC))
382 return sprintf(&buf[cnt], "device is not configured!\n");
384 /* Update device statistics */
385 if (wandev->update) {
387 rslt = wandev->update(wandev);
391 return sprintf(&buf[cnt], "Device is busy!\n");
394 return sprintf(&buf[cnt],
395 "Device is not configured!\n");
400 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
401 "total packets received", wandev->stats.rx_packets);
402 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
403 "total packets transmitted", wandev->stats.tx_packets);
404 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
405 "total bytes received", wandev->stats.rx_bytes);
406 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
407 "total bytes transmitted", wandev->stats.tx_bytes);
408 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
409 "bad packets received", wandev->stats.rx_errors);
410 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
411 "packet transmit problems", wandev->stats.tx_errors);
412 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
413 "received frames dropped", wandev->stats.rx_dropped);
414 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
415 "transmit frames dropped", wandev->stats.tx_dropped);
416 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
417 "multicast packets received", wandev->stats.multicast);
418 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
419 "transmit collisions", wandev->stats.collisions);
420 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
421 "receive length errors", wandev->stats.rx_length_errors);
422 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
423 "receiver overrun errors", wandev->stats.rx_over_errors);
424 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
425 "CRC errors", wandev->stats.rx_crc_errors);
426 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
427 "frame format errors (aborts)", wandev->stats.rx_frame_errors);
428 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
429 "receiver fifo overrun", wandev->stats.rx_fifo_errors);
430 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
431 "receiver missed packet", wandev->stats.rx_missed_errors);
432 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
433 "aborted frames transmitted", wandev->stats.tx_aborted_errors);
438 #else /* ------------------- END OF LINUX 2.4.X VERSION -------------*/
442 /* Proc filesystem interface */
443 static int router_proc_perms(struct inode *, int);
445 static ssize_t router_proc_read(struct file *file, char *buf, size_t count, loff_t *ppos);
447 static int router_proc_read(
448 struct inode* inode, struct file* file, char* buf, int count);
449 static int device_write(
450 struct inode* inode, struct file* file, const char* buf, int count);
453 /* Methods for preparing data for reading proc entries */
454 static int config_get_info(char* buf, char** start, off_t offs, int len,
456 static int status_get_info(char* buf, char** start, off_t offs, int len,
458 static int wandev_get_info(char* buf, char** start, off_t offs, int len,
468 * Names of the proc directory entries
471 static char name_root[] = ROUTER_NAME;
472 static char name_conf[] = "config";
473 static char name_stat[] = "status";
476 * Structures for interfacing with the /proc filesystem.
477 * Router creates its own directory /proc/net/router with the folowing
479 * config device configuration
480 * status global device statistics
481 * <device> entry for each WAN device
485 * Generic /proc/net/router/<file> file and inode operations
488 static struct file_operations router_fops =
491 router_proc_read, /* read */
497 NULL, /* no special open code */
499 NULL, /* no special release code */
500 NULL /* can't fsync */
503 static struct file_operations router_fops =
506 router_proc_read, /* read */
512 NULL, /* no special open code */
513 NULL, /* no special release code */
514 NULL /* can't fsync */
518 static struct inode_operations router_inode =
530 NULL, /* follow link */
533 NULL, /* writepage */
540 * /proc/net/router/<device> file and inode operations
544 static struct file_operations wandev_fops =
547 router_proc_read, /* read */
551 wanrouter_ioctl, /* ioctl */
553 NULL, /* no special open code */
555 NULL, /* no special release code */
556 NULL /* can't fsync */
559 static struct file_operations wandev_fops =
562 router_proc_read, /* read */
563 device_write, /* write */
566 wanrouter_ioctl, /* ioctl */
568 NULL, /* no special open code */
569 NULL, /* no special release code */
570 NULL /* can't fsync */
574 static struct inode_operations wandev_inode =
587 NULL, /* follow_link */
589 NULL, /* writepage */
596 * Proc filesystem derectory entries.
603 static struct proc_dir_entry proc_router =
606 sizeof(name_root) - 1, /* .namelen */
607 name_root, /* .name */
608 0555 | S_IFDIR, /* .mode */
613 &proc_dir_inode_operations, /* .ops */
614 NULL, /* .get_info */
615 NULL, /* .fill_node */
623 * /proc/net/router/config
626 static struct proc_dir_entry proc_router_conf =
629 sizeof(name_conf) - 1, /* .namelen */
630 name_conf, /* .name */
631 0444 | S_IFREG, /* .mode */
636 &router_inode, /* .ops */
637 &config_get_info, /* .get_info */
638 NULL, /* .fill_node */
646 * /proc/net/router/status
649 static struct proc_dir_entry proc_router_stat =
652 sizeof(name_stat) - 1, /* .namelen */
653 name_stat, /* .name */
654 0444 | S_IFREG, /* .mode */
659 &router_inode, /* .ops */
660 status_get_info, /* .get_info */
661 NULL, /* .fill_node */
669 static char conf_hdr[] =
670 "Device name | port |IRQ|DMA| mem.addr |mem.size|"
671 "option1|option2|option3|option4\n";
673 static char stat_hdr[] =
674 "Device name |protocol|station|interface|clocking|baud rate| MTU |ndev"
679 * Interface functions
683 * Initialize router proc interface.
687 __initfunc(int wanrouter_proc_init (void))
689 int err = proc_register(proc_net, &proc_router);
692 proc_register(&proc_router, &proc_router_conf);
693 proc_register(&proc_router, &proc_router_stat);
698 int wanrouter_proc_init (void)
700 int err = proc_register_dynamic(&proc_net, &proc_router);
703 proc_register_dynamic(&proc_router, &proc_router_conf);
704 proc_register_dynamic(&proc_router, &proc_router_stat);
711 * Clean up router proc interface.
714 void wanrouter_proc_cleanup (void)
716 proc_unregister(&proc_router, proc_router_conf.low_ino);
717 proc_unregister(&proc_router, proc_router_stat.low_ino);
719 proc_unregister(proc_net, proc_router.low_ino);
721 proc_unregister(&proc_net, proc_router.low_ino);
726 * Add directory entry for WAN device.
729 int wanrouter_proc_add (wan_device_t* wandev)
731 if (wandev->magic != ROUTER_MAGIC)
734 memset(&wandev->dent, 0, sizeof(wandev->dent));
735 wandev->dent.namelen = strlen(wandev->name);
736 wandev->dent.name = wandev->name;
737 wandev->dent.mode = 0444 | S_IFREG;
738 wandev->dent.nlink = 1;
739 wandev->dent.ops = &wandev_inode;
740 wandev->dent.get_info = &wandev_get_info;
741 wandev->dent.data = wandev;
743 return proc_register(&proc_router, &wandev->dent);
745 return proc_register_dynamic(&proc_router, &wandev->dent);
750 * Delete directory entry for WAN device.
753 int wanrouter_proc_delete(wan_device_t* wandev)
755 if (wandev->magic != ROUTER_MAGIC)
757 proc_unregister(&proc_router, wandev->dent.low_ino);
761 /****** Proc filesystem entry points ****************************************/
764 * Verify access rights.
767 static int router_proc_perms (struct inode* inode, int op)
773 * Read router proc directory entry.
774 * This is universal routine for reading all entries in /proc/net/wanrouter
775 * directory. Each directory entry contains a pointer to the 'method' for
776 * preparing data for that entry.
778 * o allocate kernel buffer
779 * o call get_info() to prepare data
780 * o copy data to user space
781 * o release kernel buffer
783 * Return: number of bytes copied to user space (0, if no data)
787 static ssize_t router_proc_read(struct file* file, char* buf, size_t count,
790 struct inode *inode = file->f_dentry->d_inode;
791 struct proc_dir_entry* dent;
798 dent = inode->u.generic_ip;
799 if ((dent == NULL) || (dent->get_info == NULL))
802 page = kmalloc(PROC_BUFSZ, GFP_KERNEL);
806 pos = dent->get_info(page, dent->data, 0, 0, 0);
809 len = min_t(unsigned int, pos - offs, count);
810 if (copy_to_user(buf, (page + offs), len)) {
823 static int router_proc_read(
824 struct inode* inode, struct file* file, char* buf, int count)
826 struct proc_dir_entry* dent;
828 int err, pos, offs, len;
832 dent = inode->u.generic_ip;
833 if ((dent == NULL) || (dent->get_info == NULL))
835 err = verify_area(VERIFY_WRITE, buf, count);
838 page = kmalloc(PROC_BUFSZ, GFP_KERNEL);
842 pos = dent->get_info(page, dent->data, 0, 0, 0);
845 len = min_t(unsigned int, pos - offs, count);
846 memcpy_tofs((void*)buf, (void*)(page + offs), len);
857 * Prepare data for reading 'Config' entry.
858 * Return length of data.
861 static int config_get_info(char* buf, char** start, off_t offs, int len,
864 int cnt = sizeof(conf_hdr) - 1;
865 wan_device_t* wandev;
866 strcpy(buf, conf_hdr);
867 for (wandev = router_devlist;
868 wandev && (cnt < (PROC_BUFSZ - 120));
869 wandev = wandev->next) {
870 if (wandev->state) cnt += sprintf(&buf[cnt],
871 "%-15s|0x%-4X|%3u|%3u| 0x%-8lX |0x%-6X|%7u|%7u|%7u|%7u\n",
888 * Prepare data for reading 'Status' entry.
889 * Return length of data.
892 static int status_get_info(char* buf, char** start, off_t offs, int len,
896 wan_device_t* wandev;
898 //cnt += sprintf(&buf[cnt], "\nSTATUS:\n\n");
899 strcpy(&buf[cnt], stat_hdr);
900 cnt += sizeof(stat_hdr) - 1;
902 for (wandev = router_devlist;
903 wandev && (cnt < (PROC_BUFSZ - 80));
904 wandev = wandev->next) {
905 if (!wandev->state) continue;
906 cnt += sprintf(&buf[cnt],
907 "%-15s|%-8s|%-7s|%-9s|%-8s|%9u|%5u|%3u |",
909 PROT_DECODE(wandev->config_id),
910 wandev->config_id == WANCONFIG_FR ?
911 (wandev->station ? " Node" : " CPE") :
912 (wandev->config_id == WANCONFIG_X25 ?
913 (wandev->station ? " DCE" : " DTE") :
915 wandev->interface ? " V.35" : " RS-232",
916 wandev->clocking ? "internal" : "external",
921 switch (wandev->state) {
923 case WAN_UNCONFIGURED:
924 cnt += sprintf(&buf[cnt], "%-12s\n", "unconfigured");
927 case WAN_DISCONNECTED:
928 cnt += sprintf(&buf[cnt], "%-12s\n", "disconnected");
932 cnt += sprintf(&buf[cnt], "%-12s\n", "connecting");
936 cnt += sprintf(&buf[cnt], "%-12s\n", "connected");
940 cnt += sprintf(&buf[cnt], "%-12s\n", "ft1 ready");
944 cnt += sprintf(&buf[cnt], "%-12s\n", "invalid");
952 * Prepare data for reading <device> entry.
953 * Return length of data.
955 * On entry, the 'start' argument will contain a pointer to WAN device
959 static int wandev_get_info(char* buf, char** start, off_t offs, int len,
962 wan_device_t* wandev = (void*)start;
966 if ((wandev == NULL) || (wandev->magic != ROUTER_MAGIC))
969 return sprintf(&buf[cnt], "Device is not configured!\n");
971 /* Update device statistics */
972 if (wandev->update) {
974 rslt = wandev->update(wandev);
978 return sprintf(&buf[cnt], "Device is busy!\n");
981 return sprintf(&buf[cnt],
982 "Device is not configured!\n");
987 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
988 "total packets received", wandev->stats.rx_packets);
989 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
990 "total packets transmitted", wandev->stats.tx_packets);
992 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
993 "total bytes received", wandev->stats.rx_bytes);
994 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
995 "total bytes transmitted", wandev->stats.tx_bytes);
997 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
998 "bad packets received", wandev->stats.rx_errors);
999 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1000 "packet transmit problems", wandev->stats.tx_errors);
1001 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1002 "received frames dropped", wandev->stats.rx_dropped);
1003 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1004 "transmit frames dropped", wandev->stats.tx_dropped);
1005 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1006 "multicast packets received", wandev->stats.multicast);
1007 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1008 "transmit collisions", wandev->stats.collisions);
1009 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1010 "receive length errors", wandev->stats.rx_length_errors);
1011 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1012 "receiver overrun errors", wandev->stats.rx_over_errors);
1013 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1014 "CRC errors", wandev->stats.rx_crc_errors);
1015 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1016 "frame format errors (aborts)", wandev->stats.rx_frame_errors);
1017 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1018 "receiver fifo overrun", wandev->stats.rx_fifo_errors);
1019 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1020 "receiver missed packet", wandev->stats.rx_missed_errors);
1021 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1022 "aborted frames transmitted", wandev->stats.tx_aborted_errors);
1027 #endif /* End of ifdef LINUX_2_4 */
1033 * No /proc - output stubs
1036 int __init wanrouter_proc_init(void)
1041 void wanrouter_proc_cleanup(void)
1046 int wanrouter_proc_add(wan_device_t *wandev)
1051 int wanrouter_proc_delete(wan_device_t *wandev)
1058 /*============================================================================
1059 * Write WAN device ???.
1060 * o Find WAN device associated with this node
1063 static int device_write(
1064 struct inode* inode, struct file* file, const char* buf, int count)
1066 int err = verify_area(VERIFY_READ, buf, count);
1067 struct proc_dir_entry* dent;
1068 wan_device_t* wandev;
1070 if (err) return err;
1072 dent = inode->u.generic_ip;
1073 if ((dent == NULL) || (dent->data == NULL))
1076 wandev = dent->data;
1078 printk(KERN_ERR "%s: writing %d bytes to %s...\n",
1079 name_root, count, dent->name);