merged
authorMartin Troxler <ch1010277@ch10lt194>
Mon, 14 Mar 2011 16:57:47 +0100
changeset 2046 4cf0161c445a
parent 2042 8b358effa78b (current diff)
parent 2045 ff2a13a4603c (diff)
child 2047 f4266c6fce7c
merged
master/master.c
--- a/configure.ac	Mon Mar 14 11:20:05 2011 +0100
+++ b/configure.ac	Mon Mar 14 16:57:47 2011 +0100
@@ -513,6 +513,31 @@
 fi
 
 #------------------------------------------------------------------------------
+# Use 2 datagrams (payload+last-byte) when sending to mailbox (reduces frame size)
+#------------------------------------------------------------------------------
+
+AC_ARG_ENABLE([mboxframesize],
+    AS_HELP_STRING([--enable-mboxframesize],
+                   [Reduced frame size when sending to mailbox, uses 2 datagrams (default: no)]),
+    [
+        case "${enableval}" in
+            yes) mboxframesize=1
+                ;;
+            no) mboxframesize=0
+                ;;
+            *) AC_MSG_ERROR([Invalid value for --enable-mboxframesize])
+                ;;
+        esac
+    ],
+    [mboxframesize=0]
+)
+
+if test "x${mboxframesize}" = "x1"; then
+    AC_DEFINE([EC_REDUCE_MBOXFRAMESIZE], [1], [Reduced frame size when sending to mailbox])
+fi
+
+
+#------------------------------------------------------------------------------
 # Read alias address from register
 #------------------------------------------------------------------------------
 
--- a/master/ethernet.c	Mon Mar 14 11:20:05 2011 +0100
+++ b/master/ethernet.c	Mon Mar 14 16:57:47 2011 +0100
@@ -111,6 +111,7 @@
     eoe->slave = slave;
 
     ec_datagram_init(&eoe->datagram);
+    ec_mbox_init(&eoe->mbox,&eoe->datagram);
     eoe->queue_datagram = 0;
     eoe->state = ec_eoe_state_rx_start;
     eoe->opened = 0;
@@ -220,6 +221,7 @@
 
     free_netdev(eoe->dev);
 
+    ec_mbox_clear(&eoe->mbox);
     ec_datagram_clear(&eoe->datagram);
 }
 
@@ -294,7 +296,7 @@
     printk("\n");
 #endif
 
-    data = ec_slave_mbox_prepare_send(eoe->slave, &eoe->datagram,
+    data = ec_slave_mbox_prepare_send(eoe->slave, &eoe->mbox,
             0x02, current_size + 4);
     if (IS_ERR(data))
         return PTR_ERR(data);
@@ -324,7 +326,8 @@
 
     // if the datagram was not sent, or is not yet received, skip this cycle
     if (eoe->queue_datagram ||
-        eoe->datagram.state == EC_DATAGRAM_SENT || eoe->datagram.state == EC_DATAGRAM_QUEUED)
+        ec_mbox_is_datagram_state(&eoe->mbox,EC_DATAGRAM_QUEUED) ||
+        ec_mbox_is_datagram_state(&eoe->mbox,EC_DATAGRAM_SENT))
         return;
 
     // call state function
@@ -349,7 +352,7 @@
 void ec_eoe_queue(ec_eoe_t *eoe /**< EoE handler */)
 {
    if (eoe->queue_datagram) {
-       ec_master_queue_fsm_datagram(eoe->slave->master, &eoe->datagram);
+       ec_master_mbox_queue_datagrams(eoe->slave->master, &eoe->mbox);
        eoe->queue_datagram = 0;
    }
 }
@@ -395,7 +398,7 @@
         return;
     }
 
-    ec_slave_mbox_prepare_check(eoe->slave, &eoe->datagram);
+    ec_slave_mbox_prepare_check(eoe->slave, &eoe->mbox);
     eoe->queue_datagram = 1;
     eoe->state = ec_eoe_state_rx_check;
 }
@@ -409,7 +412,7 @@
  */
 void ec_eoe_state_rx_check(ec_eoe_t *eoe /**< EoE handler */)
 {
-    if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) {
+    if (!ec_mbox_is_datagram_state(&eoe->mbox,EC_DATAGRAM_RECEIVED)) {
         eoe->stats.rx_errors++;
 #if EOE_DEBUG_LEVEL >= 1
         EC_SLAVE_WARN(eoe->slave, "Failed to receive mbox"
@@ -419,14 +422,14 @@
         return;
     }
 
-    if (!ec_slave_mbox_check(&eoe->datagram)) {
+    if (!ec_slave_mbox_check(&eoe->mbox)) {
         eoe->rx_idle = 1;
         eoe->state = ec_eoe_state_tx_start;
         return;
     }
 
     eoe->rx_idle = 0;
-    ec_slave_mbox_prepare_fetch(eoe->slave, &eoe->datagram);
+    ec_slave_mbox_prepare_fetch(eoe->slave, &eoe->mbox);
     eoe->queue_datagram = 1;
     eoe->state = ec_eoe_state_rx_fetch;
 }
@@ -448,7 +451,7 @@
     unsigned int i;
 #endif
 
-    if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) {
+    if (!ec_mbox_is_datagram_state(&eoe->mbox,EC_DATAGRAM_RECEIVED)) {
         eoe->stats.rx_errors++;
 #if EOE_DEBUG_LEVEL >= 1
         EC_SLAVE_WARN(eoe->slave, "Failed to receive mbox"
@@ -458,7 +461,7 @@
         return;
     }
 
-    data = ec_slave_mbox_fetch(eoe->slave, &eoe->datagram,
+    data = ec_slave_mbox_fetch(eoe->slave, &eoe->mbox,
             &mbox_prot, &rec_size);
     if (IS_ERR(data)) {
         eoe->stats.rx_errors++;
@@ -685,7 +688,7 @@
  */
 void ec_eoe_state_tx_sent(ec_eoe_t *eoe /**< EoE handler */)
 {
-    if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) {
+    if (!ec_mbox_is_datagram_state(&eoe->mbox,EC_DATAGRAM_RECEIVED)) {
         if (eoe->tries) {
             eoe->tries--; // try again
             eoe->queue_datagram = 1;
@@ -701,7 +704,7 @@
         return;
     }
 
-    if (eoe->datagram.working_counter != 1) {
+    if (!ec_mbox_is_datagram_wc(&eoe->mbox,1)) {
         if (eoe->tries) {
             eoe->tries--; // try again
             eoe->queue_datagram = 1;
--- a/master/ethernet.h	Mon Mar 14 11:20:05 2011 +0100
+++ b/master/ethernet.h	Mon Mar 14 16:57:47 2011 +0100
@@ -73,6 +73,7 @@
     struct list_head list; /**< list item */
     ec_slave_t *slave; /**< pointer to the corresponding slave */
     ec_datagram_t datagram; /**< datagram */
+    ec_mailbox_t mbox; /**< mailbox */
     unsigned int queue_datagram; /**< the datagram is ready for queuing */
     void (*state)(ec_eoe_t *); /**< state function for the state machine */
     struct net_device *dev; /**< net_device for virtual ethernet device */
--- a/master/fsm_coe.c	Mon Mar 14 11:20:05 2011 +0100
+++ b/master/fsm_coe.c	Mon Mar 14 16:57:47 2011 +0100
@@ -168,11 +168,11 @@
 */
 
 void ec_fsm_coe_init(ec_fsm_coe_t *fsm, /**< finite state machine */
-                     ec_datagram_t *datagram /**< datagram */
+                     ec_mailbox_t *mbox /**< mailbox */
                      )
 {
     fsm->state = NULL;
-    fsm->datagram = datagram;
+    fsm->mbox = mbox;
 }
 
 /*****************************************************************************/
@@ -286,7 +286,7 @@
 
 void ec_fsm_coe_dict_start(ec_fsm_coe_t *fsm /**< finite state machine */)
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
     ec_slave_t *slave = fsm->slave;
     uint8_t *data;
 
@@ -303,7 +303,7 @@
         return;
     }
 
-    data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 8);
+    data = ec_slave_mbox_prepare_send(slave, mbox, 0x03, 8);
     if (IS_ERR(data)) {
         fsm->state = ec_fsm_coe_error;
         return;
@@ -328,13 +328,14 @@
 
 void ec_fsm_coe_dict_request(ec_fsm_coe_t *fsm /**< finite state machine */)
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
+    ec_datagram_t *datagram = mbox->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+    if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && fsm->retries--)
         return; // FIXME: request again?
 
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Failed to receive CoE dictionary"
                 " request datagram: ");
@@ -342,7 +343,7 @@
         return;
     }
 
-    if (datagram->working_counter != 1) {
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Reception of CoE dictionary request failed: ");
         ec_datagram_print_wc_error(datagram);
@@ -351,7 +352,7 @@
 
     fsm->jiffies_start = datagram->jiffies_sent;
 
-    ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+    ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_coe_dict_check;
 }
@@ -364,20 +365,21 @@
 
 void ec_fsm_coe_dict_check(ec_fsm_coe_t *fsm /**< finite state machine */)
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
+    ec_datagram_t *datagram = mbox->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
-        return;
-
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && fsm->retries--)
+        return;
+
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
         ec_datagram_print_state(datagram);
         return;
     }
 
-    if (datagram->working_counter != 1) {
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave,"Reception of CoE mailbox check"
                 " datagram failed: ");
@@ -385,7 +387,7 @@
         return;
     }
 
-    if (!ec_slave_mbox_check(datagram)) {
+    if (!ec_slave_mbox_check(mbox)) {
         unsigned long diff_ms =
             (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
         if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
@@ -395,13 +397,13 @@
             return;
         }
 
-        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+        ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
         fsm->retries = EC_FSM_RETRIES;
         return;
     }
 
     // Fetch response
-    ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
+    ec_slave_mbox_prepare_fetch(slave, mbox); // can not fail.
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_coe_dict_response;
 }
@@ -415,18 +417,21 @@
 
 void ec_fsm_coe_dict_response(ec_fsm_coe_t *fsm /**< finite state machine */)
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
+    ec_datagram_t *datagram = mbox->datagram;
     ec_slave_t *slave = fsm->slave;
     uint8_t *data, mbox_prot;
     size_t rec_size;
     unsigned int sdo_count, i;
     uint16_t sdo_index, fragments_left;
     ec_sdo_t *sdo;
-
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+    bool first_segment;
+    size_t index_list_offset;
+
+    if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && fsm->retries--)
         return; // FIXME: request again?
 
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Failed to receive CoE dictionary"
                 " response datagram: ");
@@ -434,14 +439,14 @@
         return;
     }
 
-    if (datagram->working_counter != 1) {
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Reception of CoE dictionary response failed: ");
         ec_datagram_print_wc_error(datagram);
         return;
     }
 
-    data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size);
+    data = ec_slave_mbox_fetch(slave, mbox, &mbox_prot, &rec_size);
     if (IS_ERR(data)) {
         fsm->state = ec_fsm_coe_error;
         return;
@@ -456,7 +461,7 @@
 
     if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
         // check for CoE response again
-        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+        ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
         fsm->retries = EC_FSM_RETRIES;
         fsm->state = ec_fsm_coe_dict_check;
         return;
@@ -490,7 +495,7 @@
                     " Retrying...\n");
             ec_print_data(data, rec_size);
         }
-        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+        ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
         fsm->retries = EC_FSM_RETRIES;
         fsm->state = ec_fsm_coe_dict_check;
         return;
@@ -503,8 +508,8 @@
         return;
     }
 
-    bool first_segment = list_empty(&slave->sdo_dictionary) ? true : false;
-    size_t index_list_offset = first_segment ? 8 : 6;
+    first_segment = list_empty(&slave->sdo_dictionary) ? true : false;
+    index_list_offset = first_segment ? 8 : 6;
 
     sdo_count = (rec_size - index_list_offset) / 2;
 
@@ -534,7 +539,7 @@
     if (EC_READ_U8(data + 2) & 0x80 || fragments_left) {
         // more messages waiting. check again.
         fsm->jiffies_start = datagram->jiffies_sent;
-        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+        ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
         fsm->retries = EC_FSM_RETRIES;
         fsm->state = ec_fsm_coe_dict_check;
         return;
@@ -549,7 +554,7 @@
     // fetch SDO descriptions
     fsm->sdo = list_entry(slave->sdo_dictionary.next, ec_sdo_t, list);
 
-    data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 8);
+    data = ec_slave_mbox_prepare_send(slave, mbox, 0x03, 8);
     if (IS_ERR(data)) {
         fsm->state = ec_fsm_coe_error;
         return;
@@ -574,13 +579,14 @@
 
 void ec_fsm_coe_dict_desc_request(ec_fsm_coe_t *fsm /**< finite state machine */)
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
+    ec_datagram_t *datagram = mbox->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+    if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && fsm->retries--)
         return; // FIXME: check for response first?
 
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Failed to receive CoE SDO"
                 " description request datagram: ");
