]> rtime.felk.cvut.cz Git - socketcan-devel.git/blob - patch-series/net-2.6.24/04-can-bcm-proto.diff
Rename some variables for readability.
[socketcan-devel.git] / patch-series / net-2.6.24 / 04-can-bcm-proto.diff
1 DESC
2 CAN: Add broadcast manager (bcm) protocol
3 EDESC
4 This patch adds the CAN broadcast manager (bcm) protocol.
5
6 Signed-off-by: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
7 Signed-off-by: Urs Thuermann <urs.thuermann@volkswagen.de>
8
9 ---
10  include/linux/can/bcm.h |   65 +
11  net/can/Kconfig         |   13 
12  net/can/Makefile        |    3 
13  net/can/bcm.c           | 1763 ++++++++++++++++++++++++++++++++++++++++++++++++
14  4 files changed, 1844 insertions(+)
15
16 Index: net-2.6.24/include/linux/can/bcm.h
17 ===================================================================
18 --- /dev/null   1970-01-01 00:00:00.000000000 +0000
19 +++ net-2.6.24/include/linux/can/bcm.h  2007-10-05 11:13:17.000000000 +0200
20 @@ -0,0 +1,65 @@
21 +/*
22 + * linux/can/bcm.h
23 + *
24 + * Definitions for CAN Broadcast Manager (BCM)
25 + *
26 + * Author: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
27 + * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
28 + * All rights reserved.
29 + *
30 + * Send feedback to <socketcan-users@lists.berlios.de>
31 + *
32 + */
33 +
34 +#ifndef CAN_BCM_H
35 +#define CAN_BCM_H
36 +
37 +/**
38 + * struct bcm_msg_head - head of messages to/from the broadcast manager
39 + * @opcode:    opcode, see enum below.
40 + * @flags:     special flags, see below.
41 + * @count:     number of frames to send before changing interval.
42 + * @ival1:     interval for the first @count frames.
43 + * @ival2:     interval for the following frames.
44 + * @can_id:    CAN ID of frames to be sent or received.
45 + * @nframes:   number of frames appended to the message head.
46 + * @frames:    array of CAN frames.
47 + */
48 +struct bcm_msg_head {
49 +       int opcode;
50 +       int flags;
51 +       int count;
52 +       struct timeval ival1, ival2;
53 +       canid_t can_id;
54 +       int nframes;
55 +       struct can_frame frames[0];
56 +};
57 +
58 +enum {
59 +       TX_SETUP = 1,   /* create (cyclic) transmission task */
60 +       TX_DELETE,      /* remove (cyclic) transmission task */
61 +       TX_READ,        /* read properties of (cyclic) transmission task */
62 +       TX_SEND,        /* send one CAN frame */
63 +       RX_SETUP,       /* create RX content filter subscription */
64 +       RX_DELETE,      /* remove RX content filter subscription */
65 +       RX_READ,        /* read properties of RX content filter subscription */
66 +       TX_STATUS,      /* reply to TX_READ request */
67 +       TX_EXPIRED,     /* notification on performed transmissions (count=0) */
68 +       RX_STATUS,      /* reply to RX_READ request */
69 +       RX_TIMEOUT,     /* cyclic message is absent */
70 +       RX_CHANGED      /* updated CAN frame (detected content change) */
71 +};
72 +
73 +#define SETTIMER            0x0001
74 +#define STARTTIMER          0x0002
75 +#define TX_COUNTEVT         0x0004
76 +#define TX_ANNOUNCE         0x0008
77 +#define TX_CP_CAN_ID        0x0010
78 +#define RX_FILTER_ID        0x0020
79 +#define RX_CHECK_DLC        0x0040
80 +#define RX_NO_AUTOTIMER     0x0080
81 +#define RX_ANNOUNCE_RESUME  0x0100
82 +#define TX_RESET_MULTI_IDX  0x0200
83 +#define RX_RTR_FRAME        0x0400
84 +
85 +#endif /* CAN_BCM_H */
86 Index: net-2.6.24/net/can/Kconfig
87 ===================================================================
88 --- net-2.6.24.orig/net/can/Kconfig     2007-10-05 11:12:35.000000000 +0200
89 +++ net-2.6.24/net/can/Kconfig  2007-10-05 11:13:49.000000000 +0200
90 @@ -27,6 +27,19 @@
91           socket has several filter options e.g. ID masking / error frames.
92           To receive/send raw CAN messages, use AF_CAN with protocol CAN_RAW.
93  
94 +config CAN_BCM
95 +       tristate "Broadcast Manager CAN Protocol (with content filtering)"
96 +       depends on CAN
97 +       default N
98 +       ---help---
99 +         The Broadcast Manager offers content filtering, timeout monitoring,
100 +         sending of RTR frames, and cyclic CAN messages without permanent user
101 +         interaction. The BCM can be 'programmed' via the BSD socket API and
102 +         informs you on demand e.g. only on content updates / timeouts.
103 +         You probably want to use the bcm socket in most cases where cyclic
104 +         CAN messages are used on the bus (e.g. in automotive environments).
105 +         To use the Broadcast Manager, use AF_CAN with protocol CAN_BCM.
106 +
107  config CAN_DEBUG_CORE
108         bool "CAN Core debugging messages"
109         depends on CAN
110 Index: net-2.6.24/net/can/Makefile
111 ===================================================================
112 --- net-2.6.24.orig/net/can/Makefile    2007-10-05 11:11:41.000000000 +0200
113 +++ net-2.6.24/net/can/Makefile 2007-10-05 11:13:17.000000000 +0200
114 @@ -7,3 +7,6 @@
115  
116  obj-$(CONFIG_CAN_RAW)  += can-raw.o
117  can-raw-objs           := raw.o
118 +
119 +obj-$(CONFIG_CAN_BCM)  += can-bcm.o
120 +can-bcm-objs           := bcm.o
121 Index: net-2.6.24/net/can/bcm.c
122 ===================================================================
123 --- /dev/null   1970-01-01 00:00:00.000000000 +0000
124 +++ net-2.6.24/net/can/bcm.c    2007-10-05 11:13:17.000000000 +0200
125 @@ -0,0 +1,1763 @@
126 +/*
127 + * bcm.c - Broadcast Manager to filter/send (cyclic) CAN content
128 + *
129 + * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
130 + * All rights reserved.
131 + *
132 + * Redistribution and use in source and binary forms, with or without
133 + * modification, are permitted provided that the following conditions
134 + * are met:
135 + * 1. Redistributions of source code must retain the above copyright
136 + *    notice, this list of conditions and the following disclaimer.
137 + * 2. Redistributions in binary form must reproduce the above copyright
138 + *    notice, this list of conditions and the following disclaimer in the
139 + *    documentation and/or other materials provided with the distribution.
140 + * 3. Neither the name of Volkswagen nor the names of its contributors
141 + *    may be used to endorse or promote products derived from this software
142 + *    without specific prior written permission.
143 + *
144 + * Alternatively, provided that this notice is retained in full, this
145 + * software may be distributed under the terms of the GNU General
146 + * Public License ("GPL") version 2, in which case the provisions of the
147 + * GPL apply INSTEAD OF those given above.
148 + *
149 + * The provided data structures and external interfaces from this code
150 + * are not restricted to be used by modules with a GPL compatible license.
151 + *
152 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
153 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
154 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
155 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
156 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
157 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
158 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
159 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
160 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
161 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
162 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
163 + * DAMAGE.
164 + *
165 + * Send feedback to <socketcan-users@lists.berlios.de>
166 + *
167 + */
168 +
169 +#include <linux/module.h>
170 +#include <linux/init.h>
171 +#include <linux/list.h>
172 +#include <linux/proc_fs.h>
173 +#include <linux/uio.h>
174 +#include <linux/net.h>
175 +#include <linux/netdevice.h>
176 +#include <linux/socket.h>
177 +#include <linux/if_arp.h>
178 +#include <linux/skbuff.h>
179 +#include <linux/can.h>
180 +#include <linux/can/core.h>
181 +#include <linux/can/bcm.h>
182 +#include <net/sock.h>
183 +#include <net/net_namespace.h>
184 +
185 +/* use of last_frames[index].can_dlc */
186 +#define RX_RECV    0x40 /* received data for this element */
187 +#define RX_THR     0x80 /* element not been sent due to throttle feature */
188 +#define BCM_CAN_DLC_MASK 0x0F /* clean private flags in can_dlc by masking */
189 +
190 +/* get best masking value for can_rx_register() for a given single can_id */
191 +#define REGMASK(id) ((id & CAN_RTR_FLAG) | ((id & CAN_EFF_FLAG) ? \
192 +                       (CAN_EFF_MASK | CAN_EFF_FLAG) : CAN_SFF_MASK))
193 +
194 +#define CAN_BCM_VERSION CAN_VERSION
195 +static __initdata const char banner[] = KERN_INFO
196 +       "can: broadcast manager protocol (rev " CAN_BCM_VERSION ")\n";
197 +
198 +MODULE_DESCRIPTION("PF_CAN broadcast manager protocol");
199 +MODULE_LICENSE("Dual BSD/GPL");
200 +MODULE_AUTHOR("Oliver Hartkopp <oliver.hartkopp@volkswagen.de>");
201 +
202 +#ifdef CONFIG_CAN_DEBUG_CORE
203 +#define DBG_PREFIX "can-bcm"
204 +#define DBG_VAR    bcm_debug
205 +static int bcm_debug;
206 +module_param_named(debug, bcm_debug, int, S_IRUGO);
207 +MODULE_PARM_DESC(debug, "debug print mask: 1:debug, 2:frames, 4:skbs");
208 +#endif
209 +
210 +/* easy access to can_frame payload */
211 +static inline u64 GET_U64(const struct can_frame *cp)
212 +{
213 +       return *(u64 *)cp->data;
214 +}
215 +
216 +struct bcm_op {
217 +       struct list_head list;
218 +       int ifindex;
219 +       canid_t can_id;
220 +       int flags;
221 +       unsigned long j_ival1, j_ival2, j_lastmsg;
222 +       unsigned long frames_abs, frames_filtered;
223 +       struct timer_list timer, thrtimer;
224 +       struct timeval ival1, ival2;
225 +       ktime_t rx_stamp;
226 +       int rx_ifindex;
227 +       int count;
228 +       int nframes;
229 +       int currframe;
230 +       struct can_frame *frames;
231 +       struct can_frame *last_frames;
232 +       struct can_frame sframe;
233 +       struct can_frame last_sframe;
234 +       struct sock *sk;
235 +       struct net_device *rx_reg_dev;
236 +};
237 +
238 +static struct proc_dir_entry *proc_dir;
239 +
240 +struct bcm_sock {
241 +       struct sock sk;
242 +       int bound;
243 +       int ifindex;
244 +       struct notifier_block notifier;
245 +       struct list_head rx_ops;
246 +       struct list_head tx_ops;
247 +       unsigned long dropped_usr_msgs;
248 +       struct proc_dir_entry *bcm_proc_read;
249 +       char procname [9]; /* pointer printed in ASCII with \0 */
250 +};
251 +
252 +static inline struct bcm_sock *bcm_sk(const struct sock *sk)
253 +{
254 +       return (struct bcm_sock *)sk;
255 +}
256 +
257 +#define CFSIZ sizeof(struct can_frame)
258 +#define OPSIZ sizeof(struct bcm_op)
259 +#define MHSIZ sizeof(struct bcm_msg_head)
260 +
261 +/*
262 + * rounded_tv2jif - calculate jiffies from timeval including optional up
263 + * @tv: pointer to timeval
264 + *
265 + * Description:
266 + * Unlike timeval_to_jiffies() provided in include/linux/jiffies.h, this
267 + * function is intentionally more relaxed on precise timer ticks to get
268 + * exact one jiffy for requested 1000us on a 1000HZ machine.
269 + * This code is to be removed when upgrading to kernel hrtimer.
270 + *
271 + * Return:
272 + *  calculated jiffies (max: ULONG_MAX)
273 + */
274 +static unsigned long rounded_tv2jif(const struct timeval *tv)
275 +{
276 +       unsigned long sec  = tv->tv_sec;
277 +       unsigned long usec = tv->tv_usec;
278 +       unsigned long jif;
279 +
280 +       if (sec > ULONG_MAX / HZ)
281 +               return ULONG_MAX;
282 +
283 +       /* round up to get at least the requested time */
284 +       usec += 1000000 / HZ - 1;
285 +
286 +       jif  = usec / (1000000 / HZ);
287 +
288 +       if (sec * HZ > ULONG_MAX - jif)
289 +               return ULONG_MAX;
290 +
291 +       return jif + sec * HZ;
292 +}
293 +
294 +/*
295 + * procfs functions
296 + */
297 +static char *bcm_proc_getifname(int ifindex)
298 +{
299 +       struct net_device *dev;
300 +
301 +       if (!ifindex)
302 +               return "any";
303 +
304 +       dev = __dev_get_by_index(&init_net, ifindex); /* no usage counting */
305 +       if (dev)
306 +               return dev->name;
307 +
308 +       return "???";
309 +}
310 +
311 +static int bcm_read_proc(char *page, char **start, off_t off,
312 +                        int count, int *eof, void *data)
313 +{
314 +       int len = 0;
315 +       struct sock *sk = (struct sock *)data;
316 +       struct bcm_sock *bo = bcm_sk(sk);
317 +       struct bcm_op *op;
318 +
319 +       len += snprintf(page + len, PAGE_SIZE - len, ">>> socket %p",
320 +                       sk->sk_socket);
321 +       len += snprintf(page + len, PAGE_SIZE - len, " / sk %p", sk);
322 +       len += snprintf(page + len, PAGE_SIZE - len, " / bo %p", bo);
323 +       len += snprintf(page + len, PAGE_SIZE - len, " / dropped %lu",
324 +                       bo->dropped_usr_msgs);
325 +       len += snprintf(page + len, PAGE_SIZE - len, " / bound %s",
326 +                       bcm_proc_getifname(bo->ifindex));
327 +       len += snprintf(page + len, PAGE_SIZE - len, " <<<\n");
328 +
329 +       list_for_each_entry(op, &bo->rx_ops, list) {
330 +
331 +               unsigned long reduction;
332 +
333 +               /* print only active entries & prevent division by zero */
334 +               if (!op->frames_abs)
335 +                       continue;
336 +
337 +               len += snprintf(page + len, PAGE_SIZE - len,
338 +                               "rx_op: %03X %-5s ",
339 +                               op->can_id, bcm_proc_getifname(op->ifindex));
340 +               len += snprintf(page + len, PAGE_SIZE - len, "[%d]%c ",
341 +                               op->nframes,
342 +                               (op->flags & RX_CHECK_DLC)?'d':' ');
343 +               if (op->j_ival1)
344 +                       len += snprintf(page + len, PAGE_SIZE - len,
345 +                                       "timeo=%ld ", op->j_ival1);
346 +
347 +               if (op->j_ival2)
348 +                       len += snprintf(page + len, PAGE_SIZE - len,
349 +                                       "thr=%ld ", op->j_ival2);
350 +
351 +               len += snprintf(page + len, PAGE_SIZE - len,
352 +                               "# recv %ld (%ld) => reduction: ",
353 +                               op->frames_filtered, op->frames_abs);
354 +
355 +               reduction = 100 - (op->frames_filtered * 100) / op->frames_abs;
356 +
357 +               len += snprintf(page + len, PAGE_SIZE - len, "%s%ld%%\n",
358 +                               (reduction == 100)?"near ":"", reduction);
359 +
360 +               if (len > PAGE_SIZE - 200) {
361 +                       /* mark output cut off */
362 +                       len += snprintf(page + len, PAGE_SIZE - len, "(..)\n");
363 +                       break;
364 +               }
365 +       }
366 +
367 +       list_for_each_entry(op, &bo->tx_ops, list) {
368 +
369 +               len += snprintf(page + len, PAGE_SIZE - len,
370 +                               "tx_op: %03X %s [%d] ",
371 +                               op->can_id, bcm_proc_getifname(op->ifindex),
372 +                               op->nframes);
373 +               if (op->j_ival1)
374 +                       len += snprintf(page + len, PAGE_SIZE - len, "t1=%ld ",
375 +                                       op->j_ival1);
376 +
377 +               if (op->j_ival2)
378 +                       len += snprintf(page + len, PAGE_SIZE - len, "t2=%ld ",
379 +                                       op->j_ival2);
380 +
381 +               len += snprintf(page + len, PAGE_SIZE - len, "# sent %ld\n",
382 +                               op->frames_abs);
383 +
384 +               if (len > PAGE_SIZE - 100) {
385 +                       /* mark output cut off */
386 +                       len += snprintf(page + len, PAGE_SIZE - len, "(..)\n");
387 +                       break;
388 +               }
389 +       }
390 +
391 +       len += snprintf(page + len, PAGE_SIZE - len, "\n");
392 +
393 +       *eof = 1;
394 +       return len;
395 +}
396 +
397 +/*
398 + * bcm_can_tx - send the (next) CAN frame to the appropriate CAN interface
399 + *              of the given bcm tx op
400 + */
401 +static void bcm_can_tx(struct bcm_op *op)
402 +{
403 +       struct sk_buff *skb;
404 +       struct net_device *dev;
405 +       struct can_frame *cf = &op->frames[op->currframe];
406 +
407 +       DBG_FRAME("BCM: bcm_can_tx: sending frame", cf);
408 +
409 +       /* no target device? => exit */
410 +       if (!op->ifindex)
411 +               return;
412 +
413 +       dev = dev_get_by_index(&init_net, op->ifindex);
414 +       if (!dev) {
415 +               /* RFC: should this bcm_op remove itself here? */
416 +               return;
417 +       }
418 +
419 +       skb = alloc_skb(CFSIZ, gfp_any());
420 +       if (!skb)
421 +               goto out;
422 +
423 +       memcpy(skb_put(skb, CFSIZ), cf, CFSIZ);
424 +
425 +       /* send with loopback */
426 +       skb->dev = dev;
427 +       skb->sk = op->sk;
428 +       can_send(skb, 1);
429 +
430 +       /* update statistics */
431 +       op->currframe++;
432 +       op->frames_abs++;
433 +
434 +       /* reached last frame? */
435 +       if (op->currframe >= op->nframes)
436 +               op->currframe = 0;
437 + out:
438 +       dev_put(dev);
439 +}
440 +
441 +/*
442 + * bcm_send_to_user - send a BCM message to the userspace
443 + *                    (consisting of bcm_msg_head + x CAN frames)
444 + */
445 +static void bcm_send_to_user(struct bcm_op *op, struct bcm_msg_head *head,
446 +                            struct can_frame *frames, int has_timestamp)
447 +{
448 +       struct sk_buff *skb;
449 +       struct can_frame *firstframe;
450 +       struct sockaddr_can *addr;
451 +       struct sock *sk = op->sk;
452 +       int datalen = head->nframes * CFSIZ;
453 +       int err;
454 +
455 +       skb = alloc_skb(sizeof(*head) + datalen, gfp_any());
456 +       if (!skb)
457 +               return;
458 +
459 +       memcpy(skb_put(skb, sizeof(*head)), head, sizeof(*head));
460 +
461 +       if (head->nframes) {
462 +               /* can_frames starting here */
463 +               firstframe = (struct can_frame *) skb_tail_pointer(skb);
464 +
465 +               memcpy(skb_put(skb, datalen), frames, datalen);
466 +
467 +               /*
468 +                * the BCM uses the can_dlc-element of the can_frame
469 +                * structure for internal purposes. This is only
470 +                * relevant for updates that are generated by the
471 +                * BCM, where nframes is 1
472 +                */
473 +               if (head->nframes == 1)
474 +                       firstframe->can_dlc &= BCM_CAN_DLC_MASK;
475 +       }
476 +
477 +       if (has_timestamp) {
478 +               /* restore rx timestamp */
479 +               skb->tstamp = op->rx_stamp;
480 +       }
481 +
482 +       /*
483 +        *  Put the datagram to the queue so that bcm_recvmsg() can
484 +        *  get it from there.  We need to pass the interface index to
485 +        *  bcm_recvmsg().  We pass a whole struct sockaddr_can in skb->cb
486 +        *  containing the interface index.
487 +        */
488 +
489 +       BUILD_BUG_ON(sizeof(skb->cb) < sizeof(struct sockaddr_can));
490 +       addr = (struct sockaddr_can *)skb->cb;
491 +       memset(addr, 0, sizeof(*addr));
492 +       addr->can_family  = AF_CAN;
493 +       addr->can_ifindex = op->rx_ifindex;
494 +
495 +       err = sock_queue_rcv_skb(sk, skb);
496 +       if (err < 0) {
497 +               struct bcm_sock *bo = bcm_sk(sk);
498 +
499 +               DBG("sock_queue_rcv_skb failed: %d\n", err);
500 +               kfree_skb(skb);
501 +               /* don't care about overflows in this statistic */
502 +               bo->dropped_usr_msgs++;
503 +       }
504 +}
505 +
506 +/*
507 + * bcm_tx_timeout_handler - performes cyclic CAN frame transmissions
508 + */
509 +static void bcm_tx_timeout_handler(unsigned long data)
510 +{
511 +       struct bcm_op *op = (struct bcm_op *)data;
512 +
513 +       DBG("Called with bcm_op %p\n", op);
514 +
515 +       if (op->j_ival1 && (op->count > 0)) {
516 +
517 +               op->count--;
518 +               if (!op->count && (op->flags & TX_COUNTEVT)) {
519 +                       struct bcm_msg_head msg_head;
520 +
521 +                       /* create notification to user */
522 +                       DBG("sending TX_EXPIRED for can_id %03X\n",
523 +                           op->can_id);
524 +
525 +                       msg_head.opcode  = TX_EXPIRED;
526 +                       msg_head.flags   = op->flags;
527 +                       msg_head.count   = op->count;
528 +                       msg_head.ival1   = op->ival1;
529 +                       msg_head.ival2   = op->ival2;
530 +                       msg_head.can_id  = op->can_id;
531 +                       msg_head.nframes = 0;
532 +
533 +                       bcm_send_to_user(op, &msg_head, NULL, 0);
534 +               }
535 +       }
536 +
537 +       DBG("count=%d j_ival1=%ld j_ival2=%ld\n",
538 +           op->count, op->j_ival1, op->j_ival2);
539 +
540 +       if (op->j_ival1 && (op->count > 0)) {
541 +
542 +               op->timer.expires = jiffies + op->j_ival1;
543 +               add_timer(&op->timer);
544 +
545 +               DBG("adding timer ival1. func=%p data=%p exp=0x%08X\n",
546 +                   op->timer.function,
547 +                   (char *) op->timer.data,
548 +                   (unsigned int) op->timer.expires);
549 +
550 +               /* send (next) frame */
551 +               bcm_can_tx(op);
552 +
553 +       } else {
554 +               if (op->j_ival2) {
555 +                       op->timer.expires = jiffies + op->j_ival2;
556 +                       add_timer(&op->timer);
557 +
558 +                       DBG("adding timer ival2. func=%p data=%p exp=0x%08X\n",
559 +                           op->timer.function,
560 +                           (char *) op->timer.data,
561 +                           (unsigned int) op->timer.expires);
562 +
563 +                       /* send (next) frame */
564 +                       bcm_can_tx(op);
565 +
566 +               } else
567 +                       DBG("no timer restart\n");
568 +       }
569 +
570 +       return;
571 +}
572 +
573 +/*
574 + * bcm_rx_changed - create a RX_CHANGED notification due to changed content
575 + */
576 +static void bcm_rx_changed(struct bcm_op *op, struct can_frame *data)
577 +{
578 +       struct bcm_msg_head head;
579 +
580 +       op->j_lastmsg = jiffies;
581 +
582 +       /* update statistics */
583 +       op->frames_filtered++;
584 +
585 +       /* prevent statistics overflow */
586 +       if (op->frames_filtered > ULONG_MAX/100)
587 +               op->frames_filtered = op->frames_abs = 0;
588 +
589 +       DBG("setting j_lastmsg to 0x%08X for rx_op %p\n",
590 +           (unsigned int) op->j_lastmsg, op);
591 +       DBG("sending notification\n");
592 +
593 +       head.opcode  = RX_CHANGED;
594 +       head.flags   = op->flags;
595 +       head.count   = op->count;
596 +       head.ival1   = op->ival1;
597 +       head.ival2   = op->ival2;
598 +       head.can_id  = op->can_id;
599 +       head.nframes = 1;
600 +
601 +       bcm_send_to_user(op, &head, data, 1);
602 +}
603 +
604 +/*
605 + * bcm_rx_update_and_send - process a detected relevant receive content change
606 + *                          1. update the last received data
607 + *                          2. send a notification to the user (if possible)
608 + */
609 +static void bcm_rx_update_and_send(struct bcm_op *op,
610 +                                  struct can_frame *lastdata,
611 +                                  struct can_frame *rxdata)
612 +{
613 +       unsigned long nexttx = op->j_lastmsg + op->j_ival2;
614 +
615 +       memcpy(lastdata, rxdata, CFSIZ);
616 +
617 +       /* mark as used */
618 +       lastdata->can_dlc |= RX_RECV;
619 +
620 +       /* throttle bcm_rx_changed ? */
621 +       if ((op->thrtimer.expires) ||
622 +           ((op->j_ival2) && (nexttx > jiffies))) {
623 +               /* we are already waiting OR we have to start waiting */
624 +
625 +               /* mark as 'throttled' */
626 +               lastdata->can_dlc |= RX_THR;
627 +
628 +               if (!(op->thrtimer.expires)) {
629 +                       /* start the timer only the first time */
630 +                       op->thrtimer.expires = nexttx;
631 +                       add_timer(&op->thrtimer);
632 +
633 +                       DBG("adding thrtimer. func=%p data=%p exp=0x%08X\n",
634 +                           op->thrtimer.function,
635 +                           (char *) op->thrtimer.data,
636 +                           (unsigned int) op->thrtimer.expires);
637 +               }
638 +
639 +       } else {
640 +               /* send RX_CHANGED to the user immediately */
641 +               bcm_rx_changed(op, rxdata);
642 +       }
643 +}
644 +
645 +/*
646 + * bcm_rx_cmp_to_index - (bit)compares the currently received data to formerly
647 + *                       received data stored in op->last_frames[]
648 + */
649 +static void bcm_rx_cmp_to_index(struct bcm_op *op, int index,
650 +                               struct can_frame *rxdata)
651 +{
652 +       /*
653 +        * no one uses the MSBs of can_dlc for comparation,
654 +        * so we use it here to detect the first time of reception
655 +        */
656 +
657 +       if (!(op->last_frames[index].can_dlc & RX_RECV)) {
658 +               /* received data for the first time => send update to user */
659 +               DBG("first time :)\n");
660 +               bcm_rx_update_and_send(op, &op->last_frames[index], rxdata);
661 +               return;
662 +       }
663 +
664 +       /* do a real check in can_frame data section */
665 +
666 +       DBG("op->frames[index].data = 0x%016llx\n",
667 +           GET_U64(&op->frames[index]));
668 +       DBG("op->last_frames[index].data = 0x%016llx\n",
669 +           GET_U64(&op->last_frames[index]));
670 +       DBG("rxdata->data = 0x%016llx\n", GET_U64(rxdata));
671 +
672 +       if ((GET_U64(&op->frames[index]) & GET_U64(rxdata)) !=
673 +           (GET_U64(&op->frames[index]) & GET_U64(&op->last_frames[index]))) {
674 +               DBG("relevant data change :)\n");
675 +               bcm_rx_update_and_send(op, &op->last_frames[index], rxdata);
676 +               return;
677 +       }
678 +
679 +       if (op->flags & RX_CHECK_DLC) {
680 +               /* do a real check in can_frame dlc */
681 +               if (rxdata->can_dlc != (op->last_frames[index].can_dlc &
682 +                                       BCM_CAN_DLC_MASK)) {
683 +                       DBG("dlc change :)\n");
684 +                       bcm_rx_update_and_send(op, &op->last_frames[index],
685 +                                              rxdata);
686 +                       return;
687 +               }
688 +       }
689 +       DBG("no relevant change :(\n");
690 +}
691 +
692 +/*
693 + * bcm_rx_starttimer - enable timeout monitoring for CAN frame receiption
694 + */
695 +static void bcm_rx_starttimer(struct bcm_op *op)
696 +{
697 +       if (op->flags & RX_NO_AUTOTIMER)
698 +               return;
699 +
700 +       if (op->j_ival1) {
701 +               op->timer.expires = jiffies + op->j_ival1;
702 +
703 +               DBG("adding rx timeout timer ival1. func=%p data=%p "
704 +                   "exp=0x%08X\n",
705 +                   op->timer.function,
706 +                   (char *) op->timer.data,
707 +                   (unsigned int) op->timer.expires);
708 +
709 +               add_timer(&op->timer);
710 +       }
711 +}
712 +
713 +/*
714 + * bcm_rx_timeout_handler - when the (cyclic) CAN frame receiption timed out
715 + */
716 +static void bcm_rx_timeout_handler(unsigned long data)
717 +{
718 +       struct bcm_op *op = (struct bcm_op *)data;
719 +       struct bcm_msg_head msg_head;
720 +
721 +       DBG("sending RX_TIMEOUT for can_id %03X. op is %p\n", op->can_id, op);
722 +
723 +       msg_head.opcode  = RX_TIMEOUT;
724 +       msg_head.flags   = op->flags;
725 +       msg_head.count   = op->count;
726 +       msg_head.ival1   = op->ival1;
727 +       msg_head.ival2   = op->ival2;
728 +       msg_head.can_id  = op->can_id;
729 +       msg_head.nframes = 0;
730 +
731 +       bcm_send_to_user(op, &msg_head, NULL, 0);
732 +
733 +       /* no restart of the timer is done here! */
734 +
735 +       /* if user wants to be informed, when cyclic CAN-Messages come back */
736 +       if ((op->flags & RX_ANNOUNCE_RESUME) && op->last_frames) {
737 +               /* clear received can_frames to indicate 'nothing received' */
738 +               memset(op->last_frames, 0, op->nframes * CFSIZ);
739 +               DBG("RX_ANNOUNCE_RESTART\n");
740 +       }
741 +}
742 +
743 +/*
744 + * bcm_rx_thr_handler - the time for blocked content updates is over now:
745 + *                      Check for throttled data and send it to the userspace
746 + */
747 +static void bcm_rx_thr_handler(unsigned long data)
748 +{
749 +       struct bcm_op *op = (struct bcm_op *)data;
750 +       int i = 0;
751 +
752 +       /* mark disabled / consumed timer */
753 +       op->thrtimer.expires = 0;
754 +
755 +       if (op->nframes > 1) {
756 +               DBG("sending MUX RX_CHANGED for can_id %03X. op is %p\n",
757 +                   op->can_id, op);
758 +               /* for MUX filter we start at index 1 */
759 +               for (i = 1; i < op->nframes; i++) {
760 +                       if ((op->last_frames) &&
761 +                           (op->last_frames[i].can_dlc & RX_THR)) {
762 +                               op->last_frames[i].can_dlc &= ~RX_THR;
763 +                               bcm_rx_changed(op, &op->last_frames[i]);
764 +                       }
765 +               }
766 +
767 +       } else {
768 +               DBG("sending simple RX_CHANGED for can_id %03X. op is %p\n",
769 +                   op->can_id, op);
770 +               /* for RX_FILTER_ID and simple filter */
771 +               if (op->last_frames && (op->last_frames[0].can_dlc & RX_THR)) {
772 +                       op->last_frames[0].can_dlc &= ~RX_THR;
773 +                       bcm_rx_changed(op, &op->last_frames[0]);
774 +               }
775 +       }
776 +}
777 +
778 +/*
779 + * bcm_rx_handler - handle a CAN frame receiption
780 + */
781 +static void bcm_rx_handler(struct sk_buff *skb, void *data)
782 +{
783 +       struct bcm_op *op = (struct bcm_op *)data;
784 +       struct can_frame rxframe;
785 +       int i;
786 +
787 +       /* disable timeout */
788 +       del_timer(&op->timer);
789 +
790 +       DBG("Called with bcm_op %p\n", op);
791 +
792 +       if (skb->len == sizeof(rxframe)) {
793 +               memcpy(&rxframe, skb->data, sizeof(rxframe));
794 +               /* save rx timestamp */
795 +               op->rx_stamp = skb->tstamp;
796 +               /* save originator for recvfrom() */
797 +               op->rx_ifindex = skb->dev->ifindex;
798 +               /* update statistics */
799 +               op->frames_abs++;
800 +               kfree_skb(skb);
801 +               DBG("got can_frame with can_id %03X\n", rxframe.can_id);
802 +
803 +       } else {
804 +               DBG("Wrong skb->len = %d\n", skb->len);
805 +               kfree_skb(skb);
806 +               return;
807 +       }
808 +
809 +       DBG_FRAME("BCM: bcm_rx_handler: CAN frame", &rxframe);
810 +
811 +       if (op->can_id != rxframe.can_id) {
812 +               DBG("ERROR! Got wrong can_id %03X! Expected %03X.\n",
813 +                   rxframe.can_id, op->can_id);
814 +               return;
815 +       }
816 +
817 +       if (op->flags & RX_RTR_FRAME) {
818 +               /* send reply for RTR-request */
819 +               DBG("RTR-request\n");
820 +
821 +               /* send op->frames[0] to CAN device */
822 +               bcm_can_tx(op);
823 +               return;
824 +       }
825 +
826 +       if (op->flags & RX_FILTER_ID) {
827 +               /* the easiest case */
828 +               DBG("Easy does it with RX_FILTER_ID\n");
829 +
830 +               bcm_rx_update_and_send(op, &op->last_frames[0], &rxframe);
831 +               bcm_rx_starttimer(op);
832 +               return;
833 +       }
834 +
835 +       if (op->nframes == 1) {
836 +               /* simple compare with index 0 */
837 +               DBG("Simple compare\n");
838 +
839 +               bcm_rx_cmp_to_index(op, 0, &rxframe);
840 +               bcm_rx_starttimer(op);
841 +               return;
842 +       }
843 +
844 +       if (op->nframes > 1) {
845 +               /* multiplex compare */
846 +               DBG("Multiplex compare\n");
847 +
848 +               /*
849 +                * find the first multiplex mask that fits.
850 +                * Remark: The MUX-mask is stored in index 0
851 +                */
852 +
853 +               for (i = 1; i < op->nframes; i++) {
854 +                       if ((GET_U64(&op->frames[0]) & GET_U64(&rxframe)) ==
855 +                           (GET_U64(&op->frames[0]) &
856 +                            GET_U64(&op->frames[i]))) {
857 +                               DBG("found MUX index %d\n", i);
858 +                               bcm_rx_cmp_to_index(op, i, &rxframe);
859 +                               break;
860 +                       }
861 +               }
862 +               bcm_rx_starttimer(op);
863 +       }
864 +}
865 +
866 +/*
867 + * helpers for bcm_op handling: find & delete bcm [rx|tx] op elements
868 + */
869 +static struct bcm_op *bcm_find_op(struct list_head *ops, canid_t can_id,
870 +                                 int ifindex)
871 +{
872 +       struct bcm_op *op;
873 +
874 +       list_for_each_entry(op, ops, list) {
875 +               if ((op->can_id == can_id) && (op->ifindex == ifindex))
876 +                       return op;
877 +       }
878 +
879 +       return NULL;
880 +}
881 +
882 +static void bcm_remove_op(struct bcm_op *op)
883 +{
884 +       del_timer(&op->timer);
885 +       del_timer(&op->thrtimer);
886 +
887 +       if ((op->frames) && (op->frames != &op->sframe))
888 +               kfree(op->frames);
889 +
890 +       if ((op->last_frames) && (op->last_frames != &op->last_sframe))
891 +               kfree(op->last_frames);
892 +
893 +       kfree(op);
894 +
895 +       return;
896 +}
897 +
898 +static void bcm_rx_unreg(struct net_device *dev, struct bcm_op *op)
899 +{
900 +       if (op->rx_reg_dev == dev) {
901 +               can_rx_unregister(dev, op->can_id, REGMASK(op->can_id),
902 +                                 bcm_rx_handler, op);
903 +
904 +               /* mark as removed subscription */
905 +               op->rx_reg_dev = NULL;
906 +       } else
907 +               printk(KERN_ERR "can-bcm: bcm_rx_unreg: registered device "
908 +                      "mismatch %p %p\n", op->rx_reg_dev, dev);
909 +}
910 +
911 +/*
912 + * bcm_delete_rx_op - find and remove a rx op (returns number of removed ops)
913 + */
914 +static int bcm_delete_rx_op(struct list_head *ops, canid_t can_id, int ifindex)
915 +{
916 +       struct bcm_op *op, *n;
917 +
918 +       list_for_each_entry_safe(op, n, ops, list) {
919 +               if ((op->can_id == can_id) && (op->ifindex == ifindex)) {
920 +                       DBG("removing rx_op %p for can_id %03X\n",
921 +                           op, op->can_id);
922 +
923 +                       /*
924 +                        * Don't care if we're bound or not (due to netdev
925 +                        * problems) can_rx_unregister() is always a save
926 +                        * thing to do here.
927 +                        */
928 +                       if (op->ifindex) {
929 +                               /*
930 +                                * Only remove subscriptions that had not
931 +                                * been removed due to NETDEV_UNREGISTER
932 +                                * in bcm_notifier()
933 +                                */
934 +                               if (op->rx_reg_dev) {
935 +                                       struct net_device *dev;
936 +
937 +                                       dev = dev_get_by_index(&init_net,
938 +                                                              op->ifindex);
939 +                                       if (dev) {
940 +                                               bcm_rx_unreg(dev, op);
941 +                                               dev_put(dev);
942 +                                       }
943 +                               }
944 +                       } else
945 +                               can_rx_unregister(NULL, op->can_id,
946 +                                                 REGMASK(op->can_id),
947 +                                                 bcm_rx_handler, op);
948 +
949 +                       list_del(&op->list);
950 +                       bcm_remove_op(op);
951 +                       return 1; /* done */
952 +               }
953 +       }
954 +
955 +       return 0; /* not found */
956 +}
957 +
958 +/*
959 + * bcm_delete_tx_op - find and remove a tx op (returns number of removed ops)
960 + */
961 +static int bcm_delete_tx_op(struct list_head *ops, canid_t can_id, int ifindex)
962 +{
963 +       struct bcm_op *op, *n;
964 +
965 +       list_for_each_entry_safe(op, n, ops, list) {
966 +               if ((op->can_id == can_id) && (op->ifindex == ifindex)) {
967 +                       DBG("removing rx_op %p for can_id %03X\n",
968 +                           op, op->can_id);
969 +                       list_del(&op->list);
970 +                       bcm_remove_op(op);
971 +                       return 1; /* done */
972 +               }
973 +       }
974 +
975 +       return 0; /* not found */
976 +}
977 +
978 +/*
979 + * bcm_read_op - read out a bcm_op and send it to the user (for bcm_sendmsg)
980 + */
981 +static int bcm_read_op(struct list_head *ops, struct bcm_msg_head *msg_head,
982 +                      int ifindex)
983 +{
984 +       struct bcm_op *op = bcm_find_op(ops, msg_head->can_id, ifindex);
985 +
986 +       if (!op) {
987 +               DBG("TRX_READ: did not find op for can_id %03X\n",
988 +                   msg_head->can_id);
989 +               return -EINVAL;
990 +       }
991 +
992 +       DBG("TRX_READ: sending status for can_id %03X\n",
993 +           msg_head->can_id);
994 +       /* put current values into msg_head */
995 +       msg_head->flags   = op->flags;
996 +       msg_head->count   = op->count;
997 +       msg_head->ival1   = op->ival1;
998 +       msg_head->ival2   = op->ival2;
999 +       msg_head->nframes = op->nframes;
1000 +
1001 +       bcm_send_to_user(op, msg_head, op->frames, 0);
1002 +
1003 +       return MHSIZ;
1004 +}
1005 +
1006 +/*
1007 + * bcm_tx_setup - create or update a bcm tx op (for bcm_sendmsg)
1008 + */
1009 +static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
1010 +                       int ifindex, struct sock *sk)
1011 +{
1012 +       struct bcm_sock *bo = bcm_sk(sk);
1013 +       struct bcm_op *op;
1014 +       int i, err;
1015 +
1016 +       /* we need a real device to send frames */
1017 +       if (!ifindex)
1018 +               return -ENODEV;
1019 +
1020 +       /* we need at least one can_frame */
1021 +       if (msg_head->nframes < 1)
1022 +               return -EINVAL;
1023 +
1024 +       /* check the given can_id */
1025 +       op = bcm_find_op(&bo->tx_ops, msg_head->can_id, ifindex);
1026 +
1027 +       if (op) {
1028 +               /* update existing BCM operation */
1029 +
1030 +               DBG("TX_SETUP: modifying existing tx_op %p for can_id %03X\n",
1031 +                   op, msg_head->can_id);
1032 +
1033 +               /*
1034 +                * Do we need more space for the can_frames than currently
1035 +                * allocated? -> This is a _really_ unusual use-case and
1036 +                * therefore (complexity / locking) it is not supported.
1037 +                */
1038 +               if (msg_head->nframes > op->nframes)
1039 +                       return -E2BIG;
1040 +
1041 +               /* update can_frames content */
1042 +               for (i = 0; i < msg_head->nframes; i++) {
1043 +                       err = memcpy_fromiovec((u8 *)&op->frames[i],
1044 +                                              msg->msg_iov, CFSIZ);
1045 +                       if (err < 0)
1046 +                               return err;
1047 +
1048 +                       if (msg_head->flags & TX_CP_CAN_ID) {
1049 +                               /* copy can_id into frame */
1050 +                               op->frames[i].can_id = msg_head->can_id;
1051 +                       }
1052 +               }
1053 +
1054 +       } else {
1055 +               /* insert new BCM operation for the given can_id */
1056 +
1057 +               op = kzalloc(OPSIZ, GFP_KERNEL);
1058 +               if (!op)
1059 +                       return -ENOMEM;
1060 +
1061 +               DBG("TX_SETUP: creating new tx_op %p for can_id %03X\n",
1062 +                   op, msg_head->can_id);
1063 +
1064 +               op->can_id    = msg_head->can_id;
1065 +
1066 +               /* create array for can_frames and copy the data */
1067 +               if (msg_head->nframes > 1) {
1068 +                       op->frames = kmalloc(msg_head->nframes * CFSIZ,
1069 +                                            GFP_KERNEL);
1070 +                       if (!op->frames) {
1071 +                               kfree(op);
1072 +                               return -ENOMEM;
1073 +                       }
1074 +               } else
1075 +                       op->frames = &op->sframe;
1076 +
1077 +               for (i = 0; i < msg_head->nframes; i++) {
1078 +                       err = memcpy_fromiovec((u8 *)&op->frames[i],
1079 +                                              msg->msg_iov, CFSIZ);
1080 +                       if (err < 0) {
1081 +                               if (op->frames != &op->sframe)
1082 +                                       kfree(op->frames);
1083 +                               kfree(op);
1084 +                               return err;
1085 +                       }
1086 +
1087 +                       if (msg_head->flags & TX_CP_CAN_ID) {
1088 +                               /* copy can_id into frame */
1089 +                               op->frames[i].can_id = msg_head->can_id;
1090 +                       }
1091 +               }
1092 +
1093 +               /* tx_ops never compare with previous received messages */
1094 +               op->last_frames = NULL;
1095 +
1096 +               /* bcm_can_tx / bcm_tx_timeout_handler needs this */
1097 +               op->sk = sk;
1098 +
1099 +               op->ifindex = ifindex;
1100 +
1101 +               /* initialize uninitialized (kmalloc) structure */
1102 +               init_timer(&op->timer);
1103 +
1104 +               /* currently unused in tx_ops */
1105 +               init_timer(&op->thrtimer);
1106 +
1107 +               /* handler for tx_ops */
1108 +               op->timer.function = bcm_tx_timeout_handler;
1109 +
1110 +               /* timer.data points to this op-structure */
1111 +               op->timer.data = (unsigned long)op;
1112 +
1113 +               /* add this bcm_op to the list of the tx_ops */
1114 +               list_add(&op->list, &bo->tx_ops);
1115 +
1116 +       } /* if ((op = bcm_find_op(&bo->tx_ops, msg_head->can_id, ifindex))) */
1117 +
1118 +       if (op->nframes != msg_head->nframes) {
1119 +               op->nframes   = msg_head->nframes;
1120 +               /* start multiple frame transmission with index 0 */
1121 +               op->currframe = 0;
1122 +       }
1123 +
1124 +       /* check flags */
1125 +
1126 +       op->flags = msg_head->flags;
1127 +
1128 +       if (op->flags & TX_RESET_MULTI_IDX) {
1129 +               /* start multiple frame transmission with index 0 */
1130 +               op->currframe = 0;
1131 +       }
1132 +
1133 +       if (op->flags & SETTIMER) {
1134 +               /* set timer values */
1135 +
1136 +               op->count = msg_head->count;
1137 +               op->ival1 = msg_head->ival1;
1138 +               op->ival2 = msg_head->ival2;
1139 +               op->j_ival1 = rounded_tv2jif(&msg_head->ival1);
1140 +               op->j_ival2 = rounded_tv2jif(&msg_head->ival2);
1141 +
1142 +               DBG("TX_SETUP: SETTIMER count=%d j_ival1=%ld j_ival2=%ld\n",
1143 +                   op->count, op->j_ival1, op->j_ival2);
1144 +
1145 +               /* disable an active timer due to zero values? */
1146 +               if (!op->j_ival1 && !op->j_ival2) {
1147 +                       del_timer(&op->timer);
1148 +                       DBG("TX_SETUP: SETTIMER disabled timer.\n");
1149 +               }
1150 +       }
1151 +
1152 +       if ((op->flags & STARTTIMER) &&
1153 +           ((op->j_ival1 && op->count) || op->j_ival2)) {
1154 +
1155 +               del_timer(&op->timer);
1156 +
1157 +               /* spec: send can_frame when starting timer */
1158 +               op->flags |= TX_ANNOUNCE;
1159 +
1160 +               if (op->j_ival1 && (op->count > 0)) {
1161 +                       op->timer.expires = jiffies + op->j_ival1;
1162 +                       /* op->count-- is done in bcm_tx_timeout_handler */
1163 +                       DBG("TX_SETUP: adding timer ival1. func=%p data=%p "
1164 +                           "exp=0x%08X\n",
1165 +                           op->timer.function,
1166 +                           (char *) op->timer.data,
1167 +                           (unsigned int) op->timer.expires);
1168 +
1169 +               } else {
1170 +                       op->timer.expires = jiffies + op->j_ival2;
1171 +                       DBG("TX_SETUP: adding timer ival2. func=%p data=%p "
1172 +                           "exp=0x%08X\n",
1173 +                           op->timer.function,
1174 +                           (char *) op->timer.data,
1175 +                           (unsigned int) op->timer.expires);
1176 +               }
1177 +
1178 +               add_timer(&op->timer);
1179 +       }
1180 +
1181 +       if (op->flags & TX_ANNOUNCE)
1182 +               bcm_can_tx(op);
1183 +
1184 +       return msg_head->nframes * CFSIZ + MHSIZ;
1185 +}
1186 +
1187 +/*
1188 + * bcm_rx_setup - create or update a bcm rx op (for bcm_sendmsg)
1189 + */
1190 +static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
1191 +                       int ifindex, struct sock *sk)
1192 +{
1193 +       struct bcm_sock *bo = bcm_sk(sk);
1194 +       struct bcm_op *op;
1195 +       int do_rx_register;
1196 +       int err = 0;
1197 +
1198 +       if ((msg_head->flags & RX_FILTER_ID) || (!(msg_head->nframes))) {
1199 +               /* be robust against wrong usage ... */
1200 +               msg_head->flags |= RX_FILTER_ID;
1201 +               msg_head->nframes = 0; /* ignore trailing garbage */
1202 +       }
1203 +
1204 +       if ((msg_head->flags & RX_RTR_FRAME) &&
1205 +           ((msg_head->nframes != 1) ||
1206 +            (!(msg_head->can_id & CAN_RTR_FLAG)))) {
1207 +
1208 +               DBG("RX_SETUP: bad RX_RTR_FRAME setup!\n");
1209 +               return -EINVAL;
1210 +       }
1211 +
1212 +       /* check the given can_id */
1213 +       op = bcm_find_op(&bo->rx_ops, msg_head->can_id, ifindex);
1214 +       if (op) {
1215 +               /* update existing BCM operation */
1216 +
1217 +               DBG("RX_SETUP: modifying existing rx_op %p for can_id %03X\n",
1218 +                   op, msg_head->can_id);
1219 +
1220 +               /*
1221 +                * Do we need more space for the can_frames than currently
1222 +                * allocated? -> This is a _really_ unusual use-case and
1223 +                * therefore (complexity / locking) it is not supported.
1224 +                */
1225 +               if (msg_head->nframes > op->nframes)
1226 +                       return -E2BIG;
1227 +
1228 +               if (msg_head->nframes) {
1229 +                       /* update can_frames content */
1230 +                       err = memcpy_fromiovec((u8 *)op->frames,
1231 +                                              msg->msg_iov,
1232 +                                              msg_head->nframes * CFSIZ);
1233 +                       if (err < 0)
1234 +                               return err;
1235 +
1236 +                       /* clear last_frames to indicate 'nothing received' */
1237 +                       memset(op->last_frames, 0, msg_head->nframes * CFSIZ);
1238 +               }
1239 +
1240 +               op->nframes = msg_head->nframes;
1241 +
1242 +               /* Only an update -> do not call can_rx_register() */
1243 +               do_rx_register = 0;
1244 +
1245 +       } else {
1246 +               /* insert new BCM operation for the given can_id */
1247 +
1248 +               op = kzalloc(OPSIZ, GFP_KERNEL);
1249 +               if (!op)
1250 +                       return -ENOMEM;
1251 +
1252 +               DBG("RX_SETUP: creating new rx_op %p for can_id %03X\n",
1253 +                   op, msg_head->can_id);
1254 +
1255 +               op->can_id    = msg_head->can_id;
1256 +               op->nframes   = msg_head->nframes;
1257 +
1258 +               if (msg_head->nframes > 1) {
1259 +                       /* create array for can_frames and copy the data */
1260 +                       op->frames = kmalloc(msg_head->nframes * CFSIZ,
1261 +                                            GFP_KERNEL);
1262 +                       if (!op->frames) {
1263 +                               kfree(op);
1264 +                               return -ENOMEM;
1265 +                       }
1266 +
1267 +                       /* create and init array for received can_frames */
1268 +                       op->last_frames = kzalloc(msg_head->nframes * CFSIZ,
1269 +                                                 GFP_KERNEL);
1270 +                       if (!op->last_frames) {
1271 +                               kfree(op->frames);
1272 +                               kfree(op);
1273 +                               return -ENOMEM;
1274 +                       }
1275 +
1276 +               } else {
1277 +                       op->frames = &op->sframe;
1278 +                       op->last_frames = &op->last_sframe;
1279 +               }
1280 +
1281 +               if (msg_head->nframes) {
1282 +                       err = memcpy_fromiovec((u8 *)op->frames, msg->msg_iov,
1283 +                                              msg_head->nframes * CFSIZ);
1284 +                       if (err < 0) {
1285 +                               if (op->frames != &op->sframe)
1286 +                                       kfree(op->frames);
1287 +                               if (op->last_frames != &op->last_sframe)
1288 +                                       kfree(op->last_frames);
1289 +                               kfree(op);
1290 +                               return err;
1291 +                       }
1292 +               }
1293 +
1294 +               op->sk = sk;
1295 +               op->ifindex = ifindex;
1296 +
1297 +               /* initialize uninitialized (kzalloc) structure */
1298 +               init_timer(&op->timer);
1299 +
1300 +               /* init throttle timer for RX_CHANGED */
1301 +               init_timer(&op->thrtimer);
1302 +
1303 +               /* handler for rx timeouts */
1304 +               op->timer.function = bcm_rx_timeout_handler;
1305 +
1306 +               /* timer.data points to this op-structure */
1307 +               op->timer.data = (unsigned long)op;
1308 +
1309 +               /* handler for RX_CHANGED throttle timeouts */
1310 +               op->thrtimer.function = bcm_rx_thr_handler;
1311 +
1312 +               /* timer.data points to this op-structure */
1313 +               op->thrtimer.data = (unsigned long)op;
1314 +
1315 +               /* mark disabled timer */
1316 +               op->thrtimer.expires = 0;
1317 +
1318 +               /* add this bcm_op to the list of the rx_ops */
1319 +               list_add(&op->list, &bo->rx_ops);
1320 +
1321 +               /* call can_rx_register() */
1322 +               do_rx_register = 1;
1323 +
1324 +       } /* if ((op = bcm_find_op(&bo->rx_ops, msg_head->can_id, ifindex))) */
1325 +
1326 +       /* check flags */
1327 +       op->flags = msg_head->flags;
1328 +
1329 +       if (op->flags & RX_RTR_FRAME) {
1330 +
1331 +               /* no timers in RTR-mode */
1332 +               del_timer(&op->thrtimer);
1333 +               del_timer(&op->timer);
1334 +
1335 +               /*
1336 +                * funny feature in RX(!)_SETUP only for RTR-mode:
1337 +                * copy can_id into frame BUT without RTR-flag to
1338 +                * prevent a full-load-loopback-test ... ;-]
1339 +                */
1340 +               if ((op->flags & TX_CP_CAN_ID) ||
1341 +                   (op->frames[0].can_id == op->can_id))
1342 +                       op->frames[0].can_id = op->can_id & ~CAN_RTR_FLAG;
1343 +
1344 +       } else {
1345 +               if (op->flags & SETTIMER) {
1346 +
1347 +                       /* set timer value */
1348 +                       op->ival1 = msg_head->ival1;
1349 +                       op->ival2 = msg_head->ival2;
1350 +                       op->j_ival1 = rounded_tv2jif(&msg_head->ival1);
1351 +                       op->j_ival2 = rounded_tv2jif(&msg_head->ival2);
1352 +
1353 +                       DBG("RX_SETUP: SETTIMER j_ival1=%ld j_ival2=%ld\n",
1354 +                           op->j_ival1, op->j_ival2);
1355 +
1356 +                       /* disable an active timer due to zero value? */
1357 +                       if (!op->j_ival1) {
1358 +                               del_timer(&op->timer);
1359 +                               DBG("RX_SETUP: disabled timer rx timeouts.\n");
1360 +                       }
1361 +
1362 +                       /* free currently blocked msgs ? */
1363 +                       if (op->thrtimer.expires) {
1364 +                               DBG("RX_SETUP: unblocking throttled msgs.\n");
1365 +                               del_timer(&op->thrtimer);
1366 +                               /* send blocked msgs hereafter */
1367 +                               op->thrtimer.expires = jiffies + 2;
1368 +                               add_timer(&op->thrtimer);
1369 +                       }
1370 +                       /*
1371 +                        * if (op->j_ival2) is zero, no (new) throttling
1372 +                        * will happen. For details see functions
1373 +                        * bcm_rx_update_and_send() and bcm_rx_thr_handler()
1374 +                        */
1375 +               }
1376 +
1377 +               if ((op->flags & STARTTIMER) && op->j_ival1) {
1378 +
1379 +                       del_timer(&op->timer);
1380 +                       op->timer.expires = jiffies + op->j_ival1;
1381 +
1382 +                       DBG("RX_SETUP: adding timer ival1. func=%p data=%p"
1383 +                           " exp=0x%08X\n",
1384 +                           (char *) op->timer.function,
1385 +                           (char *) op->timer.data,
1386 +                           (unsigned int) op->timer.expires);
1387 +
1388 +                       add_timer(&op->timer);
1389 +               }
1390 +       }
1391 +
1392 +       /* now we can register for can_ids, if we added a new bcm_op */
1393 +       if (do_rx_register) {
1394 +               DBG("RX_SETUP: can_rx_register() for can_id %03X. "
1395 +                   "rx_op is %p\n", op->can_id, op);
1396 +
1397 +               if (ifindex) {
1398 +                       struct net_device *dev;
1399 +
1400 +                       dev = dev_get_by_index(&init_net, ifindex);
1401 +                       if (dev) {
1402 +                               err = can_rx_register(dev, op->can_id,
1403 +                                                     REGMASK(op->can_id),
1404 +                                                     bcm_rx_handler, op,
1405 +                                                     "bcm");
1406 +
1407 +                               op->rx_reg_dev = dev;
1408 +                               dev_put(dev);
1409 +                       }
1410 +
1411 +               } else
1412 +                       err = can_rx_register(NULL, op->can_id,
1413 +                                             REGMASK(op->can_id),
1414 +                                             bcm_rx_handler, op, "bcm");
1415 +               if (err) {
1416 +                       /* this bcm rx op is broken -> remove it */
1417 +                       list_del(&op->list);
1418 +                       bcm_remove_op(op);
1419 +                       return err;
1420 +               }
1421 +       }
1422 +
1423 +       return msg_head->nframes * CFSIZ + MHSIZ;
1424 +}
1425 +
1426 +/*
1427 + * bcm_tx_send - send a single CAN frame to the CAN interface (for bcm_sendmsg)
1428 + */
1429 +static int bcm_tx_send(struct msghdr *msg, int ifindex, struct sock *sk)
1430 +{
1431 +       struct sk_buff *skb;
1432 +       struct net_device *dev;
1433 +       int err;
1434 +
1435 +       /* just copy and send one can_frame */
1436 +
1437 +       if (!ifindex) /* we need a real device to send frames */
1438 +               return -ENODEV;
1439 +
1440 +       skb = alloc_skb(CFSIZ, GFP_KERNEL);
1441 +
1442 +       if (!skb)
1443 +               return -ENOMEM;
1444 +
1445 +       err = memcpy_fromiovec(skb_put(skb, CFSIZ), msg->msg_iov, CFSIZ);
1446 +       if (err < 0) {
1447 +               kfree_skb(skb);
1448 +               return err;
1449 +       }
1450 +
1451 +       DBG_FRAME("BCM: TX_SEND: sending frame",
1452 +                 (struct can_frame *)skb->data);
1453 +
1454 +       dev = dev_get_by_index(&init_net, ifindex);
1455 +       if (!dev) {
1456 +               kfree_skb(skb);
1457 +               return -ENODEV;
1458 +       }
1459 +
1460 +       skb->dev = dev;
1461 +       skb->sk  = sk;
1462 +       can_send(skb, 1); /* send with loopback */
1463 +       dev_put(dev);
1464 +
1465 +       return CFSIZ + MHSIZ;
1466 +}
1467 +
1468 +/*
1469 + * bcm_sendmsg - process BCM commands (opcodes) from the userspace
1470 + */
1471 +static int bcm_sendmsg(struct kiocb *iocb, struct socket *sock,
1472 +                      struct msghdr *msg, size_t size)
1473 +{
1474 +       struct sock *sk = sock->sk;
1475 +       struct bcm_sock *bo = bcm_sk(sk);
1476 +       int ifindex = bo->ifindex; /* default ifindex for this bcm_op */
1477 +       struct bcm_msg_head msg_head;
1478 +       int ret; /* read bytes or error codes as return value */
1479 +
1480 +       if (!bo->bound) {
1481 +               DBG("sock %p not bound\n", sk);
1482 +               return -ENOTCONN;
1483 +       }
1484 +
1485 +       /* check for alternative ifindex for this bcm_op */
1486 +
1487 +       if (!ifindex && msg->msg_name) {
1488 +               /* no bound device as default => check msg_name */
1489 +               struct sockaddr_can *addr =
1490 +                       (struct sockaddr_can *)msg->msg_name;
1491 +
1492 +               if (addr->can_family != AF_CAN)
1493 +                       return -EINVAL;
1494 +
1495 +               ifindex = addr->can_ifindex; /* ifindex from sendto() */
1496 +
1497 +               if (ifindex) {
1498 +                       struct net_device *dev;
1499 +
1500 +                       dev = dev_get_by_index(&init_net, ifindex);
1501 +                       if (!dev) {
1502 +                               DBG("device %d not found\n", ifindex);
1503 +                               return -ENODEV;
1504 +                       }
1505 +
1506 +                       if (dev->type != ARPHRD_CAN) {
1507 +                               DBG("device %d no CAN device\n", ifindex);
1508 +                               dev_put(dev);
1509 +                               return -ENODEV;
1510 +                       }
1511 +
1512 +                       dev_put(dev);
1513 +               }
1514 +       }
1515 +
1516 +       /* read message head information */
1517 +
1518 +       ret = memcpy_fromiovec((u8 *)&msg_head, msg->msg_iov, MHSIZ);
1519 +       if (ret < 0)
1520 +               return ret;
1521 +
1522 +       DBG("opcode %d for can_id %03X\n", msg_head.opcode, msg_head.can_id);
1523 +
1524 +       lock_sock(sk);
1525 +
1526 +       switch (msg_head.opcode) {
1527 +
1528 +       case TX_SETUP:
1529 +               ret = bcm_tx_setup(&msg_head, msg, ifindex, sk);
1530 +               break;
1531 +
1532 +       case RX_SETUP:
1533 +               ret = bcm_rx_setup(&msg_head, msg, ifindex, sk);
1534 +               break;
1535 +
1536 +       case TX_DELETE:
1537 +               if (bcm_delete_tx_op(&bo->tx_ops, msg_head.can_id, ifindex))
1538 +                       ret = MHSIZ;
1539 +               else
1540 +                       ret = -EINVAL;
1541 +               break;
1542 +
1543 +       case RX_DELETE:
1544 +               if (bcm_delete_rx_op(&bo->rx_ops, msg_head.can_id, ifindex))
1545 +                       ret = MHSIZ;
1546 +               else
1547 +                       ret = -EINVAL;
1548 +               break;
1549 +
1550 +       case TX_READ:
1551 +               /* reuse msg_head for the reply to TX_READ */
1552 +               msg_head.opcode  = TX_STATUS;
1553 +               ret = bcm_read_op(&bo->tx_ops, &msg_head, ifindex);
1554 +               break;
1555 +
1556 +       case RX_READ:
1557 +               /* reuse msg_head for the reply to RX_READ */
1558 +               msg_head.opcode  = RX_STATUS;
1559 +               ret = bcm_read_op(&bo->rx_ops, &msg_head, ifindex);
1560 +               break;
1561 +
1562 +       case TX_SEND:
1563 +               /* we need at least one can_frame */
1564 +               if (msg_head.nframes < 1)
1565 +                       ret = -EINVAL;
1566 +               else
1567 +                       ret = bcm_tx_send(msg, ifindex, sk);
1568 +               break;
1569 +
1570 +       default:
1571 +               DBG("Unknown opcode %d\n", msg_head.opcode);
1572 +               ret = -EINVAL;
1573 +               break;
1574 +       }
1575 +
1576 +       release_sock(sk);
1577 +
1578 +       return ret;
1579 +}
1580 +
1581 +/*
1582 + * notification handler for netdevice status changes
1583 + */
1584 +static int bcm_notifier(struct notifier_block *nb, unsigned long msg,
1585 +                       void *data)
1586 +{
1587 +       struct net_device *dev = (struct net_device *)data;
1588 +       struct bcm_sock *bo = container_of(nb, struct bcm_sock, notifier);
1589 +       struct sock *sk = &bo->sk;
1590 +       struct bcm_op *op;
1591 +       int notify_enodev = 0;
1592 +
1593 +       DBG("msg %ld for dev %p (%s idx %d) sk %p bo->ifindex %d\n",
1594 +           msg, dev, dev->name, dev->ifindex, sk, bo->ifindex);
1595 +
1596 +       if (dev->nd_net != &init_net)
1597 +               return NOTIFY_DONE;
1598 +
1599 +       if (dev->type != ARPHRD_CAN)
1600 +               return NOTIFY_DONE;
1601 +
1602 +       switch (msg) {
1603 +
1604 +       case NETDEV_UNREGISTER:
1605 +               lock_sock(sk);
1606 +
1607 +               /* remove device specific receive entries */
1608 +               list_for_each_entry(op, &bo->rx_ops, list)
1609 +                       if (op->rx_reg_dev == dev)
1610 +                               bcm_rx_unreg(dev, op);
1611 +
1612 +               /* remove device reference, if this is our bound device */
1613 +               if (bo->bound && bo->ifindex == dev->ifindex) {
1614 +                       bo->bound   = 0;
1615 +                       bo->ifindex = 0;
1616 +                       notify_enodev = 1;
1617 +               }
1618 +
1619 +               release_sock(sk);
1620 +
1621 +               if (notify_enodev) {
1622 +                       sk->sk_err = ENODEV;
1623 +                       if (!sock_flag(sk, SOCK_DEAD))
1624 +                               sk->sk_error_report(sk);
1625 +               }
1626 +               break;
1627 +
1628 +       case NETDEV_DOWN:
1629 +               if (bo->bound && bo->ifindex == dev->ifindex) {
1630 +                       sk->sk_err = ENETDOWN;
1631 +                       if (!sock_flag(sk, SOCK_DEAD))
1632 +                               sk->sk_error_report(sk);
1633 +               }
1634 +       }
1635 +
1636 +       return NOTIFY_DONE;
1637 +}
1638 +
1639 +/*
1640 + * initial settings for all BCM sockets to be set at socket creation time
1641 + */
1642 +static int bcm_init(struct sock *sk)
1643 +{
1644 +       struct bcm_sock *bo = bcm_sk(sk);
1645 +
1646 +       bo->bound            = 0;
1647 +       bo->ifindex          = 0;
1648 +       bo->dropped_usr_msgs = 0;
1649 +       bo->bcm_proc_read    = NULL;
1650 +
1651 +       INIT_LIST_HEAD(&bo->tx_ops);
1652 +       INIT_LIST_HEAD(&bo->rx_ops);
1653 +
1654 +       /* set notifier */
1655 +       bo->notifier.notifier_call = bcm_notifier;
1656 +
1657 +       register_netdevice_notifier(&bo->notifier);
1658 +
1659 +       return 0;
1660 +}
1661 +
1662 +/*
1663 + * standard socket functions
1664 + */
1665 +static int bcm_release(struct socket *sock)
1666 +{
1667 +       struct sock *sk = sock->sk;
1668 +       struct bcm_sock *bo = bcm_sk(sk);
1669 +       struct bcm_op *op, *next;
1670 +
1671 +       DBG("socket %p, sk %p\n", sock, sk);
1672 +
1673 +       /* remove bcm_ops, timer, rx_unregister(), etc. */
1674 +
1675 +       unregister_netdevice_notifier(&bo->notifier);
1676 +
1677 +       lock_sock(sk);
1678 +
1679 +       list_for_each_entry_safe(op, next, &bo->tx_ops, list) {
1680 +               DBG("removing tx_op %p for can_id %03X\n", op, op->can_id);
1681 +               bcm_remove_op(op);
1682 +       }
1683 +
1684 +       list_for_each_entry_safe(op, next, &bo->rx_ops, list) {
1685 +               DBG("removing rx_op %p for can_id %03X\n", op, op->can_id);
1686 +
1687 +               /*
1688 +                * Don't care if we're bound or not (due to netdev problems)
1689 +                * can_rx_unregister() is always a save thing to do here.
1690 +                */
1691 +               if (op->ifindex) {
1692 +                       /*
1693 +                        * Only remove subscriptions that had not
1694 +                        * been removed due to NETDEV_UNREGISTER
1695 +                        * in bcm_notifier()
1696 +                        */
1697 +                       if (op->rx_reg_dev) {
1698 +                               struct net_device *dev;
1699 +
1700 +                               dev = dev_get_by_index(&init_net, op->ifindex);
1701 +                               if (dev) {
1702 +                                       bcm_rx_unreg(dev, op);
1703 +                                       dev_put(dev);
1704 +                               }
1705 +                       }
1706 +               } else
1707 +                       can_rx_unregister(NULL, op->can_id,
1708 +                                         REGMASK(op->can_id),
1709 +                                         bcm_rx_handler, op);
1710 +
1711 +               bcm_remove_op(op);
1712 +       }
1713 +
1714 +       /* remove procfs entry */
1715 +       if (proc_dir && bo->bcm_proc_read)
1716 +               remove_proc_entry(bo->procname, proc_dir);
1717 +
1718 +       /* remove device reference */
1719 +       if (bo->bound) {
1720 +               bo->bound   = 0;
1721 +               bo->ifindex = 0;
1722 +       }
1723 +
1724 +       release_sock(sk);
1725 +       sock_put(sk);
1726 +
1727 +       return 0;
1728 +}
1729 +
1730 +static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len,
1731 +                      int flags)
1732 +{
1733 +       struct sockaddr_can *addr = (struct sockaddr_can *)uaddr;
1734 +       struct sock *sk = sock->sk;
1735 +       struct bcm_sock *bo = bcm_sk(sk);
1736 +
1737 +       if (bo->bound)
1738 +               return -EISCONN;
1739 +
1740 +       /* bind a device to this socket */
1741 +       if (addr->can_ifindex) {
1742 +               struct net_device *dev;
1743 +
1744 +               dev = dev_get_by_index(&init_net, addr->can_ifindex);
1745 +               if (!dev) {
1746 +                       DBG("could not find device index %d\n",
1747 +                           addr->can_ifindex);
1748 +                       return -ENODEV;
1749 +               }
1750 +
1751 +               if (dev->type != ARPHRD_CAN) {
1752 +                       DBG("device %d no CAN device\n", addr->can_ifindex);
1753 +                       dev_put(dev);
1754 +                       return -ENODEV;
1755 +               }
1756 +
1757 +               bo->ifindex = dev->ifindex;
1758 +               dev_put(dev);
1759 +
1760 +               DBG("socket %p bound to device %s (idx %d)\n",
1761 +                   sock, dev->name, dev->ifindex);
1762 +
1763 +       } else {
1764 +               /* no interface reference for ifindex = 0 ('any' CAN device) */
1765 +               bo->ifindex = 0;
1766 +       }
1767 +
1768 +       bo->bound = 1;
1769 +
1770 +       if (proc_dir) {
1771 +               /* unique socket address as filename */
1772 +               sprintf(bo->procname, "%p", sock);
1773 +               bo->bcm_proc_read = create_proc_read_entry(bo->procname, 0644,
1774 +                                                          proc_dir,
1775 +                                                          bcm_read_proc, sk);
1776 +       }
1777 +
1778 +       return 0;
1779 +}
1780 +
1781 +static int bcm_recvmsg(struct kiocb *iocb, struct socket *sock,
1782 +                      struct msghdr *msg, size_t size, int flags)
1783 +{
1784 +       struct sock *sk = sock->sk;
1785 +       struct sk_buff *skb;
1786 +       int error = 0;
1787 +       int noblock;
1788 +       int err;
1789 +
1790 +       DBG("socket %p, sk %p\n", sock, sk);
1791 +
1792 +       noblock =  flags & MSG_DONTWAIT;
1793 +       flags   &= ~MSG_DONTWAIT;
1794 +       skb = skb_recv_datagram(sk, flags, noblock, &error);
1795 +       if (!skb)
1796 +               return error;
1797 +
1798 +       DBG("delivering skbuff %p\n", skb);
1799 +       DBG_SKB(skb);
1800 +
1801 +       if (skb->len < size)
1802 +               size = skb->len;
1803 +
1804 +       err = memcpy_toiovec(msg->msg_iov, skb->data, size);
1805 +       if (err < 0) {
1806 +               skb_free_datagram(sk, skb);
1807 +               return err;
1808 +       }
1809 +
1810 +       sock_recv_timestamp(msg, sk, skb);
1811 +
1812 +       if (msg->msg_name) {
1813 +               msg->msg_namelen = sizeof(struct sockaddr_can);
1814 +               memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
1815 +       }
1816 +
1817 +       DBG("freeing sock %p, skbuff %p\n", sk, skb);
1818 +       skb_free_datagram(sk, skb);
1819 +
1820 +       return size;
1821 +}
1822 +
1823 +static struct proto_ops bcm_ops __read_mostly = {
1824 +       .family        = PF_CAN,
1825 +       .release       = bcm_release,
1826 +       .bind          = sock_no_bind,
1827 +       .connect       = bcm_connect,
1828 +       .socketpair    = sock_no_socketpair,
1829 +       .accept        = sock_no_accept,
1830 +       .getname       = sock_no_getname,
1831 +       .poll          = datagram_poll,
1832 +       .ioctl         = NULL,          /* use can_ioctl() from af_can.c */
1833 +       .listen        = sock_no_listen,
1834 +       .shutdown      = sock_no_shutdown,
1835 +       .setsockopt    = sock_no_setsockopt,
1836 +       .getsockopt    = sock_no_getsockopt,
1837 +       .sendmsg       = bcm_sendmsg,
1838 +       .recvmsg       = bcm_recvmsg,
1839 +       .mmap          = sock_no_mmap,
1840 +       .sendpage      = sock_no_sendpage,
1841 +};
1842 +
1843 +static struct proto bcm_proto __read_mostly = {
1844 +       .name       = "CAN_BCM",
1845 +       .owner      = THIS_MODULE,
1846 +       .obj_size   = sizeof(struct bcm_sock),
1847 +       .init       = bcm_init,
1848 +};
1849 +
1850 +static struct can_proto bcm_can_proto __read_mostly = {
1851 +       .type       = SOCK_DGRAM,
1852 +       .protocol   = CAN_BCM,
1853 +       .capability = -1,
1854 +       .ops        = &bcm_ops,
1855 +       .prot       = &bcm_proto,
1856 +};
1857 +
1858 +static int __init bcm_module_init(void)
1859 +{
1860 +       int err;
1861 +
1862 +       printk(banner);
1863 +
1864 +       err = can_proto_register(&bcm_can_proto);
1865 +       if (err < 0) {
1866 +               printk(KERN_ERR "can: registration of bcm protocol failed\n");
1867 +               return err;
1868 +       }
1869 +
1870 +       /* create /proc/net/can-bcm directory */
1871 +       proc_dir = proc_mkdir("can-bcm", init_net.proc_net);
1872 +
1873 +       if (proc_dir)
1874 +               proc_dir->owner = THIS_MODULE;
1875 +
1876 +       return 0;
1877 +}
1878 +
1879 +static void __exit bcm_module_exit(void)
1880 +{
1881 +       can_proto_unregister(&bcm_can_proto);
1882 +
1883 +       if (proc_dir)
1884 +               proc_net_remove(&init_net, "can-bcm");
1885 +}
1886 +
1887 +module_init(bcm_module_init);
1888 +module_exit(bcm_module_exit);