]> rtime.felk.cvut.cz Git - socketcan-devel.git/blob - kernel/2.6/drivers/net/can/slcan.c
Device interface coding style cleanup (dev.c, dev.h)
[socketcan-devel.git] / kernel / 2.6 / drivers / net / can / slcan.c
1 /*
2  * slcan.c - serial line CAN interface driver (using tty line discipline)
3  *
4  * Copyright (c) 2007 Volkswagen Group Electronic Research
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of Volkswagen nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * Alternatively, provided that this notice is retained in full, this
20  * software may be distributed under the terms of the GNU General
21  * Public License ("GPL") version 2, in which case the provisions of the
22  * GPL apply INSTEAD OF those given above.
23  *
24  * The provided data structures and external interfaces from this code
25  * are not restricted to be used by modules with a GPL compatible license.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
38  * DAMAGE.
39  *
40  * Send feedback to <socketcan-users@lists.berlios.de>
41  *
42  */
43
44 /*
45  * This file is derived from linux/drivers/net/slip.c
46  *
47  * Therefore it has the same (strange?) behaviour not to unregister the
48  * netdevice when detaching the tty. Is there any better solution?
49  *
50  * Do not try to attach, detach and re-attach a tty for this reason ...
51  *
52  * slip.c Authors: Laurence Culhane, <loz@holmes.demon.co.uk>
53  *                 Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
54  */
55
56 #include <linux/module.h>
57 #include <linux/moduleparam.h>
58
59 #include <asm/system.h>
60 #include <asm/uaccess.h>
61 #include <linux/bitops.h>
62 #include <linux/string.h>
63 #include <linux/mm.h>
64 #include <linux/interrupt.h>
65 #include <linux/in.h>
66 #include <linux/tty.h>
67 #include <linux/errno.h>
68 #include <linux/netdevice.h>
69 #include <linux/etherdevice.h>
70 #include <linux/skbuff.h>
71 #include <linux/rtnetlink.h>
72 #include <linux/if_arp.h>
73 #include <linux/if_ether.h>
74 #include <linux/if_slip.h>
75 #include <linux/delay.h>
76 #include <linux/init.h>
77
78 #include <linux/can.h>
79
80 #include <linux/can/version.h> /* for RCSID. Removed by mkpatch script */
81 RCSID("$Id$");
82
83 static __initdata const char banner[] =
84         KERN_INFO "slcan: serial line CAN interface driver\n";
85
86 MODULE_ALIAS_LDISC(N_SLCAN);
87 MODULE_DESCRIPTION("serial line CAN interface");
88 MODULE_LICENSE("Dual BSD/GPL");
89 MODULE_AUTHOR("Oliver Hartkopp <oliver.hartkopp@volkswagen.de>");
90
91 #ifdef CONFIG_CAN_DEBUG_DEVICES
92 static int debug = 0;
93 module_param(debug, int, S_IRUGO);
94 #define DBG(args...)       (debug & 1 ? \
95                                (printk(KERN_DEBUG "slcan %s: ", __func__), \
96                                 printk(args)) : 0)
97 #else
98 #define DBG(args...)
99 #endif
100
101 #ifndef N_SLCAN
102 #error Your kernel does not support tty line discipline N_SLCAN
103 #endif
104 /*
105  * As there is currently no line discipline N_SLCAN in the mainstream kernel
106  * you will have to modify two kernel includes & recompile the kernel.
107  *
108  * Add this in include/asm/termios.h after the definition of N_HCI:
109  *        #define N_SLCAN         16
110  *
111  * Increment NR_LDICS in include/linux/tty.h from 16 to 17
112  *
113  * NEW: Since Kernel 2.6.21 you only have to change include/linux/tty.h
114  *
115  */
116
117 #define SLC_CHECK_TRANSMIT
118 #define SLCAN_MAGIC 0x53CA
119
120 static int maxdev = 10;         /* MAX number of SLCAN channels;
121                                    This can be overridden with
122                                    insmod slcan.ko maxdev=nnn   */
123 module_param(maxdev, int, 0);
124 MODULE_PARM_DESC(maxdev, "Maximum number of slcan interfaces");
125
126 /* maximum rx buffer len: extended CAN frame with timestamp */
127 #define SLC_MTU (sizeof("T1111222281122334455667788EA5F\r")+1)
128
129 struct slcan {
130         int                     magic;
131
132         /* Various fields. */
133         struct tty_struct       *tty;           /* ptr to TTY structure      */
134         struct net_device       *dev;           /* easy for intr handling    */
135         spinlock_t              lock;
136
137         /* These are pointers to the malloc()ed frame buffers. */
138         unsigned char           rbuff[SLC_MTU]; /* receiver buffer           */
139         int                     rcount;         /* received chars counter    */
140         unsigned char           xbuff[SLC_MTU]; /* transmitter buffer        */
141         unsigned char           *xhead;         /* pointer to next XMIT byte */
142         int                     xleft;          /* bytes left in XMIT queue  */
143
144 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
145         /* SLCAN interface statistics. */
146         struct net_device_stats stats;
147 #endif
148
149         unsigned long           flags;          /* Flag values/ mode etc     */
150 #define SLF_INUSE               0               /* Channel in use            */
151 #define SLF_ERROR               1               /* Parity, etc. error        */
152
153         unsigned char           leased;
154         dev_t                   line;
155         pid_t                   pid;
156 };
157
158 static struct net_device **slcan_devs;
159
160  /************************************************************************
161   *                     SLCAN ENCAPSULATION FORMAT                       *
162   ************************************************************************/
163
164 /*
165  * A CAN frame has a can_id (11 bit standard frame format OR 29 bit extended
166  * frame format) a data length code (can_dlc) which can be from 0 to 8
167  * and up to <can_dlc> data bytes as payload.
168  * Additionally a CAN frame may become a remote transmission frame if the
169  * RTR-bit is set. This causes another ECU to send a CAN frame with the
170  * given can_id.
171  *
172  * The SLCAN ASCII representation of these different frame types is:
173  * <type> <id> <dlc> <data>*
174  *
175  * Extended frames (29 bit) are defined by capital characters in the type.
176  * RTR frames are defined as 'r' types - normal frames have 't' type:
177  * t => 11 bit data frame
178  * r => 11 bit RTR frame
179  * T => 29 bit data frame
180  * R => 29 bit RTR frame
181  *
182  * The <id> is 3 (standard) or 8 (extended) bytes in ASCII Hex (base64).
183  * The <dlc> is a one byte ASCII number ('0' - '8')
184  * The <data> section has at much ASCII Hex bytes as defined by the <dlc>
185  *
186  * Examples:
187  *
188  * t1230 : can_id 0x123, can_dlc 0, no data
189  * t4563112233 : can_id 0x456, can_dlc 3, data 0x11 0x22 0x33
190  * T12ABCDEF2AA55 : extended can_id 0x12ABCDEF, can_dlc 2, data 0xAA 0x55
191  * r1230 : can_id 0x123, can_dlc 0, no data, remote transmission request
192  *
193  */
194
195  /************************************************************************
196   *                     STANDARD SLCAN DECAPSULATION                     *
197   ************************************************************************/
198
199 static int asc2nibble(char c) {
200
201         if ((c >= '0') && (c <= '9'))
202                 return c - '0';
203
204         if ((c >= 'A') && (c <= 'F'))
205                 return c - 'A' + 10;
206
207         if ((c >= 'a') && (c <= 'f'))
208                 return c - 'a' + 10;
209
210         return 16; /* error */
211 }
212
213 /* Send one completely decapsulated can_frame to the network layer */
214 static void slc_bump(struct slcan *sl)
215 {
216         struct net_device_stats *stats = sl->dev->get_stats(sl->dev);
217         struct sk_buff *skb;
218         struct can_frame cf;
219         int i, dlc_pos, tmp;
220         char cmd = sl->rbuff[0];
221
222         if ((cmd != 't') && (cmd != 'T') && (cmd != 'r') && (cmd != 'R'))
223                 return;
224
225         if (cmd & 0x20) /* tiny chars 'r' 't' => standard frame format */
226                 dlc_pos = 4; /* dlc position tiiid */
227         else
228                 dlc_pos = 9; /* dlc position Tiiiiiiiid */
229
230         if (!((sl->rbuff[dlc_pos] >= '0') && (sl->rbuff[dlc_pos] < '9')))
231                 return;
232
233         cf.can_dlc = sl->rbuff[dlc_pos] & 0x0F; /* get can_dlc */
234
235         sl->rbuff[dlc_pos] = 0; /* terminate can_id string */
236         cf.can_id = simple_strtoul(sl->rbuff+1, NULL, 16);
237
238         if (!(cmd & 0x20)) /* NO tiny chars => extended frame format */
239                 cf.can_id |= CAN_EFF_FLAG;
240
241         if ((cmd | 0x20) == 'r') /* RTR frame */
242                 cf.can_id |= CAN_RTR_FLAG;
243
244         *(u64 *) (&cf.data) = 0; /* clear payload */
245
246         for (i = 0, dlc_pos++; i < cf.can_dlc; i++){
247
248                 if ((tmp = asc2nibble(sl->rbuff[dlc_pos++])) > 0x0F)
249                         return;
250                 cf.data[i] = (tmp << 4);
251                 if ((tmp = asc2nibble(sl->rbuff[dlc_pos++])) > 0x0F)
252                         return;
253                 cf.data[i] |= tmp;
254         }
255
256
257         skb = dev_alloc_skb(sizeof(struct can_frame));
258         if (!skb)
259                 return;
260
261         skb->dev = sl->dev;
262         skb->protocol = htons(ETH_P_CAN);
263         skb->pkt_type = PACKET_BROADCAST;
264         skb->ip_summed = CHECKSUM_UNNECESSARY;
265         memcpy(skb_put(skb, sizeof(struct can_frame)),
266                &cf, sizeof(struct can_frame));
267         netif_rx(skb);
268
269         sl->dev->last_rx = jiffies;
270         stats->rx_packets++;
271         stats->rx_bytes += cf.can_dlc;
272 }
273
274 /* parse tty input stream */
275 static void slcan_unesc(struct slcan *sl, unsigned char s)
276 {
277         struct net_device_stats *stats = sl->dev->get_stats(sl->dev);
278
279         if ((s == '\r') || (s == '\a')) { /* CR or BEL ends the pdu */
280                 if (!test_and_clear_bit(SLF_ERROR, &sl->flags) &&
281                     (sl->rcount > 4))  {
282                         slc_bump(sl);
283                 }
284                 sl->rcount = 0;
285         } else {
286                 if (!test_bit(SLF_ERROR, &sl->flags))  {
287                         if (sl->rcount < SLC_MTU)  {
288                                 sl->rbuff[sl->rcount++] = s;
289                                 return;
290                         } else {
291                                 stats->rx_over_errors++;
292                                 set_bit(SLF_ERROR, &sl->flags);
293                         }
294                 }
295         }
296 }
297
298  /************************************************************************
299   *                     STANDARD SLCAN ENCAPSULATION                     *
300   ************************************************************************/
301
302 /* Encapsulate one can_frame and stuff into a TTY queue. */
303 static void slc_encaps(struct slcan *sl, struct can_frame *cf)
304 {
305         struct net_device_stats *stats = sl->dev->get_stats(sl->dev);
306         int actual, idx, i;
307         char cmd;
308
309         if (cf->can_id & CAN_RTR_FLAG)
310                 cmd = 'R'; /* becomes 'r' in standard frame format */
311         else
312                 cmd = 'T'; /* becomes 't' in standard frame format */
313
314         if (cf->can_id & CAN_EFF_FLAG)
315                 sprintf(sl->xbuff, "%c%08X%d", cmd,
316                         cf->can_id & CAN_EFF_MASK, cf->can_dlc);
317         else
318                 sprintf(sl->xbuff, "%c%03X%d", cmd | 0x20,
319                         cf->can_id & CAN_SFF_MASK, cf->can_dlc);
320
321         idx = strlen(sl->xbuff);
322
323         for (i = 0; i < cf->can_dlc; i++)
324                 sprintf(&sl->xbuff[idx + 2*i], "%02X", cf->data[i]);
325
326         DBG("ASCII frame = '%s'\n", sl->xbuff);
327
328         strcat(sl->xbuff, "\r"); /* add terminating character */
329
330         /* Order of next two lines is *very* important.
331          * When we are sending a little amount of data,
332          * the transfer may be completed inside driver.write()
333          * routine, because it's running with interrupts enabled.
334          * In this case we *never* got WRITE_WAKEUP event,
335          * if we did not request it before write operation.
336          *       14 Oct 1994  Dmitry Gorodchanin.
337          */
338         sl->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
339         actual = sl->tty->driver->write(sl->tty, sl->xbuff, strlen(sl->xbuff));
340 #ifdef SLC_CHECK_TRANSMIT
341         sl->dev->trans_start = jiffies;
342 #endif
343         sl->xleft = strlen(sl->xbuff) - actual;
344         sl->xhead = sl->xbuff + actual;
345         stats->tx_bytes += cf->can_dlc;
346 }
347
348 /*
349  * Called by the driver when there's room for more data.  If we have
350  * more packets to send, we send them here.
351  */
352 static void slcan_write_wakeup(struct tty_struct *tty)
353 {
354         int actual;
355         struct slcan *sl = (struct slcan *) tty->disc_data;
356         struct net_device_stats *stats = sl->dev->get_stats(sl->dev);
357
358         /* First make sure we're connected. */
359         if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev)) {
360                 return;
361         }
362         if (sl->xleft <= 0)  {
363                 /* Now serial buffer is almost free & we can start
364                  * transmission of another packet */
365                 stats->tx_packets++;
366                 tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
367                 netif_wake_queue(sl->dev);
368                 return;
369         }
370
371         actual = tty->driver->write(tty, sl->xhead, sl->xleft);
372         sl->xleft -= actual;
373         sl->xhead += actual;
374 }
375
376 static void slc_tx_timeout(struct net_device *dev)
377 {
378         struct slcan *sl = netdev_priv(dev);
379
380         spin_lock(&sl->lock);
381
382         if (netif_queue_stopped(dev)) {
383                 if (!netif_running(dev))
384                         goto out;
385
386                 /* May be we must check transmitter timeout here ?
387                  *      14 Oct 1994 Dmitry Gorodchanin.
388                  */
389 #ifdef SLC_CHECK_TRANSMIT
390                 if (time_before(jiffies, dev->trans_start + 20 * HZ))  {
391                         /* 20 sec timeout not reached */
392                         goto out;
393                 }
394                 printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name,
395                        (sl->tty->driver->chars_in_buffer(sl->tty) || sl->xleft)
396                        ? "bad line quality" : "driver error");
397                 sl->xleft = 0;
398                 sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
399                 netif_wake_queue(sl->dev);
400 #endif
401         }
402 out:
403         spin_unlock(&sl->lock);
404 }
405
406
407 /******************************************
408  *   Routines looking at netdevice side.
409  ******************************************/
410
411 /* Send a can_frame to a TTY queue. */
412 static int slc_xmit(struct sk_buff *skb, struct net_device *dev)
413 {
414         struct slcan *sl = netdev_priv(dev);
415
416         if (skb->len != sizeof(struct can_frame))
417                 goto out;
418
419         spin_lock(&sl->lock);
420         if (!netif_running(dev))  {
421                 spin_unlock(&sl->lock);
422                 printk(KERN_WARNING "%s: xmit: iface is down\n", dev->name);
423                 goto out;
424         }
425
426         if (sl->tty == NULL) {
427                 spin_unlock(&sl->lock);
428                 goto out;
429         }
430
431         netif_stop_queue(sl->dev);
432         slc_encaps(sl, (struct can_frame *) skb->data); /* encaps & send */
433         spin_unlock(&sl->lock);
434
435 out:
436         kfree_skb(skb);
437         return 0;
438 }
439
440
441 /* Netdevice UP -> DOWN routine */
442 static int slc_close(struct net_device *dev)
443 {
444         struct slcan *sl = netdev_priv(dev);
445
446         spin_lock_bh(&sl->lock);
447         if (sl->tty) {
448                 /* TTY discipline is running. */
449                 sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
450         }
451         netif_stop_queue(dev);
452         sl->rcount   = 0;
453         sl->xleft    = 0;
454         spin_unlock_bh(&sl->lock);
455
456         return 0;
457 }
458
459 /* Netdevice DOWN -> UP routine */
460 static int slc_open(struct net_device *dev)
461 {
462         struct slcan *sl = netdev_priv(dev);
463
464         if (sl->tty==NULL)
465                 return -ENODEV;
466
467         sl->flags &= (1 << SLF_INUSE);
468         netif_start_queue(dev);
469         return 0;
470 }
471
472 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
473 /* Netdevice get statistics request */
474 static struct net_device_stats *slc_get_stats(struct net_device *dev)
475 {
476         struct slcan *sl = netdev_priv(dev);
477
478         return (&sl->stats);
479 }
480 #endif
481
482 /* Netdevice register callback */
483 static void slc_setup(struct net_device *dev)
484 {
485         dev->open               = slc_open;
486         dev->destructor         = free_netdev;
487         dev->stop               = slc_close;
488 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
489         dev->get_stats          = slc_get_stats;
490 #endif
491         dev->hard_start_xmit    = slc_xmit;
492
493         dev->hard_header_len    = 0;
494         dev->addr_len           = 0;
495         dev->tx_queue_len       = 10;
496
497         dev->mtu                = sizeof(struct can_frame);
498         dev->type               = ARPHRD_CAN;
499 #ifdef SLC_CHECK_TRANSMIT
500         dev->tx_timeout         = slc_tx_timeout;
501         dev->watchdog_timeo     = 20*HZ;
502 #endif
503
504         /* New-style flags. */
505         dev->flags              = IFF_NOARP;
506         dev->features           = NETIF_F_NO_CSUM;
507 }
508
509 /******************************************
510  * Routines looking at TTY side.
511  ******************************************/
512
513 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
514 static int slcan_receive_room(struct tty_struct *tty)
515 {
516         return 65536;  /* We can handle an infinite amount of data. :-) */
517 }
518 #endif
519
520 /*
521  * Handle the 'receiver data ready' interrupt.
522  * This function is called by the 'tty_io' module in the kernel when
523  * a block of SLCAN data has been received, which can now be decapsulated
524  * and sent on to some IP layer for further processing. This will not
525  * be re-entered while running but other ldisc functions may be called
526  * in parallel
527  */
528
529 static void slcan_receive_buf(struct tty_struct *tty,
530                               const unsigned char *cp, char *fp, int count)
531 {
532         struct slcan *sl = (struct slcan *) tty->disc_data;
533         struct net_device_stats *stats = sl->dev->get_stats(sl->dev);
534
535         if (!sl || sl->magic != SLCAN_MAGIC ||
536             !netif_running(sl->dev))
537                 return;
538
539         /* Read the characters out of the buffer */
540         while (count--) {
541                 if (fp && *fp++) {
542                         if (!test_and_set_bit(SLF_ERROR, &sl->flags))  {
543                                 stats->rx_errors++;
544                         }
545                         cp++;
546                         continue;
547                 }
548                 slcan_unesc(sl, *cp++);
549         }
550 }
551
552 /************************************
553  *  slcan_open helper routines.
554  ************************************/
555
556 /* Collect hanged up channels */
557
558 static void slc_sync(void)
559 {
560         int i;
561         struct net_device *dev;
562         struct slcan      *sl;
563
564         for (i = 0; i < maxdev; i++) {
565                 if ((dev = slcan_devs[i]) == NULL)
566                         break;
567
568                 sl = netdev_priv(dev);
569                 if (sl->tty || sl->leased)
570                         continue;
571                 if (dev->flags&IFF_UP)
572                         dev_close(dev);
573         }
574 }
575
576
577 /* Find a free SLCAN channel, and link in this `tty' line. */
578 static struct slcan *slc_alloc(dev_t line)
579 {
580         int i;
581         int sel = -1;
582         int score = -1;
583         struct net_device *dev = NULL;
584         struct slcan       *sl;
585
586         if (slcan_devs == NULL)
587                 return NULL;    /* Master array missing ! */
588
589         for (i = 0; i < maxdev; i++) {
590                 dev = slcan_devs[i];
591                 if (dev == NULL)
592                         break;
593
594                 sl = netdev_priv(dev);
595                 if (sl->leased) {
596                         if (sl->line != line)
597                                 continue;
598                         if (sl->tty)
599                                 return NULL;
600
601                         /* Clear ESCAPE & ERROR flags */
602                         sl->flags &= (1 << SLF_INUSE);
603                         return sl;
604                 }
605
606                 if (sl->tty)
607                         continue;
608
609                 if (current->pid == sl->pid) {
610                         if (sl->line == line && score < 3) {
611                                 sel = i;
612                                 score = 3;
613                                 continue;
614                         }
615                         if (score < 2) {
616                                 sel = i;
617                                 score = 2;
618                         }
619                         continue;
620                 }
621                 if (sl->line == line && score < 1) {
622                         sel = i;
623                         score = 1;
624                         continue;
625                 }
626                 if (score < 0) {
627                         sel = i;
628                         score = 0;
629                 }
630         }
631
632         if (sel >= 0) {
633                 i = sel;
634                 dev = slcan_devs[i];
635                 if (score > 1) {
636                         sl = netdev_priv(dev);
637                         sl->flags &= (1 << SLF_INUSE);
638                         return sl;
639                 }
640         }
641
642         /* Sorry, too many, all slots in use */
643         if (i >= maxdev)
644                 return NULL;
645
646         if (dev) {
647                 sl = netdev_priv(dev);
648                 if (test_bit(SLF_INUSE, &sl->flags)) {
649                         unregister_netdevice(dev);
650                         free_netdev(dev); /* new in slcan.c */
651                         dev = NULL;
652                         slcan_devs[i] = NULL;
653                 }
654         }
655
656         if (!dev) {
657                 char name[IFNAMSIZ];
658                 sprintf(name, "slc%d", i);
659
660                 dev = alloc_netdev(sizeof(*sl), name, slc_setup);
661                 if (!dev)
662                         return NULL;
663                 dev->base_addr  = i;
664         }
665
666         sl = netdev_priv(dev);
667
668         /* Initialize channel control data */
669         sl->magic       = SLCAN_MAGIC;
670         sl->dev         = dev;
671         spin_lock_init(&sl->lock);
672         slcan_devs[i] = dev;
673
674         return sl;
675 }
676
677 /*
678  * Open the high-level part of the SLCAN channel.
679  * This function is called by the TTY module when the
680  * SLCAN line discipline is called for.  Because we are
681  * sure the tty line exists, we only have to link it to
682  * a free SLCAN channel...
683  *
684  * Called in process context serialized from other ldisc calls.
685  */
686
687 static int slcan_open(struct tty_struct *tty)
688 {
689         struct slcan *sl;
690         int err;
691
692         if(!capable(CAP_NET_ADMIN))
693                 return -EPERM;
694
695         /* RTnetlink lock is misused here to serialize concurrent
696            opens of slcan channels. There are better ways, but it is
697            the simplest one.
698          */
699         rtnl_lock();
700
701         /* Collect hanged up channels. */
702         slc_sync();
703
704         sl = (struct slcan *) tty->disc_data;
705
706         err = -EEXIST;
707         /* First make sure we're not already connected. */
708         if (sl && sl->magic == SLCAN_MAGIC)
709                 goto err_exit;
710
711         /* OK.  Find a free SLCAN channel to use. */
712         err = -ENFILE;
713         if ((sl = slc_alloc(tty_devnum(tty))) == NULL)
714                 goto err_exit;
715
716         sl->tty = tty;
717         tty->disc_data = sl;
718         sl->line = tty_devnum(tty);
719         sl->pid = current->pid;
720
721 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
722         /* FIXME: already done before we were called - seems this can go */
723         if (tty->driver->flush_buffer)
724                 tty->driver->flush_buffer(tty);
725 #endif
726
727         if (!test_bit(SLF_INUSE, &sl->flags)) {
728                 /* Perform the low-level SLCAN initialization. */
729                 sl->rcount   = 0;
730                 sl->xleft    = 0;
731
732                 set_bit(SLF_INUSE, &sl->flags);
733
734                 if ((err = register_netdevice(sl->dev)))
735                         goto err_free_chan;
736         }
737
738         /* Done.  We have linked the TTY line to a channel. */
739         rtnl_unlock();
740
741 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
742         tty->receive_room = 65536;      /* We don't flow control */
743 #endif
744
745         return sl->dev->base_addr;
746
747 err_free_chan:
748         sl->tty = NULL;
749         tty->disc_data = NULL;
750         clear_bit(SLF_INUSE, &sl->flags);
751
752 err_exit:
753         rtnl_unlock();
754
755         /* Count references from TTY module */
756         return err;
757 }
758
759 /*
760
761   FIXME: 1,2 are fixed 3 was never true anyway.
762
763    Let me to blame a bit.
764    1. TTY module calls this funstion on soft interrupt.
765    2. TTY module calls this function WITH MASKED INTERRUPTS!
766    3. TTY module does not notify us about line discipline
767       shutdown,
768
769    Seems, now it is clean. The solution is to consider netdevice and
770    line discipline sides as two independent threads.
771
772    By-product (not desired): slc? does not feel hangups and remains open.
773    It is supposed, that user level program (dip, diald, slattach...)
774    will catch SIGHUP and make the rest of work.
775
776    I see no way to make more with current tty code. --ANK
777  */
778
779 /*
780  * Close down a SLCAN channel.
781  * This means flushing out any pending queues, and then returning. This
782  * call is serialized against other ldisc functions.
783  */
784 static void slcan_close(struct tty_struct *tty)
785 {
786         struct slcan *sl = (struct slcan *) tty->disc_data;
787
788         /* First make sure we're connected. */
789         if (!sl || sl->magic != SLCAN_MAGIC || sl->tty != tty)
790                 return;
791
792         tty->disc_data = NULL;
793         sl->tty = NULL;
794         if (!sl->leased)
795                 sl->line = 0;
796
797         /* Count references from TTY module */
798 }
799
800 /* Perform I/O control on an active SLCAN channel. */
801 static int slcan_ioctl(struct tty_struct *tty, struct file *file,
802                        unsigned int cmd, unsigned long arg)
803 {
804         struct slcan *sl = (struct slcan *) tty->disc_data;
805         unsigned int tmp;
806
807         /* First make sure we're connected. */
808         if (!sl || sl->magic != SLCAN_MAGIC) {
809                 return -EINVAL;
810         }
811
812         switch(cmd) {
813         case SIOCGIFNAME:
814                 tmp = strlen(sl->dev->name) + 1;
815                 if (copy_to_user((void __user *)arg, sl->dev->name, tmp))
816                         return -EFAULT;
817                 return 0;
818
819         case SIOCSIFHWADDR:
820                 return -EINVAL;
821
822
823         /* Allow stty to read, but not set, the serial port */
824         case TCGETS:
825         case TCGETA:
826                 return n_tty_ioctl(tty, file, cmd, arg);
827
828         default:
829                 return -ENOIOCTLCMD;
830         }
831 }
832
833 static struct tty_ldisc slc_ldisc = {
834         .owner          = THIS_MODULE,
835         .magic          = TTY_LDISC_MAGIC,
836         .name           = "slcan",
837         .open           = slcan_open,
838         .close          = slcan_close,
839         .ioctl          = slcan_ioctl,
840         .receive_buf    = slcan_receive_buf,
841 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
842         .receive_room   = slcan_receive_room,
843 #endif
844         .write_wakeup   = slcan_write_wakeup,
845 };
846
847 /************************************
848  * general slcan module init/exit
849  ************************************/
850
851 static int __init slcan_init(void)
852 {
853         int status;
854
855         if (maxdev < 4)
856                 maxdev = 4; /* Sanity */
857
858         printk(banner);
859         printk(KERN_INFO "slcan: %d dynamic interface channels.\n", maxdev );
860
861         slcan_devs = kmalloc(sizeof(struct net_device *)*maxdev, GFP_KERNEL);
862         if (!slcan_devs) {
863                 printk(KERN_ERR "slcan: can't allocate slcan device array!\n");
864                 return -ENOMEM;
865         }
866
867         /* Clear the pointer array, we allocate devices when we need them */
868         memset(slcan_devs, 0, sizeof(struct net_device *)*maxdev);
869
870         /* Fill in our line protocol discipline, and register it */
871         if ((status = tty_register_ldisc(N_SLCAN, &slc_ldisc)) != 0)  {
872                 printk(KERN_ERR "slcan: can't register line discipline\n");
873                 kfree(slcan_devs);
874         }
875         return status;
876 }
877
878 static void __exit slcan_exit(void)
879 {
880         int i;
881         struct net_device *dev;
882         struct slcan *sl;
883         unsigned long timeout = jiffies + HZ;
884         int busy = 0;
885
886         if (slcan_devs == NULL)
887                 return;
888
889         /* First of all: check for active disciplines and hangup them.
890          */
891         do {
892                 if (busy)
893                         msleep_interruptible(100);
894
895                 busy = 0;
896                 for (i = 0; i < maxdev; i++) {
897                         dev = slcan_devs[i];
898                         if (!dev)
899                                 continue;
900                         sl = netdev_priv(dev);
901                         spin_lock_bh(&sl->lock);
902                         if (sl->tty) {
903                                 busy++;
904                                 tty_hangup(sl->tty);
905                         }
906                         spin_unlock_bh(&sl->lock);
907                 }
908         } while (busy && time_before(jiffies, timeout));
909
910
911         for (i = 0; i < maxdev; i++) {
912                 dev = slcan_devs[i];
913                 if (!dev)
914                         continue;
915                 slcan_devs[i] = NULL;
916
917                 sl = netdev_priv(dev);
918                 if (sl->tty) {
919                         printk(KERN_ERR "%s: tty discipline still running\n",
920                                dev->name);
921                         /* Intentionally leak the control block. */
922                         dev->destructor = NULL;
923                 }
924
925                 unregister_netdev(dev);
926         }
927
928         kfree(slcan_devs);
929         slcan_devs = NULL;
930
931         if ((i = tty_unregister_ldisc(N_SLCAN)))
932         {
933                 printk(KERN_ERR "slcan: can't unregister ldisc (err %d)\n", i);
934         }
935 }
936
937 module_init(slcan_init);
938 module_exit(slcan_exit);