@@ -588,7 +594,7 @@
         return;
     }
 
-    if (datagram->working_counter != 1) {
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
                 " request failed: ");
@@ -598,7 +604,7 @@
 
     fsm->jiffies_start = datagram->jiffies_sent;
 
-    ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+    ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_coe_dict_desc_check;
 }
@@ -611,20 +617,21 @@
 
 void ec_fsm_coe_dict_desc_check(ec_fsm_coe_t *fsm /**< finite state machine */)
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
+    ec_datagram_t *datagram = mbox->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
-        return;
-
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && fsm->retries--)
+        return;
+
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
         ec_datagram_print_state(datagram);
         return;
     }
 
-    if (datagram->working_counter != 1) {
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
                 " datagram failed: ");
@@ -632,7 +639,7 @@
         return;
     }
 
-    if (!ec_slave_mbox_check(datagram)) {
+    if (!ec_slave_mbox_check(mbox)) {
         unsigned long diff_ms =
             (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
         if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
@@ -643,13 +650,13 @@
             return;
         }
 
-        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+        ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
         fsm->retries = EC_FSM_RETRIES;
         return;
     }
 
     // Fetch response
-    ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
+    ec_slave_mbox_prepare_fetch(slave, mbox); // can not fail.
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_coe_dict_desc_response;
 }
@@ -664,16 +671,17 @@
 void ec_fsm_coe_dict_desc_response(ec_fsm_coe_t *fsm
                                    /**< finite state machine */)
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
+    ec_datagram_t *datagram = mbox->datagram;
     ec_slave_t *slave = fsm->slave;
     ec_sdo_t *sdo = fsm->sdo;
     uint8_t *data, mbox_prot;
     size_t rec_size, name_size;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+    if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && fsm->retries--)
         return; // FIXME: request again?
 
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Failed to receive CoE SDO description"
                 " response datagram: ");
@@ -681,7 +689,7 @@
         return;
     }
 
-    if (datagram->working_counter != 1) {
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
                 " response failed: ");
@@ -689,7 +697,7 @@
         return;
     }
 
-    data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size);
+    data = ec_slave_mbox_fetch(slave, mbox, &mbox_prot, &rec_size);
     if (IS_ERR(data)) {
         fsm->state = ec_fsm_coe_error;
         return;
@@ -704,7 +712,7 @@
 
     if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
         // check for CoE response again
-        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+        ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
         fsm->retries = EC_FSM_RETRIES;
         fsm->state = ec_fsm_coe_dict_desc_check;
         return;
@@ -742,7 +750,7 @@
             ec_print_data(data, rec_size);
         }
         // check for CoE response again
-        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+        ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
         fsm->retries = EC_FSM_RETRIES;
         fsm->state = ec_fsm_coe_dict_desc_check;
         return;
@@ -780,7 +788,7 @@
 
     fsm->subindex = 0;
 
-    data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 10);
+    data = ec_slave_mbox_prepare_send(slave, mbox, 0x03, 10);
     if (IS_ERR(data)) {
         fsm->state = ec_fsm_coe_error;
         return;
@@ -808,13 +816,14 @@
 void ec_fsm_coe_dict_entry_request(ec_fsm_coe_t *fsm
                                    /**< finite state machine */)
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
+    ec_datagram_t *datagram = mbox->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+    if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && fsm->retries--)
         return; // FIXME: check for response first?
 
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Failed to receive CoE SDO entry"
                 " request datagram: ");
@@ -822,7 +831,7 @@
         return;
     }
 
-    if (datagram->working_counter != 1) {
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Reception of CoE SDO entry request failed: ");
         ec_datagram_print_wc_error(datagram);
@@ -831,7 +840,7 @@
 
     fsm->jiffies_start = datagram->jiffies_sent;
 
-    ec_slave_mbox_prepare_check(slave, datagram); // can not fail
+    ec_slave_mbox_prepare_check(slave, mbox); // can not fail
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_coe_dict_entry_check;
 }
@@ -845,20 +854,21 @@
 void ec_fsm_coe_dict_entry_check(ec_fsm_coe_t *fsm
                                  /**< finite state machine */)
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
+    ec_datagram_t *datagram = mbox->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
-        return;
-
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && fsm->retries--)
+        return;
+
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
         ec_datagram_print_state(datagram);
         return;
     }
 
-    if (datagram->working_counter != 1) {
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
                 " datagram failed: ");
@@ -866,7 +876,7 @@
         return;
     }
 
-    if (!ec_slave_mbox_check(datagram)) {
+    if (!ec_slave_mbox_check(mbox)) {
         unsigned long diff_ms =
             (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
         if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
@@ -877,13 +887,13 @@
             return;
         }
 
-        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+        ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
         fsm->retries = EC_FSM_RETRIES;
         return;
     }
 
     // Fetch response
-    ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
+    ec_slave_mbox_prepare_fetch(slave, mbox); // can not fail.
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_coe_dict_entry_response;
 }
@@ -898,7 +908,8 @@
 void ec_fsm_coe_dict_entry_response(ec_fsm_coe_t *fsm
                                     /**< finite state machine */)
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
+    ec_datagram_t *datagram = mbox->datagram;
     ec_slave_t *slave = fsm->slave;
     ec_sdo_t *sdo = fsm->sdo;
     uint8_t *data, mbox_prot;
@@ -906,10 +917,10 @@
     ec_sdo_entry_t *entry;
     u16 word;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+    if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && fsm->retries--)
         return; // FIXME: request again?
 
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Failed to receive CoE SDO"
                 " description response datagram: ");
@@ -917,7 +928,7 @@
         return;
     }
 
-    if (datagram->working_counter != 1) {
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
                 " response failed: ");
@@ -925,7 +936,7 @@
         return;
     }
 
-    data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size);
+    data = ec_slave_mbox_fetch(slave, mbox, &mbox_prot, &rec_size);
     if (IS_ERR(data)) {
         fsm->state = ec_fsm_coe_error;
         return;
@@ -940,7 +951,7 @@
 
     if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
         // check for CoE response again
-        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+        ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
         fsm->retries = EC_FSM_RETRIES;
         fsm->state = ec_fsm_coe_dict_entry_check;
         return;
@@ -981,7 +992,7 @@
             ec_print_data(data, rec_size);
         }
         // check for CoE response again
-        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+        ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
         fsm->retries = EC_FSM_RETRIES;
         fsm->state = ec_fsm_coe_dict_entry_check;
         return;
@@ -1033,7 +1044,7 @@
     if (fsm->subindex < sdo->max_subindex) {
         fsm->subindex++;
 
-        data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 10);
+        data = ec_slave_mbox_prepare_send(slave, mbox, 0x03, 10);
         if (IS_ERR(data)) {
             fsm->state = ec_fsm_coe_error;
             return;
@@ -1056,7 +1067,7 @@
     if (fsm->sdo->list.next != &slave->sdo_dictionary) {
         fsm->sdo = list_entry(fsm->sdo->list.next, ec_sdo_t, list);
 
-        data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 8);
+        data = ec_slave_mbox_prepare_send(slave, mbox, 0x03, 8);
         if (IS_ERR(data)) {
             fsm->state = ec_fsm_coe_error;
             return;
@@ -1086,7 +1097,7 @@
         ec_fsm_coe_t *fsm /**< finite state machine */
         )
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
     ec_slave_t *slave = fsm->slave;
     ec_sdo_request_t *request = fsm->request;
     uint8_t *data;
@@ -1120,7 +1131,7 @@
     }
 
     if (request->data_size <= 4) { // use expedited transfer type
-        data = ec_slave_mbox_prepare_send(slave, datagram, 0x03,
+        data = ec_slave_mbox_prepare_send(slave, mbox, 0x03,
                 EC_COE_DOWN_REQ_HEADER_SIZE);
         if (IS_ERR(data)) {
             request->errno = PTR_ERR(data);
@@ -1162,7 +1173,7 @@
             data_size = required_data_size;
         }
 
-        data = ec_slave_mbox_prepare_send(slave, datagram, 0x03,
+        data = ec_slave_mbox_prepare_send(slave, mbox, 0x03,
                 data_size);
         if (IS_ERR(data)) {
             request->errno = PTR_ERR(data);
@@ -1211,14 +1222,15 @@
 
 void ec_fsm_coe_down_request(ec_fsm_coe_t *fsm /**< finite state machine */)
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
+    ec_datagram_t *datagram = mbox->datagram;
     ec_slave_t *slave = fsm->slave;
     unsigned long diff_ms;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+    if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && fsm->retries--)
         return; // FIXME: check for response first?
 
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         fsm->request->errno = EIO;
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Failed to receive CoE download"
@@ -1229,8 +1241,8 @@
 
     diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
 
-    if (datagram->working_counter != 1) {
-        if (!datagram->working_counter) {
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
+        if (ec_mbox_is_datagram_wc(mbox,0)) {
             if (diff_ms < fsm->request->response_timeout) {
 #if DEBUG_RETRIES
                 EC_SLAVE_DBG(slave, 1, "Slave did not respond to SDO"
@@ -1259,7 +1271,7 @@
 
     fsm->jiffies_start = datagram->jiffies_sent;
 
-    ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+    ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_coe_down_check;
 }
@@ -1270,13 +1282,14 @@
  */
 void ec_fsm_coe_down_check(ec_fsm_coe_t *fsm /**< finite state machine */)
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
+    ec_datagram_t *datagram = mbox->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
-        return;
-
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && fsm->retries--)
+        return;
+
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         fsm->request->errno = EIO;
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check"
@@ -1285,7 +1298,7 @@
         return;
     }
 
-    if (datagram->working_counter != 1) {
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         fsm->request->errno = EIO;
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
@@ -1294,7 +1307,7 @@
         return;
     }
 
-    if (!ec_slave_mbox_check(datagram)) {
+    if (!ec_slave_mbox_check(mbox)) {
         unsigned long diff_ms =
             (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
         if (diff_ms >= fsm->request->response_timeout) {
@@ -1306,13 +1319,13 @@
             return;
         }
 
-        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+        ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
         fsm->retries = EC_FSM_RETRIES;
         return;
     }
 
     // Fetch response
-    ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
+    ec_slave_mbox_prepare_fetch(slave, mbox); // can not fail.
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_coe_down_response;
 }
@@ -1325,7 +1338,7 @@
         ec_fsm_coe_t *fsm /**< finite state machine */
         )
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
     ec_slave_t *slave = fsm->slave;
     ec_sdo_request_t *request = fsm->request;
     size_t max_segment_size =
@@ -1352,7 +1365,7 @@
             + EC_COE_DOWN_SEG_MIN_DATA_SIZE;
     }
 
-    data = ec_slave_mbox_prepare_send(slave, datagram, 0x03,
+    data = ec_slave_mbox_prepare_send(slave, mbox, 0x03,
             data_size);
     if (IS_ERR(data)) {
         request->errno = PTR_ERR(data);
@@ -1392,16 +1405,17 @@
 
 void ec_fsm_coe_down_response(ec_fsm_coe_t *fsm /**< finite state machine */)
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
+    ec_datagram_t *datagram = datagram;
     ec_slave_t *slave = fsm->slave;
     uint8_t *data, mbox_prot;
     size_t rec_size;
     ec_sdo_request_t *request = fsm->request;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+    if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && fsm->retries--)
         return; // FIXME: request again?
 
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         request->errno = EIO;
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Failed to receive CoE download"
@@ -1410,7 +1424,7 @@
         return;
     }
 
-    if (datagram->working_counter != 1) {
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         request->errno = EIO;
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Reception of CoE download response failed: ");
@@ -1418,7 +1432,7 @@
         return;
     }
 
-    data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size);
+    data = ec_slave_mbox_fetch(slave, mbox, &mbox_prot, &rec_size);
     if (IS_ERR(data)) {
         request->errno = PTR_ERR(data);
         fsm->state = ec_fsm_coe_error;
@@ -1435,7 +1449,7 @@
 
     if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
         // check for CoE response again
-        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+        ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
         fsm->retries = EC_FSM_RETRIES;
         fsm->state = ec_fsm_coe_down_check;
         return;
@@ -1487,7 +1501,7 @@
             ec_print_data(data, rec_size);
         }
         // check for CoE response again
-        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+        ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
         fsm->retries = EC_FSM_RETRIES;
         fsm->state = ec_fsm_coe_down_check;
         return;
@@ -1509,13 +1523,14 @@
 
 void ec_fsm_coe_down_seg_check(ec_fsm_coe_t *fsm /**< finite state machine */)
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
+    ec_datagram_t *datagram = mbox->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
-        return;
-
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && fsm->retries--)
+        return;
+
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         fsm->request->errno = EIO;
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
@@ -1523,7 +1538,7 @@
         return;
     }
 
-    if (datagram->working_counter != 1) {
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         fsm->request->errno = EIO;
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Reception of CoE mailbox segment check"
@@ -1532,7 +1547,7 @@
         return;
     }
 
-    if (!ec_slave_mbox_check(datagram)) {
+    if (!ec_slave_mbox_check(mbox)) {
         unsigned long diff_ms =
             (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
         if (diff_ms >= fsm->request->response_timeout) {
@@ -1543,13 +1558,13 @@
             return;
         }
 
-        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+        ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
         fsm->retries = EC_FSM_RETRIES;
         return;
     }
 
     // Fetch response
-    ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
+    ec_slave_mbox_prepare_fetch(slave, mbox); // can not fail.
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_coe_down_seg_response;
 }
@@ -1565,16 +1580,17 @@
         ec_fsm_coe_t *fsm /**< finite state machine */
         )
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
+    ec_datagram_t *datagram = mbox->datagram;
     ec_slave_t *slave = fsm->slave;
     uint8_t *data, mbox_prot;
     size_t rec_size;
     ec_sdo_request_t *request = fsm->request;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+    if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && fsm->retries--)
         return; // FIXME: request again?
 
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         request->errno = EIO;
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Failed to receive CoE download response"
@@ -1583,7 +1599,7 @@
         return;
     }
 
