From 2f9dfa4f0ca77ea40dc58d052e0c86f53a4dbd1d Mon Sep 17 00:00:00 2001
From: Florian Pose <fp@igh-essen.com>
Date: Tue, 27 Jan 2009 14:14:37 +0000
Subject: [PATCH] Allow the slave to not respond to the mailbox sync manager
 configuration datagram for a certain time.

---
 TODO                      |  1 -
 master/fsm_slave_config.c | 33 ++++++++++++++++++++++++++++++++-
 master/fsm_slave_config.h |  2 ++
 3 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/TODO b/TODO
index 0c739db9..3aa6c4b2 100644
--- a/TODO
+++ b/TODO
@@ -26,7 +26,6 @@ Version 1.5.0:
 * Bus simulator interface.
 * Implement ecrt_master_slave() in kernel space.
 * Rename phy-commands to register commands.
-* Timeout for sync manager config after clearing.
 
 Future issues:
 
diff --git a/master/fsm_slave_config.c b/master/fsm_slave_config.c
index b0bcb034..57c0f6d8 100644
--- a/master/fsm_slave_config.c
+++ b/master/fsm_slave_config.c
@@ -451,6 +451,8 @@ void ec_fsm_slave_config_enter_mbox_sync(
             slave->sii.boot_tx_mailbox_size;
     }
 
+    fsm->take_time = 1;
+
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_slave_config_state_mbox_sync;
 }
@@ -479,7 +481,36 @@ void ec_fsm_slave_config_state_mbox_sync(
         return;
     }
 
-    if (datagram->working_counter != 1) {
+    if (fsm->take_time) {
+        fsm->take_time = 0;
+        fsm->jiffies_start = datagram->jiffies_sent;
+    }
+
+    /* Because the sync manager configurations are cleared during the last
+     * cycle, some slaves do not immediately respond to the mailbox sync
+     * manager configuration datagram. Therefore, resend the datagram for
+     * a certain time, if the slave does not respond.
+     */
+    if (datagram->working_counter == 0) {
+        unsigned long diff = datagram->jiffies_received - fsm->jiffies_start;
+
+        if (diff >= HZ) {
+            slave->error_flag = 1;
+            fsm->state = ec_fsm_slave_config_state_error;
+            EC_ERR("Timeout while configuring mailbox sync managers of"
+                    " slave %u.\n", slave->ring_position);
+            return;
+        }
+        else if (slave->master->debug_level) {
+            EC_DBG("Resending after %u ms...\n",
+                    (unsigned int) diff * 1000 / HZ);
+        }
+
+        // send configuration datagram again
+        fsm->retries = EC_FSM_RETRIES;
+        return;
+    }
+    else if (datagram->working_counter != 1) {
         slave->error_flag = 1;
         fsm->state = ec_fsm_slave_config_state_error;
         EC_ERR("Failed to set sync managers of slave %u: ",
diff --git a/master/fsm_slave_config.h b/master/fsm_slave_config.h
index a6e56809..0af962c1 100644
--- a/master/fsm_slave_config.h
+++ b/master/fsm_slave_config.h
@@ -60,6 +60,8 @@ struct ec_fsm_slave_config
     unsigned int retries; /**< Retries on datagram timeout. */
     ec_sdo_request_t *request; /**< SDO request for SDO configuration. */
     ec_sdo_request_t request_copy; /**< Copied SDO request. */
+    unsigned long jiffies_start; /**< For timeout calculations. */
+    unsigned int take_time; /**< Store jiffies after datagram reception. */
 };
 
 /*****************************************************************************/
-- 
GitLab