[PATCH] m68k: rtc __user annotations
[linux-2.6] / net / wanrouter / wanmain.c
1 /*****************************************************************************
2 * wanmain.c     WAN Multiprotocol Router Module. Main code.
3 *
4 *               This module is completely hardware-independent and provides
5 *               the following common services for the WAN Link Drivers:
6 *                o WAN device managenment (registering, unregistering)
7 *                o Network interface management
8 *                o Physical connection management (dial-up, incoming calls)
9 *                o Logical connection management (switched virtual circuits)
10 *                o Protocol encapsulation/decapsulation
11 *
12 * Author:       Gideon Hack
13 *
14 * Copyright:    (c) 1995-1999 Sangoma Technologies Inc.
15 *
16 *               This program is free software; you can redistribute it and/or
17 *               modify it under the terms of the GNU General Public License
18 *               as published by the Free Software Foundation; either version
19 *               2 of the License, or (at your option) any later version.
20 * ============================================================================
21 * Nov 24, 2000  Nenad Corbic    Updated for 2.4.X kernels
22 * Nov 07, 2000  Nenad Corbic    Fixed the Mulit-Port PPP for kernels 2.2.16 and
23 *                               greater.
24 * Aug 2,  2000  Nenad Corbic    Block the Multi-Port PPP from running on
25 *                               kernels 2.2.16 or greater.  The SyncPPP
26 *                               has changed.
27 * Jul 13, 2000  Nenad Corbic    Added SyncPPP support
28 *                               Added extra debugging in device_setup().
29 * Oct 01, 1999  Gideon Hack     Update for s514 PCI card
30 * Dec 27, 1996  Gene Kozin      Initial version (based on Sangoma's WANPIPE)
31 * Jan 16, 1997  Gene Kozin      router_devlist made public
32 * Jan 31, 1997  Alan Cox        Hacked it about a bit for 2.1
33 * Jun 27, 1997  Alan Cox        realigned with vendor code
34 * Oct 15, 1997  Farhan Thawar   changed wan_encapsulate to add a pad byte of 0
35 * Apr 20, 1998  Alan Cox        Fixed 2.1 symbols
36 * May 17, 1998  K. Baranowski   Fixed SNAP encapsulation in wan_encapsulate
37 * Dec 15, 1998  Arnaldo Melo    support for firmwares of up to 128000 bytes
38 *                               check wandev->setup return value
39 * Dec 22, 1998  Arnaldo Melo    vmalloc/vfree used in device_setup to allocate
40 *                               kernel memory and copy configuration data to
41 *                               kernel space (for big firmwares)
42 * Jun 02, 1999  Gideon Hack     Updates for Linux 2.0.X and 2.2.X kernels.
43 *****************************************************************************/
44
45 #include <linux/config.h>
46 #include <linux/stddef.h>       /* offsetof(), etc. */
47 #include <linux/capability.h>
48 #include <linux/errno.h>        /* return codes */
49 #include <linux/kernel.h>
50 #include <linux/init.h>
51 #include <linux/module.h>       /* support for loadable modules */
52 #include <linux/slab.h>         /* kmalloc(), kfree() */
53 #include <linux/mm.h>
54 #include <linux/string.h>       /* inline mem*, str* functions */
55
56 #include <asm/byteorder.h>      /* htons(), etc. */
57 #include <linux/wanrouter.h>    /* WAN router API definitions */
58
59 #include <linux/vmalloc.h>      /* vmalloc, vfree */
60 #include <asm/uaccess.h>        /* copy_to/from_user */
61 #include <linux/init.h>         /* __initfunc et al. */
62 #include <net/syncppp.h>
63
64 #define KMEM_SAFETYZONE 8
65
66 /***********FOR DEBUGGING PURPOSES*********************************************
67 static void * dbg_kmalloc(unsigned int size, int prio, int line) {
68         int i = 0;
69         void * v = kmalloc(size+sizeof(unsigned int)+2*KMEM_SAFETYZONE*8,prio);
70         char * c1 = v;
71         c1 += sizeof(unsigned int);
72         *((unsigned int *)v) = size;
73
74         for (i = 0; i < KMEM_SAFETYZONE; i++) {
75                 c1[0] = 'D'; c1[1] = 'E'; c1[2] = 'A'; c1[3] = 'D';
76                 c1[4] = 'B'; c1[5] = 'E'; c1[6] = 'E'; c1[7] = 'F';
77                 c1 += 8;
78         }
79         c1 += size;
80         for (i = 0; i < KMEM_SAFETYZONE; i++) {
81                 c1[0] = 'M'; c1[1] = 'U'; c1[2] = 'N'; c1[3] = 'G';
82                 c1[4] = 'W'; c1[5] = 'A'; c1[6] = 'L'; c1[7] = 'L';
83                 c1 += 8;
84         }
85         v = ((char *)v) + sizeof(unsigned int) + KMEM_SAFETYZONE*8;
86         printk(KERN_INFO "line %d  kmalloc(%d,%d) = %p\n",line,size,prio,v);
87         return v;
88 }
89 static void dbg_kfree(void * v, int line) {
90         unsigned int * sp = (unsigned int *)(((char *)v) - (sizeof(unsigned int) + KMEM_SAFETYZONE*8));
91         unsigned int size = *sp;
92         char * c1 = ((char *)v) - KMEM_SAFETYZONE*8;
93         int i = 0;
94         for (i = 0; i < KMEM_SAFETYZONE; i++) {
95                 if (   c1[0] != 'D' || c1[1] != 'E' || c1[2] != 'A' || c1[3] != 'D'
96                     || c1[4] != 'B' || c1[5] != 'E' || c1[6] != 'E' || c1[7] != 'F') {
97                         printk(KERN_INFO "kmalloced block at %p has been corrupted (underrun)!\n",v);
98                         printk(KERN_INFO " %4x: %2x %2x %2x %2x %2x %2x %2x %2x\n", i*8,
99                                         c1[0],c1[1],c1[2],c1[3],c1[4],c1[5],c1[6],c1[7] );
100                 }
101                 c1 += 8;
102         }
103         c1 += size;
104         for (i = 0; i < KMEM_SAFETYZONE; i++) {
105                 if (   c1[0] != 'M' || c1[1] != 'U' || c1[2] != 'N' || c1[3] != 'G'
106                     || c1[4] != 'W' || c1[5] != 'A' || c1[6] != 'L' || c1[7] != 'L'
107                    ) {
108                         printk(KERN_INFO "kmalloced block at %p has been corrupted (overrun):\n",v);
109                         printk(KERN_INFO " %4x: %2x %2x %2x %2x %2x %2x %2x %2x\n", i*8,
110                                         c1[0],c1[1],c1[2],c1[3],c1[4],c1[5],c1[6],c1[7] );
111                 }
112                 c1 += 8;
113         }
114         printk(KERN_INFO "line %d  kfree(%p)\n",line,v);
115         v = ((char *)v) - (sizeof(unsigned int) + KMEM_SAFETYZONE*8);
116         kfree(v);
117 }
118
119 #define kmalloc(x,y) dbg_kmalloc(x,y,__LINE__)
120 #define kfree(x) dbg_kfree(x,__LINE__)
121 *****************************************************************************/
122
123 /*
124  *      Function Prototypes
125  */
126
127 /*
128  *      WAN device IOCTL handlers
129  */
130
131 static int wanrouter_device_setup(struct wan_device *wandev,
132                                   wandev_conf_t __user *u_conf);
133 static int wanrouter_device_stat(struct wan_device *wandev,
134                                  wandev_stat_t __user *u_stat);
135 static int wanrouter_device_shutdown(struct wan_device *wandev);
136 static int wanrouter_device_new_if(struct wan_device *wandev,
137                                    wanif_conf_t __user *u_conf);
138 static int wanrouter_device_del_if(struct wan_device *wandev,
139                                    char __user *u_name);
140
141 /*
142  *      Miscellaneous
143  */
144
145 static struct wan_device *wanrouter_find_device(char *name);
146 static int wanrouter_delete_interface(struct wan_device *wandev, char *name);
147 void lock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags);
148 void unlock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags);
149
150
151
152 /*
153  *      Global Data
154  */
155
156 static char wanrouter_fullname[]  = "Sangoma WANPIPE Router";
157 static char wanrouter_copyright[] = "(c) 1995-2000 Sangoma Technologies Inc.";
158 static char wanrouter_modname[] = ROUTER_NAME; /* short module name */
159 struct wan_device* wanrouter_router_devlist; /* list of registered devices */
160
161 /*
162  *      Organize Unique Identifiers for encapsulation/decapsulation
163  */
164
165 static unsigned char wanrouter_oui_ether[] = { 0x00, 0x00, 0x00 };
166 #if 0
167 static unsigned char wanrouter_oui_802_2[] = { 0x00, 0x80, 0xC2 };
168 #endif
169
170 static int __init wanrouter_init(void)
171 {
172         int err;
173
174         printk(KERN_INFO "%s v%u.%u %s\n",
175                wanrouter_fullname, ROUTER_VERSION, ROUTER_RELEASE,
176                wanrouter_copyright);
177
178         err = wanrouter_proc_init();
179         if (err)
180                 printk(KERN_INFO "%s: can't create entry in proc filesystem!\n",
181                        wanrouter_modname);
182
183         return err;
184 }
185
186 static void __exit wanrouter_cleanup (void)
187 {
188         wanrouter_proc_cleanup();
189 }
190
191 /*
192  * This is just plain dumb.  We should move the bugger to drivers/net/wan,
193  * slap it first in directory and make it module_init().  The only reason
194  * for subsys_initcall() here is that net goes after drivers (why, BTW?)
195  */
196 subsys_initcall(wanrouter_init);
197 module_exit(wanrouter_cleanup);
198
199 /*
200  *      Kernel APIs
201  */
202
203 /*
204  *      Register WAN device.
205  *      o verify device credentials
206  *      o create an entry for the device in the /proc/net/router directory
207  *      o initialize internally maintained fields of the wan_device structure
208  *      o link device data space to a singly-linked list
209  *      o if it's the first device, then start kernel 'thread'
210  *      o increment module use count
211  *
212  *      Return:
213  *      0       Ok
214  *      < 0     error.
215  *
216  *      Context:        process
217  */
218
219
220 int register_wan_device(struct wan_device *wandev)
221 {
222         int err, namelen;
223
224         if ((wandev == NULL) || (wandev->magic != ROUTER_MAGIC) ||
225             (wandev->name == NULL))
226                 return -EINVAL;
227
228         namelen = strlen(wandev->name);
229         if (!namelen || (namelen > WAN_DRVNAME_SZ))
230                 return -EINVAL;
231
232         if (wanrouter_find_device(wandev->name))
233                 return -EEXIST;
234
235 #ifdef WANDEBUG
236         printk(KERN_INFO "%s: registering WAN device %s\n",
237                wanrouter_modname, wandev->name);
238 #endif
239
240         /*
241          *      Register /proc directory entry
242          */
243         err = wanrouter_proc_add(wandev);
244         if (err) {
245                 printk(KERN_INFO
246                         "%s: can't create /proc/net/router/%s entry!\n",
247                         wanrouter_modname, wandev->name);
248                 return err;
249         }
250
251         /*
252          *      Initialize fields of the wan_device structure maintained by the
253          *      router and update local data.
254          */
255
256         wandev->ndev = 0;
257         wandev->dev  = NULL;
258         wandev->next = wanrouter_router_devlist;
259         wanrouter_router_devlist = wandev;
260         return 0;
261 }
262
263 /*
264  *      Unregister WAN device.
265  *      o shut down device
266  *      o unlink device data space from the linked list
267  *      o delete device entry in the /proc/net/router directory
268  *      o decrement module use count
269  *
270  *      Return:         0       Ok
271  *                      <0      error.
272  *      Context:        process
273  */
274
275
276 int unregister_wan_device(char *name)
277 {
278         struct wan_device *wandev, *prev;
279
280         if (name == NULL)
281                 return -EINVAL;
282
283         for (wandev = wanrouter_router_devlist, prev = NULL;
284                 wandev && strcmp(wandev->name, name);
285                 prev = wandev, wandev = wandev->next)
286                 ;
287         if (wandev == NULL)
288                 return -ENODEV;
289
290 #ifdef WANDEBUG
291         printk(KERN_INFO "%s: unregistering WAN device %s\n",
292                wanrouter_modname, name);
293 #endif
294
295         if (wandev->state != WAN_UNCONFIGURED)
296                 wanrouter_device_shutdown(wandev);
297
298         if (prev)
299                 prev->next = wandev->next;
300         else
301                 wanrouter_router_devlist = wandev->next;
302
303         wanrouter_proc_delete(wandev);
304         return 0;
305 }
306
307 /*
308  *      Encapsulate packet.
309  *
310  *      Return: encapsulation header size
311  *              < 0     - unsupported Ethertype
312  *
313  *      Notes:
314  *      1. This function may be called on interrupt context.
315  */
316
317
318 int wanrouter_encapsulate(struct sk_buff *skb, struct net_device *dev,
319                           unsigned short type)
320 {
321         int hdr_len = 0;
322
323         switch (type) {
324         case ETH_P_IP:          /* IP datagram encapsulation */
325                 hdr_len += 1;
326                 skb_push(skb, 1);
327                 skb->data[0] = NLPID_IP;
328                 break;
329
330         case ETH_P_IPX:         /* SNAP encapsulation */
331         case ETH_P_ARP:
332                 hdr_len += 7;
333                 skb_push(skb, 7);
334                 skb->data[0] = 0;
335                 skb->data[1] = NLPID_SNAP;
336                 memcpy(&skb->data[2], wanrouter_oui_ether,
337                        sizeof(wanrouter_oui_ether));
338                 *((unsigned short*)&skb->data[5]) = htons(type);
339                 break;
340
341         default:                /* Unknown packet type */
342                 printk(KERN_INFO
343                         "%s: unsupported Ethertype 0x%04X on interface %s!\n",
344                         wanrouter_modname, type, dev->name);
345                 hdr_len = -EINVAL;
346         }
347         return hdr_len;
348 }
349
350
351 /*
352  *      Decapsulate packet.
353  *
354  *      Return: Ethertype (in network order)
355  *                      0       unknown encapsulation
356  *
357  *      Notes:
358  *      1. This function may be called on interrupt context.
359  */
360
361
362 __be16 wanrouter_type_trans(struct sk_buff *skb, struct net_device *dev)
363 {
364         int cnt = skb->data[0] ? 0 : 1; /* there may be a pad present */
365         __be16 ethertype;
366
367         switch (skb->data[cnt]) {
368         case NLPID_IP:          /* IP datagramm */
369                 ethertype = htons(ETH_P_IP);
370                 cnt += 1;
371                 break;
372
373         case NLPID_SNAP:        /* SNAP encapsulation */
374                 if (memcmp(&skb->data[cnt + 1], wanrouter_oui_ether,
375                            sizeof(wanrouter_oui_ether))){
376                         printk(KERN_INFO
377                                 "%s: unsupported SNAP OUI %02X-%02X-%02X "
378                                 "on interface %s!\n", wanrouter_modname,
379                                 skb->data[cnt+1], skb->data[cnt+2],
380                                 skb->data[cnt+3], dev->name);
381                         return 0;
382                 }
383                 ethertype = *((__be16*)&skb->data[cnt+4]);
384                 cnt += 6;
385                 break;
386
387         /* add other protocols, e.g. CLNP, ESIS, ISIS, if needed */
388
389         default:
390                 printk(KERN_INFO
391                         "%s: unsupported NLPID 0x%02X on interface %s!\n",
392                         wanrouter_modname, skb->data[cnt], dev->name);
393                 return 0;
394         }
395         skb->protocol = ethertype;
396         skb->pkt_type = PACKET_HOST;    /*      Physically point to point */
397         skb_pull(skb, cnt);
398         skb->mac.raw  = skb->data;
399         return ethertype;
400 }
401
402
403 /*
404  *      WAN device IOCTL.
405  *      o find WAN device associated with this node
406  *      o execute requested action or pass command to the device driver
407  */
408
409 int wanrouter_ioctl(struct inode *inode, struct file *file,
410                 unsigned int cmd, unsigned long arg)
411 {
412         int err = 0;
413         struct proc_dir_entry *dent;
414         struct wan_device *wandev;
415         void __user *data = (void __user *)arg;
416
417         if (!capable(CAP_NET_ADMIN))
418                 return -EPERM;
419
420         if ((cmd >> 8) != ROUTER_IOCTL)
421                 return -EINVAL;
422
423         dent = PDE(inode);
424         if ((dent == NULL) || (dent->data == NULL))
425                 return -EINVAL;
426
427         wandev = dent->data;
428         if (wandev->magic != ROUTER_MAGIC)
429                 return -EINVAL;
430
431         switch (cmd) {
432         case ROUTER_SETUP:
433                 err = wanrouter_device_setup(wandev, data);
434                 break;
435
436         case ROUTER_DOWN:
437                 err = wanrouter_device_shutdown(wandev);
438                 break;
439
440         case ROUTER_STAT:
441                 err = wanrouter_device_stat(wandev, data);
442                 break;
443
444         case ROUTER_IFNEW:
445                 err = wanrouter_device_new_if(wandev, data);
446                 break;
447
448         case ROUTER_IFDEL:
449                 err = wanrouter_device_del_if(wandev, data);
450                 break;
451
452         case ROUTER_IFSTAT:
453                 break;
454
455         default:
456                 if ((cmd >= ROUTER_USER) &&
457                     (cmd <= ROUTER_USER_MAX) &&
458                     wandev->ioctl)
459                         err = wandev->ioctl(wandev, cmd, arg);
460                 else err = -EINVAL;
461         }
462         return err;
463 }
464
465 /*
466  *      WAN Driver IOCTL Handlers
467  */
468
469 /*
470  *      Setup WAN link device.
471  *      o verify user address space
472  *      o allocate kernel memory and copy configuration data to kernel space
473  *      o if configuration data includes extension, copy it to kernel space too
474  *      o call driver's setup() entry point
475  */
476
477 static int wanrouter_device_setup(struct wan_device *wandev,
478                                   wandev_conf_t __user *u_conf)
479 {
480         void *data = NULL;
481         wandev_conf_t *conf;
482         int err = -EINVAL;
483
484         if (wandev->setup == NULL) {    /* Nothing to do ? */
485                 printk(KERN_INFO "%s: ERROR, No setup script: wandev->setup()\n",
486                                 wandev->name);
487                 return 0;
488         }
489
490         conf = kmalloc(sizeof(wandev_conf_t), GFP_KERNEL);
491         if (conf == NULL){
492                 printk(KERN_INFO "%s: ERROR, Failed to allocate kernel memory !\n",
493                                 wandev->name);
494                 return -ENOBUFS;
495         }
496
497         if (copy_from_user(conf, u_conf, sizeof(wandev_conf_t))) {
498                 printk(KERN_INFO "%s: Failed to copy user config data to kernel space!\n",
499                                 wandev->name);
500                 kfree(conf);
501                 return -EFAULT;
502         }
503
504         if (conf->magic != ROUTER_MAGIC) {
505                 kfree(conf);
506                 printk(KERN_INFO "%s: ERROR, Invalid MAGIC Number\n",
507                                 wandev->name);
508                 return -EINVAL;
509         }
510
511         if (conf->data_size && conf->data) {
512                 if (conf->data_size > 128000 || conf->data_size < 0) {
513                         printk(KERN_INFO
514                             "%s: ERROR, Invalid firmware data size %i !\n",
515                                         wandev->name, conf->data_size);
516                         kfree(conf);
517                         return -EINVAL;
518                 }
519
520                 data = vmalloc(conf->data_size);
521                 if (!data) {
522                         printk(KERN_INFO
523                                 "%s: ERROR, Faild allocate kernel memory !\n",
524                                 wandev->name);
525                         kfree(conf);
526                         return -ENOBUFS;
527                 }
528                 if (!copy_from_user(data, conf->data, conf->data_size)) {
529                         conf->data = data;
530                         err = wandev->setup(wandev, conf);
531                 } else {
532                         printk(KERN_INFO
533                              "%s: ERROR, Faild to copy from user data !\n",
534                                wandev->name);
535                         err = -EFAULT;
536                 }
537                 vfree(data);
538         } else {
539                 printk(KERN_INFO
540                     "%s: ERROR, No firmware found ! Firmware size = %i !\n",
541                                 wandev->name, conf->data_size);
542         }
543
544         kfree(conf);
545         return err;
546 }
547
548 /*
549  *      Shutdown WAN device.
550  *      o delete all not opened logical channels for this device
551  *      o call driver's shutdown() entry point
552  */
553
554 static int wanrouter_device_shutdown(struct wan_device *wandev)
555 {
556         struct net_device *dev;
557         int err=0;
558
559         if (wandev->state == WAN_UNCONFIGURED)
560                 return 0;
561
562         printk(KERN_INFO "\n%s: Shutting Down!\n",wandev->name);
563
564         for (dev = wandev->dev; dev;) {
565                 err = wanrouter_delete_interface(wandev, dev->name);
566                 if (err)
567                         return err;
568                 /* The above function deallocates the current dev
569                  * structure. Therefore, we cannot use dev->priv
570                  * as the next element: wandev->dev points to the
571                  * next element */
572                 dev = wandev->dev;
573         }
574
575         if (wandev->ndev)
576                 return -EBUSY;  /* there are opened interfaces  */
577
578         if (wandev->shutdown)
579                 err=wandev->shutdown(wandev);
580
581         return err;
582 }
583
584 /*
585  *      Get WAN device status & statistics.
586  */
587
588 static int wanrouter_device_stat(struct wan_device *wandev,
589                                  wandev_stat_t __user *u_stat)
590 {
591         wandev_stat_t stat;
592
593         memset(&stat, 0, sizeof(stat));
594
595         /* Ask device driver to update device statistics */
596         if ((wandev->state != WAN_UNCONFIGURED) && wandev->update)
597                 wandev->update(wandev);
598
599         /* Fill out structure */
600         stat.ndev  = wandev->ndev;
601         stat.state = wandev->state;
602
603         if (copy_to_user(u_stat, &stat, sizeof(stat)))
604                 return -EFAULT;
605
606         return 0;
607 }
608
609 /*
610  *      Create new WAN interface.
611  *      o verify user address space
612  *      o copy configuration data to kernel address space
613  *      o allocate network interface data space
614  *      o call driver's new_if() entry point
615  *      o make sure there is no interface name conflict
616  *      o register network interface
617  */
618
619 static int wanrouter_device_new_if(struct wan_device *wandev,
620                                    wanif_conf_t __user *u_conf)
621 {
622         wanif_conf_t *cnf;
623         struct net_device *dev = NULL;
624 #ifdef CONFIG_WANPIPE_MULTPPP
625         struct ppp_device *pppdev=NULL;
626 #endif
627         int err;
628
629         if ((wandev->state == WAN_UNCONFIGURED) || (wandev->new_if == NULL))
630                 return -ENODEV;
631
632         cnf = kmalloc(sizeof(wanif_conf_t), GFP_KERNEL);
633         if (!cnf)
634                 return -ENOBUFS;
635
636         err = -EFAULT;
637         if (copy_from_user(cnf, u_conf, sizeof(wanif_conf_t)))
638                 goto out;
639
640         err = -EINVAL;
641         if (cnf->magic != ROUTER_MAGIC)
642                 goto out;
643
644         if (cnf->config_id == WANCONFIG_MPPP) {
645 #ifdef CONFIG_WANPIPE_MULTPPP
646                 pppdev = kmalloc(sizeof(struct ppp_device), GFP_KERNEL);
647                 err = -ENOBUFS;
648                 if (pppdev == NULL)
649                         goto out;
650                 memset(pppdev, 0, sizeof(struct ppp_device));
651                 pppdev->dev = kmalloc(sizeof(struct net_device), GFP_KERNEL);
652                 if (pppdev->dev == NULL) {
653                         kfree(pppdev);
654                         err = -ENOBUFS;
655                         goto out;
656                 }
657                 memset(pppdev->dev, 0, sizeof(struct net_device));
658                 err = wandev->new_if(wandev, (struct net_device *)pppdev, cnf);
659                 dev = pppdev->dev;
660 #else
661                 printk(KERN_INFO "%s: Wanpipe Mulit-Port PPP support has not been compiled in!\n",
662                                 wandev->name);
663                 err = -EPROTONOSUPPORT;
664                 goto out;
665 #endif
666         } else {
667                 dev = kmalloc(sizeof(struct net_device), GFP_KERNEL);
668                 err = -ENOBUFS;
669                 if (dev == NULL)
670                         goto out;
671                 memset(dev, 0, sizeof(struct net_device));
672                 err = wandev->new_if(wandev, dev, cnf);
673         }
674
675         if (!err) {
676                 /* Register network interface. This will invoke init()
677                  * function supplied by the driver.  If device registered
678                  * successfully, add it to the interface list.
679                  */
680
681                 if (dev->name == NULL) {
682                         err = -EINVAL;
683                 } else {
684
685                         #ifdef WANDEBUG
686                         printk(KERN_INFO "%s: registering interface %s...\n",
687                                 wanrouter_modname, dev->name);
688                         #endif
689
690                         err = register_netdev(dev);
691                         if (!err) {
692                                 struct net_device *slave = NULL;
693                                 unsigned long smp_flags=0;
694
695                                 lock_adapter_irq(&wandev->lock, &smp_flags);
696
697                                 if (wandev->dev == NULL) {
698                                         wandev->dev = dev;
699                                 } else {
700                                         for (slave=wandev->dev;
701                                          *((struct net_device **)slave->priv);
702                                  slave = *((struct net_device **)slave->priv));
703
704                                      *((struct net_device **)slave->priv) = dev;
705                                 }
706                                 ++wandev->ndev;
707
708                                 unlock_adapter_irq(&wandev->lock, &smp_flags);
709                                 err = 0;        /* done !!! */
710                                 goto out;
711                         }
712                 }
713                 if (wandev->del_if)
714                         wandev->del_if(wandev, dev);
715         }
716
717         /* This code has moved from del_if() function */
718         kfree(dev->priv);
719         dev->priv = NULL;
720
721 #ifdef CONFIG_WANPIPE_MULTPPP
722         if (cnf->config_id == WANCONFIG_MPPP)
723                 kfree(pppdev);
724         else
725                 kfree(dev);
726 #else
727         /* Sync PPP is disabled */
728         if (cnf->config_id != WANCONFIG_MPPP)
729                 kfree(dev);
730 #endif
731
732 out:
733         kfree(cnf);
734         return err;
735 }
736
737
738 /*
739  *      Delete WAN logical channel.
740  *       o verify user address space
741  *       o copy configuration data to kernel address space
742  */
743
744 static int wanrouter_device_del_if(struct wan_device *wandev, char __user *u_name)
745 {
746         char name[WAN_IFNAME_SZ + 1];
747         int err = 0;
748
749         if (wandev->state == WAN_UNCONFIGURED)
750                 return -ENODEV;
751
752         memset(name, 0, sizeof(name));
753
754         if (copy_from_user(name, u_name, WAN_IFNAME_SZ))
755                 return -EFAULT;
756
757         err = wanrouter_delete_interface(wandev, name);
758         if (err)
759                 return err;
760
761         /* If last interface being deleted, shutdown card
762          * This helps with administration at leaf nodes
763          * (You can tell if the person at the other end of the phone
764          * has an interface configured) and avoids DoS vulnerabilities
765          * in binary driver files - this fixes a problem with the current
766          * Sangoma driver going into strange states when all the network
767          * interfaces are deleted and the link irrecoverably disconnected.
768          */
769
770         if (!wandev->ndev && wandev->shutdown)
771                 err = wandev->shutdown(wandev);
772
773         return err;
774 }
775
776 /*
777  *      Miscellaneous Functions
778  */
779
780 /*
781  *      Find WAN device by name.
782  *      Return pointer to the WAN device data space or NULL if device not found.
783  */
784
785 static struct wan_device *wanrouter_find_device(char *name)
786 {
787         struct wan_device *wandev;
788
789         for (wandev = wanrouter_router_devlist;
790              wandev && strcmp(wandev->name, name);
791                 wandev = wandev->next);
792         return wandev;
793 }
794
795 /*
796  *      Delete WAN logical channel identified by its name.
797  *      o find logical channel by its name
798  *      o call driver's del_if() entry point
799  *      o unregister network interface
800  *      o unlink channel data space from linked list of channels
801  *      o release channel data space
802  *
803  *      Return: 0               success
804  *              -ENODEV         channel not found.
805  *              -EBUSY          interface is open
806  *
807  *      Note: If (force != 0), then device will be destroyed even if interface
808  *      associated with it is open. It's caller's responsibility to make
809  *      sure that opened interfaces are not removed!
810  */
811
812 static int wanrouter_delete_interface(struct wan_device *wandev, char *name)
813 {
814         struct net_device *dev = NULL, *prev = NULL;
815         unsigned long smp_flags=0;
816
817         lock_adapter_irq(&wandev->lock, &smp_flags);
818         dev = wandev->dev;
819         prev = NULL;
820         while (dev && strcmp(name, dev->name)) {
821                 struct net_device **slave = dev->priv;
822                 prev = dev;
823                 dev = *slave;
824         }
825         unlock_adapter_irq(&wandev->lock, &smp_flags);
826
827         if (dev == NULL)
828                 return -ENODEV; /* interface not found */
829
830         if (netif_running(dev))
831                 return -EBUSY;  /* interface in use */
832
833         if (wandev->del_if)
834                 wandev->del_if(wandev, dev);
835
836         lock_adapter_irq(&wandev->lock, &smp_flags);
837         if (prev) {
838                 struct net_device **prev_slave = prev->priv;
839                 struct net_device **slave = dev->priv;
840
841                 *prev_slave = *slave;
842         } else {
843                 struct net_device **slave = dev->priv;
844                 wandev->dev = *slave;
845         }
846         --wandev->ndev;
847         unlock_adapter_irq(&wandev->lock, &smp_flags);
848
849         printk(KERN_INFO "%s: unregistering '%s'\n", wandev->name, dev->name);
850
851         /* Due to new interface linking method using dev->priv,
852          * this code has moved from del_if() function.*/
853         kfree(dev->priv);
854         dev->priv=NULL;
855
856         unregister_netdev(dev);
857
858         free_netdev(dev);
859
860         return 0;
861 }
862
863 void lock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags)
864 {
865         spin_lock_irqsave(lock, *smp_flags);
866 }
867
868
869 void unlock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags)
870 {
871         spin_unlock_irqrestore(lock, *smp_flags);
872 }
873
874 EXPORT_SYMBOL(register_wan_device);
875 EXPORT_SYMBOL(unregister_wan_device);
876 EXPORT_SYMBOL(wanrouter_encapsulate);
877 EXPORT_SYMBOL(wanrouter_type_trans);
878 EXPORT_SYMBOL(lock_adapter_irq);
879 EXPORT_SYMBOL(unlock_adapter_irq);
880
881 MODULE_LICENSE("GPL");
882
883 /*
884  *      End
885  */