-    if (datagram->working_counter != 1) {
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         request->errno = EIO;
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Reception of CoE download response failed: ");
@@ -1591,7 +1607,7 @@
         return;
     }
 
-    data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size);
+    data = ec_slave_mbox_fetch(slave, mbox, &mbox_prot, &rec_size);
     if (IS_ERR(data)) {
         request->errno = PTR_ERR(data);
         fsm->state = ec_fsm_coe_error;
@@ -1608,7 +1624,7 @@
 
     if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
         // check for CoE response again
-        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+        ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
         fsm->retries = EC_FSM_RETRIES;
         fsm->state = ec_fsm_coe_down_check;
         return;
@@ -1658,7 +1674,7 @@
             ec_print_data(data, rec_size);
         }
         // check for CoE response again
-        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+        ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
         fsm->retries = EC_FSM_RETRIES;
         fsm->state = ec_fsm_coe_down_seg_check;
         return;
@@ -1689,7 +1705,7 @@
 
 void ec_fsm_coe_up_start(ec_fsm_coe_t *fsm /**< finite state machine */)
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
     ec_slave_t *slave = fsm->slave;
     ec_master_t *master = slave->master;
     ec_sdo_request_t *request = fsm->request;
@@ -1705,7 +1721,7 @@
         return;
     }
 
-    data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 10);
+    data = ec_slave_mbox_prepare_send(slave, mbox, 0x03, 10);
     if (IS_ERR(data)) {
         request->errno = PTR_ERR(data);
         fsm->state = ec_fsm_coe_error;
@@ -1737,14 +1753,15 @@
 
 void ec_fsm_coe_up_request(ec_fsm_coe_t *fsm /**< finite state machine */)
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
+    ec_datagram_t *datagram = mbox->datagram;
     ec_slave_t *slave = fsm->slave;
     unsigned long diff_ms;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+    if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && fsm->retries--)
         return; // FIXME: check for response first?
 
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         fsm->request->errno = EIO;
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Failed to receive CoE upload request: ");
@@ -1754,8 +1771,8 @@
 
     diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
 
-    if (datagram->working_counter != 1) {
-        if (!datagram->working_counter) {
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
+        if (ec_mbox_is_datagram_wc(mbox,0)) {
             if (diff_ms < fsm->request->response_timeout) {
 #if DEBUG_RETRIES
                 EC_SLAVE_DBG(slave, 1, "Slave did not respond to"
@@ -1784,7 +1801,7 @@
 
     fsm->jiffies_start = datagram->jiffies_sent;
 
-    ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+    ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_coe_up_check;
 }
@@ -1797,13 +1814,14 @@
 
 void ec_fsm_coe_up_check(ec_fsm_coe_t *fsm /**< finite state machine */)
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
+    ec_datagram_t *datagram = mbox->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
-        return;
-
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && fsm->retries--)
+        return;
+
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         fsm->request->errno = EIO;
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
@@ -1811,7 +1829,7 @@
         return;
     }
 
-    if (datagram->working_counter != 1) {
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         fsm->request->errno = EIO;
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
@@ -1820,7 +1838,7 @@
         return;
     }
 
-    if (!ec_slave_mbox_check(datagram)) {
+    if (!ec_slave_mbox_check(mbox)) {
         unsigned long diff_ms =
             (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
         if (diff_ms >= fsm->request->response_timeout) {
@@ -1832,13 +1850,13 @@
             return;
         }
 
-        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+        ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
         fsm->retries = EC_FSM_RETRIES;
         return;
     }
 
     // Fetch response
-    ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
+    ec_slave_mbox_prepare_fetch(slave, mbox); // can not fail.
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_coe_up_response;
 }
@@ -1852,7 +1870,7 @@
         )
 {
     uint8_t *data =
-        ec_slave_mbox_prepare_send(fsm->slave, fsm->datagram, 0x03, 10);
+        ec_slave_mbox_prepare_send(fsm->slave, fsm->mbox, 0x03, 10);
     if (IS_ERR(data)) {
         fsm->request->errno = PTR_ERR(data);
         fsm->state = ec_fsm_coe_error;
@@ -1879,7 +1897,8 @@
 
 void ec_fsm_coe_up_response(ec_fsm_coe_t *fsm /**< finite state machine */)
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
+    ec_datagram_t *datagram = mbox->datagram;
     ec_slave_t *slave = fsm->slave;
     ec_master_t *master = slave->master;
     uint16_t rec_index;
@@ -1889,10 +1908,10 @@
     unsigned int expedited, size_specified;
     int ret;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+    if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && fsm->retries--)
         return; // FIXME: request again?
 
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         request->errno = EIO;
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Failed to receive CoE upload response"
@@ -1901,7 +1920,7 @@
         return;
     }
 
-    if (datagram->working_counter != 1) {
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         request->errno = EIO;
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Reception of CoE upload response failed: ");
@@ -1909,7 +1928,7 @@
         return;
     }
 
-    data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size);
+    data = ec_slave_mbox_fetch(slave, mbox, &mbox_prot, &rec_size);
     if (IS_ERR(data)) {
         request->errno = PTR_ERR(data);
         fsm->state = ec_fsm_coe_error;
@@ -1931,7 +1950,7 @@
 
     if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
         // check for CoE response again
-        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+        ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
         fsm->retries = EC_FSM_RETRIES;
         fsm->state = ec_fsm_coe_up_check;
         return;
@@ -1982,7 +2001,7 @@
         ec_print_data(data, rec_size);
 
         // check for CoE response again
-        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+        ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
         fsm->retries = EC_FSM_RETRIES;
         fsm->state = ec_fsm_coe_up_check;
         return;
@@ -2078,13 +2097,14 @@
 
 void ec_fsm_coe_up_seg_request(ec_fsm_coe_t *fsm /**< finite state machine */)
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
+    ec_datagram_t *datagram = mbox->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+    if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && fsm->retries--)
         return; // FIXME: check for response first?
 
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         fsm->request->errno = EIO;
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Failed to receive CoE upload segment"
@@ -2093,7 +2113,7 @@
         return;
     }
 
-    if (datagram->working_counter != 1) {
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         fsm->request->errno = EIO;
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Reception of CoE upload segment"
@@ -2104,7 +2124,7 @@
 
     fsm->jiffies_start = datagram->jiffies_sent;
 
-    ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+    ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_coe_up_seg_check;
 }
@@ -2117,13 +2137,14 @@
 
 void ec_fsm_coe_up_seg_check(ec_fsm_coe_t *fsm /**< finite state machine */)
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
+    ec_datagram_t *datagram = mbox->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
-        return;
-
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && fsm->retries--)
+        return;
+
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         fsm->request->errno = EIO;
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check"
@@ -2132,7 +2153,7 @@
         return;
     }
 
-    if (datagram->working_counter != 1) {
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         fsm->request->errno = EIO;
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Reception of CoE mailbox check datagram"
@@ -2141,7 +2162,7 @@
         return;
     }
 
-    if (!ec_slave_mbox_check(datagram)) {
+    if (!ec_slave_mbox_check(mbox)) {
         unsigned long diff_ms =
             (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
         if (diff_ms >= fsm->request->response_timeout) {
@@ -2152,13 +2173,13 @@
             return;
         }
 
-        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+        ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
         fsm->retries = EC_FSM_RETRIES;
         return;
     }
 
     // Fetch response
-    ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
+    ec_slave_mbox_prepare_fetch(slave, mbox); // can not fail.
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_coe_up_seg_response;
 }
@@ -2172,7 +2193,8 @@
 
 void ec_fsm_coe_up_seg_response(ec_fsm_coe_t *fsm /**< finite state machine */)
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
+    ec_datagram_t *datagram = mbox->datagram;
     ec_slave_t *slave = fsm->slave;
     ec_master_t *master = slave->master;
     uint8_t *data, mbox_prot;
@@ -2180,10 +2202,10 @@
     ec_sdo_request_t *request = fsm->request;
     unsigned int last_segment;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+    if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && fsm->retries--)
         return; // FIXME: request again?
 
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         request->errno = EIO;
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Failed to receive CoE upload segment"
@@ -2192,7 +2214,7 @@
         return;
     }
 
-    if (datagram->working_counter != 1) {
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         request->errno = EIO;
         fsm->state = ec_fsm_coe_error;
         EC_SLAVE_ERR(slave, "Reception of CoE upload segment"
@@ -2201,7 +2223,7 @@
         return;
     }
 
-    data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size);
+    data = ec_slave_mbox_fetch(slave, mbox, &mbox_prot, &rec_size);
     if (IS_ERR(data)) {
         request->errno = PTR_ERR(data);
         fsm->state = ec_fsm_coe_error;
@@ -2223,7 +2245,7 @@
 
     if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
         // check for CoE response again
-        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+        ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
         fsm->retries = EC_FSM_RETRIES;
         fsm->state = ec_fsm_coe_up_seg_check;
         return;
@@ -2256,7 +2278,7 @@
             ec_print_data(data, rec_size);
         }
         // check for CoE response again
-        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+        ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
         fsm->retries = EC_FSM_RETRIES;
         fsm->state = ec_fsm_coe_up_seg_check;
         return;
--- a/master/fsm_coe.h	Mon Mar 14 11:20:05 2011 +0100
+++ b/master/fsm_coe.h	Mon Mar 14 16:57:47 2011 +0100
@@ -39,6 +39,7 @@
 
 #include "globals.h"
 #include "datagram.h"
+#include "mailbox.h"
 #include "slave.h"
 #include "sdo.h"
 #include "sdo_request.h"
@@ -51,7 +52,7 @@
  */
 struct ec_fsm_coe {
     ec_slave_t *slave; /**< slave the FSM runs on */
-    ec_datagram_t *datagram; /**< datagram used in the state machine */
+    ec_mailbox_t *mbox; /**< mailbox used in the state machine */
     unsigned int retries; /**< retries upon datagram timeout */
 
     void (*state)(ec_fsm_coe_t *); /**< CoE state function */
@@ -67,7 +68,7 @@
 
 /*****************************************************************************/
 
-void ec_fsm_coe_init(ec_fsm_coe_t *, ec_datagram_t *);
+void ec_fsm_coe_init(ec_fsm_coe_t *, ec_mailbox_t *);
 void ec_fsm_coe_clear(ec_fsm_coe_t *);
 
 void ec_fsm_coe_dictionary(ec_fsm_coe_t *, ec_slave_t *);
--- a/master/fsm_foe.c	Mon Mar 14 11:20:05 2011 +0100
+++ b/master/fsm_foe.c	Mon Mar 14 16:57:47 2011 +0100
@@ -107,11 +107,11 @@
 /** Constructor.
  */
 void ec_fsm_foe_init(ec_fsm_foe_t *fsm, /**< finite state machine */
-                     ec_datagram_t *datagram /**< datagram */
+                     ec_mailbox_t *mbox /**< mailbox */
                      )
 {
-    fsm->state     = NULL;
-    fsm->datagram  = datagram;
+    fsm->state = NULL;
+    fsm->mbox  = mbox;
 }
 
 /*****************************************************************************/
@@ -207,7 +207,7 @@
     }
 
     data = ec_slave_mbox_prepare_send(fsm->slave,
-            fsm->datagram, EC_MBOX_TYPE_FILEACCESS,
+            fsm->mbox,EC_MBOX_TYPE_FILEACCESS,
             current_size + EC_FOE_HEADER_SIZE);
     if (IS_ERR(data))
         return -1;
@@ -238,7 +238,7 @@
 
     current_size = fsm->tx_filename_len;
 
