Removed ecrt_master_run(), removed datagram queueing from state
authorFlorian Pose <fp@igh-essen.com>
Thu, 08 Mar 2007 13:02:42 +0000
changeset 637 d5d04c868e0e
parent 636 9114b3a5f9d3
child 638 b0994b4e3b37
Removed ecrt_master_run(), removed datagram queueing from state
machines, added datagram injection, two different master thread
functions.
NEWS
TODO
examples/mini/mini.c
examples/rtai/rtai_sample.c
include/ecrt.h
master/fsm_change.c
master/fsm_coe.c
master/fsm_master.c
master/fsm_master.h
master/fsm_sii.c
master/fsm_slave.c
master/master.c
master/master.h
--- a/NEWS	Thu Mar 08 08:10:32 2007 +0000
+++ b/NEWS	Thu Mar 08 13:02:42 2007 +0000
@@ -16,6 +16,8 @@
 * Changed format of sysconfig file and accordingly adjusted functionality
   of the init script to handle device ID lists.
 * Realtime interface changes:
+  - ecrt_master_run() became obsolete, because the master state machine is now
+    run in process context.
   - Added ecrt_master_get_status() to get information about the bus.
   - Added functions to set up an alternative PDO mapping, i. e.
     ec_slave_pdo_mapping_clear(), ec_slave_pdo_mapping_add() and
--- a/TODO	Thu Mar 08 08:10:32 2007 +0000
+++ b/TODO	Thu Mar 08 13:02:42 2007 +0000
@@ -7,7 +7,6 @@
 -------------------------------------------------------------------------------
 
 * Release 1.3:
-  - Remove ecrt_master_run(). Make master FSM run in process context instead.
   - Remove addressing scheme "X:Y".
   - Allow only MAC address as device ID.
   - Remove ugly ec_slave_is_coupler().
--- a/examples/mini/mini.c	Thu Mar 08 08:10:32 2007 +0000
+++ b/examples/mini/mini.c	Thu Mar 08 13:02:42 2007 +0000
@@ -130,8 +130,6 @@
     ecrt_domain_queue(domain1);
     spin_unlock(&master_lock);
 
-    ecrt_master_run(master);
-
     spin_lock(&master_lock);
     ecrt_master_send(master);
     spin_unlock(&master_lock);
--- a/examples/rtai/rtai_sample.c	Thu Mar 08 08:10:32 2007 +0000
+++ b/examples/rtai/rtai_sample.c	Thu Mar 08 13:02:42 2007 +0000
@@ -91,7 +91,6 @@
 
         rt_sem_wait(&master_sem);
         ecrt_domain_queue(domain1);
-        ecrt_master_run(master);
         ecrt_master_send(master);
         rt_sem_signal(&master_sem);
 		
--- a/include/ecrt.h	Thu Mar 08 08:10:32 2007 +0000
+++ b/include/ecrt.h	Thu Mar 08 13:02:42 2007 +0000
@@ -59,8 +59,8 @@
 
 /*****************************************************************************/
 
-#define ECRT_VER_MAJOR 1U
-#define ECRT_VER_MINOR 2U
+#define ECRT_VER_MAJOR 1
+#define ECRT_VER_MINOR 3
 
 #define ECRT_VERSION(a,b) (((a) << 8) + (b))
 #define ECRT_VERSION_MAGIC ECRT_VERSION(ECRT_VER_MAJOR, ECRT_VER_MINOR)
@@ -150,8 +150,6 @@
 void ecrt_master_send(ec_master_t *master);
 void ecrt_master_receive(ec_master_t *master);
 
-void ecrt_master_run(ec_master_t *master);
-
 ec_slave_t *ecrt_master_get_slave(const ec_master_t *, const char *);
 
 void ecrt_master_get_status(const ec_master_t *master, ec_master_status_t *);
--- a/master/fsm_change.c	Thu Mar 08 08:10:32 2007 +0000
+++ b/master/fsm_change.c	Thu Mar 08 13:02:42 2007 +0000
@@ -158,7 +158,6 @@
     // write new state to slave
     ec_datagram_npwr(datagram, slave->station_address, 0x0120, 2);
     EC_WRITE_U16(datagram->data, fsm->requested_state);
-    ec_master_queue_datagram(fsm->slave->master, datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_change_state_check;
 }
@@ -175,10 +174,8 @@
     ec_datagram_t *datagram = fsm->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return;
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_change_state_error;
@@ -206,7 +203,6 @@
         // repeat writing new state to slave
         ec_datagram_npwr(datagram, slave->station_address, 0x0120, 2);
         EC_WRITE_U16(datagram->data, fsm->requested_state);
-        ec_master_queue_datagram(fsm->slave->master, datagram);
         fsm->retries = EC_FSM_RETRIES;
         return;
     }
@@ -215,7 +211,6 @@
 
     // read AL status from slave
     ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2);
-    ec_master_queue_datagram(fsm->slave->master, datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_change_state_status;
 }
@@ -232,10 +227,8 @@
     ec_datagram_t *datagram = fsm->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return;
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_change_state_error;
@@ -291,7 +284,6 @@
                req_state, slave->ring_position, cur_state);
         // fetch AL status error code
         ec_datagram_nprd(datagram, slave->station_address, 0x0134, 2);
