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