-    data = ec_slave_mbox_prepare_send(fsm->slave, fsm->datagram,
+    data = ec_slave_mbox_prepare_send(fsm->slave, fsm->mbox,
             EC_MBOX_TYPE_FILEACCESS, current_size + EC_FOE_HEADER_SIZE);
     if (IS_ERR(data))
         return -1;
@@ -308,21 +308,22 @@
         ec_fsm_foe_t *fsm /**< FoE statemachine. */
         )
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
+    ec_datagram_t *datagram = mbox->datagram;
     ec_slave_t *slave = fsm->slave;
 
 #ifdef DEBUG_FOE
     printk("ec_fsm_foe_ack_check()\n");
 #endif
 
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
         EC_SLAVE_ERR(slave, "Failed to receive FoE mailbox check datagram: ");
         ec_datagram_print_state(datagram);
         return;
     }
 
-    if (datagram->working_counter != 1) {
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         // slave did not put anything in the mailbox yet
         ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
         EC_SLAVE_ERR(slave, "Reception of FoE mailbox check datagram"
@@ -331,7 +332,7 @@
         return;
     }
 
-    if (!ec_slave_mbox_check(datagram)) {
+    if (!ec_slave_mbox_check(mbox)) {
         unsigned long diff_ms =
             (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
         if (diff_ms >= EC_FSM_FOE_TIMEOUT) {
@@ -340,13 +341,13 @@
             return;
         }
 
-        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+        ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
         fsm->retries = EC_FSM_RETRIES;
         return;
     }
 
     // Fetch response
-    ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
+    ec_slave_mbox_prepare_fetch(slave, mbox); // can not fail.
 
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_foe_state_ack_read;
@@ -360,7 +361,8 @@
         ec_fsm_foe_t *fsm /**< FoE statemachine. */
         )
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
+    ec_datagram_t *datagram = mbox->datagram;
     ec_slave_t *slave = fsm->slave;
     uint8_t *data, mbox_prot;
     uint8_t opCode;
@@ -370,21 +372,21 @@
     printk("ec_fsm_foe_ack_read()\n");
 #endif
 
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
         EC_SLAVE_ERR(slave, "Failed to receive FoE ack response datagram: ");
         ec_datagram_print_state(datagram);
         return;
     }
 
-    if (datagram->working_counter != 1) {
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
         EC_SLAVE_ERR(slave, "Reception of FoE ack response failed: ");
         ec_datagram_print_wc_error(datagram);
         return;
     }
 
-    if (!(data = ec_slave_mbox_fetch(fsm->slave, datagram,
+    if (!(data = ec_slave_mbox_fetch(fsm->slave, fsm->mbox,
                     &mbox_prot, &rec_size))) {
         ec_foe_set_tx_error(fsm, FOE_PROT_ERROR);
         return;
@@ -440,21 +442,22 @@
         ec_fsm_foe_t *fsm /**< FoE statemachine. */
         )
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
+    ec_datagram_t *datagram = mbox->datagram;
     ec_slave_t *slave = fsm->slave;
 
 #ifdef DEBUG_FOE
     printk("ec_foe_state_sent_wrq()\n");
 #endif
 
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
         EC_SLAVE_ERR(slave, "Failed to send FoE WRQ: ");
         ec_datagram_print_state(datagram);
         return;
     }
 
-    if (datagram->working_counter != 1) {
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         // slave did not put anything in the mailbox yet
         ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
         EC_SLAVE_ERR(slave, "Reception of FoE WRQ failed: ");
@@ -464,7 +467,7 @@
 
     fsm->jiffies_start = datagram->jiffies_sent;
 
-    ec_slave_mbox_prepare_check(fsm->slave, datagram); // can not fail.
+    ec_slave_mbox_prepare_check(fsm->slave, fsm->mbox); // can not fail.
 
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_foe_state_ack_check;
@@ -481,28 +484,29 @@
         ec_fsm_foe_t *fsm /**< Foe statemachine. */
         )
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
+    ec_datagram_t *datagram = mbox->datagram;
     ec_slave_t *slave = fsm->slave;
 
 #ifdef DEBUG_FOE
     printk("ec_fsm_foe_state_data_sent()\n");
 #endif
 
-    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         ec_foe_set_tx_error(fsm, FOE_RECEIVE_ERROR);
         EC_SLAVE_ERR(slave, "Failed to receive FoE ack response datagram: ");
         ec_datagram_print_state(datagram);
         return;
     }
 
-    if (fsm->datagram->working_counter != 1) {
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         ec_foe_set_tx_error(fsm, FOE_WC_ERROR);
         EC_SLAVE_ERR(slave, "Reception of FoE data send failed: ");
         ec_datagram_print_wc_error(datagram);
         return;
     }
 
-    ec_slave_mbox_prepare_check(fsm->slave, fsm->datagram);
+    ec_slave_mbox_prepare_check(slave, mbox);
     fsm->jiffies_start = jiffies;
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_foe_state_ack_check;
@@ -519,7 +523,7 @@
 
     current_size = fsm->rx_filename_len;
 
-    data = ec_slave_mbox_prepare_send(fsm->slave, fsm->datagram,
+    data = ec_slave_mbox_prepare_send(fsm->slave, fsm->mbox,
             EC_MBOX_TYPE_FILEACCESS, current_size + EC_FOE_HEADER_SIZE);
     if (IS_ERR(data))
         return -1;
@@ -546,7 +550,7 @@
 {
     uint8_t *data;
 
-    data = ec_slave_mbox_prepare_send(foe->slave, foe->datagram,
+    data = ec_slave_mbox_prepare_send(foe->slave, foe->mbox,
             EC_MBOX_TYPE_FILEACCESS, EC_FOE_HEADER_SIZE);
     if (IS_ERR(data))
         return -1;
@@ -568,21 +572,22 @@
         ec_fsm_foe_t *fsm /**< FoE statemachine. */
         )
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
+    ec_datagram_t *datagram = mbox->datagram;
     ec_slave_t *slave = fsm->slave;
 
 #ifdef DEBUG_FOE
     printk("ec_foe_state_rrq_sent()\n");
 #endif
 
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
         EC_SLAVE_ERR(slave, "Failed to send FoE RRQ: ");
         ec_datagram_print_state(datagram);
         return;
     }
 
-    if (datagram->working_counter != 1) {
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         // slave did not put anything in the mailbox yet
         ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
         EC_SLAVE_ERR(slave, "Reception of FoE RRQ failed: ");
@@ -592,7 +597,7 @@
 
     fsm->jiffies_start = datagram->jiffies_sent;
 
-    ec_slave_mbox_prepare_check(fsm->slave, datagram); // can not fail.
+    ec_slave_mbox_prepare_check(fsm->slave, fsm->mbox); // can not fail.
 
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_foe_state_data_check;
@@ -657,28 +662,29 @@
         ec_fsm_foe_t *fsm /**< FoE statemachine. */
         )
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
+    ec_datagram_t *datagram = mbox->datagram;
     ec_slave_t *slave = fsm->slave;
 
 #ifdef DEBUG_FOE
     printk("ec_fsm_foe_state_data_check()\n");
 #endif
 
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
         EC_SLAVE_ERR(slave, "Failed to send FoE DATA READ: ");
         ec_datagram_print_state(datagram);
         return;
     }
 
-    if (datagram->working_counter != 1) {
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
         EC_SLAVE_ERR(slave, "Reception of FoE DATA READ: ");
         ec_datagram_print_wc_error(datagram);
         return;
     }
 
-    if (!ec_slave_mbox_check(datagram)) {
+    if (!ec_slave_mbox_check(mbox)) {
         unsigned long diff_ms =
             (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
         if (diff_ms >= EC_FSM_FOE_TIMEOUT) {
@@ -687,13 +693,13 @@
             return;
         }
 
-        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+        ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
         fsm->retries = EC_FSM_RETRIES;
         return;
     }
 
     // Fetch response
-    ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
+    ec_slave_mbox_prepare_fetch(slave, mbox); // can not fail.
 
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_foe_state_data_read;
@@ -711,28 +717,29 @@
     size_t rec_size;
     uint8_t *data, opCode, packet_no, mbox_prot;
 
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
+    ec_datagram_t *datagram = mbox->datagram;
     ec_slave_t *slave = fsm->slave;
 
 #ifdef DEBUG_FOE
     printk("ec_fsm_foe_state_data_read()\n");
 #endif
 
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
         EC_SLAVE_ERR(slave, "Failed to receive FoE DATA READ datagram: ");
         ec_datagram_print_state(datagram);
         return;
     }
 
-    if (datagram->working_counter != 1) {
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
         EC_SLAVE_ERR(slave, "Reception of FoE DATA READ failed: ");
         ec_datagram_print_wc_error(datagram);
         return;
     }
 
-    if (!(data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size))) {
+    if (!(data = ec_slave_mbox_fetch(slave, mbox, &mbox_prot, &rec_size))) {
         ec_foe_set_rx_error(fsm, FOE_MBOX_FETCH_ERROR);
         return;
     }
@@ -831,21 +838,22 @@
         ec_fsm_foe_t *fsm /**< FoE statemachine. */
         )
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
+    ec_datagram_t *datagram = mbox->datagram;
     ec_slave_t *slave = fsm->slave;
 
 #ifdef DEBUG_FOE
     printk("ec_foe_state_sent_ack()\n");
 #endif
 
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
         EC_SLAVE_ERR(slave, "Failed to send FoE ACK: ");
         ec_datagram_print_state(datagram);
         return;
     }
 
-    if (datagram->working_counter != 1) {
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         // slave did not put anything into the mailbox yet
         ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
         EC_SLAVE_ERR(slave, "Reception of FoE ACK failed: ");
@@ -855,7 +863,7 @@
 
     fsm->jiffies_start = datagram->jiffies_sent;
 
-    ec_slave_mbox_prepare_check(fsm->slave, datagram); // can not fail.
+    ec_slave_mbox_prepare_check(fsm->slave, fsm->mbox); // can not fail.
 
     if (fsm->rx_last_packet) {
         fsm->rx_expected_packet_no = 0;
--- a/master/fsm_foe.h	Mon Mar 14 11:20:05 2011 +0100
+++ b/master/fsm_foe.h	Mon Mar 14 16:57:47 2011 +0100
@@ -51,7 +51,7 @@
  */
 struct ec_fsm_foe {
     ec_slave_t *slave; /**< slave the FSM runs on */
-    ec_datagram_t *datagram; /**< datagram used in the state machine */
+    ec_mailbox_t *mbox; /**< mailbox used in the state machine */
     unsigned int retries; /**< retries upon datagram timeout */
 
     void (*state)(ec_fsm_foe_t *); /**< FoE state function */
@@ -80,7 +80,7 @@
 
 /*****************************************************************************/
 
-void ec_fsm_foe_init(ec_fsm_foe_t *, ec_datagram_t *);
+void ec_fsm_foe_init(ec_fsm_foe_t *, ec_mailbox_t *);
 void ec_fsm_foe_clear(ec_fsm_foe_t *);
 
 int ec_fsm_foe_exec(ec_fsm_foe_t *);
--- a/master/fsm_master.c	Mon Mar 14 11:20:05 2011 +0100
+++ b/master/fsm_master.c	Mon Mar 14 16:57:47 2011 +0100
@@ -85,6 +85,7 @@
 {
     fsm->master = master;
     fsm->datagram = datagram;
+    fsm->mbox = &master->fsm_mbox;
     fsm->state = ec_fsm_master_state_start;
     fsm->idle = 0;
     fsm->link_state = 0;
@@ -93,7 +94,7 @@
     fsm->slave_states = EC_SLAVE_STATE_UNKNOWN;
 
     // init sub-state-machines
-    ec_fsm_coe_init(&fsm->fsm_coe, fsm->datagram);
+    ec_fsm_coe_init(&fsm->fsm_coe, fsm->mbox);
     ec_fsm_pdo_init(&fsm->fsm_pdo, &fsm->fsm_coe);
     ec_fsm_change_init(&fsm->fsm_change, fsm->datagram);
     ec_fsm_slave_config_init(&fsm->fsm_slave_config, fsm->datagram,
@@ -133,12 +134,11 @@
         ec_fsm_master_t *fsm /**< Master state machine. */
         )
 {
-    if (fsm->datagram->state == EC_DATAGRAM_SENT
-        || fsm->datagram->state == EC_DATAGRAM_QUEUED) {
+    if (ec_mbox_is_datagram_state(fsm->mbox,EC_DATAGRAM_QUEUED)
+        || ec_mbox_is_datagram_state(fsm->mbox,EC_DATAGRAM_SENT)) {
         // datagram was not sent or received yet.
         return 0;
     }
-
     fsm->state(fsm);
     return 1;
 }
--- a/master/fsm_master.h	Mon Mar 14 11:20:05 2011 +0100
+++ b/master/fsm_master.h	Mon Mar 14 16:57:47 2011 +0100
@@ -39,6 +39,7 @@
 
 #include "globals.h"
 #include "datagram.h"
+#include "mailbox.h"
 #include "foe_request.h"
 #include "sdo_request.h"
 #include "soe_request.h"
@@ -127,6 +128,7 @@
 struct ec_fsm_master {
     ec_master_t *master; /**< master the FSM runs on */
     ec_datagram_t *datagram; /**< datagram used in the state machine */
+    ec_mailbox_t* mbox; /**< mailbox used in the CoE state machine */
     unsigned int retries; /**< retries on datagram timeout. */
 
     void (*state)(ec_fsm_master_t *); /**< master state function */
--- a/master/fsm_slave.c	Mon Mar 14 11:20:05 2011 +0100
+++ b/master/fsm_slave.c	Mon Mar 14 16:57:47 2011 +0100
@@ -57,21 +57,21 @@
 void ec_fsm_slave_init(
         ec_fsm_slave_t *fsm, /**< Slave state machine. */
         ec_slave_t *slave, /**< EtherCAT slave. */
-        ec_datagram_t *datagram /**< Datagram object to use. */
+        ec_mailbox_t *mbox/**< Datagram object to use. */
         )
 {
     fsm->slave = slave;
-    fsm->datagram = datagram;
-    fsm->datagram->data_size = 0;
+    fsm->mbox = mbox;
+    slave->datagram.data_size = 0;
 
     EC_SLAVE_DBG(slave, 1, "Init FSM.\n");
 
     fsm->state = ec_fsm_slave_state_idle;
 
     // init sub-state-machines
-    ec_fsm_coe_init(&fsm->fsm_coe, fsm->datagram);
-    ec_fsm_foe_init(&fsm->fsm_foe, fsm->datagram);
-    ec_fsm_soe_init(&fsm->fsm_soe, fsm->datagram);
+    ec_fsm_coe_init(&fsm->fsm_coe, fsm->mbox);
+    ec_fsm_foe_init(&fsm->fsm_foe, fsm->mbox);
+    ec_fsm_soe_init(&fsm->fsm_soe, fsm->mbox);
 }
 
 /*****************************************************************************/
@@ -101,8 +101,8 @@
         ec_fsm_slave_t *fsm /**< Slave state machine. */
         )
 {
-    if (fsm->datagram->state == EC_DATAGRAM_SENT
-        || fsm->datagram->state == EC_DATAGRAM_QUEUED) {
+    if (ec_mbox_is_datagram_state(fsm->mbox,EC_DATAGRAM_QUEUED)
+        || ec_mbox_is_datagram_state(fsm->mbox,EC_DATAGRAM_SENT)) {
         // datagram was not sent or received yet.
         return 0;
     }
@@ -208,7 +208,7 @@
         fsm->state = ec_fsm_slave_state_sdo_request;
         ec_fsm_coe_transfer(&fsm->fsm_coe, slave, &request->req);
         ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately
-        ec_master_queue_request_fsm_datagram(fsm->slave->master,fsm->datagram);
+        ec_slave_mbox_queue_datagrams(slave, fsm->mbox);
         return 1;
     }
     return 0;
@@ -227,7 +227,7 @@
 
     if (ec_fsm_coe_exec(&fsm->fsm_coe))
     {
-        ec_master_queue_request_fsm_datagram(fsm->slave->master,fsm->datagram);
+        ec_slave_mbox_queue_datagrams(slave, fsm->mbox);
         return;
     }
     if (!ec_fsm_coe_success(&fsm->fsm_coe)) {
@@ -285,7 +285,7 @@
         fsm->state = ec_fsm_slave_state_foe_request;
         ec_fsm_foe_transfer(&fsm->fsm_foe, slave, &request->req);
         ec_fsm_foe_exec(&fsm->fsm_foe);
-        ec_master_queue_request_fsm_datagram(fsm->slave->master,fsm->datagram);
+        ec_slave_mbox_queue_datagrams(slave, fsm->mbox);
         return 1;
     }
     return 0;
@@ -304,7 +304,7 @@
 
     if (ec_fsm_foe_exec(&fsm->fsm_foe))
     {
-        ec_master_queue_request_fsm_datagram(fsm->slave->master,fsm->datagram);
+        ec_slave_mbox_queue_datagrams(slave, fsm->mbox);
         return;
     }
 
@@ -376,7 +376,7 @@
         fsm->state = ec_fsm_slave_state_soe_request;
         ec_fsm_soe_transfer(&fsm->fsm_soe, slave, &request->req);
         ec_fsm_soe_exec(&fsm->fsm_soe); // execute immediately
-        ec_master_queue_request_fsm_datagram(fsm->slave->master, fsm->datagram);
+        ec_slave_mbox_queue_datagrams(slave, fsm->mbox);
         return 1;
     }
     return 0;
@@ -394,7 +394,7 @@
     ec_master_soe_request_t *request = fsm->soe_request;
 
     if (ec_fsm_soe_exec(&fsm->fsm_soe)) {
-        ec_master_queue_request_fsm_datagram(fsm->slave->master, fsm->datagram);
+        ec_slave_mbox_queue_datagrams(slave, fsm->mbox);
         return;
     }
 
--- a/master/fsm_slave.h	Mon Mar 14 11:20:05 2011 +0100
+++ b/master/fsm_slave.h	Mon Mar 14 16:57:47 2011 +0100
@@ -50,7 +50,7 @@
  */
 struct ec_fsm_slave {
     ec_slave_t *slave; /**< slave the FSM runs on */
-    ec_datagram_t *datagram; /**< datagram used in the state machine */
+    ec_mailbox_t *mbox; /**< mailbox used in the state machine */
 
     void (*state)(ec_fsm_slave_t *); /**< master state function */
     ec_master_sdo_request_t *sdo_request; /**< SDO request to process. */
@@ -65,7 +65,7 @@
 
 /*****************************************************************************/
 
-void ec_fsm_slave_init(ec_fsm_slave_t *, ec_slave_t *, ec_datagram_t *);
+void ec_fsm_slave_init(ec_fsm_slave_t *, ec_slave_t *, ec_mailbox_t *);
 void ec_fsm_slave_clear(ec_fsm_slave_t *);
 
 int ec_fsm_slave_exec(ec_fsm_slave_t *);
--- a/master/fsm_slave_config.c	Mon Mar 14 11:20:05 2011 +0100
+++ b/master/fsm_slave_config.c	Mon Mar 14 16:57:47 2011 +0100
@@ -177,8 +177,8 @@
         ec_fsm_slave_config_t *fsm /**< slave state machine */
         )
 {
-    if (fsm->datagram->state == EC_DATAGRAM_SENT
-        || fsm->datagram->state == EC_DATAGRAM_QUEUED) {
+    if (fsm->datagram->state == EC_DATAGRAM_QUEUED
+        || fsm->datagram->state == EC_DATAGRAM_SENT) {
         // datagram was not sent or received yet.
         return ec_fsm_slave_config_running(fsm);
     }
@@ -738,8 +738,7 @@
             ec_soe_request_write(&fsm->soe_request_copy);
             ec_fsm_soe_transfer(fsm_soe, fsm->slave, &fsm->soe_request_copy);
             ec_fsm_soe_exec(fsm_soe); // execute immediately
-            ec_master_queue_request_fsm_datagram(slave->master,
-                    fsm_soe->datagram);
+            ec_slave_mbox_queue_datagrams(slave, fsm_soe->mbox);
             return;
         }
     }
@@ -760,7 +759,7 @@
     ec_fsm_soe_t *fsm_soe = &slave->fsm.fsm_soe;
 
     if (ec_fsm_soe_exec(fsm_soe)) {
-        ec_master_queue_request_fsm_datagram(slave->master, fsm_soe->datagram);
+        ec_slave_mbox_queue_datagrams(slave, fsm_soe->mbox);
         return;
     }
 
@@ -785,8 +784,7 @@
             ec_soe_request_write(&fsm->soe_request_copy);
             ec_fsm_soe_transfer(fsm_soe, fsm->slave, &fsm->soe_request_copy);
             ec_fsm_soe_exec(fsm_soe); // execute immediately
-            ec_master_queue_request_fsm_datagram(slave->master,
-                    fsm_soe->datagram);
+            ec_slave_mbox_queue_datagrams(slave, fsm_soe->mbox);
             return;
         }
     }
@@ -1454,8 +1452,7 @@
             ec_soe_request_write(&fsm->soe_request_copy);
             ec_fsm_soe_transfer(fsm_soe, fsm->slave, &fsm->soe_request_copy);
             ec_fsm_soe_exec(fsm_soe); // execute immediately
-            ec_master_queue_request_fsm_datagram(slave->master,
-                    fsm_soe->datagram);
+            ec_slave_mbox_queue_datagrams(slave, fsm_soe->mbox);
             return;
         }
     }
@@ -1476,7 +1473,7 @@
     ec_fsm_soe_t *fsm_soe = &slave->fsm.fsm_soe;
 
     if (ec_fsm_soe_exec(fsm_soe)) {
-        ec_master_queue_request_fsm_datagram(slave->master, fsm_soe->datagram);
+        ec_slave_mbox_queue_datagrams(slave, fsm_soe->mbox);
         return;
     }
 
@@ -1501,8 +1498,7 @@
             ec_soe_request_write(&fsm->soe_request_copy);
             ec_fsm_soe_transfer(fsm_soe, fsm->slave, &fsm->soe_request_copy);
             ec_fsm_soe_exec(fsm_soe); // execute immediately
-            ec_master_queue_request_fsm_datagram(slave->master,
-                    fsm_soe->datagram);
+            ec_slave_mbox_queue_datagrams(slave, fsm_soe->mbox);
             return;
         }
     }