-        ec_master_queue_datagram(fsm->slave->master, datagram);
         fsm->retries = EC_FSM_RETRIES;
         fsm->state = ec_fsm_change_state_code;
         return;
@@ -312,7 +304,6 @@
  again:
     // no timeout yet. check again
     ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2);
-    ec_master_queue_datagram(fsm->slave->master, datagram);
     fsm->retries = EC_FSM_RETRIES;
 }
 
@@ -369,10 +360,8 @@
     uint32_t code;
     const ec_code_msg_t *al_msg;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return;
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_change_state_error;
@@ -416,7 +405,6 @@
 
     ec_datagram_npwr(datagram, slave->station_address, 0x0120, 2);
     EC_WRITE_U16(datagram->data, slave->current_state);
-    ec_master_queue_datagram(fsm->slave->master, datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_change_state_ack;
 }
@@ -432,10 +420,8 @@
     ec_datagram_t *datagram = fsm->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return;
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_change_state_error;
@@ -456,7 +442,6 @@
 
     // read new AL status
     ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2);
-    ec_master_queue_datagram(fsm->slave->master, datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_change_state_check_ack;
 }
@@ -473,10 +458,8 @@
     ec_datagram_t *datagram = fsm->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return;
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_change_state_error;
@@ -526,7 +509,6 @@
 
     // reread new AL status
     ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2);
-    ec_master_queue_datagram(fsm->slave->master, datagram);
     fsm->retries = EC_FSM_RETRIES;
 }
 
--- a/master/fsm_coe.c	Thu Mar 08 08:10:32 2007 +0000
+++ b/master/fsm_coe.c	Thu Mar 08 13:02:42 2007 +0000
@@ -260,7 +260,6 @@
     EC_WRITE_U16(data + 4, 0x0000);
     EC_WRITE_U16(data + 6, 0x0001); // deliver all SDOs!
 
-    ec_master_queue_datagram(fsm->slave->master, datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_coe_dict_request;
 }
@@ -277,11 +276,8 @@
     ec_datagram_t *datagram = fsm->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        // FIXME: request again?
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return; // FIXME: request again?
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_coe_error;
@@ -301,7 +297,6 @@
     fsm->cycles_start = datagram->cycles_sent;
 
     ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
-    ec_master_queue_datagram(fsm->slave->master, datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_coe_dict_check;
 }
@@ -317,10 +312,8 @@
     ec_datagram_t *datagram = fsm->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return;
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_coe_error;
@@ -348,14 +341,12 @@
         }
 
         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
-        ec_master_queue_datagram(fsm->slave->master, datagram);
         fsm->retries = EC_FSM_RETRIES;
         return;
     }
 
     // Fetch response
     ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
-    ec_master_queue_datagram(fsm->slave->master, datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_coe_dict_response;
 }
@@ -377,11 +368,8 @@
     uint16_t sdo_index;
     ec_sdo_t *sdo;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        // FIXME: request again?
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return; // FIXME: request again?
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_coe_error;
@@ -464,7 +452,6 @@
     if (EC_READ_U8(data + 2) & 0x80) { // more messages waiting. check again.
         fsm->cycles_start = datagram->cycles_sent;
         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
-        ec_master_queue_datagram(fsm->slave->master, datagram);
         fsm->retries = EC_FSM_RETRIES;
         fsm->state = ec_fsm_coe_dict_check;
         return;
@@ -490,7 +477,6 @@
     EC_WRITE_U16(data + 4, 0x0000);
     EC_WRITE_U16(data + 6, fsm->sdo->index); // SDO index
 
-    ec_master_queue_datagram(fsm->slave->master, datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_coe_dict_desc_request;
 }
@@ -507,11 +493,8 @@
     ec_datagram_t *datagram = fsm->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        // FIXME: check for response first?
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return; // FIXME: check for response first?
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_coe_error;
@@ -531,7 +514,6 @@
     fsm->cycles_start = datagram->cycles_sent;
 
     ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
-    ec_master_queue_datagram(fsm->slave->master, datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_coe_dict_desc_check;
 }
@@ -547,10 +529,8 @@
     ec_datagram_t *datagram = fsm->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return;
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_coe_error;
@@ -577,14 +557,12 @@
         }
 
         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
-        ec_master_queue_datagram(fsm->slave->master, datagram);
         fsm->retries = EC_FSM_RETRIES;
         return;
     }
 
     // Fetch response
     ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
-    ec_master_queue_datagram(fsm->slave->master, datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_coe_dict_desc_response;
 }
@@ -605,11 +583,8 @@
     uint8_t *data, mbox_prot;
     size_t rec_size, name_size;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        // FIXME: request again?
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return; // FIXME: request again?
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_coe_error;
@@ -704,7 +679,6 @@
     EC_WRITE_U8 (data + 8, fsm->subindex); // SDO subindex
     EC_WRITE_U8 (data + 9, 0x00); // value info (no values)
 
-    ec_master_queue_datagram(fsm->slave->master, datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_coe_dict_entry_request;
 }
