[PATCH v1 03/16] j1939: transport: use rxtimer to force session abort

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



If CAN bus is broken we won't be able to get loop back abort
signal from the bus. So, use rxtimer to force abort directly.

Signed-off-by: Oleksij Rempel <o.rempel@xxxxxxxxxxxxxx>
---
 net/can/j1939/j1939-priv.h |  3 +++
 net/can/j1939/transport.c  | 27 +++++++++++++++++++++++----
 2 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/net/can/j1939/j1939-priv.h b/net/can/j1939/j1939-priv.h
index 9ebb2c74f4f6..6f7abd12bc54 100644
--- a/net/can/j1939/j1939-priv.h
+++ b/net/can/j1939/j1939-priv.h
@@ -208,6 +208,9 @@ void j1939_sock_pending_del(struct sock *sk);
 enum j1939_session_state {
 	J1939_SESSION_NEW,
 	J1939_SESSION_ACTIVE,
+	/* waiting for abort signal on the bus */
+	J1939_SESSION_WAITING_ABORT,
+	J1939_SESSION_ACTIVE_MAX,
 	J1939_SESSION_DONE,
 };
 
diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c
index 06b77de6aa85..cd68b98fee92 100644
--- a/net/can/j1939/transport.c
+++ b/net/can/j1939/transport.c
@@ -833,7 +833,8 @@ bool j1939_session_deactivate(struct j1939_session *session)
 	bool active = false;
 
 	j1939_session_list_lock(session->priv);
-	if (session->state == J1939_SESSION_ACTIVE) {
+	if (session->state >= J1939_SESSION_ACTIVE &&
+	    session->state < J1939_SESSION_ACTIVE_MAX) {
 		active = true;
 
 		list_del_init(&session->active_session_list_entry);
@@ -934,9 +935,27 @@ static enum hrtimer_restart j1939_tp_rxtimer(struct hrtimer *hrtimer)
 						     rxtimer);
 	struct j1939_priv *priv = session->priv;
 
-	netdev_alert(priv->ndev, "%s: timeout\n", __func__);
-	j1939_session_txtimer_cancel(session);
-	j1939_session_cancel(session, J1939_XTP_ABORT_TIMEOUT);
+	if (session->state == J1939_SESSION_WAITING_ABORT) {
+		netdev_alert(priv->ndev, "%s: abort rx timeout. Force session deactivation\n",
+			     __func__);
+
+		j1939_session_deactivate_activate_next(session);
+	} else {
+		netdev_alert(priv->ndev, "%s: rx timeout, send abort\n",
+			     __func__);
+
+		j1939_session_list_lock(session->priv);
+		if (session->state >= J1939_SESSION_ACTIVE &&
+		    session->state < J1939_SESSION_ACTIVE_MAX) {
+			session->state = J1939_SESSION_WAITING_ABORT;
+			j1939_session_get(session);
+			hrtimer_start(&session->rxtimer, ms_to_ktime(1250),
+				      HRTIMER_MODE_REL_SOFT);
+			j1939_session_cancel(session, J1939_XTP_ABORT_TIMEOUT);
+		}
+		j1939_session_list_unlock(session->priv);
+	}
+
 	j1939_session_put(session);
 
 	return HRTIMER_NORESTART;
-- 
2.20.1




[Index of Archives]     [Automotive Discussions]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]     [CAN Bus]

  Powered by Linux