--- a/master/fsm_slave_scan.c	Mon Mar 14 11:20:05 2011 +0100
+++ b/master/fsm_slave_scan.c	Mon Mar 14 16:57:47 2011 +0100
@@ -137,8 +137,8 @@
 
 int ec_fsm_slave_scan_exec(ec_fsm_slave_scan_t *fsm /**< slave state machine */)
 {
-    if (fsm->datagram->state == EC_DATAGRAM_SENT
-        || fsm->datagram->state == EC_DATAGRAM_QUEUED) {
+    if (fsm->datagram->state == EC_DATAGRAM_QUEUED
+        || fsm->datagram->state == EC_DATAGRAM_SENT) {
         // datagram was not sent or received yet.
         return ec_fsm_slave_scan_running(fsm);
     }
--- a/master/fsm_soe.c	Mon Mar 14 11:20:05 2011 +0100
+++ b/master/fsm_soe.c	Mon Mar 14 16:57:47 2011 +0100
@@ -106,11 +106,11 @@
  */
 void ec_fsm_soe_init(
         ec_fsm_soe_t *fsm, /**< finite state machine */
-        ec_datagram_t *datagram /**< datagram */
+        ec_mailbox_t *mbox /**< mailbox */
         )
 {
     fsm->state = NULL;
-    fsm->datagram = datagram;
+    fsm->mbox = mbox;
 }
 
 /*****************************************************************************/
@@ -195,7 +195,7 @@
  */
 void ec_fsm_soe_read_start(ec_fsm_soe_t *fsm /**< finite state machine */)
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
     ec_slave_t *slave = fsm->slave;
     ec_master_t *master = slave->master;
     ec_soe_request_t *request = fsm->request;
@@ -211,7 +211,7 @@
         return;
     }
 
-    data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_SOE,
+    data = ec_slave_mbox_prepare_send(slave, mbox, EC_MBOX_TYPE_SOE,
             EC_SOE_SIZE);
     if (IS_ERR(data)) {
         fsm->state = ec_fsm_soe_error;
@@ -240,25 +240,25 @@
  */
 void ec_fsm_soe_read_request(ec_fsm_soe_t *fsm /**< finite state machine */)
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
     ec_slave_t *slave = fsm->slave;
     unsigned long diff_ms;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+    if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && fsm->retries--)
         return; // FIXME: check for response first?
 
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         fsm->state = ec_fsm_soe_error;
         EC_SLAVE_ERR(slave, "Failed to receive SoE read request: ");
-        ec_datagram_print_state(datagram);
+        ec_datagram_print_state(mbox->datagram);
         ec_fsm_soe_print_error(fsm);
         return;
     }
 
     diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
 