@@ -722,11 +696,8 @@
     ec_datagram_t *datagram = fsm->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        // FIXME: check for response first?
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return; // FIXME: check for response first?
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_coe_error;
@@ -746,7 +717,6 @@
     fsm->cycles_start = datagram->cycles_sent;
 
     ec_slave_mbox_prepare_check(slave, datagram); // can not fail
-    ec_master_queue_datagram(fsm->slave->master, datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_coe_dict_entry_check;
 }
@@ -763,10 +733,8 @@
     ec_datagram_t *datagram = fsm->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return;
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_coe_error;
@@ -793,14 +761,12 @@
         }
 
         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
-        ec_master_queue_datagram(fsm->slave->master, datagram);
         fsm->retries = EC_FSM_RETRIES;
         return;
     }
 
     // Fetch response
     ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
-    ec_master_queue_datagram(fsm->slave->master, datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_coe_dict_entry_response;
 }
@@ -822,11 +788,8 @@
     size_t rec_size, data_size;
     ec_sdo_entry_t *entry;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        // FIXME: request again?
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return; // FIXME: request again?
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_coe_error;
@@ -932,7 +895,6 @@
         EC_WRITE_U8 (data + 8, fsm->subindex); // SDO subindex
         EC_WRITE_U8 (data + 9, 0x00); // value info (no values)
 
-        ec_master_queue_datagram(fsm->slave->master, datagram);
         fsm->retries = EC_FSM_RETRIES;
         fsm->state = ec_fsm_coe_dict_entry_request;
         return;
@@ -953,7 +915,6 @@
         EC_WRITE_U16(data + 4, 0x0000);
         EC_WRITE_U16(data + 6, fsm->sdo->index); // SDO index
 
-        ec_master_queue_datagram(fsm->slave->master, datagram);
         fsm->retries = EC_FSM_RETRIES;
         fsm->state = ec_fsm_coe_dict_desc_request;
         return;
@@ -1001,7 +962,6 @@
     EC_WRITE_U32(data + 6, sdodata->size);
     memcpy(data + 10, sdodata->data, sdodata->size);
 
-    ec_master_queue_datagram(fsm->slave->master, datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_coe_down_request;
 }
@@ -1018,11 +978,8 @@
     ec_datagram_t *datagram = fsm->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        // FIXME: check for response first?
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return; // FIXME: check for response first?
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_coe_error;
@@ -1042,7 +999,6 @@
     fsm->cycles_start = datagram->cycles_sent;
 
     ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
-    ec_master_queue_datagram(fsm->slave->master, datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_coe_down_check;
 }
@@ -1058,10 +1014,8 @@
     ec_datagram_t *datagram = fsm->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return;
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_coe_error;
@@ -1088,14 +1042,12 @@
         }
 
         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
-        ec_master_queue_datagram(fsm->slave->master, datagram);
         fsm->retries = EC_FSM_RETRIES;
         return;
     }
 
     // Fetch response
     ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
-    ec_master_queue_datagram(fsm->slave->master, datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_coe_down_response;
 }
@@ -1115,11 +1067,8 @@
     size_t rec_size;
     ec_sdo_data_t *sdodata = fsm->sdodata;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        // FIXME: request again?
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return; // FIXME: request again?
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_coe_error;
@@ -1222,7 +1171,6 @@
         ec_print_data(data, 10);
     }
 
-    ec_master_queue_datagram(fsm->slave->master, datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_coe_up_request;
 }
@@ -1239,11 +1187,8 @@
     ec_datagram_t *datagram = fsm->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        // FIXME: check for response first?
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return; // FIXME: check for response first?
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_coe_error;
@@ -1263,7 +1208,6 @@
     fsm->cycles_start = datagram->cycles_sent;
 
     ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
-    ec_master_queue_datagram(fsm->slave->master, datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_coe_up_check;
 }
@@ -1279,10 +1223,8 @@
     ec_datagram_t *datagram = fsm->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return;
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_coe_error;
@@ -1309,14 +1251,12 @@
         }
 
         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
-        ec_master_queue_datagram(fsm->slave->master, datagram);
         fsm->retries = EC_FSM_RETRIES;
         return;
     }
 
     // Fetch response
     ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
-    ec_master_queue_datagram(fsm->slave->master, datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_coe_up_response;
 }
@@ -1341,11 +1281,8 @@
     uint32_t complete_size;
     unsigned int expedited, size_specified;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        // FIXME: request again?
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return; // FIXME: request again?
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_coe_error;
@@ -1468,7 +1405,6 @@
                 ec_print_data(data, 3);
             }
 
-            ec_master_queue_datagram(fsm->slave->master, datagram);
             fsm->retries = EC_FSM_RETRIES;
             fsm->state = ec_fsm_coe_up_seg_request;
             return;
@@ -1490,11 +1426,8 @@
     ec_datagram_t *datagram = fsm->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        // FIXME: check for response first?
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return; // FIXME: check for response first?
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_coe_error;
@@ -1514,7 +1447,6 @@
     fsm->cycles_start = datagram->cycles_sent;
 
     ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
-    ec_master_queue_datagram(fsm->slave->master, datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_coe_up_seg_check;
 }
@@ -1530,10 +1462,8 @@
     ec_datagram_t *datagram = fsm->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return;
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_coe_error;
@@ -1560,14 +1490,12 @@
         }
 
         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
