]> rtime.felk.cvut.cz Git - socketcan-devel.git/blob - kernel/2.6/net/can/af_can.c
added CAN error frame support.
[socketcan-devel.git] / kernel / 2.6 / net / can / af_can.c
1 /*
2  * af_can.c
3  *
4  * Copyright (c) 2002-2005 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, the following disclaimer and
12  *    the referenced file 'COPYING'.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of Volkswagen nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * Alternatively, provided that this notice is retained in full, this
21  * software may be distributed under the terms of the GNU General
22  * Public License ("GPL") version 2 as distributed in the 'COPYING'
23  * file from the main directory of the linux kernel source.
24  *
25  * The provided data structures and external interfaces from this code
26  * are not restricted to be used by modules with a GPL compatible license.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
39  * DAMAGE.
40  *
41  * Send feedback to <llcf@volkswagen.de>
42  *
43  */
44
45 #include <linux/module.h>
46 #include <linux/version.h>
47 #include <linux/kmod.h>
48 #include <linux/init.h>
49 #include <linux/spinlock.h>
50 #include <linux/socket.h>
51 #include <linux/skbuff.h>
52 #include <linux/net.h>
53 #include <linux/netdevice.h>
54 #include <net/sock.h>
55 #include <asm/uaccess.h>
56
57 #include <linux/can/af_can.h>
58
59 #include "version.h"
60
61 RCSID("$Id$");
62
63 #define NAME "Volkswagen AG - Low Level CAN Framework (LLCF)"
64 #define IDENT "af_can"
65 static __initdata const char banner[] = BANNER(NAME);
66
67 MODULE_DESCRIPTION(NAME);
68 MODULE_LICENSE("Dual BSD/GPL");
69 MODULE_AUTHOR("Urs Thuermann <urs.thuermann@volkswagen.de>, "
70               "Oliver Hartkopp <oliver.hartkopp@volkswagen.de>");
71
72 int stats_timer = 1; /* default: on */
73 module_param(stats_timer, int, S_IRUGO);
74
75 #ifdef DEBUG
76 static int debug = 0;
77 module_param(debug, int, S_IRUGO);
78 #define DBG(args...)       (debug & 1 ? \
79                                (printk(KERN_DEBUG "CAN %s: ", __func__), \
80                                 printk(args)) : 0)
81 #define DBG_FRAME(args...) (debug & 2 ? can_debug_cframe(args) : 0)
82 #define DBG_SKB(skb)       (debug & 4 ? can_debug_skb(skb) : 0)
83 #else
84 #define DBG(args...)
85 #define DBG_FRAME(args...)
86 #define DBG_SKB(skb)
87 #endif
88
89 static __init int  can_init(void);
90 static __exit void can_exit(void);
91
92 static int can_create(struct socket *sock, int protocol);
93 static int can_notifier(struct notifier_block *nb,
94                         unsigned long msg, void *data);
95 static int can_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
96 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
97 static int can_rcv(struct sk_buff *skb, struct net_device *dev,
98                    struct packet_type *pt, struct net_device *orig_dev);
99 #else
100 static int can_rcv(struct sk_buff *skb, struct net_device *dev,
101                    struct packet_type *pt);
102 #endif
103 static int can_rcv_filter(struct rcv_dev_list *q, struct sk_buff *skb);
104 static struct rcv_list **find_rcv_list(canid_t *can_id, canid_t *mask, struct net_device *dev);
105
106 struct notifier_list {
107     struct notifier_list *next;
108     struct net_device *dev;
109     void (*func)(unsigned long msg, void *data);
110     void *data;
111 };
112
113 static struct notifier_list *nlist;
114
115 struct rcv_dev_list *rx_dev_list;
116 struct rcv_dev_list rx_alldev_list;
117 rwlock_t rcv_lists_lock = RW_LOCK_UNLOCKED;
118
119 static struct packet_type can_packet = {
120     .type = __constant_htons(ETH_P_CAN),
121     .dev  = NULL,
122     .func = can_rcv,
123 };
124
125 static struct net_proto_family can_family_ops = {
126     .family = PF_CAN,
127     .create = can_create,
128     .owner  = THIS_MODULE,
129 };
130
131 static struct notifier_block can_netdev_notifier = {
132     .notifier_call = can_notifier,
133 };
134
135 static struct can_proto *proto_tab[CAN_MAX];
136
137 extern struct timer_list stattimer; /* timer for statistics update */
138 extern struct s_stats  stats;       /* statistics */
139 extern struct s_pstats pstats;
140
141 module_init(can_init);
142 module_exit(can_exit);
143
144 /**************************************************/
145 /* af_can module init/exit functions              */
146 /**************************************************/
147
148 static __init int can_init(void)
149 {
150     printk(banner);
151
152     if (stats_timer) {
153         /* statistics init */
154         init_timer(&stattimer);
155     }
156
157     /* procfs init */
158     can_init_proc();
159
160     /* protocol register */
161     sock_register(&can_family_ops);
162     register_netdevice_notifier(&can_netdev_notifier);
163     dev_add_pack(&can_packet);
164
165     return 0;
166 }
167
168 static __exit void can_exit(void)
169 {
170     if (stats_timer) {
171         /* stop statistics timer */
172         del_timer(&stattimer);
173     }
174
175     /* procfs remove */
176     can_remove_proc();
177
178     /* protocol unregister */
179     dev_remove_pack(&can_packet);
180     unregister_netdevice_notifier(&can_netdev_notifier);
181     sock_unregister(PF_CAN);
182 }
183
184 /**************************************************/
185 /* af_can protocol functions                      */
186 /**************************************************/
187
188 void can_proto_register(int proto, struct can_proto *cp)
189 {
190     if (proto < 0 || proto >= CAN_MAX) {
191         printk(KERN_ERR "CAN: protocol number %d out of range\n", proto);
192         return;
193     }
194     if (proto_tab[proto]) {
195         printk(KERN_ERR "CAN: protocol %d already registered\n", proto);
196         return;
197     }
198
199 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
200     if (proto_register(cp->prot, 0) != 0) {
201         return;
202     }
203 #endif
204     proto_tab[proto] = cp;
205
206     /* use our generic ioctl function if the module doesn't bring its own */
207     if (!cp->ops->ioctl)
208         cp->ops->ioctl = can_ioctl;
209 }
210
211 void can_proto_unregister(int proto)
212 {
213     struct can_proto *cp;
214
215     if (!(cp = proto_tab[proto])) {
216         printk(KERN_ERR "CAN: protocol %d is not registered\n", proto);
217         return;
218     }
219 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
220     proto_unregister(cp->prot);
221 #endif
222     proto_tab[proto] = NULL;
223 }
224
225 void can_dev_register(struct net_device *dev,
226                       void (*func)(unsigned long msg, void *), void *data)
227 {
228     struct notifier_list *p = kmalloc(GFP_KERNEL, sizeof(*p));
229
230     DBG("called for %s\n", dev->name);
231
232     if (!p)
233         return;
234     p->next = nlist;
235     p->dev  = dev;
236     p->func = func;
237     p->data = data;
238     nlist = p;
239 }
240
241 void can_dev_unregister(struct net_device *dev,
242                         void (*func)(unsigned long msg, void *), void *data)
243 {
244     struct notifier_list *p, **q;
245
246     DBG("called for %s\n", dev->name);
247
248     for (q = &nlist; p = *q; q = &p->next) {
249         if (p->dev == dev && p->func == func && p->data == data) {
250             *q = p->next;
251             kfree(p);
252             return;
253         }
254     }
255 }
256
257 /**************************************************/
258 /* af_can socket functions                        */
259 /**************************************************/
260
261 static void can_sock_destruct(struct sock *sk)
262 {
263     DBG("called for sock %p\n", sk);
264
265     skb_queue_purge(&sk->sk_receive_queue);
266     if (sk->sk_protinfo)
267         kfree(sk->sk_protinfo);
268 }
269
270 static int can_create(struct socket *sock, int protocol)
271 {
272     struct sock *sk;
273     struct can_proto *cp;
274
275     DBG("socket %p, type %d, proto %d\n", sock, sock->type, protocol);
276
277     sock->state = SS_UNCONNECTED;
278
279     switch (sock->type) {
280     case SOCK_SEQPACKET:
281         switch (protocol) {
282         case CAN_TP16:
283             break;
284         case CAN_TP20:
285             break;
286         case CAN_MCNET:
287             break;
288         case CAN_ISOTP:
289             break;
290         default:
291             return -EPROTONOSUPPORT;
292         }
293         break;
294     case SOCK_DGRAM:
295         switch (protocol) {
296         case CAN_BCM:
297             break;
298         case CAN_BAP:
299             break;
300         default:
301             return -EPROTONOSUPPORT;
302         }
303         break;
304     case SOCK_RAW:
305         switch (protocol) {
306         case CAN_RAW:
307             break;
308         default:
309             return -EPROTONOSUPPORT;
310         }
311         break;
312     default:
313         return -ESOCKTNOSUPPORT;
314         break;
315     }
316
317     DBG("looking up proto %d in proto_tab[]\n", protocol);
318
319     /* try to load protocol module, when CONFIG_KMOD is defined */
320     if (!proto_tab[protocol]) {
321         char module_name[30];
322         sprintf(module_name, "can-proto-%d", protocol);
323         if (request_module(module_name) == -ENOSYS)
324             printk(KERN_INFO "af_can: request_module(%s) not implemented.\n",
325                    module_name);
326     }
327
328     /* check for success */
329     if (!(cp = proto_tab[protocol]))
330         return -EPROTONOSUPPORT;
331
332     sock->ops = cp->ops;
333
334 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
335     sk = sk_alloc(PF_CAN, GFP_KERNEL, cp->prot, 1);
336     if (!sk)
337         goto oom;
338 #else
339     sk = sk_alloc(PF_CAN, GFP_KERNEL, 1, 0);
340     if (!sk)
341         goto oom;
342     if (cp->obj_size &&
343         !(sk->sk_protinfo = kmalloc(cp->obj_size, GFP_KERNEL))) {
344         sk_free(sk);
345         goto oom;
346     }
347     sk_set_owner(sk, proto_tab[protocol]->owner);
348 #endif
349     sock_init_data(sock, sk);
350     sk->sk_destruct = can_sock_destruct;
351
352     DBG("created sock: %p\n", sk);
353
354     return 0;
355
356  oom:
357     return -ENOMEM;
358 }
359
360 static int can_notifier(struct notifier_block *nb,
361                         unsigned long msg, void *data)
362 {
363     struct net_device *dev = (struct net_device *)data;
364     struct notifier_list *p;
365
366     DBG("called for %s, msg = %lu\n", dev->name, msg);
367
368     for (p = nlist; p; p = p->next) {
369         if (p->dev == dev)
370             p->func(msg, p->data);
371     }
372     return 0;
373 }
374
375 static int can_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
376 {
377     struct sock *sk = sock->sk;
378
379     switch (cmd) {
380     case SIOCGSTAMP:
381         return sock_get_timestamp(sk, (struct timeval __user *)arg);
382     default:
383 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
384         return -ENOIOCTLCMD;
385 #else
386         return dev_ioctl(cmd, (void *)arg);
387 #endif
388     }
389     return 0;
390 }
391
392 /**************************************************/
393 /* af_can tx path                                 */
394 /**************************************************/
395
396 int can_send(struct sk_buff *skb)
397 {
398     struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
399     int err;
400
401     if (!(skb->dev->flags & IFF_UP))
402         err = -ENETDOWN;
403     else if ((err = dev_queue_xmit(skb)) > 0)  /* send to netdevice */
404         err = net_xmit_errno(err);
405
406     /* update statistics */
407     stats.tx_frames++;
408     stats.tx_frames_delta++;
409
410     newskb->protocol  = htons(ETH_P_CAN);
411     newskb->ip_summed = CHECKSUM_UNNECESSARY;
412     netif_rx(newskb);                          /* local loopback */
413
414     return err;
415 }
416
417 /**************************************************/
418 /* af_can rx path                                 */
419 /**************************************************/
420
421 void can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask,
422         void (*func)(struct sk_buff *, void *), void *data, char *ident)
423 {
424     struct rcv_list *p, **q;
425     struct rcv_dev_list *d;
426
427     DBG("dev %p, id %03X, mask %03X, callback %p, data %p, ident %s\n",
428         dev, can_id, mask, func, data, ident);
429
430     write_lock(&rcv_lists_lock);
431
432     q = find_rcv_list(&can_id, &mask, dev);
433
434     if (!q) {
435         printk(KERN_ERR "CAN: receive list not found for "
436                "dev %s, id %03X, mask %03X, ident %s\n",
437                dev->name, can_id, mask, ident);
438         goto out;
439     }
440
441     /* insert   (dev,canid,mask) -> (func,data) */
442     if (!(p = kmalloc(sizeof(struct rcv_list), GFP_KERNEL)))
443         return;
444
445     p->can_id  = can_id;
446     p->mask    = mask;
447     p->matches = 0;
448     p->func    = func;
449     p->data    = data;
450     p->ident   = ident;
451     p->next = *q;
452     *q = p;
453
454     if (!dev)
455         d = &rx_alldev_list;
456     else
457         for (d = rx_dev_list; d; d = d->next)
458             if (d->dev == dev)
459                 break;
460     d->entries++;
461
462     pstats.rcv_entries++;
463     if (pstats.rcv_entries_max < pstats.rcv_entries)
464         pstats.rcv_entries_max = pstats.rcv_entries;
465
466 out:
467     write_unlock(&rcv_lists_lock);
468 }
469
470 void can_rx_unregister(struct net_device *dev, canid_t can_id, canid_t mask,
471         void (*func)(struct sk_buff *, void *), void *data)
472 {
473     struct rcv_list *p, **q;
474     struct rcv_dev_list *d;
475
476     DBG("dev %p, id %03X, mask %03X, callback %p, data %p\n",
477         dev, can_id, mask, func, data);
478
479     write_lock(&rcv_lists_lock);
480
481     q = find_rcv_list(&can_id, &mask, dev);
482
483     if (!q) {
484         printk(KERN_ERR "CAN: receive list not found for "
485                "dev %s, id %03X, mask %03X\n", dev->name, can_id, mask);
486         goto out;
487     }
488
489     for (; p = *q; q = &p->next) {
490         if (p->can_id == can_id && p->mask == mask
491             && p->func == func && p->data == data)
492             break;
493     }
494
495     if (!p) {
496         printk(KERN_ERR "CAN: receive list entry not found for "
497                "dev %s, id %03X, mask %03X\n", dev->name, can_id, mask);
498         goto out;
499     }
500
501     *q = p->next;
502     kfree(p);
503
504     if (pstats.rcv_entries > 0)
505         pstats.rcv_entries--;
506
507     if (!dev)
508         d = &rx_alldev_list;
509     else
510         for (d = rx_dev_list; d; d = d->next)
511             if (d->dev == dev)
512                 break;
513     d->entries--;
514
515     if(!d->entries)
516         d->dev = NULL; /* mark unused */
517
518 out:
519     write_unlock(&rcv_lists_lock);
520 }
521
522 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
523 static int can_rcv(struct sk_buff *skb, struct net_device *dev,
524                    struct packet_type *pt, struct net_device *orig_dev)
525 #else
526 static int can_rcv(struct sk_buff *skb, struct net_device *dev,
527                    struct packet_type *pt)
528 #endif
529 {
530     struct rcv_dev_list *q;
531     int matches;
532
533     DBG("received skbuff on device %s, ptype %04x\n",
534         dev->name, ntohs(pt->type));
535     DBG_SKB(skb);
536     DBG_FRAME("af_can: can_rcv: received CAN frame",
537               (struct can_frame *)skb->data);
538
539     /* update statistics */
540     stats.rx_frames++;
541     stats.rx_frames_delta++;
542
543     matches = can_rcv_filter(&rx_alldev_list, skb);
544
545     /* find receive list for this device */
546     for (q = rx_dev_list; q; q = q->next)
547         if (q->dev == dev)
548             break;
549
550     if (q)
551         matches += can_rcv_filter(q, skb);
552
553     DBG("freeing skbuff %p\n", skb);
554     kfree_skb(skb);
555
556     if (matches > 0) {
557         stats.matches++;
558         stats.matches_delta++;
559     }
560
561     return 0;
562 }
563
564
565 static inline void deliver(struct sk_buff *skb, struct rcv_list *p)
566 {
567     struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC);
568     DBG("skbuff %p cloned to %p\n", skb, clone);
569     if (clone) {
570         p->func(clone, p->data);
571         p->matches++;    /* update specific statistics */
572     }
573 }
574     
575 static int can_rcv_filter(struct rcv_dev_list *q, struct sk_buff *skb)
576 {
577     struct rcv_list *p;
578     int matches = 0;
579     struct can_frame *cf = (struct can_frame*)skb->data;
580     canid_t can_id = cf->can_id;
581
582     if (q->entries == 0)
583         return 0;
584
585     if (can_id & CAN_ERR_FLAG) {
586         /* check for error frame entries only */
587         for (p = q->rx_err; p; p = p->next) {
588             if (can_id & p->mask) {
589                 DBG("match on rx_err skbuff %p\n", skb);
590                 deliver(skb, p);
591                 matches++;
592             }
593         }
594         goto out;
595     }
596
597     /* check for unfiltered entries */
598     for (p = q->rx_all; p; p = p->next) {
599         DBG("match on rx_all skbuff %p\n", skb);
600         deliver(skb, p);
601         matches++;
602     }
603
604     /* check for can_id/mask entries */
605     for (p = q->rx_fil; p; p = p->next) {
606         if ((can_id & p->mask) == p->can_id) {
607             DBG("match on rx_fil skbuff %p\n", skb);
608             deliver(skb, p);
609             matches++;
610         }
611     }
612
613     /* check for inverted can_id/mask entries */
614     for (p = q->rx_inv; p; p = p->next) {
615         if ((can_id & p->mask) != p->can_id) {
616             DBG("match on rx_inv skbuff %p\n", skb);
617             deliver(skb, p);
618             matches++;
619         }
620     }
621
622     /* check CAN_ID specific entries */
623     if (can_id & CAN_EFF_FLAG) {
624         for (p = q->rx_eff; p; p = p->next) {
625             if (p->can_id == can_id) {
626                 DBG("match on rx_eff skbuff %p\n", skb);
627                 deliver(skb, p);
628                 matches++;
629             }
630         }
631     } else {
632         for (p = q->rx_sff[can_id & CAN_SFF_MASK]; p; p = p->next) {
633             DBG("match on rx_sff skbuff %p\n", skb);
634             deliver(skb, p);
635             matches++;
636         }
637     }
638
639 out:
640     return matches;
641 }
642
643 static struct rcv_list **find_rcv_list(canid_t *can_id, canid_t *mask, struct net_device *dev)
644 {
645     canid_t inv = *can_id & CAN_INV_FILTER; /* save flag before masking values */
646     canid_t eff = *can_id & *mask & CAN_EFF_FLAG; /* correct EFF check? */
647     canid_t rtr = *can_id & *mask & CAN_RTR_FLAG; /* correct RTR check? */
648     canid_t err = *mask & CAN_ERR_FLAG; /* mask for error frames only */
649
650     struct rcv_dev_list *p;
651
652     /* make some paranoic operations */
653     if (*can_id & CAN_EFF_FLAG)
654         *mask &= (CAN_EFF_MASK | eff | rtr);
655     else
656         *mask &= (CAN_SFF_MASK | rtr);
657
658     *can_id &= *mask;
659
660     /* find receive list for this device */
661     if (!dev)
662         p = &rx_alldev_list;
663     else
664         for (p = rx_dev_list; p; p = p->next)
665             if (p->dev == dev)
666                 break;
667
668     if (!p) {
669         /* arrange new rcv_dev_list for this device */
670
671         /* find deactivated receive list for this device */
672         for (p = rx_dev_list; p; p = p->next)
673             if (p->dev == NULL)
674                 break;
675
676         if (p) {
677             DBG("reactivating rcv_dev_list for %s\n", dev->name); 
678             p->dev = dev;
679         } else {
680             /* create new rcv_dev_list for this device */
681             DBG("creating new rcv_dev_list for %s\n", dev->name);
682             if (!(p = kmalloc(sizeof(struct rcv_dev_list), GFP_KERNEL))) {
683                 printk(KERN_ERR "CAN: allocation of receive list failed\n");
684                 return NULL;
685             }
686             memset (p, 0, sizeof(struct rcv_dev_list));
687             p->dev      = dev;
688             p->next     = rx_dev_list;
689             rx_dev_list = p;
690         }
691     }
692
693     if (err) /* error frames */
694         return &p->rx_err;
695
696     if (inv) /* inverse can_id/can_mask filter and RTR */
697         return &p->rx_inv;
698
699     if (*can_id & CAN_RTR_FLAG) /* positive filter RTR */
700         return &p->rx_fil;
701
702     if (!(*mask)) /* mask == 0 => no filter */
703         return &p->rx_all;
704
705     if (*can_id & CAN_EFF_FLAG) {
706         if (*mask == CAN_EFF_MASK) /* filter exact EFF can_id */
707             return &p->rx_eff;
708     } else {
709         if (*mask == CAN_SFF_MASK) /* filter exact SFF can_id */
710             return &p->rx_sff[*can_id];
711     }
712
713     return &p->rx_fil;  /* filter via can_id/can_mask */
714 }
715
716 /**************************************************/
717 /* af_can utility stuff                           */
718 /**************************************************/
719
720 unsigned long timeval2jiffies(struct timeval *tv, int round_up)
721 {
722     unsigned long jif;
723     unsigned long sec  = tv->tv_sec;
724     unsigned long usec = tv->tv_usec;
725
726     if (sec > ULONG_MAX / HZ)          /* check for overflow */
727         return ULONG_MAX;
728
729     if (round_up)                      /* any usec below one HZ? */
730         usec += 1000000 / HZ - 1;      /* pump it up */
731
732     jif = usec / (1000000 / HZ);
733
734     if (sec * HZ > ULONG_MAX - jif)    /* check for overflow */
735         return ULONG_MAX;
736     else
737         return jif + sec * HZ;
738 }
739
740
741 /**************************************************/
742 /* af_can debugging stuff                         */
743 /**************************************************/
744
745 #ifdef DEBUG
746
747 void can_debug_cframe(const char *msg, struct can_frame *cf, ...)
748 {
749     va_list ap;
750     int len;
751     int dlc, i;
752     char buf[1024];
753     
754     len = sprintf(buf, KERN_DEBUG);
755     va_start(ap, cf);
756     len += snprintf(buf + len, sizeof(buf) - 64, msg, ap);
757     buf[len++] = ':';
758     buf[len++] = ' ';
759     va_end(ap);
760
761     if ((dlc = cf->can_dlc) > 8)
762         dlc = 8;
763
764     if (cf->can_id & CAN_EFF_FLAG)
765         len += sprintf(buf + len, "<%08X> [%X] ",
766                        cf->can_id & CAN_EFF_MASK, dlc);
767     else
768         len += sprintf(buf + len, "<%03X> [%X] ",
769                        cf->can_id & CAN_SFF_MASK, dlc);
770
771     for (i = 0; i < dlc; i++)
772         len += sprintf(buf + len, "%02X ", cf->data[i]);
773
774     if (cf->can_id & CAN_RTR_FLAG)
775         len += sprintf(buf + len, "(RTR)");
776
777     buf[len++] = '\n';
778     buf[len]   = '\0';
779     printk(buf);
780 }
781
782 void can_debug_skb(struct sk_buff *skb)
783 {
784     int len, nbytes, i;
785     char buf[1024];
786
787     len = sprintf(buf,
788                   KERN_DEBUG "  skbuff at %p, dev: %d, proto: %04x\n"
789                   KERN_DEBUG "  users: %d, dataref: %d, nr_frags: %d, "
790                   "h,d,t,e,l: %p %+d %+d %+d, %d",
791                   skb, skb->dev ? skb->dev->ifindex : -1, ntohs(skb->protocol),
792                   atomic_read(&skb->users),
793                   atomic_read(&(skb_shinfo(skb)->dataref)),
794                   skb_shinfo(skb)->nr_frags,
795                   skb->head, skb->data - skb->head,
796                   skb->tail - skb->head, skb->end - skb->head, skb->len);
797     nbytes = skb->end - skb->head;
798     for (i = 0; i < nbytes; i++) {
799         if (i % 16 == 0)
800             len += sprintf(buf + len, "\n" KERN_DEBUG "  ");
801         if (len < sizeof(buf) - 16) {
802             len += sprintf(buf + len, " %02x", skb->head[i]);
803         } else {
804             len += sprintf(buf + len, "...");
805             break;
806         }
807     }
808     buf[len++] = '\n';
809     buf[len]   = '\0';
810     printk(buf);
811 }
812
813 EXPORT_SYMBOL(can_debug_cframe);
814 EXPORT_SYMBOL(can_debug_skb);
815
816 #endif
817
818 /**************************************************/
819 /* Exported symbols                               */
820 /**************************************************/
821 EXPORT_SYMBOL(can_proto_register);
822 EXPORT_SYMBOL(can_proto_unregister);
823 EXPORT_SYMBOL(can_rx_register);
824 EXPORT_SYMBOL(can_rx_unregister);
825 EXPORT_SYMBOL(can_dev_register);
826 EXPORT_SYMBOL(can_dev_unregister);
827 EXPORT_SYMBOL(can_send);
828 EXPORT_SYMBOL(timeval2jiffies);