-    if (datagram->working_counter != 1) {
-        if (!datagram->working_counter) {
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
+        if (ec_mbox_is_datagram_wc(mbox,0)) {
             if (diff_ms < EC_SOE_RESPONSE_TIMEOUT) {
                 // no response; send request datagram again
                 return;
@@ -267,13 +267,13 @@
         fsm->state = ec_fsm_soe_error;
         EC_SLAVE_ERR(slave, "Reception of SoE read request"
                 " failed after %lu ms: ", diff_ms);
-        ec_datagram_print_wc_error(datagram);
-        ec_fsm_soe_print_error(fsm);
-        return;
-    }
-
-    fsm->jiffies_start = datagram->jiffies_sent;
-    ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+        ec_datagram_print_wc_error(mbox->datagram);
+        ec_fsm_soe_print_error(fsm);
+        return;
+    }
+
+    fsm->jiffies_start = mbox->datagram->jiffies_sent;
+    ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_soe_read_check;
 }
@@ -284,32 +284,32 @@
  */
 void ec_fsm_soe_read_check(ec_fsm_soe_t *fsm /**< finite state machine */)
 {
-    ec_datagram_t *datagram = fsm->datagram;
-    ec_slave_t *slave = fsm->slave;
-
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
-        return;
-
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    ec_mailbox_t *mbox = fsm->mbox;
+    ec_slave_t *slave = fsm->slave;
+
+    if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && fsm->retries--)
+        return;
+
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         fsm->state = ec_fsm_soe_error;
         EC_SLAVE_ERR(slave, "Failed to receive SoE mailbox check datagram: ");
-        ec_datagram_print_state(datagram);
-        ec_fsm_soe_print_error(fsm);
-        return;
-    }
-
-    if (datagram->working_counter != 1) {
+        ec_datagram_print_state(mbox->datagram);
+        ec_fsm_soe_print_error(fsm);
+        return;
+    }
+
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         fsm->state = ec_fsm_soe_error;
         EC_SLAVE_ERR(slave, "Reception of SoE mailbox check"
                 " datagram failed: ");
-        ec_datagram_print_wc_error(datagram);
-        ec_fsm_soe_print_error(fsm);
-        return;
-    }
-
-    if (!ec_slave_mbox_check(datagram)) {
+        ec_datagram_print_wc_error(mbox->datagram);
+        ec_fsm_soe_print_error(fsm);
+        return;
+    }
+
+    if (!ec_slave_mbox_check(mbox)) {
         unsigned long diff_ms =
-            (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
+            (mbox->datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
         if (diff_ms >= EC_SOE_RESPONSE_TIMEOUT) {
             fsm->state = ec_fsm_soe_error;
             EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting for"
@@ -318,13 +318,13 @@
             return;
         }
 
-        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+        ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
         fsm->retries = EC_FSM_RETRIES;
         return;
     }
 
     // Fetch response
-    ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
+    ec_slave_mbox_prepare_fetch(slave, mbox); // can not fail.
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_soe_read_response;
 }
@@ -335,7 +335,7 @@
  */
 void ec_fsm_soe_read_response(ec_fsm_soe_t *fsm /**< finite state machine */)
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
     ec_slave_t *slave = fsm->slave;
     ec_master_t *master = slave->master;
     uint8_t *data, mbox_prot, header, opcode, incomplete, error_flag,
@@ -343,26 +343,26 @@
     size_t rec_size, data_size;
     ec_soe_request_t *req = fsm->request;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+    if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && fsm->retries--)
         return; // FIXME: request again?
 
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         fsm->state = ec_fsm_soe_error;
         EC_SLAVE_ERR(slave, "Failed to receive SoE read response datagram: ");
-        ec_datagram_print_state(datagram);
-        ec_fsm_soe_print_error(fsm);
-        return;
-    }
-
-    if (datagram->working_counter != 1) {
+        ec_datagram_print_state(mbox->datagram);
+        ec_fsm_soe_print_error(fsm);
+        return;
+    }
+
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         fsm->state = ec_fsm_soe_error;
         EC_SLAVE_ERR(slave, "Reception of SoE read response failed: ");
-        ec_datagram_print_wc_error(datagram);
-        ec_fsm_soe_print_error(fsm);
-        return;
-    }
-
-    data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size);
+        ec_datagram_print_wc_error(mbox->datagram);
+        ec_fsm_soe_print_error(fsm);
+        return;
+    }
+
+    data = ec_slave_mbox_fetch(slave, mbox, &mbox_prot, &rec_size);
     if (IS_ERR(data)) {
         fsm->state = ec_fsm_soe_error;
         ec_fsm_soe_print_error(fsm);
@@ -435,8 +435,8 @@
     if (incomplete) {
         EC_SLAVE_DBG(slave, 1, "SoE data incomplete. Waiting for fragment"
                 " at offset %zu.\n", req->data_size);
-        fsm->jiffies_start = datagram->jiffies_sent;
-        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+        fsm->jiffies_start = mbox->datagram->jiffies_sent;
+        ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
         fsm->retries = EC_FSM_RETRIES;
         fsm->state = ec_fsm_soe_read_check;
     } else {
@@ -459,7 +459,7 @@
         ec_fsm_soe_t *fsm /**< finite state machine */
         )
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
     ec_slave_t *slave = fsm->slave;
     ec_master_t *master = slave->master;
     ec_soe_request_t *req = fsm->request;
@@ -485,7 +485,7 @@
         fragments_left++;
     }
 
-    data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_SOE,
+    data = ec_slave_mbox_prepare_send(slave, mbox, EC_MBOX_TYPE_SOE,
             EC_SOE_SIZE + fragment_size);
     if (IS_ERR(data)) {
         fsm->state = ec_fsm_soe_error;
@@ -539,25 +539,25 @@
  */
 void ec_fsm_soe_write_request(ec_fsm_soe_t *fsm /**< finite state machine */)
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
     ec_slave_t *slave = fsm->slave;
     unsigned long diff_ms;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+    if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && fsm->retries--)
         return; // FIXME: check for response first?
 
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         fsm->state = ec_fsm_soe_error;
         EC_SLAVE_ERR(slave, "Failed to receive SoE write request: ");
-        ec_datagram_print_state(datagram);
+        ec_datagram_print_state(mbox->datagram);
         ec_fsm_soe_print_error(fsm);
         return;
     }
 
     diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
 
-    if (datagram->working_counter != 1) {
-        if (!datagram->working_counter) {
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
+        if (ec_mbox_is_datagram_wc(mbox,0)) {
             if (diff_ms < EC_SOE_RESPONSE_TIMEOUT) {
                 // no response; send request datagram again
                 return;
@@ -566,14 +566,14 @@
         fsm->state = ec_fsm_soe_error;
         EC_SLAVE_ERR(slave, "Reception of SoE write request"
                 " failed after %lu ms: ", diff_ms);
-        ec_datagram_print_wc_error(datagram);
-        ec_fsm_soe_print_error(fsm);
-        return;
-    }
-
-    fsm->jiffies_start = datagram->jiffies_sent;
-
-    ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+        ec_datagram_print_wc_error(mbox->datagram);
+        ec_fsm_soe_print_error(fsm);
+        return;
+    }
+
+    fsm->jiffies_start = mbox->datagram->jiffies_sent;
+
+    ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
     fsm->retries = EC_FSM_RETRIES;
     fsm->state = ec_fsm_soe_write_check;
 }
@@ -584,25 +584,25 @@
  */
 void ec_fsm_soe_write_check(ec_fsm_soe_t *fsm /**< finite state machine */)
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
     ec_slave_t *slave = fsm->slave;
     ec_soe_request_t *req = fsm->request;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
-        return;
-
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && fsm->retries--)
+        return;
+
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         fsm->state = ec_fsm_soe_error;
         EC_SLAVE_ERR(slave, "Failed to receive SoE write request datagram: ");
-        ec_datagram_print_state(datagram);
-        ec_fsm_soe_print_error(fsm);
-        return;
-    }
-
-    if (datagram->working_counter != 1) {
+        ec_datagram_print_state(mbox->datagram);
+        ec_fsm_soe_print_error(fsm);
+        return;
+    }
+
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         fsm->state = ec_fsm_soe_error;
         EC_SLAVE_ERR(slave, "Reception of SoE write request datagram: ");
-        ec_datagram_print_wc_error(datagram);
+        ec_datagram_print_wc_error(mbox->datagram);
         ec_fsm_soe_print_error(fsm);
         return;
     }
