From: hartkopp Date: Wed, 21 Jan 2009 10:14:42 +0000 (+0000) Subject: Updated to latest CAN core changes: X-Git-Url: http://rtime.felk.cvut.cz/gitweb/socketcan-devel.git/commitdiff_plain/3e4350c1649adfabd198c201d7a1ead9b2199fd3 Updated to latest CAN core changes: From commit r890: - removed avoidable copy of data in bcm_rx_handler() - some removal of duplicate code From commit r894: Omit unneeded skb_clone() calls. The AF_CAN core delivered always cloned sk_buffs to the AF_CAN protocols, although this was _only_ needed by the can-raw protocol. With this (additionally documented) change, the AF_CAN core calls the callback functions of the registered AF_CAN protocols with the original (uncloned) sk_buff pointer and let's the can-raw protocol do the skb_clone() itself which omits all unneeded skb_clone() calls for other AF_CAN protocols. git-svn-id: svn://svn.berlios.de//socketcan/trunk@914 030b6a49-0b11-0410-94ab-b0dab22257f2 --- diff --git a/kernel/2.6/net/can/bcm-prior-2-6-22.c b/kernel/2.6/net/can/bcm-prior-2-6-22.c index 6e43511..062b2f3 100644 --- a/kernel/2.6/net/can/bcm-prior-2-6-22.c +++ b/kernel/2.6/net/can/bcm-prior-2-6-22.c @@ -98,7 +98,11 @@ struct bcm_op { unsigned long frames_abs, frames_filtered; struct timeval ival1, ival2; struct timer_list timer, thrtimer; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14) + struct skb_timeval rx_stamp; +#else struct timeval rx_stamp; +#endif unsigned long j_ival1, j_ival2, j_lastmsg; int rx_ifindex; int count; @@ -361,7 +365,7 @@ static void bcm_send_to_user(struct bcm_op *op, struct bcm_msg_head *head, if (has_timestamp) { /* restore rx timestamp */ - skb_set_timestamp(skb, &op->rx_stamp); + skb->tstamp = op->rx_stamp; } /* @@ -393,12 +397,12 @@ static void bcm_send_to_user(struct bcm_op *op, struct bcm_msg_head *head, static void bcm_tx_timeout_handler(unsigned long data) { struct bcm_op *op = (struct bcm_op *)data; + struct bcm_msg_head msg_head; if (op->j_ival1 && (op->count > 0)) { op->count--; if (!op->count && (op->flags & TX_COUNTEVT)) { - struct bcm_msg_head msg_head; /* create notification to user */ msg_head.opcode = TX_EXPIRED; @@ -427,8 +431,6 @@ static void bcm_tx_timeout_handler(unsigned long data) mod_timer(&op->timer, jiffies + op->j_ival2); } } - - return; } /* @@ -447,6 +449,9 @@ static void bcm_rx_changed(struct bcm_op *op, struct can_frame *data) if (op->frames_filtered > ULONG_MAX/100) op->frames_filtered = op->frames_abs = 0; + /* this element is not throttled anymore */ + data->can_dlc &= (BCM_CAN_DLC_MASK|RX_RECV); + head.opcode = RX_CHANGED; head.flags = op->flags; head.count = op->count; @@ -465,23 +470,20 @@ static void bcm_rx_changed(struct bcm_op *op, struct can_frame *data) */ static void bcm_rx_update_and_send(struct bcm_op *op, struct can_frame *lastdata, - struct can_frame *rxdata) + const struct can_frame *rxdata) { unsigned long nexttx = op->j_lastmsg + op->j_ival2; memcpy(lastdata, rxdata, CFSIZ); - /* mark as used */ - lastdata->can_dlc |= RX_RECV; + /* mark as used and throttled by default */ + lastdata->can_dlc |= (RX_RECV|RX_THR); /* throttle bcm_rx_changed ? */ if ((op->thrtimer.expires) || ((op->j_ival2) && (nexttx > jiffies))) { /* we are already waiting OR we have to start waiting */ - /* mark as 'throttled' */ - lastdata->can_dlc |= RX_THR; - if (!(op->thrtimer.expires)) { /* start the timer only the first time */ mod_timer(&op->thrtimer, nexttx); @@ -489,7 +491,7 @@ static void bcm_rx_update_and_send(struct bcm_op *op, } else { /* send RX_CHANGED to the user immediately */ - bcm_rx_changed(op, rxdata); + bcm_rx_changed(op, lastdata); } } @@ -498,7 +500,7 @@ static void bcm_rx_update_and_send(struct bcm_op *op, * received data stored in op->last_frames[] */ static void bcm_rx_cmp_to_index(struct bcm_op *op, int index, - struct can_frame *rxdata) + const struct can_frame *rxdata) { /* * no one uses the MSBs of can_dlc for comparation, @@ -550,6 +552,7 @@ static void bcm_rx_timeout_handler(unsigned long data) struct bcm_op *op = (struct bcm_op *)data; struct bcm_msg_head msg_head; + /* create notification to user */ msg_head.opcode = RX_TIMEOUT; msg_head.flags = op->flags; msg_head.count = op->count; @@ -569,6 +572,18 @@ static void bcm_rx_timeout_handler(unsigned long data) } } +/* + * bcm_rx_do_flush - helper for bcm_rx_thr_flush + */ +static inline int bcm_rx_do_flush(struct bcm_op *op, int index) +{ + if ((op->last_frames) && (op->last_frames[index].can_dlc & RX_THR)) { + bcm_rx_changed(op, &op->last_frames[index]); + return 1; + } + return 0; +} + /* * bcm_rx_thr_flush - Check for throttled data and send it to the userspace */ @@ -580,22 +595,12 @@ static int bcm_rx_thr_flush(struct bcm_op *op) int i; /* for MUX filter we start at index 1 */ - for (i = 1; i < op->nframes; i++) { - if ((op->last_frames) && - (op->last_frames[i].can_dlc & RX_THR)) { - op->last_frames[i].can_dlc &= ~RX_THR; - bcm_rx_changed(op, &op->last_frames[i]); - updated++; - } - } + for (i = 1; i < op->nframes; i++) + updated += bcm_rx_do_flush(op, i); } else { /* for RX_FILTER_ID and simple filter */ - if (op->last_frames && (op->last_frames[0].can_dlc & RX_THR)) { - op->last_frames[0].can_dlc &= ~RX_THR; - bcm_rx_changed(op, &op->last_frames[0]); - updated++; - } + updated += bcm_rx_do_flush(op, 0); } return updated; @@ -623,29 +628,21 @@ static void bcm_rx_thr_handler(unsigned long data) static void bcm_rx_handler(struct sk_buff *skb, void *data) { struct bcm_op *op = (struct bcm_op *)data; - struct can_frame rxframe; + const struct can_frame *rxframe = (struct can_frame *)skb->data; int i; /* disable timeout */ del_timer(&op->timer); - if (skb->len == sizeof(rxframe)) { - memcpy(&rxframe, skb->data, sizeof(rxframe)); - /* save rx timestamp */ - skb_get_timestamp(skb, &op->rx_stamp); - /* save originator for recvfrom() */ - op->rx_ifindex = skb->dev->ifindex; - /* update statistics */ - op->frames_abs++; - kfree_skb(skb); - - } else { - kfree_skb(skb); + if (op->can_id != rxframe->can_id) return; - } - if (op->can_id != rxframe.can_id) - return; + /* save rx timestamp */ + op->rx_stamp = skb->tstamp; + /* save originator for recvfrom() */ + op->rx_ifindex = skb->dev->ifindex; + /* update statistics */ + op->frames_abs++; if (op->flags & RX_RTR_FRAME) { /* send reply for RTR-request (placed in op->frames[0]) */ @@ -655,16 +652,14 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data) if (op->flags & RX_FILTER_ID) { /* the easiest case */ - bcm_rx_update_and_send(op, &op->last_frames[0], &rxframe); - bcm_rx_starttimer(op); - return; + bcm_rx_update_and_send(op, &op->last_frames[0], rxframe); + goto rx_starttimer; } if (op->nframes == 1) { /* simple compare with index 0 */ - bcm_rx_cmp_to_index(op, 0, &rxframe); - bcm_rx_starttimer(op); - return; + bcm_rx_cmp_to_index(op, 0, rxframe); + goto rx_starttimer; } if (op->nframes > 1) { @@ -676,15 +671,17 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data) */ for (i = 1; i < op->nframes; i++) { - if ((GET_U64(&op->frames[0]) & GET_U64(&rxframe)) == + if ((GET_U64(&op->frames[0]) & GET_U64(rxframe)) == (GET_U64(&op->frames[0]) & GET_U64(&op->frames[i]))) { - bcm_rx_cmp_to_index(op, i, &rxframe); + bcm_rx_cmp_to_index(op, i, rxframe); break; } } - bcm_rx_starttimer(op); } + +rx_starttimer: + bcm_rx_starttimer(op); } /*