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