@@ -610,9 +610,9 @@
     if (fsm->offset < req->data_size) {
         ec_fsm_soe_write_next_fragment(fsm);
     } else {
-        if (!ec_slave_mbox_check(datagram)) {
+        if (!ec_slave_mbox_check(mbox)) {
             unsigned long diff_ms =
-                (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
+                (mbox->datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
             if (diff_ms >= EC_SOE_RESPONSE_TIMEOUT) {
                 fsm->state = ec_fsm_soe_error;
                 EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting"
@@ -621,13 +621,13 @@
                 return;
             }
 
-            ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+            ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
             fsm->retries = EC_FSM_RETRIES;
             return;
         }
 
         // Fetch response
-        ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
+        ec_slave_mbox_prepare_fetch(slave, mbox); // can not fail.
         fsm->retries = EC_FSM_RETRIES;
         fsm->state = ec_fsm_soe_write_response;
     }
@@ -639,7 +639,7 @@
  */
 void ec_fsm_soe_write_response(ec_fsm_soe_t *fsm /**< finite state machine */)
 {
-    ec_datagram_t *datagram = fsm->datagram;
+    ec_mailbox_t *mbox = fsm->mbox;
     ec_slave_t *slave = fsm->slave;
     ec_master_t *master = slave->master;
     ec_soe_request_t *req = fsm->request;
@@ -647,27 +647,27 @@
     uint16_t idn;
     size_t rec_size;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
+    if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && fsm->retries--)
         return; // FIXME: request again?
 
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         fsm->state = ec_fsm_soe_error;
         EC_SLAVE_ERR(slave, "Failed to receive SoE write"
                 " response datagram: ");
-        ec_datagram_print_state(datagram);
-        ec_fsm_soe_print_error(fsm);
-        return;
-    }
-
-    if (datagram->working_counter != 1) {
+        ec_datagram_print_state(mbox->datagram);
+        ec_fsm_soe_print_error(fsm);
+        return;
+    }
+
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         fsm->state = ec_fsm_soe_error;
         EC_SLAVE_ERR(slave, "Reception of SoE write response failed: ");
-        ec_datagram_print_wc_error(datagram);
-        ec_fsm_soe_print_error(fsm);
-        return;
-    }
-
-    data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size);
+        ec_datagram_print_wc_error(mbox->datagram);
+        ec_fsm_soe_print_error(fsm);
+        return;
+    }
+
+    data = ec_slave_mbox_fetch(slave, mbox, &mbox_prot, &rec_size);
     if (IS_ERR(data)) {
         fsm->state = ec_fsm_soe_error;
         ec_fsm_soe_print_error(fsm);
--- a/master/fsm_soe.h	Mon Mar 14 11:20:05 2011 +0100
+++ b/master/fsm_soe.h	Mon Mar 14 16:57:47 2011 +0100
@@ -50,7 +50,7 @@
  */
 struct ec_fsm_soe {
     ec_slave_t *slave; /**< slave the FSM runs on */
-    ec_datagram_t *datagram; /**< datagram used in the state machine */
+    ec_mailbox_t *mbox; /**< mailbox used in the state machine */
     unsigned int retries; /**< retries upon datagram timeout */
 
     void (*state)(ec_fsm_soe_t *); /**< CoE state function */
@@ -61,7 +61,7 @@
 
 /*****************************************************************************/
 
-void ec_fsm_soe_init(ec_fsm_soe_t *, ec_datagram_t *);
+void ec_fsm_soe_init(ec_fsm_soe_t *, ec_mailbox_t *);
 void ec_fsm_soe_clear(ec_fsm_soe_t *);
 
 void ec_fsm_soe_transfer(ec_fsm_soe_t *, ec_slave_t *, ec_soe_request_t *);
--- a/master/mailbox.c	Mon Mar 14 11:20:05 2011 +0100
+++ b/master/mailbox.c	Mon Mar 14 16:57:47 2011 +0100
@@ -37,10 +37,84 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 
+#include "slave.h"
 #include "mailbox.h"
 #include "datagram.h"
 #include "master.h"
 
+
+/*****************************************************************************/
+
+/**
+   Mailbox constructor.
+*/
+
+void ec_mbox_init(ec_mailbox_t* mbox, /** mailbox */
+                        ec_datagram_t* datagram  /**< Datagram used for the mailbox content. */
+                        )
+{
+    mbox->datagram = datagram;
+#ifdef EC_REDUCE_MBOXFRAMESIZE
+    ec_datagram_init(&mbox->end_datagram);
+#endif
+}
+
+
+/*****************************************************************************/
+
+/**
+   Clears mailbox datagrams.
+*/
+
+void ec_mbox_clear(ec_mailbox_t* mbox /** mailbox */
+                         )
+{
+#ifdef EC_REDUCE_MBOXFRAMESIZE
+    ec_datagram_clear(&mbox->end_datagram);
+#endif
+}
+
+
+/*****************************************************************************/
+
+/**
+   Queues the slave datagrams.
+*/
+
+void  ec_slave_mbox_queue_datagrams(const ec_slave_t* slave, /** slave */
+                                    ec_mailbox_t* mbox /** mailbox */
+                                    )
+{
+    ec_master_queue_request_fsm_datagram(slave->master, mbox->datagram);
+#ifdef EC_REDUCE_MBOXFRAMESIZE
+    if (mbox->end_datagram.type != EC_DATAGRAM_NONE)
+    {
+        ec_master_queue_request_fsm_datagram(slave->master, &mbox->end_datagram);
+    }
+#endif
+}
+
+
+/*****************************************************************************/
+
+/**
+   Queues the datagrams.
+*/
+
+void  ec_master_mbox_queue_datagrams(ec_master_t* master, /** master */
+                                    ec_mailbox_t* mbox /** mailbox */
+                                    )
+{
+    ec_master_queue_fsm_datagram(master, mbox->datagram);
+#ifdef EC_REDUCE_MBOXFRAMESIZE
+    if (mbox->end_datagram.type != EC_DATAGRAM_NONE)
+    {
+        ec_master_queue_fsm_datagram(master, &mbox->end_datagram);
+    }
+#endif
+}
+
+
 /*****************************************************************************/
 
 /**
@@ -48,12 +122,13 @@
    \return Pointer to mailbox datagram data, or ERR_PTR() code.
 */
 
-uint8_t *ec_slave_mbox_prepare_send(const ec_slave_t *slave, /**< slave */
-                                    ec_datagram_t *datagram, /**< datagram */
+uint8_t *ec_slave_mbox_prepare_send(const ec_slave_t* slave, /** slave */
+                                    ec_mailbox_t* mbox, /** mailbox */
                                     uint8_t type, /**< mailbox protocol */
                                     size_t size /**< size of the data */
                                     )
 {
+    ec_datagram_t* datagram = mbox->datagram;
     size_t total_size;
     int ret;
 
@@ -72,8 +147,13 @@
     }
 
     ret = ec_datagram_fpwr(datagram, slave->station_address,
-            slave->configured_rx_mailbox_offset,
-            slave->configured_rx_mailbox_size);
+                           slave->configured_rx_mailbox_offset,
+#ifdef EC_REDUCE_MBOXFRAMESIZE
+                           total_size
+#else
+                           slave->configured_rx_mailbox_size
+#endif
+                           );
     if (ret)
         return ERR_PTR(ret);
 
@@ -82,6 +162,17 @@
     EC_WRITE_U8 (datagram->data + 4, 0x00); // channel & priority
     EC_WRITE_U8 (datagram->data + 5, type); // underlying protocol type
 
+#ifdef EC_REDUCE_MBOXFRAMESIZE
+    /* in order to fulfil the ESC's mailbox protocol,
+       at least the last byte of the mailbox must be written */
+    if (total_size < slave->configured_rx_mailbox_size) {
+        ret = ec_datagram_fpwr(&mbox->end_datagram, slave->station_address,
+            slave->configured_rx_mailbox_offset+slave->configured_rx_mailbox_size-1,
+            1);
+        if (ret)
+            return ERR_PTR(ret);
+    }
+#endif
     return datagram->data + EC_MBOX_HEADER_SIZE;
 }
 
@@ -93,15 +184,19 @@
    \return 0 in case of success, else < 0
 */
 
-int ec_slave_mbox_prepare_check(const ec_slave_t *slave, /**< slave */
-                                ec_datagram_t *datagram /**< datagram */
+int ec_slave_mbox_prepare_check(const ec_slave_t* slave, /** slave */
+                                ec_mailbox_t* mbox /** mailbox */
                                 )
 {
+    ec_datagram_t* datagram = mbox->datagram;
     int ret = ec_datagram_fprd(datagram, slave->station_address, 0x808, 8);
     if (ret)
         return ret;
 
     ec_datagram_zero(datagram);
+#ifdef EC_REDUCE_MBOXFRAMESIZE
+    mbox->end_datagram.type = EC_DATAGRAM_NONE;
+#endif
     return 0;
 }
 
@@ -112,9 +207,9 @@
    \return 0 in case of success, else < 0
 */
 
-int ec_slave_mbox_check(const ec_datagram_t *datagram /**< datagram */)
-{
-    return EC_READ_U8(datagram->data + 5) & 8 ? 1 : 0;
+int ec_slave_mbox_check(ec_mailbox_t* mbox /** mailbox */)
+{
+    return EC_READ_U8(mbox->datagram->data + 5) & 8 ? 1 : 0;
 }
 
 /*****************************************************************************/
@@ -124,10 +219,11 @@
    \return 0 in case of success, else < 0
 */
 
-int ec_slave_mbox_prepare_fetch(const ec_slave_t *slave, /**< slave */
-                                ec_datagram_t *datagram /**< datagram */
+int ec_slave_mbox_prepare_fetch(const ec_slave_t* slave, /** slave */
+                                ec_mailbox_t* mbox /** mailbox */
                                 )
 {
+    ec_datagram_t* datagram = mbox->datagram;
     int ret = ec_datagram_fprd(datagram, slave->station_address,
             slave->configured_tx_mailbox_offset,
             slave->configured_tx_mailbox_size);
@@ -135,6 +231,9 @@
         return ret;
 
     ec_datagram_zero(datagram);
+#ifdef EC_REDUCE_MBOXFRAMESIZE
+    mbox->end_datagram.type = EC_DATAGRAM_NONE;
+#endif
     return 0;
 }
 
@@ -162,12 +261,13 @@
  *
  * \return Pointer to the received data, or ERR_PTR() code.
  */
-uint8_t *ec_slave_mbox_fetch(const ec_slave_t *slave, /**< slave */
-                             ec_datagram_t *datagram, /**< datagram */
+uint8_t *ec_slave_mbox_fetch(const ec_slave_t* slave, /** slave */
+                             ec_mailbox_t* mbox, /** mailbox */
                              uint8_t *type, /**< expected mailbox protocol */
                              size_t *size /**< size of the received data */
                              )
 {
+    ec_datagram_t* datagram = mbox->datagram;
     size_t data_size;
 
     data_size = EC_READ_U16(datagram->data);
--- a/master/mailbox.h	Mon Mar 14 11:20:05 2011 +0100
+++ b/master/mailbox.h	Mon Mar 14 16:57:47 2011 +0100
@@ -37,7 +37,8 @@
 #ifndef __EC_MAILBOX_H__
 #define __EC_MAILBOX_H__
 
-#include "slave.h"
+#include "globals.h"
+#include "datagram.h"
 
 /*****************************************************************************/
 
@@ -47,12 +48,53 @@
 
 /*****************************************************************************/
 
-uint8_t *ec_slave_mbox_prepare_send(const ec_slave_t *, ec_datagram_t *,
+/** EtherCAT slave mailbox.
+ */
+struct ec_mailbox
+{
+    ec_datagram_t* datagram;    /**< Datagram used for the mailbox content. */
+#ifdef EC_REDUCE_MBOXFRAMESIZE
+    ec_datagram_t end_datagram; /**< Datagram used for writing the end byte to the mailbox. */
+#endif
+};
+typedef struct ec_mailbox ec_mailbox_t; /**< \see ec_mailbox. */
+
+/*****************************************************************************/
+
+void     ec_mbox_init(ec_mailbox_t *, ec_datagram_t*);
+void     ec_mbox_clear(ec_mailbox_t*);
+/**
+   Checks the datagrams states.
+*/
+static inline int ec_mbox_is_datagram_state(ec_mailbox_t*mbox,
+                                            ec_datagram_state_t state) {
+    return (mbox->datagram->state == state)
+#ifdef EC_REDUCE_MBOXFRAMESIZE
+         && (mbox->end_datagram.type == EC_DATAGRAM_NONE || mbox->end_datagram.state == state)
+#endif
+    ;
+}
+
+/**
+   Checks the datagrams working counter.
+*/
+static inline int ec_mbox_is_datagram_wc(ec_mailbox_t*mbox,
+                                         size_t wc) {
+    return (mbox->datagram->working_counter == wc)
+#ifdef EC_REDUCE_MBOXFRAMESIZE
+         && (mbox->end_datagram.type == EC_DATAGRAM_NONE || mbox->end_datagram.working_counter == wc)
+#endif
+         ;
+}
+
+void     ec_slave_mbox_queue_datagrams(const ec_slave_t*,ec_mailbox_t*);
+void     ec_master_mbox_queue_datagrams(ec_master_t*, ec_mailbox_t*);
+uint8_t *ec_slave_mbox_prepare_send(const ec_slave_t*,ec_mailbox_t *,
                                     uint8_t, size_t);
-int      ec_slave_mbox_prepare_check(const ec_slave_t *, ec_datagram_t *);
-int      ec_slave_mbox_check(const ec_datagram_t *);
-int      ec_slave_mbox_prepare_fetch(const ec_slave_t *, ec_datagram_t *);
-uint8_t *ec_slave_mbox_fetch(const ec_slave_t *, ec_datagram_t *,
+int      ec_slave_mbox_prepare_check(const ec_slave_t*,ec_mailbox_t *);
+int      ec_slave_mbox_check(ec_mailbox_t *);
+int      ec_slave_mbox_prepare_fetch(const ec_slave_t*,ec_mailbox_t *);
+uint8_t *ec_slave_mbox_fetch(const ec_slave_t*,ec_mailbox_t *,
                              uint8_t *, size_t *);
 
 /*****************************************************************************/
--- a/master/master.c	Mon Mar 14 11:20:05 2011 +0100
+++ b/master/master.c	Mon Mar 14 16:57:47 2011 +0100
@@ -228,6 +228,7 @@
     }
 
     // create state machine object
+    ec_mbox_init(&master->fsm_mbox,&master->fsm_datagram);
     ec_fsm_master_init(&master->fsm, master, &master->fsm_datagram);
 
     // init reference sync datagram
@@ -329,7 +330,7 @@
 #endif
 
     ec_cdev_clear(&master->cdev);
-    
+
 #ifdef EC_EOE
     ec_master_clear_eoe_handlers(master);
 #endif
@@ -341,6 +342,7 @@
     ec_datagram_clear(&master->sync_datagram);
     ec_datagram_clear(&master->ref_sync_datagram);
     ec_fsm_master_clear(&master->fsm);
+    ec_mbox_clear(&master->fsm_mbox);
     ec_datagram_clear(&master->fsm_datagram);
     ec_device_clear(&master->backup_device);
     ec_device_clear(&master->main_device);
@@ -1279,7 +1281,7 @@
         if (ec_mutex_lock_interruptible(&master->master_mutex))
             break;
         if (ec_fsm_master_exec(&master->fsm)) {
-            ec_master_queue_fsm_datagram(master, &master->fsm_datagram);
+            ec_master_mbox_queue_datagrams(master, &master->fsm_mbox);
         }
         for (slave = master->slaves;
                 slave < master->slaves + master->slave_count;
@@ -1343,7 +1345,7 @@
         if (ec_mutex_lock_interruptible(&master->master_mutex))
             break;
         if (ec_fsm_master_exec(&master->fsm))
-            ec_master_queue_fsm_datagram(master, &master->fsm_datagram);
+            ec_master_mbox_queue_datagrams(master, &master->fsm_mbox);
         for (slave = master->slaves;
                 slave < master->slaves + master->slave_count;
                 slave++) {
--- a/master/master.h	Mon Mar 14 11:20:05 2011 +0100
+++ b/master/master.h	Mon Mar 14 16:57:47 2011 +0100
@@ -193,6 +193,7 @@
 
     ec_fsm_master_t fsm; /**< Master state machine. */
     ec_datagram_t fsm_datagram; /**< Datagram used for state machines. */
+    ec_mailbox_t fsm_mbox; /**< Mailbox used for state machines. */
     ec_master_phase_t phase; /**< Master phase. */
     unsigned int active; /**< Master has been activated. */
     unsigned int config_changed; /**< The configuration changed. */
--- a/master/slave.c	Mon Mar 14 11:20:05 2011 +0100
+++ b/master/slave.c	Mon Mar 14 16:57:47 2011 +0100
@@ -159,19 +159,20 @@
     INIT_LIST_HEAD(&slave->soe_requests);
     init_waitqueue_head(&slave->soe_queue);
 
-    // init state machine datagram
-    ec_datagram_init(&slave->fsm_datagram);
-    snprintf(slave->fsm_datagram.name, EC_DATAGRAM_NAME_SIZE,
+    // init datagram
+    ec_datagram_init(&slave->datagram);
+    snprintf(slave->datagram.name, EC_DATAGRAM_NAME_SIZE,
             "slave%u-fsm", slave->ring_position);
-    ret = ec_datagram_prealloc(&slave->fsm_datagram, EC_MAX_DATA_SIZE);
+    ret = ec_datagram_prealloc(&slave->datagram, EC_MAX_DATA_SIZE);
     if (ret < 0) {
-        ec_datagram_clear(&slave->fsm_datagram);
+        ec_datagram_clear(&slave->datagram);
         EC_SLAVE_ERR(slave, "Failed to allocate FSM datagram.\n");
         return;
     }
+    ec_mbox_init(&slave->mbox,&slave->datagram);
 
     // create state machine object
-    ec_fsm_slave_init(&slave->fsm, slave, &slave->fsm_datagram);
+    ec_fsm_slave_init(&slave->fsm, slave, &slave->mbox);
 }
 
 /*****************************************************************************/
@@ -255,7 +256,7 @@
     if (slave->sii_words)
         kfree(slave->sii_words);
     ec_fsm_slave_clear(&slave->fsm);
-    ec_datagram_clear(&slave->fsm_datagram);
+    ec_mbox_clear(&slave->mbox);
 }
 
 /*****************************************************************************/
--- a/master/slave.h	Mon Mar 14 11:20:05 2011 +0100
+++ b/master/slave.h	Mon Mar 14 16:57:47 2011 +0100
@@ -46,6 +46,7 @@
 #include "sync.h"
 #include "sdo.h"
 #include "fsm_slave.h"
+#include "mailbox.h"
 
 /*****************************************************************************/
 
@@ -274,7 +275,8 @@
     wait_queue_head_t soe_queue; /**< Wait queue for SoE requests from user
                                    space. */
     ec_fsm_slave_t fsm; /**< Slave state machine. */
-    ec_datagram_t fsm_datagram; /**< Datagram used for state machines. */
+    ec_datagram_t datagram; /** Datagram used for data transfers */
+    ec_mailbox_t mbox; /**< Mailbox used for data transfers. */
 };
 
 /*****************************************************************************/
--- a/master/voe_handler.c	Mon Mar 14 11:20:05 2011 +0100
+++ b/master/voe_handler.c	Mon Mar 14 16:57:47 2011 +0100
@@ -88,6 +88,7 @@
     voe->request_state = EC_INT_REQUEST_INIT;
 
     ec_datagram_init(&voe->datagram);
+    ec_mbox_init(&voe->mbox,&voe->datagram);
     return ec_datagram_prealloc(&voe->datagram,
             size + EC_MBOX_HEADER_SIZE + EC_VOE_HEADER_SIZE);
 }
@@ -100,6 +101,7 @@
         ec_voe_handler_t *voe /**< VoE handler. */
         )
 {
+    ec_mbox_clear(&voe->mbox);
     ec_datagram_clear(&voe->datagram);
 }
 
@@ -191,7 +193,7 @@
     if (voe->config->slave) { // FIXME locking?
         voe->state(voe);
         if (voe->request_state == EC_INT_REQUEST_BUSY)
-            ec_master_queue_datagram(voe->config->master, &voe->datagram);
+            ec_slave_mbox_queue_datagrams(voe->config->slave,&voe->mbox);
     } else {
         voe->state = ec_voe_handler_state_error;
         voe->request_state = EC_INT_REQUEST_FAILURE;
@@ -224,7 +226,7 @@
         return;
     }
 
-    data = ec_slave_mbox_prepare_send(slave, &voe->datagram,
+    data = ec_slave_mbox_prepare_send(slave, &voe->mbox,
             EC_MBOX_TYPE_VOE, EC_VOE_HEADER_SIZE + voe->data_size);
     if (IS_ERR(data)) {
         voe->state = ec_voe_handler_state_error;
@@ -247,22 +249,22 @@
  */
 void ec_voe_handler_state_write_response(ec_voe_handler_t *voe)
 {
-    ec_datagram_t *datagram = &voe->datagram;
-    ec_slave_t *slave = voe->config->slave;
-
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && voe->retries--)
-        return;
-
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    ec_mailbox_t *mbox = &voe->mbox;
+    ec_slave_t *slave = voe->config->slave;
+
+    if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && voe->retries--)
+        return;
+
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         voe->state = ec_voe_handler_state_error;
         voe->request_state = EC_INT_REQUEST_FAILURE;
         EC_SLAVE_ERR(slave, "Failed to receive VoE write request datagram: ");
-        ec_datagram_print_state(datagram);
-        return;
-    }
-
-    if (datagram->working_counter != 1) {
-        if (!datagram->working_counter) {
+        ec_datagram_print_state(mbox->datagram);
+        return;
+    }
+
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
+        if (ec_mbox_is_datagram_wc(mbox,0)) {
             unsigned long diff_ms =
                 (jiffies - voe->jiffies_start) * 1000 / HZ;
             if (diff_ms < EC_VOE_RESPONSE_TIMEOUT) {
@@ -276,7 +278,7 @@
         voe->state = ec_voe_handler_state_error;
         voe->request_state = EC_INT_REQUEST_FAILURE;
         EC_SLAVE_ERR(slave, "Reception of VoE write request failed: ");
-        ec_datagram_print_wc_error(datagram);
+        ec_datagram_print_wc_error(mbox->datagram);
         return;
     }
 
@@ -292,7 +294,7 @@
  */
 void ec_voe_handler_state_read_start(ec_voe_handler_t *voe)
 {
-    ec_datagram_t *datagram = &voe->datagram;
+    ec_mailbox_t *mbox = &voe->mbox;
     ec_slave_t *slave = voe->config->slave;
 
     EC_SLAVE_DBG(slave, 1, "Reading VoE data.\n");
@@ -304,7 +306,7 @@
         return;
     }
 
-    ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+    ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
 
     voe->jiffies_start = jiffies;
     voe->retries = EC_FSM_RETRIES;
@@ -317,32 +319,32 @@
  */
 void ec_voe_handler_state_read_check(ec_voe_handler_t *voe)
 {
-    ec_datagram_t *datagram = &voe->datagram;
-    ec_slave_t *slave = voe->config->slave;
-
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && voe->retries--)
-        return;
-
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    ec_mailbox_t *mbox = &voe->mbox;
+    ec_slave_t *slave = voe->config->slave;
+
+    if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && voe->retries--)
+        return;
+
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         voe->state = ec_voe_handler_state_error;
         voe->request_state = EC_INT_REQUEST_FAILURE;
         EC_SLAVE_ERR(slave, "Failed to receive VoE mailbox check datagram: ");
-        ec_datagram_print_state(datagram);
-        return;
-    }
-
-    if (datagram->working_counter != 1) {
+        ec_datagram_print_state(mbox->datagram);
+        return;
+    }
+
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         voe->state = ec_voe_handler_state_error;
         voe->request_state = EC_INT_REQUEST_FAILURE;
         EC_SLAVE_ERR(slave, "Reception of VoE mailbox check"
                 " datagram failed: ");
-        ec_datagram_print_wc_error(datagram);
-        return;
-    }
-
-    if (!ec_slave_mbox_check(datagram)) {
+        ec_datagram_print_wc_error(mbox->datagram);
+        return;
+    }
+
+    if (!ec_slave_mbox_check(mbox)) {
         unsigned long diff_ms =
-            (datagram->jiffies_received - voe->jiffies_start) * 1000 / HZ;
+            (mbox->datagram->jiffies_received - voe->jiffies_start) * 1000 / HZ;
         if (diff_ms >= EC_VOE_RESPONSE_TIMEOUT) {
             voe->state = ec_voe_handler_state_error;
             voe->request_state = EC_INT_REQUEST_FAILURE;
@@ -350,13 +352,13 @@
             return;
         }
 
-        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
+        ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
         voe->retries = EC_FSM_RETRIES;
         return;
     }
 
     // Fetch response
-    ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
+    ec_slave_mbox_prepare_fetch(slave, mbox); // can not fail.
     voe->retries = EC_FSM_RETRIES;
     voe->state = ec_voe_handler_state_read_response;
 }
@@ -367,32 +369,32 @@
  */
 void ec_voe_handler_state_read_response(ec_voe_handler_t *voe)
 {
-    ec_datagram_t *datagram = &voe->datagram;
+    ec_mailbox_t *mbox = &voe->mbox;
     ec_slave_t *slave = voe->config->slave;
     ec_master_t *master = voe->config->master;
     uint8_t *data, mbox_prot;
     size_t rec_size;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && voe->retries--)
-        return;
-
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && voe->retries--)
+        return;
+
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         voe->state = ec_voe_handler_state_error;
         voe->request_state = EC_INT_REQUEST_FAILURE;
         EC_SLAVE_ERR(slave, "Failed to receive VoE read datagram: ");
-        ec_datagram_print_state(datagram);
-        return;
-    }
-
-    if (datagram->working_counter != 1) {
+        ec_datagram_print_state(mbox->datagram);
+        return;
+    }
+
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         voe->state = ec_voe_handler_state_error;
         voe->request_state = EC_INT_REQUEST_FAILURE;
         EC_SLAVE_ERR(slave, "Reception of VoE read response failed: ");
-        ec_datagram_print_wc_error(datagram);
-        return;
-    }
-
-    data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size);
+        ec_datagram_print_wc_error(mbox->datagram);
+        return;
+    }
+
+    data = ec_slave_mbox_fetch(slave, mbox, &mbox_prot, &rec_size);
     if (IS_ERR(data)) {
         voe->state = ec_voe_handler_state_error;
         voe->request_state = EC_INT_REQUEST_FAILURE;
@@ -432,7 +434,7 @@
  */
 void ec_voe_handler_state_read_nosync_start(ec_voe_handler_t *voe)
 {
-    ec_datagram_t *datagram = &voe->datagram;
+    ec_mailbox_t *mbox = &voe->mbox;
     ec_slave_t *slave = voe->config->slave;
 
     EC_SLAVE_DBG(slave, 1, "Reading VoE data.\n");
@@ -444,7 +446,7 @@
         return;
     }
 
-    ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
+    ec_slave_mbox_prepare_fetch(slave, mbox); // can not fail.
 
     voe->jiffies_start = jiffies;
     voe->retries = EC_FSM_RETRIES;
@@ -458,39 +460,39 @@
  */
 void ec_voe_handler_state_read_nosync_response(ec_voe_handler_t *voe)
 {
-    ec_datagram_t *datagram = &voe->datagram;
+    ec_mailbox_t *mbox = &voe->mbox;
     ec_slave_t *slave = voe->config->slave;
     ec_master_t *master = voe->config->master;
     uint8_t *data, mbox_prot;
     size_t rec_size;
 
-    if (datagram->state == EC_DATAGRAM_TIMED_OUT && voe->retries--)
-        return;
-
-    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+    if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && voe->retries--)
+        return;
+
+    if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
         voe->state = ec_voe_handler_state_error;
         voe->request_state = EC_INT_REQUEST_FAILURE;
         EC_SLAVE_ERR(slave, "Failed to receive VoE read datagram: ");
-        ec_datagram_print_state(datagram);
-        return;
-    }
-
-    if (datagram->working_counter == 0) {
+        ec_datagram_print_state(mbox->datagram);
+        return;
+    }
+
+    if (ec_mbox_is_datagram_wc(mbox,0)) {
         voe->state = ec_voe_handler_state_error;
         voe->request_state = EC_INT_REQUEST_FAILURE;
         EC_SLAVE_DBG(slave, 1, "Slave did not send VoE data.\n");
         return;
     }
 
