diff options
author | Oliver Hartkopp <socketcan@hartkopp.net> | 2011-09-29 15:33:47 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-11-11 12:36:45 -0500 |
commit | 8adc3d3df0562b8dc4008f458081dcc2d8b98863 (patch) | |
tree | 8b8ef461982adac4936537c94b704148577859ff /net/can | |
parent | 6d3607b179804e8ff4e2a1304ee238a4f6dc035c (diff) |
can bcm: fix incomplete tx_setup fix
commit 12d0d0d3a7349daa95dbfd5d7df8146255bc7c67 upstream.
The commit aabdcb0b553b9c9547b1a506b34d55a764745870 ("can bcm: fix tx_setup
off-by-one errors") fixed only a part of the original problem reported by
Andre Naujoks. It turned out that the original code needed to be re-ordered
to reduce complexity and to finally fix the reported frame counting issues.
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'net/can')
-rw-r--r-- | net/can/bcm.c | 48 |
1 files changed, 21 insertions, 27 deletions
diff --git a/net/can/bcm.c b/net/can/bcm.c index 8838b86f2f2..c6cc66f7286 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c | |||
@@ -343,6 +343,18 @@ static void bcm_send_to_user(struct bcm_op *op, struct bcm_msg_head *head, | |||
343 | } | 343 | } |
344 | } | 344 | } |
345 | 345 | ||
346 | static void bcm_tx_start_timer(struct bcm_op *op) | ||
347 | { | ||
348 | if (op->kt_ival1.tv64 && op->count) | ||
349 | hrtimer_start(&op->timer, | ||
350 | ktime_add(ktime_get(), op->kt_ival1), | ||
351 | HRTIMER_MODE_ABS); | ||
352 | else if (op->kt_ival2.tv64) | ||
353 | hrtimer_start(&op->timer, | ||
354 | ktime_add(ktime_get(), op->kt_ival2), | ||
355 | HRTIMER_MODE_ABS); | ||
356 | } | ||
357 | |||
346 | static void bcm_tx_timeout_tsklet(unsigned long data) | 358 | static void bcm_tx_timeout_tsklet(unsigned long data) |
347 | { | 359 | { |
348 | struct bcm_op *op = (struct bcm_op *)data; | 360 | struct bcm_op *op = (struct bcm_op *)data; |
@@ -364,23 +376,12 @@ static void bcm_tx_timeout_tsklet(unsigned long data) | |||
364 | 376 | ||
365 | bcm_send_to_user(op, &msg_head, NULL, 0); | 377 | bcm_send_to_user(op, &msg_head, NULL, 0); |
366 | } | 378 | } |
367 | |||
368 | /* send (next) frame */ | ||
369 | bcm_can_tx(op); | 379 | bcm_can_tx(op); |
370 | hrtimer_start(&op->timer, | ||
371 | ktime_add(ktime_get(), op->kt_ival1), | ||
372 | HRTIMER_MODE_ABS); | ||
373 | 380 | ||
374 | } else { | 381 | } else if (op->kt_ival2.tv64) |
375 | if (op->kt_ival2.tv64) { | 382 | bcm_can_tx(op); |
376 | 383 | ||
377 | /* send (next) frame */ | 384 | bcm_tx_start_timer(op); |
378 | bcm_can_tx(op); | ||
379 | hrtimer_start(&op->timer, | ||
380 | ktime_add(ktime_get(), op->kt_ival2), | ||
381 | HRTIMER_MODE_ABS); | ||
382 | } | ||
383 | } | ||
384 | } | 385 | } |
385 | 386 | ||
386 | /* | 387 | /* |
@@ -960,28 +961,21 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, | |||
960 | hrtimer_cancel(&op->timer); | 961 | hrtimer_cancel(&op->timer); |
961 | } | 962 | } |
962 | 963 | ||
963 | if ((op->flags & STARTTIMER) && | 964 | if (op->flags & STARTTIMER) { |
964 | ((op->kt_ival1.tv64 && op->count) || op->kt_ival2.tv64)) { | 965 | hrtimer_cancel(&op->timer); |
965 | |||
966 | /* spec: send can_frame when starting timer */ | 966 | /* spec: send can_frame when starting timer */ |
967 | op->flags |= TX_ANNOUNCE; | 967 | op->flags |= TX_ANNOUNCE; |
968 | |||
969 | /* only start timer when having more frames than sent below */ | ||
970 | if (op->kt_ival1.tv64 && (op->count > 1)) { | ||
971 | /* op->count-- is done in bcm_tx_timeout_tsklet */ | ||
972 | hrtimer_start(&op->timer, op->kt_ival1, | ||
973 | HRTIMER_MODE_REL); | ||
974 | } else | ||
975 | hrtimer_start(&op->timer, op->kt_ival2, | ||
976 | HRTIMER_MODE_REL); | ||
977 | } | 968 | } |
978 | 969 | ||
979 | if (op->flags & TX_ANNOUNCE) { | 970 | if (op->flags & TX_ANNOUNCE) { |
980 | bcm_can_tx(op); | 971 | bcm_can_tx(op); |
981 | if (op->kt_ival1.tv64 && (op->count > 0)) | 972 | if (op->count) |
982 | op->count--; | 973 | op->count--; |
983 | } | 974 | } |
984 | 975 | ||
976 | if (op->flags & STARTTIMER) | ||
977 | bcm_tx_start_timer(op); | ||
978 | |||
985 | return msg_head->nframes * CFSIZ + MHSIZ; | 979 | return msg_head->nframes * CFSIZ + MHSIZ; |
986 | } | 980 | } |
987 | 981 | ||