]> rtime.felk.cvut.cz Git - linux-lin.git/blob - sllin/sllin.c
Added minimal skeleton to use kernel worker thread.
[linux-lin.git] / sllin / sllin.c
1 /*
2  * sllin.c - serial line LIN interface driver (using tty line discipline)
3  *
4  * This file is derived from linux/drivers/net/slip.c
5  *
6  * slip.c Authors  : Laurence Culhane <loz@holmes.demon.co.uk>
7  *                   Fred N. van Kempen <waltje@uwalt.nl.mugnet.org>
8  * sllin.c Author  : Oliver Hartkopp <socketcan@hartkopp.net>
9  *
10  * This program is free software; you can redistribute it and/or modify it
11  * under the terms of the GNU General Public License as published by the
12  * Free Software Foundation; either version 2 of the License, or (at your
13  * option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License along
21  * with this program; if not, write to the Free Software Foundation, Inc.,
22  * 59 Temple Place, Suite 330, Boston, MA 02111-1307. You can also get it
23  * at http://www.gnu.org/licenses/gpl.html
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
36  * DAMAGE.
37  *
38  * Send feedback to <socketcan-users@lists.berlios.de>
39  *
40  */
41
42 #include <linux/module.h>
43 #include <linux/moduleparam.h>
44
45 #include <asm/system.h>
46 #include <linux/uaccess.h>
47 #include <linux/bitops.h>
48 #include <linux/string.h>
49 #include <linux/tty.h>
50 #include <linux/errno.h>
51 #include <linux/netdevice.h>
52 #include <linux/skbuff.h>
53 #include <linux/rtnetlink.h>
54 #include <linux/if_arp.h>
55 #include <linux/if_ether.h>
56 #include <linux/sched.h>
57 #include <linux/delay.h>
58 #include <linux/init.h>
59 #include <linux/can.h>
60 #include <linux/kthread.h>
61
62 /* Should be in include/linux/tty.h */
63 #define N_SLLIN         25
64
65 static __initdata const char banner[] =
66         KERN_INFO "sllin: serial line LIN interface driver\n";
67
68 MODULE_ALIAS_LDISC(N_SLLIN);
69 MODULE_DESCRIPTION("serial line LIN interface");
70 MODULE_LICENSE("GPL");
71 MODULE_AUTHOR("Oliver Hartkopp <socketcan@hartkopp.net>");
72
73 #define SLLIN_MAGIC 0x53CA
74
75 static int maxdev = 10;         /* MAX number of SLLIN channels;
76                                    This can be overridden with
77                                    insmod sllin.ko maxdev=nnn   */
78 module_param(maxdev, int, 0);
79 MODULE_PARM_DESC(maxdev, "Maximum number of sllin interfaces");
80
81 /* maximum rx buffer len: extended CAN frame with timestamp */
82 #define SLC_MTU (sizeof("T1111222281122334455667788EA5F\r")+1)
83
84 struct sllin {
85         int                     magic;
86
87         /* Various fields. */
88         struct tty_struct       *tty;           /* ptr to TTY structure      */
89         struct net_device       *dev;           /* easy for intr handling    */
90         spinlock_t              lock;
91
92         /* These are pointers to the malloc()ed frame buffers. */
93         unsigned char           rbuff[SLC_MTU]; /* receiver buffer           */
94         int                     rcount;         /* received chars counter    */
95         unsigned char           xbuff[SLC_MTU]; /* transmitter buffer        */
96         unsigned char           *xhead;         /* pointer to next XMIT byte */
97         int                     xleft;          /* bytes left in XMIT queue  */
98
99         unsigned long           flags;          /* Flag values/ mode etc     */
100 #define SLF_INUSE               0               /* Channel in use            */
101 #define SLF_ERROR               1               /* Parity, etc. error        */
102
103         unsigned char           leased;
104         dev_t                   line;
105         struct task_struct      *kwthread;
106         wait_queue_head_t       kwt_wq;
107 };
108
109 static struct net_device **sllin_devs;
110
111
112 static int sltty_change_speed(struct tty_struct *tty, unsigned speed)
113 {
114         struct ktermios old_termios;
115         int cflag;
116
117         mutex_lock(&tty->termios_mutex);
118         old_termios = *(tty->termios);
119         cflag = tty->termios->c_cflag;
120         tty_encode_baud_rate(tty, speed, speed);
121         if (tty->ops->set_termios)
122                 tty->ops->set_termios(tty, &old_termios);
123         //priv->io.speed = speed;
124         mutex_unlock(&tty->termios_mutex);
125
126         return 0;
127 }
128
129
130 /* Send one completely decapsulated can_frame to the network layer */
131 static void sll_bump(struct sllin *sl)
132 {
133 //      struct sk_buff *skb;
134 //      struct can_frame cf;
135 //      int i, dlc_pos, tmp;
136 //      unsigned long ultmp;
137 //      char cmd = sl->rbuff[0];
138 //
139 //      if ((cmd != 't') && (cmd != 'T') && (cmd != 'r') && (cmd != 'R'))
140 //              return;
141 //
142 //      if (cmd & 0x20) /* tiny chars 'r' 't' => standard frame format */
143 //              dlc_pos = 4; /* dlc position tiiid */
144 //      else
145 //              dlc_pos = 9; /* dlc position Tiiiiiiiid */
146 //
147 //      if (!((sl->rbuff[dlc_pos] >= '0') && (sl->rbuff[dlc_pos] < '9')))
148 //              return;
149 //
150 //      cf.can_dlc = sl->rbuff[dlc_pos] - '0'; /* get can_dlc from ASCII val */
151 //
152 //      sl->rbuff[dlc_pos] = 0; /* terminate can_id string */
153 //
154 //      if (strict_strtoul(sl->rbuff+1, 16, &ultmp))
155 //              return;
156 //
157 //      cf.can_id = ultmp;
158 //
159 //      if (!(cmd & 0x20)) /* NO tiny chars => extended frame format */
160 //              cf.can_id |= CAN_EFF_FLAG;
161 //
162 //      if ((cmd | 0x20) == 'r') /* RTR frame */
163 //              cf.can_id |= CAN_RTR_FLAG;
164 //
165 //      *(u64 *) (&cf.data) = 0; /* clear payload */
166 //
167 //      for (i = 0, dlc_pos++; i < cf.can_dlc; i++) {
168 //
169 //              tmp = asc2nibble(sl->rbuff[dlc_pos++]);
170 //              if (tmp > 0x0F)
171 //                      return;
172 //              cf.data[i] = (tmp << 4);
173 //              tmp = asc2nibble(sl->rbuff[dlc_pos++]);
174 //              if (tmp > 0x0F)
175 //                      return;
176 //              cf.data[i] |= tmp;
177 //      }
178 //
179 //
180 //      skb = dev_alloc_skb(sizeof(struct can_frame));
181 //      if (!skb)
182 //              return;
183 //
184 //      skb->dev = sl->dev;
185 //      skb->protocol = htons(ETH_P_CAN);
186 //      skb->pkt_type = PACKET_BROADCAST;
187 //      skb->ip_summed = CHECKSUM_UNNECESSARY;
188 //      memcpy(skb_put(skb, sizeof(struct can_frame)),
189 //             &cf, sizeof(struct can_frame));
190 //      netif_rx(skb);
191 //
192 //      sl->dev->stats.rx_packets++;
193 //      sl->dev->stats.rx_bytes += cf.can_dlc;
194 }
195
196 /* parse tty input stream */
197 static void sllin_unesc(struct sllin *sl, unsigned char s)
198 {
199
200         if ((s == '\r') || (s == '\a')) { /* CR or BEL ends the pdu */
201                 if (!test_and_clear_bit(SLF_ERROR, &sl->flags) &&
202                     (sl->rcount > 4))  {
203                         sll_bump(sl);
204                 }
205                 sl->rcount = 0;
206         } else {
207                 if (!test_bit(SLF_ERROR, &sl->flags))  {
208                         if (sl->rcount < SLC_MTU)  {
209                                 sl->rbuff[sl->rcount++] = s;
210                                 return;
211                         } else {
212                                 sl->dev->stats.rx_over_errors++;
213                                 set_bit(SLF_ERROR, &sl->flags);
214                         }
215                 }
216         }
217 }
218
219  /************************************************************************
220   *                     STANDARD SLLIN ENCAPSULATION                     *
221   ************************************************************************/
222
223 /* Convert particular CAN frame into LIN frame and send it to TTY queue. */
224 static void sll_encaps(struct sllin *sl, struct can_frame *cf)
225 {
226         int actual, idx, i;
227         char lframe[16] = {0x00, 0x55}; /* Fake break, Sync byte */
228         struct tty_struct *tty = sl->tty;
229
230         pr_debug("sllin: %s() invoked\n", __FUNCTION__);
231
232         /* We do care only about SFF frames */
233         if (cf->can_id & CAN_EFF_FLAG)
234                 return;
235
236         /* Send only header */
237         if (cf->can_id & CAN_RTR_FLAG) {
238                 pr_debug("sllin: %s() RTR CAN frame\n", __FUNCTION__);
239                 lframe[2] = (u8)cf->can_id; /* Get one byte LIN ID */
240
241                 sltty_change_speed(tty, 1200);
242                 tty->ops->write(tty, &lframe[0], 1);
243                 sltty_change_speed(tty, 2400);
244                 tty->ops->write(tty, &lframe[1], 1);
245                 tty->ops->write(tty, &lframe[2], 1);
246         } else {
247                 pr_debug("sllin: %s() non-RTR CAN frame\n", __FUNCTION__);
248                 /*      idx = strlen(sl->xbuff);
249
250                         for (i = 0; i < cf->can_dlc; i++)
251                         sprintf(&sl->xbuff[idx + 2*i], "%02X", cf->data[i]);
252
253                  * Order of next two lines is *very* important.
254                  * When we are sending a little amount of data,
255                  * the transfer may be completed inside the ops->write()
256                  * routine, because it's running with interrupts enabled.
257                  * In this case we *never* got WRITE_WAKEUP event,
258                  * if we did not request it before write operation.
259                  *       14 Oct 1994  Dmitry Gorodchanin.
260
261                  set_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
262                  actual = sl->tty->ops->write(sl->tty, sl->xbuff, strlen(sl->xbuff));
263                  sl->xleft = strlen(sl->xbuff) - actual;
264                  sl->xhead = sl->xbuff + actual;
265                  sl->dev->stats.tx_bytes += cf->can_dlc;
266                  */
267         }
268
269 }
270
271 /*
272  * Called by the driver when there's room for more data.  If we have
273  * more packets to send, we send them here.
274  */
275 static void sllin_write_wakeup(struct tty_struct *tty)
276 {
277         int actual;
278         struct sllin *sl = (struct sllin *) tty->disc_data;
279
280         /* First make sure we're connected. */
281         if (!sl || sl->magic != SLLIN_MAGIC || !netif_running(sl->dev))
282                 return;
283
284         if (sl->xleft <= 0)  {
285                 /* Now serial buffer is almost free & we can start
286                  * transmission of another packet */
287                 sl->dev->stats.tx_packets++;
288                 clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
289                 netif_wake_queue(sl->dev);
290                 return;
291         }
292
293         actual = tty->ops->write(tty, sl->xhead, sl->xleft);
294         sl->xleft -= actual;
295         sl->xhead += actual;
296 }
297
298 /* Send a can_frame to a TTY queue. */
299 static netdev_tx_t sll_xmit(struct sk_buff *skb, struct net_device *dev)
300 {
301         struct sllin *sl = netdev_priv(dev);
302
303         if (skb->len != sizeof(struct can_frame))
304                 goto out;
305
306         spin_lock(&sl->lock);
307         if (!netif_running(dev))  {
308                 spin_unlock(&sl->lock);
309                 printk(KERN_WARNING "%s: xmit: iface is down\n", dev->name);
310                 goto out;
311         }
312         if (sl->tty == NULL) {
313                 spin_unlock(&sl->lock);
314                 goto out;
315         }
316
317         netif_stop_queue(sl->dev);
318         sll_encaps(sl, (struct can_frame *) skb->data); /* encaps & send */
319         spin_unlock(&sl->lock);
320
321 out:
322         kfree_skb(skb);
323         return NETDEV_TX_OK;
324 }
325
326
327 /******************************************
328  *   Routines looking at netdevice side.
329  ******************************************/
330
331 /* Netdevice UP -> DOWN routine */
332 static int sll_close(struct net_device *dev)
333 {
334         struct sllin *sl = netdev_priv(dev);
335
336         spin_lock_bh(&sl->lock);
337         if (sl->tty) {
338                 /* TTY discipline is running. */
339                 clear_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
340         }
341         netif_stop_queue(dev);
342         sl->rcount   = 0;
343         sl->xleft    = 0;
344         spin_unlock_bh(&sl->lock);
345
346         return 0;
347 }
348
349 /* Netdevice DOWN -> UP routine */
350 static int sll_open(struct net_device *dev)
351 {
352         struct sllin *sl = netdev_priv(dev);
353
354         pr_debug("sllin: %s() invoked\n", __FUNCTION__);
355
356         if (sl->tty == NULL)
357                 return -ENODEV;
358
359         sl->flags &= (1 << SLF_INUSE);
360         netif_start_queue(dev);
361         return 0;
362 }
363
364 /* Hook the destructor so we can free sllin devs at the right point in time */
365 static void sll_free_netdev(struct net_device *dev)
366 {
367         int i = dev->base_addr;
368         free_netdev(dev);
369         sllin_devs[i] = NULL;
370 }
371
372 static const struct net_device_ops sll_netdev_ops = {
373         .ndo_open               = sll_open,
374         .ndo_stop               = sll_close,
375         .ndo_start_xmit         = sll_xmit,
376 };
377
378 static void sll_setup(struct net_device *dev)
379 {
380         dev->netdev_ops         = &sll_netdev_ops;
381         dev->destructor         = sll_free_netdev;
382
383         dev->hard_header_len    = 0;
384         dev->addr_len           = 0;
385         dev->tx_queue_len       = 10;
386
387         dev->mtu                = sizeof(struct can_frame);
388         dev->type               = ARPHRD_CAN;
389
390         /* New-style flags. */
391         dev->flags              = IFF_NOARP;
392         dev->features           = NETIF_F_NO_CSUM;
393 }
394
395 /******************************************
396   Routines looking at TTY side.
397  ******************************************/
398
399 /*
400  * Handle the 'receiver data ready' interrupt.
401  * This function is called by the 'tty_io' module in the kernel when
402  * a block of SLLIN data has been received, which can now be decapsulated
403  * and sent on to some IP layer for further processing. This will not
404  * be re-entered while running but other ldisc functions may be called
405  * in parallel
406  */
407
408 static void sllin_receive_buf(struct tty_struct *tty,
409                               const unsigned char *cp, char *fp, int count)
410 {
411         struct sllin *sl = (struct sllin *) tty->disc_data;
412
413         if (!sl || sl->magic != SLLIN_MAGIC || !netif_running(sl->dev))
414                 return;
415
416         /* Read the characters out of the buffer */
417         while (count--) {
418                 if (fp && *fp++) {
419                         if (!test_and_set_bit(SLF_ERROR, &sl->flags))
420                                 sl->dev->stats.rx_errors++;
421                         cp++;
422                         continue;
423                 }
424                 sllin_unesc(sl, *cp++);
425         }
426 }
427
428 /*****************************************
429  *  sllin_kwthread - kernel worker thread
430  *****************************************/
431
432 int sllin_kwthread(void *ptr)
433 {
434         struct sllin *sl = (struct sllin *)ptr;
435
436         printk(KERN_INFO "sllin: sllin_kwthread started.\n");
437
438         while (!kthread_should_stop()) {
439                 
440                 wait_event_killable(sl->kwt_wq, kthread_should_stop());
441
442         }
443
444         printk(KERN_INFO "sllin: sllin_kwthread stopped.\n");
445
446         return 0;
447 }
448
449
450 /************************************
451  *  sllin_open helper routines.
452  ************************************/
453
454 /* Collect hanged up channels */
455 static void sll_sync(void)
456 {
457         int i;
458         struct net_device *dev;
459         struct sllin      *sl;
460
461         for (i = 0; i < maxdev; i++) {
462                 dev = sllin_devs[i];
463                 if (dev == NULL)
464                         break;
465
466                 sl = netdev_priv(dev);
467                 if (sl->tty || sl->leased)
468                         continue;
469                 if (dev->flags & IFF_UP)
470                         dev_close(dev);
471         }
472 }
473
474 /* Find a free SLLIN channel, and link in this `tty' line. */
475 static struct sllin *sll_alloc(dev_t line)
476 {
477         int i;
478         struct net_device *dev = NULL;
479         struct sllin       *sl;
480
481         if (sllin_devs == NULL)
482                 return NULL;    /* Master array missing ! */
483
484         for (i = 0; i < maxdev; i++) {
485                 dev = sllin_devs[i];
486                 if (dev == NULL)
487                         break;
488
489         }
490
491         /* Sorry, too many, all slots in use */
492         if (i >= maxdev)
493                 return NULL;
494
495         if (dev) {
496                 sl = netdev_priv(dev);
497                 if (test_bit(SLF_INUSE, &sl->flags)) {
498                         unregister_netdevice(dev);
499                         dev = NULL;
500                         sllin_devs[i] = NULL;
501                 }
502         }
503
504         if (!dev) {
505                 char name[IFNAMSIZ];
506                 sprintf(name, "sllin%d", i);
507
508                 dev = alloc_netdev(sizeof(*sl), name, sll_setup);
509                 if (!dev)
510                         return NULL;
511                 dev->base_addr  = i;
512         }
513
514         sl = netdev_priv(dev);
515
516         /* Initialize channel control data */
517         sl->magic = SLLIN_MAGIC;
518         sl->dev = dev;
519         spin_lock_init(&sl->lock);
520         sllin_devs[i] = dev;
521
522         return sl;
523 }
524
525 /*
526  * Open the high-level part of the SLLIN channel.
527  * This function is called by the TTY module when the
528  * SLLIN line discipline is called for.  Because we are
529  * sure the tty line exists, we only have to link it to
530  * a free SLLIN channel...
531  *
532  * Called in process context serialized from other ldisc calls.
533  */
534
535 static int sllin_open(struct tty_struct *tty)
536 {
537         struct sllin *sl;
538         int err;
539         pr_debug("sllin: %s() invoked\n", __FUNCTION__);
540
541         if (!capable(CAP_NET_ADMIN))
542                 return -EPERM;
543
544         if (tty->ops->write == NULL)
545                 return -EOPNOTSUPP;
546
547         /* RTnetlink lock is misused here to serialize concurrent
548            opens of sllin channels. There are better ways, but it is
549            the simplest one.
550          */
551         rtnl_lock();
552
553         /* Collect hanged up channels. */
554         sll_sync();
555
556         sl = tty->disc_data;
557
558         err = -EEXIST;
559         /* First make sure we're not already connected. */
560         if (sl && sl->magic == SLLIN_MAGIC)
561                 goto err_exit;
562
563         /* OK.  Find a free SLLIN channel to use. */
564         err = -ENFILE;
565         sl = sll_alloc(tty_devnum(tty));
566         if (sl == NULL)
567                 goto err_exit;
568
569         sl->tty = tty;
570         tty->disc_data = sl;
571         sl->line = tty_devnum(tty);
572
573         if (!test_bit(SLF_INUSE, &sl->flags)) {
574                 /* Perform the low-level SLLIN initialization. */
575                 sl->rcount   = 0;
576                 sl->xleft    = 0;
577
578                 set_bit(SLF_INUSE, &sl->flags);
579
580                 init_waitqueue_head(&sl->kwt_wq);
581                 sl->kwthread = kthread_run(sllin_kwthread, sl, "sllin");
582                 if (sl->kwthread == NULL)
583                         goto err_free_chan;
584
585                 err = register_netdevice(sl->dev);
586                 if (err)
587                         goto err_free_chan_and_thread;
588         }
589
590         /* Done.  We have linked the TTY line to a channel. */
591         rtnl_unlock();
592         tty->receive_room = 65536;      /* We don't flow control */
593
594         /* TTY layer expects 0 on success */
595         return 0;
596
597 err_free_chan_and_thread:
598         kthread_stop(sl->kwthread);
599         sl->kwthread = NULL;
600
601 err_free_chan:
602         sl->tty = NULL;
603         tty->disc_data = NULL;
604         clear_bit(SLF_INUSE, &sl->flags);
605
606 err_exit:
607         rtnl_unlock();
608
609         /* Count references from TTY module */
610         return err;
611 }
612
613 /*
614  * Close down a SLLIN channel.
615  * This means flushing out any pending queues, and then returning. This
616  * call is serialized against other ldisc functions.
617  *
618  * We also use this method for a hangup event.
619  */
620
621 static void sllin_close(struct tty_struct *tty)
622 {
623         struct sllin *sl = (struct sllin *) tty->disc_data;
624
625         /* First make sure we're connected. */
626         if (!sl || sl->magic != SLLIN_MAGIC || sl->tty != tty)
627                 return;
628
629         kthread_stop(sl->kwthread);
630         sl->kwthread = NULL;
631
632         tty->disc_data = NULL;
633         sl->tty = NULL;
634         if (!sl->leased)
635                 sl->line = 0;
636
637         /* Flush network side */
638         unregister_netdev(sl->dev);
639         /* This will complete via sl_free_netdev */
640 }
641
642 static int sllin_hangup(struct tty_struct *tty)
643 {
644         sllin_close(tty);
645         return 0;
646 }
647
648 /* Perform I/O control on an active SLLIN channel. */
649 static int sllin_ioctl(struct tty_struct *tty, struct file *file,
650                        unsigned int cmd, unsigned long arg)
651 {
652         struct sllin *sl = (struct sllin *) tty->disc_data;
653         unsigned int tmp;
654
655         /* First make sure we're connected. */
656         if (!sl || sl->magic != SLLIN_MAGIC)
657                 return -EINVAL;
658
659         switch (cmd) {
660         case SIOCGIFNAME:
661                 tmp = strlen(sl->dev->name) + 1;
662                 if (copy_to_user((void __user *)arg, sl->dev->name, tmp))
663                         return -EFAULT;
664                 return 0;
665
666         case SIOCSIFHWADDR:
667                 return -EINVAL;
668
669         default:
670                 return tty_mode_ioctl(tty, file, cmd, arg);
671         }
672 }
673
674 static struct tty_ldisc_ops sll_ldisc = {
675         .owner          = THIS_MODULE,
676         .magic          = TTY_LDISC_MAGIC,
677         .name           = "sllin",
678         .open           = sllin_open,
679         .close          = sllin_close,
680         .hangup         = sllin_hangup,
681         .ioctl          = sllin_ioctl,
682         .receive_buf    = sllin_receive_buf,
683         .write_wakeup   = sllin_write_wakeup,
684 };
685
686 static int __init sllin_init(void)
687 {
688         int status;
689
690         if (maxdev < 4)
691                 maxdev = 4; /* Sanity */
692
693         printk(banner);
694         printk(KERN_INFO "sllin: %d dynamic interface channels.\n", maxdev);
695
696         sllin_devs = kzalloc(sizeof(struct net_device *)*maxdev, GFP_KERNEL);
697         if (!sllin_devs) {
698                 printk(KERN_ERR "sllin: can't allocate sllin device array!\n");
699                 return -ENOMEM;
700         }
701
702         /* Fill in our line protocol discipline, and register it */
703         status = tty_register_ldisc(N_SLLIN, &sll_ldisc);
704         if (status)  {
705                 printk(KERN_ERR "sllin: can't register line discipline\n");
706                 kfree(sllin_devs);
707         }
708         return status;
709 }
710
711 static void __exit sllin_exit(void)
712 {
713         int i;
714         struct net_device *dev;
715         struct sllin *sl;
716         unsigned long timeout = jiffies + HZ;
717         int busy = 0;
718
719         if (sllin_devs == NULL)
720                 return;
721
722         /* First of all: check for active disciplines and hangup them.
723          */
724         do {
725                 if (busy)
726                         msleep_interruptible(100);
727
728                 busy = 0;
729                 for (i = 0; i < maxdev; i++) {
730                         dev = sllin_devs[i];
731                         if (!dev)
732                                 continue;
733                         sl = netdev_priv(dev);
734                         spin_lock_bh(&sl->lock);
735                         if (sl->tty) {
736                                 busy++;
737                                 tty_hangup(sl->tty);
738                         }
739                         spin_unlock_bh(&sl->lock);
740                 }
741         } while (busy && time_before(jiffies, timeout));
742
743         /* FIXME: hangup is async so we should wait when doing this second
744            phase */
745
746         for (i = 0; i < maxdev; i++) {
747                 dev = sllin_devs[i];
748                 if (!dev)
749                         continue;
750                 sllin_devs[i] = NULL;
751
752                 sl = netdev_priv(dev);
753                 if (sl->tty) {
754                         printk(KERN_ERR "%s: tty discipline still running\n",
755                                dev->name);
756                         /* Intentionally leak the control block. */
757                         dev->destructor = NULL;
758                 }
759
760                 unregister_netdev(dev);
761         }
762
763         kfree(sllin_devs);
764         sllin_devs = NULL;
765
766         i = tty_unregister_ldisc(N_SLLIN);
767         if (i)
768                 printk(KERN_ERR "sllin: can't unregister ldisc (err %d)\n", i);
769 }
770
771 module_init(sllin_init);
772 module_exit(sllin_exit);