2 CAN: Add broadcast manager (bcm) protocol
4 This patch adds the CAN broadcast manager (bcm) protocol.
6 Signed-Off-By: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
7 Signed-Off-By: Urs Thuermann <urs.thuermann@volkswagen.de>
10 include/linux/can/bcm.h | 65 +
13 net/can/bcm.c | 1671 ++++++++++++++++++++++++++++++++++++++++++++++++
14 4 files changed, 1767 insertions(+)
16 Index: linux-2.6.22-rc2-git3/include/linux/can/bcm.h
17 ===================================================================
18 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
19 +++ linux-2.6.22-rc2-git3/include/linux/can/bcm.h 2007-05-23 12:25:52.%N +0200
24 + * Definitions for CAN Broadcast Manager (BCM)
26 + * Author: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
27 + * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
28 + * All rights reserved.
30 + * Send feedback to <socketcan-users@lists.berlios.de>
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.
48 +struct bcm_msg_head {
52 + struct timeval ival1, ival2;
55 + struct can_frame frames[0];
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) */
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
85 +#endif /* CAN_BCM_H */
86 Index: linux-2.6.22-rc2-git3/net/can/Kconfig
87 ===================================================================
88 --- linux-2.6.22-rc2-git3.orig/net/can/Kconfig 2007-05-23 12:25:52.%N +0200
89 +++ linux-2.6.22-rc2-git3/net/can/Kconfig 2007-05-23 12:25:52.%N +0200
91 Say Y here if you want non-root users to be able to access CAN_RAW
95 + tristate "Broadcast Manager CAN Protocol (with content filtering)"
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.
108 + bool "Allow non-root users to access CAN broadcast manager sockets"
112 + The Controller Area Network is a local field bus transmitting only
113 + broadcast messages without any routing and security concepts.
114 + In the majority of cases the user application has to deal with
115 + raw CAN frames. Therefore it might be reasonable NOT to restrict
116 + the CAN access only to the user root, as known from other networks.
117 + Since CAN_BCM sockets can only send and receive frames to/from CAN
118 + interfaces this does not affect security of others networks.
119 + Say Y here if you want non-root users to be able to access CAN_BCM
122 config CAN_DEBUG_CORE
123 bool "CAN Core debugging messages"
125 Index: linux-2.6.22-rc2-git3/net/can/Makefile
126 ===================================================================
127 --- linux-2.6.22-rc2-git3.orig/net/can/Makefile 2007-05-23 12:25:52.%N +0200
128 +++ linux-2.6.22-rc2-git3/net/can/Makefile 2007-05-23 12:25:52.%N +0200
131 obj-$(CONFIG_CAN_RAW) += can-raw.o
132 can-raw-objs := raw.o
134 +obj-$(CONFIG_CAN_BCM) += can-bcm.o
135 +can-bcm-objs := bcm.o
136 Index: linux-2.6.22-rc2-git3/net/can/bcm.c
137 ===================================================================
138 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
139 +++ linux-2.6.22-rc2-git3/net/can/bcm.c 2007-05-23 12:25:52.%N +0200
142 + * bcm.c - Broadcast Manager to filter/send (cyclic) CAN content
144 + * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
145 + * All rights reserved.
147 + * Redistribution and use in source and binary forms, with or without
148 + * modification, are permitted provided that the following conditions
150 + * 1. Redistributions of source code must retain the above copyright
151 + * notice, this list of conditions, the following disclaimer and
152 + * the referenced file 'COPYING'.
153 + * 2. Redistributions in binary form must reproduce the above copyright
154 + * notice, this list of conditions and the following disclaimer in the
155 + * documentation and/or other materials provided with the distribution.
156 + * 3. Neither the name of Volkswagen nor the names of its contributors
157 + * may be used to endorse or promote products derived from this software
158 + * without specific prior written permission.
160 + * Alternatively, provided that this notice is retained in full, this
161 + * software may be distributed under the terms of the GNU General
162 + * Public License ("GPL") version 2 as distributed in the 'COPYING'
163 + * file from the main directory of the linux kernel source.
165 + * The provided data structures and external interfaces from this code
166 + * are not restricted to be used by modules with a GPL compatible license.
168 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
169 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
170 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
171 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
172 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
173 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
174 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
175 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
176 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
177 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
178 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
181 + * Send feedback to <socketcan-users@lists.berlios.de>
185 +#include <linux/module.h>
186 +#include <linux/init.h>
187 +#include <linux/net.h>
188 +#include <linux/netdevice.h>
189 +#include <linux/proc_fs.h>
190 +#include <linux/poll.h>
191 +#include <linux/can.h>
192 +#include <linux/can/core.h>
193 +#include <linux/can/bcm.h>
194 +#include <net/sock.h>
196 +/* use of last_frames[index].can_dlc */
197 +#define RX_RECV 0x40 /* received data for this element */
198 +#define RX_THR 0x80 /* element not been sent due to throttle feature */
199 +#define BCM_CAN_DLC_MASK 0x0F /* clean private flags in can_dlc by masking */
201 +/* get best masking value for can_rx_register() for a given single can_id */
202 +#define REGMASK(id) ((id & CAN_RTR_FLAG) | ((id & CAN_EFF_FLAG) ? \
203 + (CAN_EFF_MASK | CAN_EFF_FLAG) : CAN_SFF_MASK))
206 +#define CAN_BCM_VERSION CAN_VERSION
207 +static __initdata const char banner[] = KERN_INFO
208 + "can: broadcast manager protocol # rev " CAN_BCM_VERSION "\n";
210 +MODULE_DESCRIPTION("PF_CAN broadcast manager protocol");
211 +MODULE_LICENSE("Dual BSD/GPL");
212 +MODULE_AUTHOR("Oliver Hartkopp <oliver.hartkopp@volkswagen.de>");
214 +#ifdef CONFIG_CAN_DEBUG_CORE
215 +static int debug = 0;
216 +module_param(debug, int, S_IRUGO);
217 +MODULE_PARM_DESC(debug, "debug print mask: 1:debug, 2:frames, 4:skbs");
220 +/* easy access to can_frame payload */
221 +static inline u64 GET_U64(const struct can_frame *cp)
223 + return *(u64*)cp->data;
227 + struct list_head list;
231 + unsigned long j_ival1, j_ival2, j_lastmsg;
232 + unsigned long frames_abs, frames_filtered;
233 + struct timer_list timer, thrtimer;
234 + struct timeval ival1, ival2;
235 + struct timeval rx_stamp;
240 + struct can_frame *frames;
241 + struct can_frame *last_frames;
242 + struct can_frame sframe;
243 + struct can_frame last_sframe;
250 + struct list_head rx_ops;
251 + struct list_head tx_ops;
252 + unsigned long dropped_usr_msgs;
253 + struct proc_dir_entry *bcm_proc_read;
254 + char procname [9]; /* pointer printed in ASCII with \0 */
257 +static struct proc_dir_entry *proc_dir = NULL;
259 +#ifdef CONFIG_CAN_BCM_USER
260 +#define BCM_CAP (-1)
262 +#define BCM_CAP CAP_NET_RAW
267 + struct bcm_opt opt;
270 +static inline struct bcm_opt *bcm_sk(const struct sock *sk)
272 + return &((struct bcm_sock *)sk)->opt;
275 +#define CFSIZ sizeof(struct can_frame)
276 +#define OPSIZ sizeof(struct bcm_op)
277 +#define MHSIZ sizeof(struct bcm_msg_head)
280 + * rounded_tv2jif - calculate jiffies from timeval including optional up
281 + * @tv: pointer to timeval
284 + * In opposite to timeval_to_jiffies() provided in include/linux/jiffies.h this
285 + * function is intentionally more relaxed on precise timer ticks to get exact
286 + * one jiffy for requested 1000us on a 1000HZ machine.
287 + * This code is to be removed when upgrading to kernel hrtimer.
290 + * calculated jiffies (max: ULONG_MAX)
292 +static unsigned long rounded_tv2jif(const struct timeval *tv)
294 + unsigned long sec = tv->tv_sec;
295 + unsigned long usec = tv->tv_usec;
298 + if (sec > ULONG_MAX / HZ)
301 + /* round up to get at least the requested time */
302 + usec += 1000000 / HZ - 1;
304 + jif = usec / (1000000 / HZ);
306 + if (sec * HZ > ULONG_MAX - jif)
309 + return jif + sec * HZ;
315 +static char *bcm_proc_getifname(int ifindex)
317 + struct net_device *dev;
322 + dev = __dev_get_by_index(ifindex); /* no usage counting */
329 +static int bcm_read_proc(char *page, char **start, off_t off,
330 + int count, int *eof, void *data)
333 + struct sock *sk = (struct sock *)data;
334 + struct bcm_opt *bo = bcm_sk(sk);
337 + len += snprintf(page + len, PAGE_SIZE - len, ">>> socket %p",
339 + len += snprintf(page + len, PAGE_SIZE - len, " / sk %p", sk);
340 + len += snprintf(page + len, PAGE_SIZE - len, " / bo %p", bo);
341 + len += snprintf(page + len, PAGE_SIZE - len, " / dropped %lu",
342 + bo->dropped_usr_msgs);
343 + len += snprintf(page + len, PAGE_SIZE - len, " / bound %s",
344 + bcm_proc_getifname(bo->ifindex));
345 + len += snprintf(page + len, PAGE_SIZE - len, " <<<\n");
347 + list_for_each_entry(op, &bo->rx_ops, list) {
349 + unsigned long reduction;
351 + /* print only active entries & prevent division by zero */
352 + if (!op->frames_abs)
355 + len += snprintf(page + len, PAGE_SIZE - len,
356 + "rx_op: %03X %-5s ",
357 + op->can_id, bcm_proc_getifname(op->ifindex));
358 + len += snprintf(page + len, PAGE_SIZE - len, "[%d]%c ",
360 + (op->flags & RX_CHECK_DLC)?'d':' ');
362 + len += snprintf(page + len, PAGE_SIZE - len,
363 + "timeo=%ld ", op->j_ival1);
366 + len += snprintf(page + len, PAGE_SIZE - len,
367 + "thr=%ld ", op->j_ival2);
369 + len += snprintf(page + len, PAGE_SIZE - len,
370 + "# recv %ld (%ld) => reduction: ",
371 + op->frames_filtered, op->frames_abs);
373 + reduction = 100 - (op->frames_filtered * 100) / op->frames_abs;
375 + len += snprintf(page + len, PAGE_SIZE - len, "%s%ld%%\n",
376 + (reduction == 100)?"near ":"", reduction);
378 + if (len > PAGE_SIZE - 200) {
379 + /* mark output cut off */
380 + len += snprintf(page + len, PAGE_SIZE - len, "(..)\n");
385 + list_for_each_entry(op, &bo->tx_ops, list) {
387 + len += snprintf(page + len, PAGE_SIZE - len,
388 + "tx_op: %03X %s [%d] ",
389 + op->can_id, bcm_proc_getifname(op->ifindex),
392 + len += snprintf(page + len, PAGE_SIZE - len, "t1=%ld ",
396 + len += snprintf(page + len, PAGE_SIZE - len, "t2=%ld ",
399 + len += snprintf(page + len, PAGE_SIZE - len, "# sent %ld\n",
402 + if (len > PAGE_SIZE - 100) {
403 + /* mark output cut off */
404 + len += snprintf(page + len, PAGE_SIZE - len, "(..)\n");
409 + len += snprintf(page + len, PAGE_SIZE - len, "\n");
416 + * bcm_can_tx - send the (next) CAN frame to the appropriate CAN interface
417 + * of the given bcm tx op
419 +static void bcm_can_tx(struct bcm_op *op)
421 + struct sk_buff *skb;
422 + struct net_device *dev;
423 + struct can_frame *cf = &op->frames[op->currframe];
425 + DBG_FRAME("BCM: bcm_can_tx: sending frame", cf);
427 + /* no target device? => exit */
431 + dev = dev_get_by_index(op->ifindex);
434 + /* RFC: should this bcm_op remove itself here? */
438 + skb = alloc_skb(CFSIZ,
439 + in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
444 + memcpy(skb_put(skb, CFSIZ), cf, CFSIZ);
446 + /* send with loopback */
451 + /* update statistics */
455 + /* reached last frame? */
456 + if (op->currframe >= op->nframes)
463 + * bcm_send_to_user - send a BCM message to the userspace
464 + * (consisting of bcm_msg_head + x CAN frames)
466 +static void bcm_send_to_user(struct bcm_op *op, struct bcm_msg_head *head,
467 + struct can_frame *frames, struct timeval *tv)
469 + struct sk_buff *skb;
470 + struct can_frame *firstframe;
471 + struct sock *sk = op->sk;
472 + int datalen = head->nframes * CFSIZ;
473 + struct sockaddr_can *addr;
476 + skb = alloc_skb(sizeof(*head) + datalen,
477 + in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
481 + memcpy(skb_put(skb, sizeof(*head)), head, sizeof(*head));
483 + /* can_frames starting here */
484 + firstframe = (struct can_frame *) skb->tail;
487 + skb_set_timestamp(skb, tv); /* restore timestamp */
489 + addr = (struct sockaddr_can *)skb->cb;
490 + memset(addr, 0, sizeof(*addr));
491 + addr->can_family = AF_CAN;
492 + /* restore originator for recvfrom() */
493 + addr->can_ifindex = op->rx_ifindex;
495 + if (head->nframes) {
496 + memcpy(skb_put(skb, datalen), frames, datalen);
499 + * the BCM uses the can_dlc-element of the can_frame
500 + * structure for internal purposes. This is only
501 + * relevant for updates that are generated by the
502 + * BCM, where nframes is 1
504 + if (head->nframes == 1)
505 + firstframe->can_dlc &= BCM_CAN_DLC_MASK;
508 + err = sock_queue_rcv_skb(sk, skb);
510 + struct bcm_opt *bo = bcm_sk(sk);
512 + DBG("sock_queue_rcv_skb failed: %d\n", err);
514 + /* don't care about overflows in this statistic */
515 + bo->dropped_usr_msgs++;
520 + * bcm_tx_timeout_handler - performes cyclic CAN frame transmissions
522 +static void bcm_tx_timeout_handler(unsigned long data)
524 + struct bcm_op *op = (struct bcm_op*)data;
526 + DBG("Called with bcm_op %p\n", op);
528 + if (op->j_ival1 && (op->count > 0)) {
531 + if (!op->count && (op->flags & TX_COUNTEVT)) {
532 + struct bcm_msg_head msg_head;
534 + /* create notification to user */
535 + DBG("sending TX_EXPIRED for can_id %03X\n",
538 + msg_head.opcode = TX_EXPIRED;
539 + msg_head.flags = op->flags;
540 + msg_head.count = op->count;
541 + msg_head.ival1 = op->ival1;
542 + msg_head.ival2 = op->ival2;
543 + msg_head.can_id = op->can_id;
544 + msg_head.nframes = 0;
546 + bcm_send_to_user(op, &msg_head, NULL, NULL);
550 + DBG("count=%d j_ival1=%ld j_ival2=%ld\n",
551 + op->count, op->j_ival1, op->j_ival2);
553 + if (op->j_ival1 && (op->count > 0)) {
555 + op->timer.expires = jiffies + op->j_ival1;
556 + add_timer(&op->timer);
558 + DBG("adding timer ival1. func=%p data=%p exp=0x%08X\n",
559 + op->timer.function,
560 + (char*) op->timer.data,
561 + (unsigned int) op->timer.expires);
563 + /* send (next) frame */
568 + op->timer.expires = jiffies + op->j_ival2;
569 + add_timer(&op->timer);
571 + DBG("adding timer ival2. func=%p data=%p exp=0x%08X\n",
572 + op->timer.function,
573 + (char*) op->timer.data,
574 + (unsigned int) op->timer.expires);
576 + /* send (next) frame */
580 + DBG("no timer restart\n");
587 + * bcm_rx_changed - create a RX_CHANGED notification due to changed content
589 +static void bcm_rx_changed(struct bcm_op *op, struct can_frame *data)
591 + struct bcm_msg_head head;
593 + op->j_lastmsg = jiffies;
595 + /* update statistics */
596 + op->frames_filtered++;
598 + /* prevent statistics overflow */
599 + if (op->frames_filtered > ULONG_MAX/100)
600 + op->frames_filtered = op->frames_abs = 0;
602 + DBG("setting j_lastmsg to 0x%08X for rx_op %p\n",
603 + (unsigned int) op->j_lastmsg, op);
604 + DBG("sending notification\n");
606 + head.opcode = RX_CHANGED;
607 + head.flags = op->flags;
608 + head.count = op->count;
609 + head.ival1 = op->ival1;
610 + head.ival2 = op->ival2;
611 + head.can_id = op->can_id;
614 + bcm_send_to_user(op, &head, data, &op->rx_stamp);
618 + * bcm_rx_update_and_send - process a detected relevant receive content change
619 + * 1. update the last received data
620 + * 2. send a notification to the user (if possible)
622 +static void bcm_rx_update_and_send(struct bcm_op *op,
623 + struct can_frame *lastdata,
624 + struct can_frame *rxdata)
626 + unsigned long nexttx = op->j_lastmsg + op->j_ival2;
628 + memcpy(lastdata, rxdata, CFSIZ);
631 + lastdata->can_dlc |= RX_RECV;
633 + /* throttle bcm_rx_changed ? */
634 + if ((op->thrtimer.expires) ||
635 + ((op->j_ival2) && (nexttx > jiffies))) {
636 + /* we are already waiting OR we have to start waiting */
638 + /* mark as 'throttled' */
639 + lastdata->can_dlc |= RX_THR;
641 + if (!(op->thrtimer.expires)) {
642 + /* start the timer only the first time */
643 + op->thrtimer.expires = nexttx;
644 + add_timer(&op->thrtimer);
646 + DBG("adding thrtimer. func=%p data=%p exp=0x%08X\n",
647 + op->thrtimer.function,
648 + (char*) op->thrtimer.data,
649 + (unsigned int) op->thrtimer.expires);
653 + /* send RX_CHANGED to the user immediately */
654 + bcm_rx_changed(op, rxdata);
659 + * bcm_rx_cmp_to_index - (bit)compares the currently received data to formerly
660 + * received data stored in op->last_frames[]
662 +static void bcm_rx_cmp_to_index(struct bcm_op *op, int index,
663 + struct can_frame *rxdata)
666 + * no one uses the MSBs of can_dlc for comparation,
667 + * so we use it here to detect the first time of reception
670 + if (!(op->last_frames[index].can_dlc & RX_RECV)) {
671 + /* received data for the first time => send update to user */
672 + DBG("first time :)\n");
673 + bcm_rx_update_and_send(op, &op->last_frames[index], rxdata);
677 + /* do a real check in can_frame data section */
679 + DBG("op->frames[index].data = 0x%016llx\n",
680 + GET_U64(&op->frames[index]));
681 + DBG("op->last_frames[index].data = 0x%016llx\n",
682 + GET_U64(&op->last_frames[index]));
683 + DBG("rxdata->data = 0x%016llx\n", GET_U64(rxdata));
685 + if ((GET_U64(&op->frames[index]) & GET_U64(rxdata)) !=
686 + (GET_U64(&op->frames[index]) & GET_U64(&op->last_frames[index]))) {
687 + DBG("relevant data change :)\n");
688 + bcm_rx_update_and_send(op, &op->last_frames[index], rxdata);
692 + if (op->flags & RX_CHECK_DLC) {
693 + /* do a real check in can_frame dlc */
694 + if (rxdata->can_dlc != (op->last_frames[index].can_dlc &
695 + BCM_CAN_DLC_MASK)) {
696 + DBG("dlc change :)\n");
697 + bcm_rx_update_and_send(op, &op->last_frames[index],
702 + DBG("no relevant change :(\n");
706 + * bcm_rx_starttimer - enable timeout monitoring for CAN frame receiption
708 +static void bcm_rx_starttimer(struct bcm_op *op)
710 + if (op->flags & RX_NO_AUTOTIMER)
714 + op->timer.expires = jiffies + op->j_ival1;
716 + DBG("adding rx timeout timer ival1. func=%p data=%p "
718 + op->timer.function,
719 + (char*) op->timer.data,
720 + (unsigned int) op->timer.expires);
722 + add_timer(&op->timer);
727 + * bcm_rx_timeout_handler - when the (cyclic) CAN frame receiption timed out
729 +static void bcm_rx_timeout_handler(unsigned long data)
731 + struct bcm_op *op = (struct bcm_op*)data;
732 + struct bcm_msg_head msg_head;
734 + DBG("sending RX_TIMEOUT for can_id %03X. op is %p\n", op->can_id, op);
736 + msg_head.opcode = RX_TIMEOUT;
737 + msg_head.flags = op->flags;
738 + msg_head.count = op->count;
739 + msg_head.ival1 = op->ival1;
740 + msg_head.ival2 = op->ival2;
741 + msg_head.can_id = op->can_id;
742 + msg_head.nframes = 0;
744 + bcm_send_to_user(op, &msg_head, NULL, NULL);
746 + /* no restart of the timer is done here! */
748 + /* if user wants to be informed, when cyclic CAN-Messages come back */
749 + if ((op->flags & RX_ANNOUNCE_RESUME) && op->last_frames) {
750 + /* clear received can_frames to indicate 'nothing received' */
751 + memset(op->last_frames, 0, op->nframes * CFSIZ);
752 + DBG("RX_ANNOUNCE_RESTART\n");
757 + * bcm_rx_thr_handler - the time for blocked content updates is over now:
758 + * Check for throttled data and send it to the userspace
760 +static void bcm_rx_thr_handler(unsigned long data)
762 + struct bcm_op *op = (struct bcm_op*)data;
765 + /* mark disabled / consumed timer */
766 + op->thrtimer.expires = 0;
768 + if (op->nframes > 1) {
769 + DBG("sending MUX RX_CHANGED for can_id %03X. op is %p\n",
771 + /* for MUX filter we start at index 1 */
772 + for (i=1; i<op->nframes; i++) {
773 + if ((op->last_frames) &&
774 + (op->last_frames[i].can_dlc & RX_THR)) {
775 + op->last_frames[i].can_dlc &= ~RX_THR;
776 + bcm_rx_changed(op, &op->last_frames[i]);
781 + DBG("sending simple RX_CHANGED for can_id %03X. op is %p\n",
783 + /* for RX_FILTER_ID and simple filter */
784 + if (op->last_frames && (op->last_frames[0].can_dlc & RX_THR)) {
785 + op->last_frames[0].can_dlc &= ~RX_THR;
786 + bcm_rx_changed(op, &op->last_frames[0]);
792 + * bcm_rx_handler - handle a CAN frame receiption
794 +static void bcm_rx_handler(struct sk_buff *skb, void *data)
796 + struct bcm_op *op = (struct bcm_op*)data;
797 + struct can_frame rxframe;
800 + /* disable timeout */
801 + del_timer(&op->timer);
803 + DBG("Called with bcm_op %p\n", op);
805 + if (skb->len == sizeof(rxframe)) {
806 + memcpy(&rxframe, skb->data, sizeof(rxframe));
807 + /* save rx timestamp */
808 + skb_get_timestamp(skb, &op->rx_stamp);
809 + /* save originator for recvfrom() */
810 + op->rx_ifindex = skb->dev->ifindex;
811 + /* update statistics */
814 + DBG("got can_frame with can_id %03X\n", rxframe.can_id);
817 + DBG("Wrong skb->len = %d\n", skb->len);
822 + DBG_FRAME("BCM: bcm_rx_handler: CAN frame", &rxframe);
824 + if (op->can_id != rxframe.can_id) {
825 + DBG("ERROR! Got wrong can_id %03X! Expected %03X.\n",
826 + rxframe.can_id, op->can_id);
830 + if (op->flags & RX_RTR_FRAME) {
831 + /* send reply for RTR-request */
832 + DBG("RTR-request\n");
834 + /* send op->frames[0] to CAN device */
839 + if (op->flags & RX_FILTER_ID) {
840 + /* the easiest case */
841 + DBG("Easy does it with RX_FILTER_ID\n");
843 + bcm_rx_update_and_send(op, &op->last_frames[0], &rxframe);
844 + bcm_rx_starttimer(op);
848 + if (op->nframes == 1) {
849 + /* simple compare with index 0 */
850 + DBG("Simple compare\n");
852 + bcm_rx_cmp_to_index(op, 0, &rxframe);
853 + bcm_rx_starttimer(op);
857 + if (op->nframes > 1) {
858 + /* multiplex compare */
859 + DBG("Multiplex compare\n");
862 + * find the first multiplex mask that fits.
863 + * Remark: The MUX-mask is stored in index 0
866 + for (i=1; i < op->nframes; i++) {
867 + if ((GET_U64(&op->frames[0]) & GET_U64(&rxframe)) ==
868 + (GET_U64(&op->frames[0]) &
869 + GET_U64(&op->frames[i]))) {
870 + DBG("found MUX index %d\n", i);
871 + bcm_rx_cmp_to_index(op, i, &rxframe);
875 + bcm_rx_starttimer(op);
880 + * helpers for bcm_op handling: find & delete bcm [rx|tx] op elements
882 +static struct bcm_op *bcm_find_op(struct list_head *ops, canid_t can_id,
887 + list_for_each_entry(op, ops, list) {
888 + if ((op->can_id == can_id) && (op->ifindex == ifindex))
895 +static void bcm_remove_op(struct bcm_op *op)
897 + del_timer(&op->timer);
898 + del_timer(&op->thrtimer);
900 + if ((op->frames) && (op->frames != &op->sframe))
903 + if ((op->last_frames) && (op->last_frames != &op->last_sframe))
904 + kfree(op->last_frames);
912 + * bcm_delete_rx_op - find and remove a rx op (returns number of removed ops)
914 +static int bcm_delete_rx_op(struct list_head *ops, canid_t can_id, int ifindex)
916 + struct bcm_op *op, *n;
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",
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.
929 + struct net_device *dev =
930 + dev_get_by_index(op->ifindex);
933 + can_rx_unregister(dev, op->can_id,
934 + REGMASK(op->can_id),
935 + bcm_rx_handler, op);
940 + can_rx_unregister(NULL, op->can_id,
941 + REGMASK(op->can_id),
942 + bcm_rx_handler, op);
944 + list_del(&op->list);
946 + return 1; /* done */
950 + return 0; /* not found */
954 + * bcm_delete_tx_op - find and remove a tx op (returns number of removed ops)
956 +static int bcm_delete_tx_op(struct list_head *ops, canid_t can_id, int ifindex)
958 + struct bcm_op *op, *n;
960 + list_for_each_entry_safe(op, n, ops, list) {
961 + if ((op->can_id == can_id) && (op->ifindex == ifindex)) {
962 + DBG("removing rx_op %p for can_id %03X\n",
964 + list_del(&op->list);
966 + return 1; /* done */
970 + return 0; /* not found */
974 + * bcm_read_op - read out a bcm_op and send it to the user (for bcm_sendmsg)
976 +static int bcm_read_op(struct list_head *ops, struct bcm_msg_head *msg_head,
979 + struct bcm_op *op = bcm_find_op(ops, msg_head->can_id, ifindex);
982 + DBG("TRX_READ: did not find op for can_id %03X\n",
987 + DBG("TRX_READ: sending status for can_id %03X\n",
989 + /* put current values into msg_head */
990 + msg_head->flags = op->flags;
991 + msg_head->count = op->count;
992 + msg_head->ival1 = op->ival1;
993 + msg_head->ival2 = op->ival2;
994 + msg_head->nframes = op->nframes;
996 + bcm_send_to_user(op, msg_head, op->frames, NULL);
1002 + * bcm_tx_setup - create or update a bcm tx op (for bcm_sendmsg)
1004 +static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
1005 + int ifindex, struct sock *sk)
1007 + struct bcm_opt *bo = bcm_sk(sk);
1008 + struct bcm_op *op;
1011 + /* we need a real device to send frames */
1015 + /* we need at least one can_frame */
1016 + if (msg_head->nframes < 1)
1019 + /* check the given can_id */
1020 + op = bcm_find_op(&bo->tx_ops, msg_head->can_id, ifindex);
1023 + /* update existing BCM operation */
1025 + DBG("TX_SETUP: modifying existing tx_op %p for can_id %03X\n",
1026 + op, msg_head->can_id);
1029 + * Do we need more space for the can_frames than currently
1030 + * allocated? -> This is a _really_ unusual use-case and
1031 + * therefore (complexity / locking) it is not supported.
1033 + if (msg_head->nframes > op->nframes)
1036 + /* update can_frames content */
1037 + for (i = 0; i < msg_head->nframes; i++) {
1038 + err = memcpy_fromiovec((u8*)&op->frames[i],
1039 + msg->msg_iov, CFSIZ);
1043 + if (msg_head->flags & TX_CP_CAN_ID) {
1044 + /* copy can_id into frame */
1045 + op->frames[i].can_id = msg_head->can_id;
1050 + /* insert new BCM operation for the given can_id */
1052 + op = kzalloc(OPSIZ, GFP_KERNEL);
1056 + DBG("TX_SETUP: creating new tx_op %p for can_id %03X\n",
1057 + op, msg_head->can_id);
1059 + op->can_id = msg_head->can_id;
1061 + /* create array for can_frames and copy the data */
1062 + if (msg_head->nframes > 1) {
1063 + op->frames = kmalloc(msg_head->nframes * CFSIZ,
1065 + if (!op->frames) {
1070 + op->frames = &op->sframe;
1072 + for (i = 0; i < msg_head->nframes; i++) {
1073 + err = memcpy_fromiovec((u8*)&op->frames[i],
1074 + msg->msg_iov, CFSIZ);
1076 + if (op->frames != &op->sframe)
1077 + kfree(op->frames);
1082 + if (msg_head->flags & TX_CP_CAN_ID) {
1083 + /* copy can_id into frame */
1084 + op->frames[i].can_id = msg_head->can_id;
1088 + /* tx_ops never compare with previous received messages */
1089 + op->last_frames = NULL;
1091 + /* bcm_can_tx / bcm_tx_timeout_handler needs this */
1094 + op->ifindex = ifindex;
1096 + /* initialize uninitialized (kmalloc) structure */
1097 + init_timer(&op->timer);
1099 + /* currently unused in tx_ops */
1100 + init_timer(&op->thrtimer);
1102 + /* handler for tx_ops */
1103 + op->timer.function = bcm_tx_timeout_handler;
1105 + /* timer.data points to this op-structure */
1106 + op->timer.data = (unsigned long)op;
1108 + /* add this bcm_op to the list of the tx_ops */
1109 + list_add(&op->list, &bo->tx_ops);
1111 + } /* if ((op = bcm_find_op(&bo->tx_ops, msg_head->can_id, ifindex))) */
1113 + if (op->nframes != msg_head->nframes) {
1114 + op->nframes = msg_head->nframes;
1115 + /* start multiple frame transmission with index 0 */
1116 + op->currframe = 0;
1121 + op->flags = msg_head->flags;
1123 + if (op->flags & TX_RESET_MULTI_IDX) {
1124 + /* start multiple frame transmission with index 0 */
1125 + op->currframe = 0;
1128 + if (op->flags & SETTIMER) {
1129 + /* set timer values */
1131 + op->count = msg_head->count;
1132 + op->ival1 = msg_head->ival1;
1133 + op->ival2 = msg_head->ival2;
1134 + op->j_ival1 = rounded_tv2jif(&msg_head->ival1);
1135 + op->j_ival2 = rounded_tv2jif(&msg_head->ival2);
1137 + DBG("TX_SETUP: SETTIMER count=%d j_ival1=%ld j_ival2=%ld\n",
1138 + op->count, op->j_ival1, op->j_ival2);
1140 + /* disable an active timer due to zero values? */
1141 + if (!op->j_ival1 && !op->j_ival2) {
1142 + del_timer(&op->timer);
1143 + DBG("TX_SETUP: SETTIMER disabled timer.\n");
1147 + if ((op->flags & STARTTIMER) &&
1148 + ((op->j_ival1 && op->count) || op->j_ival2)) {
1150 + del_timer(&op->timer);
1152 + /* spec: send can_frame when starting timer */
1153 + op->flags |= TX_ANNOUNCE;
1155 + if (op->j_ival1 && (op->count > 0)) {
1156 + op->timer.expires = jiffies + op->j_ival1;
1157 + /* op->count-- is done in bcm_tx_timeout_handler */
1158 + DBG("TX_SETUP: adding timer ival1. func=%p data=%p "
1160 + op->timer.function,
1161 + (char*) op->timer.data,
1162 + (unsigned int) op->timer.expires);
1165 + op->timer.expires = jiffies + op->j_ival2;
1166 + DBG("TX_SETUP: adding timer ival2. func=%p data=%p "
1168 + op->timer.function,
1169 + (char*) op->timer.data,
1170 + (unsigned int) op->timer.expires);
1173 + add_timer(&op->timer);
1176 + if (op->flags & TX_ANNOUNCE)
1179 + return msg_head->nframes * CFSIZ + MHSIZ;
1183 + * bcm_rx_setup - create or update a bcm rx op (for bcm_sendmsg)
1185 +static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
1186 + int ifindex, struct sock *sk)
1188 + struct bcm_opt *bo = bcm_sk(sk);
1189 + struct bcm_op *op;
1190 + int do_rx_register;
1193 + if ((msg_head->flags & RX_FILTER_ID) || (!(msg_head->nframes))) {
1194 + /* be robust against wrong usage ... */
1195 + msg_head->flags |= RX_FILTER_ID;
1196 + msg_head->nframes = 0; /* ignore trailing garbage */
1199 + if ((msg_head->flags & RX_RTR_FRAME) &&
1200 + ((msg_head->nframes != 1) ||
1201 + (!(msg_head->can_id & CAN_RTR_FLAG)))) {
1203 + DBG("RX_SETUP: bad RX_RTR_FRAME setup!\n");
1207 + /* check the given can_id */
1208 + op = bcm_find_op(&bo->rx_ops, msg_head->can_id, ifindex);
1210 + /* update existing BCM operation */
1212 + DBG("RX_SETUP: modifying existing rx_op %p for can_id %03X\n",
1213 + op, msg_head->can_id);
1216 + * Do we need more space for the can_frames than currently
1217 + * allocated? -> This is a _really_ unusual use-case and
1218 + * therefore (complexity / locking) it is not supported.
1220 + if (msg_head->nframes > op->nframes)
1223 + if (msg_head->nframes) {
1224 + /* update can_frames content */
1225 + err = memcpy_fromiovec((u8*)op->frames,
1227 + msg_head->nframes * CFSIZ);
1231 + /* clear last_frames to indicate 'nothing received' */
1232 + memset(op->last_frames, 0, msg_head->nframes * CFSIZ);
1235 + op->nframes = msg_head->nframes;
1237 + /* Only an update -> do not call can_rx_register() */
1238 + do_rx_register = 0;
1241 + /* insert new BCM operation for the given can_id */
1243 + op = kzalloc(OPSIZ, GFP_KERNEL);
1247 + DBG("RX_SETUP: creating new rx_op %p for can_id %03X\n",
1248 + op, msg_head->can_id);
1250 + op->can_id = msg_head->can_id;
1251 + op->nframes = msg_head->nframes;
1253 + if (msg_head->nframes > 1) {
1254 + /* create array for can_frames and copy the data */
1255 + op->frames = kmalloc(msg_head->nframes * CFSIZ,
1257 + if (!op->frames) {
1262 + /* create and init array for received can_frames */
1263 + op->last_frames = kzalloc(msg_head->nframes * CFSIZ,
1265 + if (!op->last_frames) {
1266 + kfree(op->frames);
1272 + op->frames = &op->sframe;
1273 + op->last_frames = &op->last_sframe;
1276 + if (msg_head->nframes) {
1277 + err = memcpy_fromiovec((u8*)op->frames, msg->msg_iov,
1278 + msg_head->nframes * CFSIZ);
1280 + if (op->frames != &op->sframe)
1281 + kfree(op->frames);
1282 + if (op->last_frames != &op->last_sframe)
1283 + kfree(op->last_frames);
1290 + op->ifindex = ifindex;
1292 + /* initialize uninitialized (kzalloc) structure */
1293 + init_timer(&op->timer);
1295 + /* init throttle timer for RX_CHANGED */
1296 + init_timer(&op->thrtimer);
1298 + /* handler for rx timeouts */
1299 + op->timer.function = bcm_rx_timeout_handler;
1301 + /* timer.data points to this op-structure */
1302 + op->timer.data = (unsigned long)op;
1304 + /* handler for RX_CHANGED throttle timeouts */
1305 + op->thrtimer.function = bcm_rx_thr_handler;
1307 + /* timer.data points to this op-structure */
1308 + op->thrtimer.data = (unsigned long)op;
1310 + /* mark disabled timer */
1311 + op->thrtimer.expires = 0;
1313 + /* add this bcm_op to the list of the tx_ops */
1314 + list_add(&op->list, &bo->rx_ops);
1316 + /* call can_rx_register() */
1317 + do_rx_register = 1;
1319 + } /* if ((op = bcm_find_op(&bo->rx_ops, msg_head->can_id, ifindex))) */
1322 + op->flags = msg_head->flags;
1324 + if (op->flags & RX_RTR_FRAME) {
1326 + /* no timers in RTR-mode */
1327 + del_timer(&op->thrtimer);
1328 + del_timer(&op->timer);
1331 + * funny feature in RX(!)_SETUP only for RTR-mode:
1332 + * copy can_id into frame BUT without RTR-flag to
1333 + * prevent a full-load-loopback-test ... ;-]
1335 + if ((op->flags & TX_CP_CAN_ID) ||
1336 + (op->frames[0].can_id == op->can_id))
1337 + op->frames[0].can_id = op->can_id & ~CAN_RTR_FLAG;
1340 + if (op->flags & SETTIMER) {
1342 + /* set timer value */
1343 + op->ival1 = msg_head->ival1;
1344 + op->ival2 = msg_head->ival2;
1345 + op->j_ival1 = rounded_tv2jif(&msg_head->ival1);
1346 + op->j_ival2 = rounded_tv2jif(&msg_head->ival2);
1348 + DBG("RX_SETUP: SETTIMER j_ival1=%ld j_ival2=%ld\n",
1349 + op->j_ival1, op->j_ival2);
1351 + /* disable an active timer due to zero value? */
1352 + if (!op->j_ival1) {
1353 + del_timer(&op->timer);
1354 + DBG("RX_SETUP: disabled timer rx timeouts.\n");
1357 + /* free currently blocked msgs ? */
1358 + if (op->thrtimer.expires) {
1359 + DBG("RX_SETUP: unblocking throttled msgs.\n");
1360 + del_timer(&op->thrtimer);
1361 + /* send blocked msgs hereafter */
1362 + op->thrtimer.expires = jiffies + 2;
1363 + add_timer(&op->thrtimer);
1366 + * if (op->j_ival2) is zero, no (new) throttling
1367 + * will happen. For details see functions
1368 + * bcm_rx_update_and_send() and bcm_rx_thr_handler()
1372 + if ((op->flags & STARTTIMER) && op->j_ival1) {
1374 + del_timer(&op->timer);
1375 + op->timer.expires = jiffies + op->j_ival1;
1377 + DBG("RX_SETUP: adding timer ival1. func=%p data=%p"
1379 + (char *) op->timer.function,
1380 + (char *) op->timer.data,
1381 + (unsigned int) op->timer.expires);
1383 + add_timer(&op->timer);
1387 + /* now we can register for can_ids, if we added a new bcm_op */
1388 + if (do_rx_register) {
1389 + DBG("RX_SETUP: can_rx_register() for can_id %03X. "
1390 + "rx_op is %p\n", op->can_id, op);
1393 + struct net_device *dev = dev_get_by_index(ifindex);
1396 + can_rx_register(dev, op->can_id,
1397 + REGMASK(op->can_id),
1398 + bcm_rx_handler, op, IDENT);
1403 + can_rx_register(NULL, op->can_id, REGMASK(op->can_id),
1404 + bcm_rx_handler, op, IDENT);
1407 + return msg_head->nframes * CFSIZ + MHSIZ;
1411 + * bcm_tx_send - send a single CAN frame to the CAN interface (for bcm_sendmsg)
1413 +static int bcm_tx_send(struct msghdr *msg, int ifindex, struct sock *sk)
1415 + struct sk_buff *skb;
1416 + struct net_device *dev;
1419 + /* just copy and send one can_frame */
1421 + if (!ifindex) /* we need a real device to send frames */
1424 + skb = alloc_skb(CFSIZ, GFP_KERNEL);
1429 + err = memcpy_fromiovec(skb_put(skb, CFSIZ), msg->msg_iov, CFSIZ);
1435 + DBG_FRAME("BCM: TX_SEND: sending frame",
1436 + (struct can_frame *)skb->data);
1438 + dev = dev_get_by_index(ifindex);
1446 + can_send(skb, 1); /* send with loopback */
1449 + return CFSIZ + MHSIZ;
1453 + * bcm_sendmsg - process BCM commands (opcodes) from the userspace
1455 +static int bcm_sendmsg(struct kiocb *iocb, struct socket *sock,
1456 + struct msghdr *msg, size_t size)
1458 + struct sock *sk = sock->sk;
1459 + struct bcm_opt *bo = bcm_sk(sk);
1460 + int ifindex = bo->ifindex; /* default ifindex for this bcm_op */
1461 + struct bcm_msg_head msg_head;
1462 + int ret; /* read bytes or error codes as return value */
1465 + DBG("sock %p not bound\n", sk);
1469 + /* check for alternative ifindex for this bcm_op */
1471 + if (!ifindex && msg->msg_name) {
1472 + /* no bound device as default => check msg_name */
1473 + struct sockaddr_can *addr =
1474 + (struct sockaddr_can *)msg->msg_name;
1476 + if (addr->can_family != AF_CAN)
1479 + ifindex = addr->can_ifindex; /* ifindex from sendto() */
1481 + if (ifindex && !dev_get_by_index(ifindex)) {
1482 + DBG("device %d not found\n", ifindex);
1487 + /* read message head information */
1489 + ret = memcpy_fromiovec((u8*)&msg_head, msg->msg_iov, MHSIZ);
1493 + DBG("opcode %d for can_id %03X\n", msg_head.opcode, msg_head.can_id);
1497 + switch (msg_head.opcode) {
1500 + ret = bcm_tx_setup(&msg_head, msg, ifindex, sk);
1504 + ret = bcm_rx_setup(&msg_head, msg, ifindex, sk);
1508 + if (bcm_delete_tx_op(&bo->tx_ops, msg_head.can_id, ifindex))
1515 + if (bcm_delete_rx_op(&bo->rx_ops, msg_head.can_id, ifindex))
1522 + /* reuse msg_head for the reply to TX_READ */
1523 + msg_head.opcode = TX_STATUS;
1524 + ret = bcm_read_op(&bo->tx_ops, &msg_head, ifindex);
1528 + /* reuse msg_head for the reply to RX_READ */
1529 + msg_head.opcode = RX_STATUS;
1530 + ret = bcm_read_op(&bo->rx_ops, &msg_head, ifindex);
1534 + /* we need at least one can_frame */
1535 + if (msg_head.nframes < 1)
1538 + ret = bcm_tx_send(msg, ifindex, sk);
1542 + DBG("Unknown opcode %d\n", msg_head.opcode);
1553 + * initial settings for all BCM sockets to be set at socket creation time
1555 +static int bcm_init(struct sock *sk)
1557 + struct bcm_opt *bo = bcm_sk(sk);
1561 + bo->dropped_usr_msgs = 0;
1562 + bo->bcm_proc_read = NULL;
1564 + INIT_LIST_HEAD(&bo->tx_ops);
1565 + INIT_LIST_HEAD(&bo->rx_ops);
1571 + * notification handler for netdevice status changes
1573 +static void bcm_notifier(unsigned long msg, void *data)
1575 + struct sock *sk = (struct sock *)data;
1576 + struct bcm_opt *bo = bcm_sk(sk);
1578 + DBG("called for sock %p\n", sk);
1582 + case NETDEV_UNREGISTER:
1587 + sk->sk_err = ENETDOWN;
1588 + if (!sock_flag(sk, SOCK_DEAD))
1589 + sk->sk_error_report(sk);
1594 + * standard socket functions
1596 +static int bcm_release(struct socket *sock)
1598 + struct sock *sk = sock->sk;
1599 + struct bcm_opt *bo = bcm_sk(sk);
1600 + struct bcm_op *op, *next;
1602 + DBG("socket %p, sk %p\n", sock, sk);
1604 + /* remove bcm_ops, timer, rx_unregister(), etc. */
1606 + list_for_each_entry_safe(op, next, &bo->tx_ops, list) {
1607 + DBG("removing tx_op %p for can_id %03X\n", op, op->can_id);
1608 + bcm_remove_op(op);
1611 + list_for_each_entry_safe(op, next, &bo->rx_ops, list) {
1612 + DBG("removing rx_op %p for can_id %03X\n", op, op->can_id);
1615 + * Don't care if we're bound or not (due to netdev problems)
1616 + * can_rx_unregister() is always a save thing to do here.
1618 + if (op->ifindex) {
1619 + struct net_device *dev = dev_get_by_index(op->ifindex);
1622 + can_rx_unregister(dev, op->can_id,
1623 + REGMASK(op->can_id),
1624 + bcm_rx_handler, op);
1629 + can_rx_unregister(NULL, op->can_id,
1630 + REGMASK(op->can_id),
1631 + bcm_rx_handler, op);
1633 + bcm_remove_op(op);
1636 + /* remove procfs entry */
1637 + if (proc_dir && bo->bcm_proc_read)
1638 + remove_proc_entry(bo->procname, proc_dir);
1640 + /* remove device notifier */
1641 + if (bo->ifindex) {
1642 + struct net_device *dev = dev_get_by_index(bo->ifindex);
1645 + can_dev_unregister(dev, bcm_notifier, sk);
1655 +static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len,
1658 + struct sockaddr_can *addr = (struct sockaddr_can *)uaddr;
1659 + struct sock *sk = sock->sk;
1660 + struct bcm_opt *bo = bcm_sk(sk);
1665 + /* bind a device to this socket */
1666 + if (addr->can_ifindex) {
1667 + struct net_device *dev = dev_get_by_index(addr->can_ifindex);
1670 + DBG("could not find device index %d\n",
1671 + addr->can_ifindex);
1674 + bo->ifindex = dev->ifindex;
1675 + can_dev_register(dev, bcm_notifier, sk); /* register notif. */
1678 + DBG("socket %p bound to device %s (idx %d)\n",
1679 + sock, dev->name, dev->ifindex);
1682 + /* no notifier for ifindex = 0 ('any' CAN device) */
1689 + /* unique socket address as filename */
1690 + sprintf(bo->procname, "%p", sock);
1691 + bo->bcm_proc_read = create_proc_read_entry(bo->procname, 0644,
1693 + bcm_read_proc, sk);
1699 +static int bcm_recvmsg(struct kiocb *iocb, struct socket *sock,
1700 + struct msghdr *msg, size_t size, int flags)
1702 + struct sock *sk = sock->sk;
1703 + struct sk_buff *skb;
1708 + DBG("socket %p, sk %p\n", sock, sk);
1710 + noblock = flags & MSG_DONTWAIT;
1711 + flags &= ~MSG_DONTWAIT;
1712 + skb = skb_recv_datagram(sk, flags, noblock, &error);
1716 + DBG("delivering skbuff %p\n", skb);
1719 + if (skb->len < size)
1722 + err = memcpy_toiovec(msg->msg_iov, skb->data, size);
1724 + skb_free_datagram(sk, skb);
1728 + sock_recv_timestamp(msg, sk, skb);
1730 + if (msg->msg_name) {
1731 + msg->msg_namelen = sizeof(struct sockaddr_can);
1732 + memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
1735 + DBG("freeing sock %p, skbuff %p\n", sk, skb);
1736 + skb_free_datagram(sk, skb);
1741 +static unsigned int bcm_poll(struct file *file, struct socket *sock,
1744 + unsigned int mask = 0;
1746 + DBG("socket %p\n", sock);
1748 + mask = datagram_poll(file, sock, wait);
1752 +static struct proto_ops bcm_ops = {
1754 + .release = bcm_release,
1755 + .bind = sock_no_bind,
1756 + .connect = bcm_connect,
1757 + .socketpair = sock_no_socketpair,
1758 + .accept = sock_no_accept,
1759 + .getname = sock_no_getname,
1761 + .ioctl = NULL, /* use can_ioctl() from af_can.c */
1762 + .listen = sock_no_listen,
1763 + .shutdown = sock_no_shutdown,
1764 + .setsockopt = sock_no_setsockopt,
1765 + .getsockopt = sock_no_getsockopt,
1766 + .sendmsg = bcm_sendmsg,
1767 + .recvmsg = bcm_recvmsg,
1768 + .mmap = sock_no_mmap,
1769 + .sendpage = sock_no_sendpage,
1772 +static struct proto bcm_proto = {
1773 + .name = "CAN_BCM",
1774 + .owner = THIS_MODULE,
1775 + .obj_size = sizeof(struct bcm_sock),
1779 +static struct can_proto bcm_can_proto = {
1780 + .type = SOCK_DGRAM,
1781 + .protocol = CAN_BCM,
1782 + .capability = BCM_CAP,
1784 + .prot = &bcm_proto,
1787 +static int __init bcm_module_init(void)
1791 + can_proto_register(&bcm_can_proto);
1793 + /* create /proc/net/can/bcm directory */
1794 + proc_dir = proc_mkdir(CAN_PROC_DIR"/"IDENT, NULL);
1797 + proc_dir->owner = THIS_MODULE;
1802 +static void __exit bcm_module_exit(void)
1804 + can_proto_unregister(&bcm_can_proto);
1807 + remove_proc_entry(CAN_PROC_DIR"/"IDENT, NULL);
1810 +module_init(bcm_module_init);
1811 +module_exit(bcm_module_exit);