-    if (datagram->working_counter != 1) {
+    if (!ec_mbox_is_datagram_wc(mbox,1)) {
         voe->state = ec_voe_handler_state_error;
         voe->request_state = EC_INT_REQUEST_FAILURE;
         EC_SLAVE_WARN(slave, "Reception of VoE read response failed: ");
-        ec_datagram_print_wc_error(datagram);
-        return;
-    }
-
-    if (!(data = ec_slave_mbox_fetch(slave, datagram,
+        ec_datagram_print_wc_error(mbox->datagram);
+        return;
+    }
+
+    if (!(data = ec_slave_mbox_fetch(slave, mbox,
                     &mbox_prot, &rec_size))) {
         voe->state = ec_voe_handler_state_error;
         voe->request_state = EC_INT_REQUEST_FAILURE;
--- a/master/voe_handler.h	Mon Mar 14 11:20:05 2011 +0100
+++ b/master/voe_handler.h	Mon Mar 14 16:57:47 2011 +0100
@@ -50,6 +50,7 @@
     struct list_head list; /**< List item. */
     ec_slave_config_t *config; /**< Parent slave configuration. */
     ec_datagram_t datagram; /**< State machine datagram. */
+    ec_mailbox_t mbox; /**< State machine mailbox. */
     uint32_t vendor_id; /**< Vendor ID for the header. */
     uint16_t vendor_type; /**< Vendor type for the header. */
     size_t data_size; /**< Size of VoE data. */