-        ec_master_queue_datagram(fsm->slave->master, datagram);
         fsm->retries = EC_FSM_RETRIES;
         return;
     }
 
     // Fetch response
     ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
-    ec_master_queue_datagram(fsm->slave->master, datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_coe_up_seg_response;
 }
@@ -1592,11 +1520,8 @@
     uint32_t seg_size;
     unsigned int last_segment;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        // FIXME: request again?
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return; // FIXME: request again?
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_coe_error;
@@ -1686,7 +1611,6 @@
             ec_print_data(data, 3);
         }
 
-        ec_master_queue_datagram(fsm->slave->master, datagram);
         fsm->retries = EC_FSM_RETRIES;
         fsm->state = ec_fsm_coe_up_seg_request;
         return;
--- a/master/fsm_master.c	Thu Mar 08 08:10:32 2007 +0000
+++ b/master/fsm_master.c	Thu Mar 08 13:02:42 2007 +0000
@@ -135,19 +135,8 @@
         && fsm->state != ec_fsm_master_state_error;
 }
 
-/*****************************************************************************/
-
-/**
-   \return true, if the master state machine terminated gracefully
-*/
-
-int ec_fsm_master_success(ec_fsm_master_t *fsm /**< master state machine */)
-{
-    return fsm->state == ec_fsm_master_state_end;
-}
-
 /******************************************************************************
- *  operation/idle state machine
+ *  master state machine
  *****************************************************************************/
 
 /**
@@ -158,7 +147,6 @@
 void ec_fsm_master_state_start(ec_fsm_master_t *fsm)
 {
     ec_datagram_brd(fsm->datagram, 0x0130, 2);
-    ec_master_queue_datagram(fsm->master, fsm->datagram);
     fsm->state = ec_fsm_master_state_broadcast;
 }
 
@@ -176,11 +164,8 @@
     ec_slave_t *slave;
     ec_master_t *master = fsm->master;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT) {
-        // always retry
-        ec_master_queue_datagram(fsm->master, fsm->datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT)
+        return; // always retry
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) { // EC_DATAGRAM_ERROR
         // link is down
@@ -260,16 +245,15 @@
 
         // begin scanning of slaves
         fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
+        fsm->state = ec_fsm_master_state_scan_slaves;
         ec_fsm_slave_start_scan(&fsm->fsm_slave, fsm->slave);
         ec_fsm_slave_exec(&fsm->fsm_slave); // execute immediately
-        fsm->state = ec_fsm_master_state_scan_slaves;
         return;
     }
 
     // fetch state from each slave
     fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
     ec_datagram_nprd(fsm->datagram, fsm->slave->station_address, 0x0130, 2);
-    ec_master_queue_datagram(master, fsm->datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_master_state_read_states;
 }
@@ -365,9 +349,9 @@
         }
 
         fsm->slave = slave;
+        fsm->state = ec_fsm_master_state_configure_slave;
         ec_fsm_slave_start_conf(&fsm->fsm_slave, slave);
         ec_fsm_slave_exec(&fsm->fsm_slave); // execute immediately
-        fsm->state = ec_fsm_master_state_configure_slave;
         return;
     }
 
@@ -391,8 +375,8 @@
             else {
                 // start uploading SDO
                 fsm->slave = slave;
+                fsm->sdo_request = master->sdo_request;
                 fsm->state = ec_fsm_master_state_sdo_request;
-                fsm->sdo_request = master->sdo_request;
                 ec_fsm_coe_upload(&fsm->fsm_coe, slave, fsm->sdo_request);
                 ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately
                 return;
@@ -446,10 +430,9 @@
     // is there another slave to query?
     if (slave->list.next != &master->slaves) {
         // process next slave
-        fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
+        fsm->slave = list_entry(slave->list.next, ec_slave_t, list);
         ec_datagram_nprd(fsm->datagram, fsm->slave->station_address,
                          0x0130, 2);
-        ec_master_queue_datagram(master, fsm->datagram);
         fsm->retries = EC_FSM_RETRIES;
         fsm->state = ec_fsm_master_state_read_states;
         return;
@@ -488,10 +471,8 @@
     ec_slave_t *slave = fsm->slave;
     ec_datagram_t *datagram = fsm->datagram;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        ec_master_queue_datagram(fsm->master, fsm->datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return;
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         EC_ERR("Failed to receive AL state datagram for slave %i"
@@ -513,9 +494,9 @@
 
     // check, if new slave state has to be acknowledged
     if (slave->current_state & EC_SLAVE_STATE_ACK_ERR && !slave->error_flag) {
+        fsm->state = ec_fsm_master_state_acknowledge;
         ec_fsm_change_ack(&fsm->fsm_change, slave);
         ec_fsm_change_exec(&fsm->fsm_change);
-        fsm->state = ec_fsm_master_state_acknowledge;
         return;
     }
 
@@ -592,8 +573,7 @@
 
     while (fsm->slave->online_state == EC_SLAVE_ONLINE) {
         if (fsm->slave->list.next == &fsm->master->slaves) { // last slave?
-            fsm->state = ec_fsm_master_state_start;
-            fsm->state(fsm); // execute immediately
+            fsm->state = ec_fsm_master_state_end;
             return;
         }
         // check next slave
@@ -606,7 +586,6 @@
     // write station address
     ec_datagram_apwr(datagram, fsm->slave->ring_position, 0x0010, 2);
     EC_WRITE_U16(datagram->data, fsm->slave->station_address);
-    ec_master_queue_datagram(fsm->master, datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_master_state_rewrite_addresses;
 }
@@ -670,10 +649,8 @@
     ec_slave_t *slave = fsm->slave;
     ec_datagram_t *datagram = fsm->datagram;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        ec_master_queue_datagram(fsm->master, fsm->datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return;
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         EC_ERR("Failed to receive address datagram for slave %i"
@@ -691,8 +668,7 @@
     }
 
     if (fsm->slave->list.next == &fsm->master->slaves) { // last slave?
-        fsm->state = ec_fsm_master_state_start;
-        fsm->state(fsm); // execute immediately
+        fsm->state = ec_fsm_master_state_end;
         return;
     }
 
@@ -712,14 +688,14 @@
 void ec_fsm_master_state_scan_slaves(ec_fsm_master_t *fsm /**< master state machine */)
 {
     ec_master_t *master = fsm->master;
-    ec_slave_t *slave;
+    ec_slave_t *slave = fsm->slave;
 
     if (ec_fsm_slave_exec(&fsm->fsm_slave)) // execute slave state machine
         return;
 
     // another slave to fetch?
-    if (fsm->slave->list.next != &master->slaves) {
-        fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
+    if (slave->list.next != &master->slaves) {
+        fsm->slave = list_entry(slave->list.next, ec_slave_t, list);
         ec_fsm_slave_start_scan(&fsm->fsm_slave, fsm->slave);
         ec_fsm_slave_exec(&fsm->fsm_slave); // execute immediately
         return;
@@ -803,9 +779,7 @@
     if (ec_fsm_master_action_process_eeprom(fsm))
         return; // processing another request
 
-    // restart master state machine.
-    fsm->state = ec_fsm_master_state_start;
-    fsm->state(fsm); // execute immediately
+    fsm->state = ec_fsm_master_state_end;
 }
 
 /*****************************************************************************/
@@ -835,9 +809,7 @@
                sdo_count, entry_count, slave->ring_position);
     }
 
