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;
251 dent = inode->u.generic_ip;
252 if ((dent == NULL) || (dent->get_info == NULL))
255 page = kmalloc(PROC_BUFSZ, GFP_KERNEL);
259 pos = dent->get_info(page, dent->data, 0, 0);
262 len = min_t(unsigned int, pos - offs, count);
263 if (copy_to_user(buf, (page + offs), len)) {
276 * Prepare data for reading 'Config' entry.
277 * Return length of data.
280 static int config_get_info(char* buf, char** start, off_t offs, int len)
282 int cnt = sizeof(conf_hdr) - 1;
283 wan_device_t* wandev;
284 strcpy(buf, conf_hdr);
285 for (wandev = router_devlist;
286 wandev && (cnt < (PROC_BUFSZ - 120));
287 wandev = wandev->next) {
288 if (wandev->state) cnt += sprintf(&buf[cnt],
289 "%-15s|0x%-4X|%3u|%3u| 0x%-8lX |0x%-6X|%7u|%7u|%7u|%7u\n",
306 * Prepare data for reading 'Status' entry.
307 * Return length of data.
310 static int status_get_info(char* buf, char** start, off_t offs, int len)
313 wan_device_t* wandev;
315 //cnt += sprintf(&buf[cnt], "\nSTATUS:\n\n");
316 strcpy(&buf[cnt], stat_hdr);
317 cnt += sizeof(stat_hdr) - 1;
319 for (wandev = router_devlist;
320 wandev && (cnt < (PROC_BUFSZ - 80));
321 wandev = wandev->next) {
322 if (!wandev->state) continue;
323 cnt += sprintf(&buf[cnt],
324 "%-15s|%-8s|%-7s|%-9s|%-8s|%9u|%5u|%3u |",
326 PROT_DECODE(wandev->config_id),
327 wandev->config_id == WANCONFIG_FR ?
328 (wandev->station ? " Node" : " CPE") :
329 (wandev->config_id == WANCONFIG_X25 ?
330 (wandev->station ? " DCE" : " DTE") :
332 wandev->interface ? " V.35" : " RS-232",
333 wandev->clocking ? "internal" : "external",
338 switch (wandev->state) {
340 case WAN_UNCONFIGURED:
341 cnt += sprintf(&buf[cnt], "%-12s\n", "unconfigured");
344 case WAN_DISCONNECTED:
345 cnt += sprintf(&buf[cnt], "%-12s\n", "disconnected");
349 cnt += sprintf(&buf[cnt], "%-12s\n", "connecting");
353 cnt += sprintf(&buf[cnt], "%-12s\n", "connected");
357 cnt += sprintf(&buf[cnt], "%-12s\n", "invalid");
365 * Prepare data for reading <device> entry.
366 * Return length of data.
368 * On entry, the 'start' argument will contain a pointer to WAN device
372 static int wandev_get_info(char* buf, char** start, off_t offs, int len)
374 wan_device_t* wandev = (void*)start;
378 if ((wandev == NULL) || (wandev->magic != ROUTER_MAGIC))
381 return sprintf(&buf[cnt], "device is not configured!\n");
383 /* Update device statistics */
384 if (wandev->update) {
386 rslt = wandev->update(wandev);
390 return sprintf(&buf[cnt], "Device is busy!\n");
393 return sprintf(&buf[cnt],
394 "Device is not configured!\n");
399 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
400 "total packets received", wandev->stats.rx_packets);
401 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
402 "total packets transmitted", wandev->stats.tx_packets);
403 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
404 "total bytes received", wandev->stats.rx_bytes);
405 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
406 "total bytes transmitted", wandev->stats.tx_bytes);
407 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
408 "bad packets received", wandev->stats.rx_errors);
409 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
410 "packet transmit problems", wandev->stats.tx_errors);
411 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
412 "received frames dropped", wandev->stats.rx_dropped);
413 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
414 "transmit frames dropped", wandev->stats.tx_dropped);
415 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
416 "multicast packets received", wandev->stats.multicast);
417 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
418 "transmit collisions", wandev->stats.collisions);
419 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
420 "receive length errors", wandev->stats.rx_length_errors);
421 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
422 "receiver overrun errors", wandev->stats.rx_over_errors);
423 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
424 "CRC errors", wandev->stats.rx_crc_errors);
425 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
426 "frame format errors (aborts)", wandev->stats.rx_frame_errors);
427 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
428 "receiver fifo overrun", wandev->stats.rx_fifo_errors);
429 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
430 "receiver missed packet", wandev->stats.rx_missed_errors);
431 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
432 "aborted frames transmitted", wandev->stats.tx_aborted_errors);
437 #else /* ------------------- END OF LINUX 2.4.X VERSION -------------*/
441 /* Proc filesystem interface */
442 static int router_proc_perms(struct inode *, int);
444 static ssize_t router_proc_read(struct file *file, char *buf, size_t count, loff_t *ppos);
446 static int router_proc_read(
447 struct inode* inode, struct file* file, char* buf, int count);
448 static int device_write(
449 struct inode* inode, struct file* file, const char* buf, int count);
452 /* Methods for preparing data for reading proc entries */
453 static int config_get_info(char* buf, char** start, off_t offs, int len,
455 static int status_get_info(char* buf, char** start, off_t offs, int len,
457 static int wandev_get_info(char* buf, char** start, off_t offs, int len,
467 * Names of the proc directory entries
470 static char name_root[] = ROUTER_NAME;
471 static char name_conf[] = "config";
472 static char name_stat[] = "status";
475 * Structures for interfacing with the /proc filesystem.
476 * Router creates its own directory /proc/net/router with the folowing
478 * config device configuration
479 * status global device statistics
480 * <device> entry for each WAN device
484 * Generic /proc/net/router/<file> file and inode operations
487 static struct file_operations router_fops =
490 router_proc_read, /* read */
496 NULL, /* no special open code */
498 NULL, /* no special release code */
499 NULL /* can't fsync */
502 static struct file_operations router_fops =
505 router_proc_read, /* read */
511 NULL, /* no special open code */
512 NULL, /* no special release code */
513 NULL /* can't fsync */
517 static struct inode_operations router_inode =
529 NULL, /* follow link */
532 NULL, /* writepage */
539 * /proc/net/router/<device> file and inode operations
543 static struct file_operations wandev_fops =
546 router_proc_read, /* read */
550 wanrouter_ioctl, /* ioctl */
552 NULL, /* no special open code */
554 NULL, /* no special release code */
555 NULL /* can't fsync */
558 static struct file_operations wandev_fops =
561 router_proc_read, /* read */
562 device_write, /* write */
565 wanrouter_ioctl, /* ioctl */
567 NULL, /* no special open code */
568 NULL, /* no special release code */
569 NULL /* can't fsync */
573 static struct inode_operations wandev_inode =
586 NULL, /* follow_link */
588 NULL, /* writepage */
595 * Proc filesystem derectory entries.
602 static struct proc_dir_entry proc_router =
605 sizeof(name_root) - 1, /* .namelen */
606 name_root, /* .name */
607 0555 | S_IFDIR, /* .mode */
612 &proc_dir_inode_operations, /* .ops */
613 NULL, /* .get_info */
614 NULL, /* .fill_node */
622 * /proc/net/router/config
625 static struct proc_dir_entry proc_router_conf =
628 sizeof(name_conf) - 1, /* .namelen */
629 name_conf, /* .name */
630 0444 | S_IFREG, /* .mode */
635 &router_inode, /* .ops */
636 &config_get_info, /* .get_info */
637 NULL, /* .fill_node */
645 * /proc/net/router/status
648 static struct proc_dir_entry proc_router_stat =
651 sizeof(name_stat) - 1, /* .namelen */
652 name_stat, /* .name */
653 0444 | S_IFREG, /* .mode */
658 &router_inode, /* .ops */
659 status_get_info, /* .get_info */
660 NULL, /* .fill_node */
668 static char conf_hdr[] =
669 "Device name | port |IRQ|DMA| mem.addr |mem.size|"
670 "option1|option2|option3|option4\n";
672 static char stat_hdr[] =
673 "Device name |protocol|station|interface|clocking|baud rate| MTU |ndev"
678 * Interface functions
682 * Initialize router proc interface.
686 __initfunc(int wanrouter_proc_init (void))
688 int err = proc_register(proc_net, &proc_router);
691 proc_register(&proc_router, &proc_router_conf);
692 proc_register(&proc_router, &proc_router_stat);
697 int wanrouter_proc_init (void)
699 int err = proc_register_dynamic(&proc_net, &proc_router);
702 proc_register_dynamic(&proc_router, &proc_router_conf);
703 proc_register_dynamic(&proc_router, &proc_router_stat);
710 * Clean up router proc interface.
713 void wanrouter_proc_cleanup (void)
715 proc_unregister(&proc_router, proc_router_conf.low_ino);
716 proc_unregister(&proc_router, proc_router_stat.low_ino);
718 proc_unregister(proc_net, proc_router.low_ino);
720 proc_unregister(&proc_net, proc_router.low_ino);
725 * Add directory entry for WAN device.
728 int wanrouter_proc_add (wan_device_t* wandev)
730 if (wandev->magic != ROUTER_MAGIC)
733 memset(&wandev->dent, 0, sizeof(wandev->dent));
734 wandev->dent.namelen = strlen(wandev->name);
735 wandev->dent.name = wandev->name;
736 wandev->dent.mode = 0444 | S_IFREG;
737 wandev->dent.nlink = 1;
738 wandev->dent.ops = &wandev_inode;
739 wandev->dent.get_info = &wandev_get_info;
740 wandev->dent.data = wandev;
742 return proc_register(&proc_router, &wandev->dent);
744 return proc_register_dynamic(&proc_router, &wandev->dent);
749 * Delete directory entry for WAN device.
752 int wanrouter_proc_delete(wan_device_t* wandev)
754 if (wandev->magic != ROUTER_MAGIC)
756 proc_unregister(&proc_router, wandev->dent.low_ino);
760 /****** Proc filesystem entry points ****************************************/
763 * Verify access rights.
766 static int router_proc_perms (struct inode* inode, int op)
772 * Read router proc directory entry.
773 * This is universal routine for reading all entries in /proc/net/wanrouter
774 * directory. Each directory entry contains a pointer to the 'method' for
775 * preparing data for that entry.
777 * o allocate kernel buffer
778 * o call get_info() to prepare data
779 * o copy data to user space
780 * o release kernel buffer
782 * Return: number of bytes copied to user space (0, if no data)
786 static ssize_t router_proc_read(struct file* file, char* buf, size_t count,
789 struct inode *inode = file->f_dentry->d_inode;
790 struct proc_dir_entry* dent;
797 dent = inode->u.generic_ip;
798 if ((dent == NULL) || (dent->get_info == NULL))
801 page = kmalloc(PROC_BUFSZ, GFP_KERNEL);
805 pos = dent->get_info(page, dent->data, 0, 0, 0);
808 len = min_t(unsigned int, pos - offs, count);
809 if (copy_to_user(buf, (page + offs), len)) {
822 static int router_proc_read(
823 struct inode* inode, struct file* file, char* buf, int count)
825 struct proc_dir_entry* dent;
827 int err, pos, offs, len;
831 dent = inode->u.generic_ip;
832 if ((dent == NULL) || (dent->get_info == NULL))
834 err = verify_area(VERIFY_WRITE, buf, count);
837 page = kmalloc(PROC_BUFSZ, GFP_KERNEL);
841 pos = dent->get_info(page, dent->data, 0, 0, 0);
844 len = min_t(unsigned int, pos - offs, count);
845 memcpy_tofs((void*)buf, (void*)(page + offs), len);
856 * Prepare data for reading 'Config' entry.
857 * Return length of data.
860 static int config_get_info(char* buf, char** start, off_t offs, int len,
863 int cnt = sizeof(conf_hdr) - 1;
864 wan_device_t* wandev;
865 strcpy(buf, conf_hdr);
866 for (wandev = router_devlist;
867 wandev && (cnt < (PROC_BUFSZ - 120));
868 wandev = wandev->next) {
869 if (wandev->state) cnt += sprintf(&buf[cnt],
870 "%-15s|0x%-4X|%3u|%3u| 0x%-8lX |0x%-6X|%7u|%7u|%7u|%7u\n",
887 * Prepare data for reading 'Status' entry.
888 * Return length of data.
891 static int status_get_info(char* buf, char** start, off_t offs, int len,
895 wan_device_t* wandev;
897 //cnt += sprintf(&buf[cnt], "\nSTATUS:\n\n");
898 strcpy(&buf[cnt], stat_hdr);
899 cnt += sizeof(stat_hdr) - 1;
901 for (wandev = router_devlist;
902 wandev && (cnt < (PROC_BUFSZ - 80));
903 wandev = wandev->next) {
904 if (!wandev->state) continue;
905 cnt += sprintf(&buf[cnt],
906 "%-15s|%-8s|%-7s|%-9s|%-8s|%9u|%5u|%3u |",
908 PROT_DECODE(wandev->config_id),
909 wandev->config_id == WANCONFIG_FR ?
910 (wandev->station ? " Node" : " CPE") :
911 (wandev->config_id == WANCONFIG_X25 ?
912 (wandev->station ? " DCE" : " DTE") :
914 wandev->interface ? " V.35" : " RS-232",
915 wandev->clocking ? "internal" : "external",
920 switch (wandev->state) {
922 case WAN_UNCONFIGURED:
923 cnt += sprintf(&buf[cnt], "%-12s\n", "unconfigured");
926 case WAN_DISCONNECTED:
927 cnt += sprintf(&buf[cnt], "%-12s\n", "disconnected");
931 cnt += sprintf(&buf[cnt], "%-12s\n", "connecting");
935 cnt += sprintf(&buf[cnt], "%-12s\n", "connected");
939 cnt += sprintf(&buf[cnt], "%-12s\n", "ft1 ready");
943 cnt += sprintf(&buf[cnt], "%-12s\n", "invalid");
951 * Prepare data for reading <device> entry.
952 * Return length of data.
954 * On entry, the 'start' argument will contain a pointer to WAN device
958 static int wandev_get_info(char* buf, char** start, off_t offs, int len,
961 wan_device_t* wandev = (void*)start;
965 if ((wandev == NULL) || (wandev->magic != ROUTER_MAGIC))
968 return sprintf(&buf[cnt], "Device is not configured!\n");
970 /* Update device statistics */
971 if (wandev->update) {
973 rslt = wandev->update(wandev);
977 return sprintf(&buf[cnt], "Device is busy!\n");
980 return sprintf(&buf[cnt],
981 "Device is not configured!\n");
986 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
987 "total packets received", wandev->stats.rx_packets);
988 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
989 "total packets transmitted", wandev->stats.tx_packets);
991 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
992 "total bytes received", wandev->stats.rx_bytes);
993 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
994 "total bytes transmitted", wandev->stats.tx_bytes);
996 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
997 "bad packets received", wandev->stats.rx_errors);
998 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
999 "packet transmit problems", wandev->stats.tx_errors);
1000 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1001 "received frames dropped", wandev->stats.rx_dropped);
1002 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1003 "transmit frames dropped", wandev->stats.tx_dropped);
1004 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1005 "multicast packets received", wandev->stats.multicast);
1006 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1007 "transmit collisions", wandev->stats.collisions);
1008 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1009 "receive length errors", wandev->stats.rx_length_errors);
1010 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1011 "receiver overrun errors", wandev->stats.rx_over_errors);
1012 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1013 "CRC errors", wandev->stats.rx_crc_errors);
1014 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1015 "frame format errors (aborts)", wandev->stats.rx_frame_errors);
1016 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1017 "receiver fifo overrun", wandev->stats.rx_fifo_errors);
1018 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1019 "receiver missed packet", wandev->stats.rx_missed_errors);
1020 cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1021 "aborted frames transmitted", wandev->stats.tx_aborted_errors);
1026 #endif /* End of ifdef LINUX_2_4 */
1032 * No /proc - output stubs
1035 int __init wanrouter_proc_init(void)
1040 void wanrouter_proc_cleanup(void)
1045 int wanrouter_proc_add(wan_device_t *wandev)
1050 int wanrouter_proc_delete(wan_device_t *wandev)
1057 /*============================================================================
1058 * Write WAN device ???.
1059 * o Find WAN device associated with this node
1062 static int device_write(
1063 struct inode* inode, struct file* file, const char* buf, int count)
1065 int err = verify_area(VERIFY_READ, buf, count);
1066 struct proc_dir_entry* dent;
1067 wan_device_t* wandev;
1069 if (err) return err;
1071 dent = inode->u.generic_ip;
1072 if ((dent == NULL) || (dent->data == NULL))
1075 wandev = dent->data;
1077 printk(KERN_ERR "%s: writing %d bytes to %s...\n",
1078 name_root, count, dent->name);