From 55b7bae29a3225bf5922d8d7ce3e2ff467650f05 Mon Sep 17 00:00:00 2001 From: hartkopp Date: Thu, 29 Sep 2011 05:38:44 +0000 Subject: [PATCH] can bcm: fix tx_setup off-by-one errors This patch fixes two off-by-one errors that canceled each other out. Checking for the same condition two times in bcm_tx_timeout_tsklet() reduced the count of frames to be sent by one. This did not show up the first time tx_setup is invoked as an additional frame is sent due to TX_ANNONCE. Invoking a second tx_setup on the same item led to a reduced (by 1) number of sent frames. Reported-by: Andre Naujoks Signed-off-by: Oliver Hartkopp Signed-off-by: David S. Miller Upstream commit https://github.com/davem330/net/commit/aabdcb0b553b9c9547b1a506b34d55a764745870 git-svn-id: svn://svn.berlios.de//socketcan/trunk@1274 030b6a49-0b11-0410-94ab-b0dab22257f2 --- kernel/2.6/net/can/bcm-prior-2-6-22.c | 11 ++++++----- kernel/2.6/net/can/bcm.c | 13 +++++++------ 2 files changed, 13 insertions(+), 11 deletions(-) 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 10b2008..1254675 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 @@ -416,9 +416,6 @@ static void bcm_tx_timeout_handler(unsigned long data) bcm_send_to_user(op, &msg_head, NULL, 0); } - } - - if (op->j_ival1 && (op->count > 0)) { /* send (next) frame */ bcm_can_tx(op); @@ -958,15 +955,19 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, /* spec: send can_frame when starting timer */ op->flags |= TX_ANNOUNCE; - if (op->j_ival1 && (op->count > 0)) { + /* only start timer when having more frames than sent below */ + if (op->j_ival1 && (op->count > 1)) { /* op->count-- is done in bcm_tx_timeout_handler */ mod_timer(&op->timer, jiffies + op->j_ival1); } else mod_timer(&op->timer, jiffies + op->j_ival2); } - if (op->flags & TX_ANNOUNCE) + if (op->flags & TX_ANNOUNCE) { bcm_can_tx(op); + if (op->j_ival1 && (op->count > 0)) + op->count--; + } return msg_head->nframes * CFSIZ + MHSIZ; } diff --git a/kernel/2.6/net/can/bcm.c b/kernel/2.6/net/can/bcm.c index 11c5279..9633398 100644 --- a/kernel/2.6/net/can/bcm.c +++ b/kernel/2.6/net/can/bcm.c @@ -481,9 +481,6 @@ static void bcm_tx_timeout_tsklet(unsigned long data) bcm_send_to_user(op, &msg_head, NULL, 0); } - } - - if (op->kt_ival1.tv64 && (op->count > 0)) { /* send (next) frame */ bcm_can_tx(op); @@ -1101,8 +1098,9 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, /* spec: send can_frame when starting timer */ op->flags |= TX_ANNOUNCE; - if (op->kt_ival1.tv64 && (op->count > 0)) { - /* op->count-- is done in bcm_tx_timeout_handler */ + /* only start timer when having more frames than sent below */ + if (op->kt_ival1.tv64 && (op->count > 1)) { + /* op->count-- is done in bcm_tx_timeout_tsklet */ hrtimer_start(&op->timer, op->kt_ival1, HRTIMER_MODE_REL); } else @@ -1110,8 +1108,11 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, HRTIMER_MODE_REL); } - if (op->flags & TX_ANNOUNCE) + if (op->flags & TX_ANNOUNCE) { bcm_can_tx(op); + if (op->kt_ival1.tv64 && (op->count > 0)) + op->count--; + } return msg_head->nframes * CFSIZ + MHSIZ; } -- 2.39.2