-    // restart master state machine.
-    fsm->state = ec_fsm_master_state_start;
-    fsm->state(fsm); // execute immediately
+    fsm->state = ec_fsm_master_state_end;
 }
 
 /*****************************************************************************/
@@ -865,9 +837,7 @@
     request->return_code = 1;
     master->sdo_seq_master++;
 
-    // restart master state machine.
-    fsm->state = ec_fsm_master_state_start;
-    fsm->state(fsm); // execute immediately
+    fsm->state = ec_fsm_master_state_end;
 }
 
 /*****************************************************************************/
--- a/master/fsm_master.h	Thu Mar 08 08:10:32 2007 +0000
+++ b/master/fsm_master.h	Thu Mar 08 13:02:42 2007 +0000
@@ -120,7 +120,6 @@
 
 int ec_fsm_master_exec(ec_fsm_master_t *);
 int ec_fsm_master_running(ec_fsm_master_t *);
-int ec_fsm_master_success(ec_fsm_master_t *);
 
 /*****************************************************************************/
 
--- a/master/fsm_sii.c	Thu Mar 08 08:10:32 2007 +0000
+++ b/master/fsm_sii.c	Thu Mar 08 13:02:42 2007 +0000
@@ -168,7 +168,6 @@
     EC_WRITE_U8 (datagram->data,     0x00); // read-only access
     EC_WRITE_U8 (datagram->data + 1, 0x01); // request read operation
     EC_WRITE_U16(datagram->data + 2, fsm->offset);
-    ec_master_queue_datagram(fsm->slave->master, datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_sii_read_check;
 }
@@ -184,10 +183,8 @@
 {
     ec_datagram_t *datagram = fsm->datagram;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return;
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_sii_error;
@@ -216,7 +213,7 @@
             ec_datagram_nprd(datagram, fsm->slave->station_address, 0x502, 10);
             break;
     }
-    ec_master_queue_datagram(fsm->slave->master, datagram);
+
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_sii_read_fetch;
 }
@@ -232,10 +229,8 @@
 {
     ec_datagram_t *datagram = fsm->datagram;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return;
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_sii_error;
@@ -281,7 +276,6 @@
                 ec_datagram_nprd(datagram, fsm->slave->station_address, 0x502, 10);
                 break;
         }
-        ec_master_queue_datagram(fsm->slave->master, datagram);
         fsm->retries = EC_FSM_RETRIES;
         return;
     }
@@ -316,7 +310,7 @@
     EC_WRITE_U8 (datagram->data + 1, 0x02); // request write operation
     EC_WRITE_U32(datagram->data + 2, fsm->offset);
     memcpy(datagram->data + 6, fsm->value, 2);
-    ec_master_queue_datagram(fsm->slave->master, datagram);
+
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_sii_write_check;
 }
