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