@@ -331,10 +325,8 @@
 {
     ec_datagram_t *datagram = fsm->datagram;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return;
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_sii_error;
@@ -356,7 +348,6 @@
 
     // issue check/fetch datagram
     ec_datagram_nprd(datagram, fsm->slave->station_address, 0x502, 2);
-    ec_master_queue_datagram(fsm->slave->master, datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_sii_write_check2;
 }
@@ -371,10 +362,8 @@
 {
     ec_datagram_t *datagram = fsm->datagram;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return;
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_sii_error;
@@ -404,7 +393,6 @@
         }
 
         // issue check/fetch datagram again
-        ec_master_queue_datagram(fsm->slave->master, datagram);
         fsm->retries = EC_FSM_RETRIES;
         return;
     }
--- a/master/fsm_slave.c	Thu Mar 08 08:10:32 2007 +0000
+++ b/master/fsm_slave.c	Thu Mar 08 13:02:42 2007 +0000
@@ -198,7 +198,6 @@
     // write station address
     ec_datagram_apwr(fsm->datagram, fsm->slave->ring_position, 0x0010, 2);
     EC_WRITE_U16(fsm->datagram->data, fsm->slave->station_address);
-    ec_master_queue_datagram(fsm->slave->master, fsm->datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_slave_scan_state_address;
 }
@@ -213,10 +212,8 @@
 {
     ec_datagram_t *datagram = fsm->datagram;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        ec_master_queue_datagram(fsm->slave->master, fsm->datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return;
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_slave_state_error;
@@ -236,7 +233,6 @@
 
     // Read AL state
     ec_datagram_nprd(datagram, fsm->slave->station_address, 0x0130, 2);
-    ec_master_queue_datagram(fsm->slave->master, datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_slave_scan_state_state;
 }
@@ -252,10 +248,8 @@
     ec_datagram_t *datagram = fsm->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return;
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_slave_state_error;
@@ -283,7 +277,6 @@
 
     // read base data
     ec_datagram_nprd(datagram, fsm->slave->station_address, 0x0000, 6);
-    ec_master_queue_datagram(fsm->slave->master, datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_slave_scan_state_base;
 }
@@ -299,10 +292,8 @@
     ec_datagram_t *datagram = fsm->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return;
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_slave_state_error;
@@ -330,7 +321,6 @@
 
     // read data link status
     ec_datagram_nprd(datagram, slave->station_address, 0x0110, 2);
-    ec_master_queue_datagram(slave->master, datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_slave_scan_state_datalink;
 }
@@ -348,10 +338,8 @@
     uint16_t dl_status;
     unsigned int i;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return;
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_slave_state_error;
@@ -620,7 +608,6 @@
     ec_datagram_npwr(datagram, slave->station_address,
                      0x0600, EC_FMMU_SIZE * slave->base_fmmu_count);
     memset(datagram->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count);
-    ec_master_queue_datagram(master, datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_slave_conf_state_clear_fmmus;
 }
@@ -636,10 +623,8 @@
 {
     ec_datagram_t *datagram = fsm->datagram;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return;
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_slave_state_error;
@@ -704,7 +689,6 @@
                 datagram->data + EC_SYNC_SIZE * i);
     }
 
-    ec_master_queue_datagram(fsm->slave->master, datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_slave_conf_state_mbox_sync;
 }
@@ -720,10 +704,8 @@
     ec_datagram_t *datagram = fsm->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return;
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_slave_state_error;
@@ -923,7 +905,6 @@
                 datagram->data + EC_SYNC_SIZE * i);
     }
 
-    ec_master_queue_datagram(fsm->slave->master, datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_slave_conf_state_pdo_sync;
 }
@@ -938,10 +919,8 @@
     ec_datagram_t *datagram = fsm->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        ec_master_queue_datagram(fsm->slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return;
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_slave_state_error;
@@ -970,7 +949,6 @@
 void ec_fsm_slave_conf_enter_fmmu(ec_fsm_slave_t *fsm /**< slave state machine */)
 {
     ec_slave_t *slave = fsm->slave;
-    ec_master_t *master = slave->master;
     ec_datagram_t *datagram = fsm->datagram;
     unsigned int j;
 
@@ -987,7 +965,6 @@
         ec_fmmu_config(&slave->fmmus[j], datagram->data + EC_FMMU_SIZE * j);
     }
 
-    ec_master_queue_datagram(master, datagram);
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_slave_conf_state_fmmu;
 }
@@ -1003,10 +980,8 @@
     ec_datagram_t *datagram = fsm->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
-        ec_master_queue_datagram(slave->master, datagram);
-        return;
-    }
+    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+        return;
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->state = ec_fsm_slave_state_error;
--- a/master/master.c	Thu Mar 08 08:10:32 2007 +0000
+++ b/master/master.c	Thu Mar 08 13:02:42 2007 +0000
@@ -57,7 +57,8 @@
 void ec_master_clear(struct kobject *);
 void ec_master_destroy_domains(ec_master_t *);
 void ec_master_sync_io(ec_master_t *);
-static int ec_master_thread(void *);
+static int ec_master_idle_thread(ec_master_t *);
+static int ec_master_operation_thread(ec_master_t *);
 void ec_master_eoe_run(unsigned long);
 void ec_master_check_sdo(unsigned long);
 int ec_master_measure_bus_time(ec_master_t *);
@@ -117,6 +118,8 @@
     init_MUTEX(&master->device_sem);
 
     master->mode = EC_MASTER_MODE_ORPHANED;
+    master->injection_seq_fsm = 0;
+    master->injection_seq_rt = 0;
 
     INIT_LIST_HEAD(&master->slaves);
     master->slave_count = 0;
@@ -367,11 +370,25 @@
 
 int ec_master_thread_start(ec_master_t *master /**< EtherCAT master */)
 {
+    int (*thread_func)(ec_master_t *);
+
+    switch (master->mode) {
+        case EC_MASTER_MODE_IDLE:
+            thread_func = ec_master_idle_thread;
+            break;
+        case EC_MASTER_MODE_OPERATION:
+            thread_func = ec_master_operation_thread;
+            break;
+        default:
+            EC_ERR("Invalid master mode while starting thread!\n");
+            return -1;
+    }
+
     init_completion(&master->thread_exit);
-    
+
     EC_INFO("Starting master thread.\n");
-    if (!(master->thread_id =
-                kernel_thread(ec_master_thread, master, CLONE_KERNEL)))
+    if (!(master->thread_id = kernel_thread((int (*)(void *)) thread_func,
+                    master, CLONE_KERNEL)))
         return -1;
     
     return 0;
@@ -403,7 +420,7 @@
     master->request_cb = ec_master_request_cb;
     master->release_cb = ec_master_release_cb;
     master->cb_data = master;
-	
+
     master->mode = EC_MASTER_MODE_IDLE;
     if (ec_master_thread_start(master)) {
         master->mode = EC_MASTER_MODE_ORPHANED;
@@ -452,9 +469,10 @@
         ecrt_master_receive(master);
     }
 
-    // finish running master FSM
+    // finish running IDLE FSM
     if (ec_fsm_master_running(&master->fsm)) {
         while (ec_fsm_master_exec(&master->fsm)) {
+            ec_master_queue_datagram(master, &master->fsm_datagram);
             ec_master_sync_io(master);
         }
     }
@@ -478,6 +496,8 @@
 
     master->eoe_checked = 0; // allow starting EoE again
     master->pdo_slaves_offline = 0; // assume all PDO slaves online
+    master->injection_seq_fsm = 0;
+    master->injection_seq_rt = 0;
 
     return 0;
 
@@ -504,6 +524,9 @@
 
     ec_master_eoe_stop(master); // stop EoE timer
     master->eoe_checked = 1; // prevent from starting again by FSM
+    ec_master_thread_stop(master); // stop master thread
+    master->injection_seq_fsm = 0;
+    master->injection_seq_rt = 0;
 
     // wait for FSM datagram
     if (master->fsm_datagram.state == EC_DATAGRAM_SENT) {
@@ -516,6 +539,7 @@
     // finish running master FSM
     if (ec_fsm_master_running(fsm)) {
         while (ec_fsm_master_exec(fsm)) {
+            ec_master_queue_datagram(master, &master->fsm_datagram);
             ec_master_sync_io(master);
         }
     }
@@ -538,6 +562,7 @@
 
         ec_fsm_slave_start_conf(&fsm_slave, slave);
         while (ec_fsm_slave_exec(&fsm_slave)) {
+            ec_master_queue_datagram(master, &master->fsm_datagram);
             ec_master_sync_io(master);
         }
     }
@@ -574,6 +599,8 @@
     list_for_each_entry(queued_datagram, &master->datagram_queue, queue) {
         if (queued_datagram == datagram) {
             master->stats.skipped++;
+            if (master->debug_level)
+                EC_DBG("skipping datagram %x.\n", (unsigned int) datagram);
             ec_master_output_stats(master);
             datagram->state = EC_DATAGRAM_QUEUED;
             return;
@@ -826,32 +853,34 @@
 /*****************************************************************************/
 
 /**
-   Master kernel thread function.
-*/
-
-static int ec_master_thread(void *data)
-{
-    ec_master_t *master = (ec_master_t *) data;
+ * Master kernel thread function for IDLE mode.
+ */
+
+static int ec_master_idle_thread(ec_master_t *master)
+{
     cycles_t cycles_start, cycles_end;
 
-    daemonize("EtherCAT");
+    daemonize("EtherCAT-IDLE");
     allow_signal(SIGTERM);
 
     while (!signal_pending(current) && master->mode == EC_MASTER_MODE_IDLE) {
         cycles_start = get_cycles();
 
-        // receive
-        spin_lock_bh(&master->internal_lock);
-        ecrt_master_receive(master);
-        spin_unlock_bh(&master->internal_lock);
+        if (ec_fsm_master_running(&master->fsm)) {
+            // receive
+            spin_lock_bh(&master->internal_lock);
+            ecrt_master_receive(master);
+            spin_unlock_bh(&master->internal_lock);
+        }
 
         // execute master state machine
-        ec_fsm_master_exec(&master->fsm);
-
-        // send
-        spin_lock_bh(&master->internal_lock);
-        ecrt_master_send(master);
-        spin_unlock_bh(&master->internal_lock);
+        if (ec_fsm_master_exec(&master->fsm)) {
+            // queue and send
+            ec_master_queue_datagram(master, &master->fsm_datagram);
+            spin_lock_bh(&master->internal_lock);
+            ecrt_master_send(master);
+            spin_unlock_bh(&master->internal_lock);
+        }
         
         cycles_end = get_cycles();
         master->idle_cycle_times[master->idle_cycle_time_pos]
@@ -867,6 +896,52 @@
     complete_and_exit(&master->thread_exit, 0);
 }
 
+/*****************************************************************************/
+
+/**
+ * Master kernel thread function for IDLE mode.
+ */
+
+static int ec_master_operation_thread(ec_master_t *master)
+{
+    cycles_t cycles_start, cycles_end;
+
+    daemonize("EtherCAT-OP");
+    allow_signal(SIGTERM);
+
+    while (!signal_pending(current) &&
+            master->mode == EC_MASTER_MODE_OPERATION) {
+
+        if (master->injection_seq_rt != master->injection_seq_fsm ||
+                master->fsm_datagram.state == EC_DATAGRAM_SENT ||
+                master->fsm_datagram.state == EC_DATAGRAM_QUEUED)
+            goto schedule;
+
+        cycles_start = get_cycles();
+
+        // output statistics
+        ec_master_output_stats(master);
+
+        // execute master state machine
+        if (ec_fsm_master_exec(&master->fsm)) {
+            // inject datagram
+            master->injection_seq_fsm++;
+        }
+
+        cycles_end = get_cycles();
+        master->idle_cycle_times[master->idle_cycle_time_pos]
+            = (u32) (cycles_end - cycles_start) * 1000 / cpu_khz;
+        master->idle_cycle_time_pos++;
+        master->idle_cycle_time_pos %= HZ;
+
+schedule:
+        set_current_state(TASK_INTERRUPTIBLE);
+        schedule_timeout(1);
+    }
+    
+    master->thread_id = 0;
+    complete_and_exit(&master->thread_exit, 0);
+}
 
 /*****************************************************************************/
 
@@ -1401,6 +1476,7 @@
     list_for_each_entry(slave, &master->slaves, list) {
         ec_fsm_slave_start_conf(&fsm_slave, slave);
         while (ec_fsm_slave_exec(&fsm_slave)) { 
+            ec_master_queue_datagram(master, &master->fsm_datagram);
             ec_master_sync_io(master);
         }
 
@@ -1414,6 +1490,14 @@
     ec_fsm_slave_clear(&fsm_slave);
     ec_master_prepare(master); // prepare asynchronous IO
 
+    if (master->debug_level)
+        EC_DBG("FSM datagram is %x.\n", (unsigned int) &master->fsm_datagram);
+
+    if (ec_master_thread_start(master)) {
+        EC_ERR("Failed to start master thread!\n");
+        return -1;
+    }
+
     return 0;
 }
 
@@ -1460,6 +1544,12 @@
 {
     ec_datagram_t *datagram, *n;
 
+    if (master->injection_seq_rt != master->injection_seq_fsm) {
+        // inject datagram produced by master FSM
+        ec_master_queue_datagram(master, &master->fsm_datagram);
+        master->injection_seq_rt = master->injection_seq_fsm;
+    }
+
     if (unlikely(!master->main_device.link_state)) {
         // link is down, no datagram can be sent
         list_for_each_entry_safe(datagram, n, &master->datagram_queue, queue) {
@@ -1510,22 +1600,6 @@
 /*****************************************************************************/
 
 /**
-   Does all cyclic master work.
-   \ingroup RealtimeInterface
-*/
-
-void ecrt_master_run(ec_master_t *master /**< EtherCAT master */)
-{
-    // output statistics
-    ec_master_output_stats(master);
-
-    // execute master state machine in a loop
-    ec_fsm_master_exec(&master->fsm);
-}
-
-/*****************************************************************************/
-
-/**
    Translates an ASCII coded bus-address to a slave pointer.
    These are the valid addressing schemes:
    - \a "X" = the X. slave on the bus,
@@ -1678,7 +1752,6 @@
 EXPORT_SYMBOL(ecrt_master_activate);
 EXPORT_SYMBOL(ecrt_master_send);
 EXPORT_SYMBOL(ecrt_master_receive);
-EXPORT_SYMBOL(ecrt_master_run);
 EXPORT_SYMBOL(ecrt_master_callbacks);
 EXPORT_SYMBOL(ecrt_master_get_slave);
 EXPORT_SYMBOL(ecrt_master_get_status);
--- a/master/master.h	Thu Mar 08 08:10:32 2007 +0000
+++ b/master/master.h	Thu Mar 08 13:02:42 2007 +0000
@@ -109,6 +109,10 @@
     ec_fsm_master_t fsm; /**< master state machine */
     ec_datagram_t fsm_datagram; /**< datagram used for state machines */
     ec_master_mode_t mode; /**< master mode */
+    unsigned int injection_seq_fsm; /**< datagram injection sequence number
+                                      for the FSM side */
+    unsigned int injection_seq_rt; /**< datagram injection sequence number
+                                     for the realtime side */
 
     struct list_head slaves; /**< list of slaves on the bus */
     unsigned int slave_count; /**< number of slaves on the bus */