Dynamischer Kommandospeicher, Domain-Kommandos als Liste.
authorFlorian Pose <fp@igh-essen.com>
Mon, 03 Apr 2006 10:03:34 +0000
changeset 144 fdc24bf62f80
parent 143 f6c4f38b699f
child 145 11a82e4fd31b
Dynamischer Kommandospeicher, Domain-Kommandos als Liste.
include/ecrt.h
master/canopen.c
master/command.c
master/command.h
master/domain.c
master/domain.h
master/master.c
master/master.h
master/slave.c
master/slave.h
rt/msr_module.c
todo.txt
--- a/include/ecrt.h	Sun Apr 02 09:26:56 2006 +0000
+++ b/include/ecrt.h	Mon Apr 03 10:03:34 2006 +0000
@@ -61,6 +61,8 @@
 void ecrt_master_async_receive(ec_master_t *master);
 void ecrt_master_prepare_async_io(ec_master_t *master);
 
+void ecrt_master_run(ec_master_t *master);
+
 void ecrt_master_debug(ec_master_t *master, int level);
 void ecrt_master_print(const ec_master_t *master, unsigned int verbosity);
 
--- a/master/canopen.c	Sun Apr 02 09:26:56 2006 +0000
+++ b/master/canopen.c	Mon Apr 03 10:03:34 2006 +0000
@@ -48,19 +48,21 @@
                           uint8_t *target /**< Speicher für 4 Bytes */
                           )
 {
-    uint8_t data[0x20];
     size_t rec_size;
-
+    uint8_t *data;
+
+    if (!(data = ec_slave_prepare_mailbox_send(slave, 0x03, 6))) return -1;
     EC_WRITE_U16(data, 0x2 << 12); // SDO request
     EC_WRITE_U8 (data + 2, (0x1 << 1 // expedited transfer
                             | 0x2 << 5));  // initiate upload request
     EC_WRITE_U16(data + 3, sdo_index);
     EC_WRITE_U8 (data + 5, sdo_subindex);
-
-    if (ec_slave_mailbox_send(slave, 0x03, data, 6)) return -1;
-
-    rec_size = 0x20;
-    if (ec_slave_mailbox_receive(slave, 0x03, data, &rec_size)) return -1;
+    if (unlikely(ec_master_simple_io(slave->master))) {
+        EC_ERR("Mailbox sending failed on slave %i!\n", slave->ring_position);
+        return -1;
+    }
+
+    if (!(data = ec_slave_mailbox_receive(slave, 0x03, &rec_size))) return -1;
 
     if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
         EC_READ_U8 (data + 2) >> 5 == 0x4) { // Abort SDO transfer request
@@ -97,7 +99,7 @@
                            size_t size
                            )
 {
-    uint8_t data[0x0A];
+    uint8_t *data;
     size_t rec_size;
 
     if (size == 0 || size > 4) {
@@ -105,6 +107,7 @@
         return -1;
     }
 
+    if (!(data = ec_slave_prepare_mailbox_send(slave, 0x03, 0x0A))) return -1;
     EC_WRITE_U16(data, 0x2 << 12); // SDO request
     EC_WRITE_U8 (data + 2, (0x1 // size specified
                             | 0x1 << 1 // expedited transfer
@@ -112,15 +115,14 @@
                             | 0x1 << 5)); // initiate download request
     EC_WRITE_U16(data + 3, sdo_index);
     EC_WRITE_U8 (data + 5, sdo_subindex);
-
     memcpy(data + 6, sdo_data, size);
     if (size < 4) memset(data + 6 + size, 0x00, 4 - size);
-
-    // Mailox senden und empfangen
-    if (ec_slave_mailbox_send(slave, 0x03, data, 0x0A)) return -1;
-
-    rec_size = 0x0A;
-    if (ec_slave_mailbox_receive(slave, 0x03, data, &rec_size)) return -1;
+    if (unlikely(ec_master_simple_io(slave->master))) {
+        EC_ERR("Mailbox sending failed on slave %i!\n", slave->ring_position);
+        return -1;
+    }
+
+    if (!(data = ec_slave_mailbox_receive(slave, 0x03, &rec_size))) return -1;
 
     if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
         EC_READ_U8 (data + 2) >> 5 == 0x4) { // Abort SDO transfer request
@@ -158,19 +160,21 @@
                         size_t *size /**< Größe des Speichers */
                         )
 {
-    uint8_t data[0x20];
+    uint8_t *data;
     size_t rec_size, data_size;
     uint32_t complete_size;
 
+    if (!(data = ec_slave_prepare_mailbox_send(slave, 0x03, 6))) return -1;
     EC_WRITE_U16(data, 0x2 << 12); // SDO request
     EC_WRITE_U8 (data + 2, 0x2 << 5); // initiate upload request
     EC_WRITE_U16(data + 3, sdo_index);
     EC_WRITE_U8 (data + 5, sdo_subindex);
-
-    if (ec_slave_mailbox_send(slave, 0x03, data, 6)) return -1;
-
-    rec_size = 0x20;
-    if (ec_slave_mailbox_receive(slave, 0x03, data, &rec_size)) return -1;
+    if (unlikely(ec_master_simple_io(slave->master))) {
+        EC_ERR("Mailbox sending failed on slave %i!\n", slave->ring_position);
+        return -1;
+    }
+
+    if (!(data = ec_slave_mailbox_receive(slave, 0x03, &rec_size))) return -1;
 
     if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
         EC_READ_U8 (data + 2) >> 5 == 0x4) { // Abort SDO transfer request
@@ -222,23 +226,26 @@
 
 int ec_slave_fetch_sdo_list(ec_slave_t *slave /**< EtherCAT-Slave */)
 {
-    uint8_t data[0xF0];
+    uint8_t *data;
     size_t rec_size;
     unsigned int i, sdo_count;
     ec_sdo_t *sdo;
     uint16_t sdo_index;
 
+    if (!(data = ec_slave_prepare_mailbox_send(slave, 0x03, 8))) return -1;
     EC_WRITE_U16(data, 0x8 << 12); // SDO information
     EC_WRITE_U8 (data + 2, 0x01); // Get OD List Request
     EC_WRITE_U8 (data + 3, 0x00);
     EC_WRITE_U16(data + 4, 0x0000);
     EC_WRITE_U16(data + 6, 0x0001); // Deliver all SDOs!
-
-    if (ec_slave_mailbox_send(slave, 0x03, data, 8)) return -1;
+    if (unlikely(ec_master_simple_io(slave->master))) {
+        EC_ERR("Mailbox sending failed on slave %i!\n", slave->ring_position);
+        return -1;
+    }
 
     do {
-        rec_size = 0xF0;
-        if (ec_slave_mailbox_receive(slave, 0x03, data, &rec_size)) return -1;
+        if (!(data = ec_slave_mailbox_receive(slave, 0x03, &rec_size)))
+            return -1;
 
         if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
             (EC_READ_U8(data + 2) & 0x7F) == 0x07) { // Error response
@@ -290,21 +297,24 @@
 
 int ec_slave_fetch_sdo_descriptions(ec_slave_t *slave /**< EtherCAT-Slave */)
 {
-    uint8_t data[0xF0];
+    uint8_t *data;
     size_t rec_size, name_size;
     ec_sdo_t *sdo;
 
     list_for_each_entry(sdo, &slave->sdo_dictionary, list) {
+        if (!(data = ec_slave_prepare_mailbox_send(slave, 0x03, 8))) return -1;
         EC_WRITE_U16(data, 0x8 << 12); // SDO information
         EC_WRITE_U8 (data + 2, 0x03); // Get object description request
         EC_WRITE_U8 (data + 3, 0x00);
         EC_WRITE_U16(data + 4, 0x0000);
         EC_WRITE_U16(data + 6, sdo->index); // SDO index
-
-        if (ec_slave_mailbox_send(slave, 0x03, data, 8)) return -1;
-
-        rec_size = 0xF0;
-        if (ec_slave_mailbox_receive(slave, 0x03, data, &rec_size))
+        if (unlikely(ec_master_simple_io(slave->master))) {
+            EC_ERR("Mailbox sending failed on slave %i!\n",
+                   slave->ring_position);
+            return -1;
+        }
+
+        if (!(data = ec_slave_mailbox_receive(slave, 0x03, &rec_size)))
             return -1;
 
         if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
@@ -370,12 +380,14 @@
                                uint8_t subindices /**< Anzahl Subindizes */
                                )
 {
-    uint8_t data[0xF0];
+    uint8_t *data;
     size_t rec_size, data_size;
     uint8_t i;
     ec_sdo_entry_t *entry;
 
     for (i = 1; i <= subindices; i++) {
+        if (!(data = ec_slave_prepare_mailbox_send(slave, 0x03, 10)))
+            return -1;
         EC_WRITE_U16(data, 0x8 << 12); // SDO information
         EC_WRITE_U8 (data + 2, 0x05); // Get entry description request
         EC_WRITE_U8 (data + 3, 0x00);
@@ -383,11 +395,13 @@
         EC_WRITE_U16(data + 6, sdo->index); // SDO index
         EC_WRITE_U8 (data + 8, i); // SDO subindex
         EC_WRITE_U8 (data + 9, 0x00); // value info (no values)
-
-        if (ec_slave_mailbox_send(slave, 0x03, data, 10)) return -1;
-
-        rec_size = 0xF0;
-        if (ec_slave_mailbox_receive(slave, 0x03, data, &rec_size))
+        if (unlikely(ec_master_simple_io(slave->master))) {
+            EC_ERR("Mailbox sending failed on slave %i!\n",
+                   slave->ring_position);
+            return -1;
+        }
+
+        if (!(data = ec_slave_mailbox_receive(slave, 0x03, &rec_size)))
             return -1;
 
         if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
--- a/master/command.c	Sun Apr 02 09:26:56 2006 +0000
+++ b/master/command.c	Mon Apr 03 10:03:34 2006 +0000
@@ -17,17 +17,70 @@
 /*****************************************************************************/
 
 #define EC_FUNC_HEADER \
+    if (unlikely(ec_command_prealloc(command, data_size))) \
+        return -1; \
     command->index = 0; \
     command->working_counter = 0; \
     command->state = EC_CMD_INIT;
 
-#define EC_FUNC_WRITE_FOOTER \
+#define EC_FUNC_FOOTER \
     command->data_size = data_size; \
-    memcpy(command->data, data, data_size);
-
-#define EC_FUNC_READ_FOOTER \
-    command->data_size = data_size; \
-    memset(command->data, 0x00, data_size);
+    memset(command->data, 0x00, data_size); \
+    return 0;
+
+/*****************************************************************************/
+
+/**
+   EtherCAT-Kommando-Konstruktor.
+*/
+
+void ec_command_init(ec_command_t *command)
+{
+    command->type = EC_CMD_NONE;
+    command->address.logical = 0x00000000;
+    command->data = NULL;
+    command->mem_size = 0;
+    command->data_size = 0;
+    command->index = 0x00;
+    command->working_counter = 0x00;
+    command->state = EC_CMD_INIT;
+}
+
+/*****************************************************************************/
+
+/**
+   EtherCAT-Kommando-Destruktor.
+*/
+
+void ec_command_clear(ec_command_t *command)
+{
+    if (command->data) kfree(command->data);
+}
+
+/*****************************************************************************/
+
+/**
+   Alloziert Speicher.
+*/
+
+int ec_command_prealloc(ec_command_t *command, size_t size)
+{
+    if (size <= command->mem_size) return 0;
+
+    if (command->data) {
+        kfree(command->data);
+        command->data = NULL;
+        command->mem_size = 0;
+    }
+
+    if (!(command->data = kmalloc(size, GFP_KERNEL))) {
+        EC_ERR("Failed to allocate %i bytes of command memory!\n", size);
+        return -1;
+    }
+
+    command->mem_size = size;
+    return 0;
+}
 
 /*****************************************************************************/
 
@@ -37,26 +90,24 @@
    Node-adressed physical read.
 */
 
-void ec_command_init_nprd(ec_command_t *command,
-                          /**< EtherCAT-Rahmen */
-                          uint16_t node_address,
-                          /**< Adresse des Knotens (Slaves) */
-                          uint16_t offset,
-                          /**< Physikalische Speicheradresse im Slave */
-                          size_t data_size
-                          /**< Länge der zu lesenden Daten */
-                          )
+int ec_command_nprd(ec_command_t *command,
+                    /**< EtherCAT-Rahmen */
+                    uint16_t node_address,
+                    /**< Adresse des Knotens (Slaves) */
+                    uint16_t offset,
+                    /**< Physikalische Speicheradresse im Slave */
+                    size_t data_size
+                    /**< Länge der zu lesenden Daten */
+                    )
 {
     if (unlikely(node_address == 0x0000))
         EC_WARN("Using node address 0x0000!\n");
 
     EC_FUNC_HEADER;
-
     command->type = EC_CMD_NPRD;
     command->address.physical.slave = node_address;
     command->address.physical.mem = offset;
-
-    EC_FUNC_READ_FOOTER;
+    EC_FUNC_FOOTER;
 }
 
 /*****************************************************************************/
@@ -67,28 +118,24 @@
    Node-adressed physical write.
 */
 
-void ec_command_init_npwr(ec_command_t *command,
-                          /**< EtherCAT-Rahmen */
-                          uint16_t node_address,
-                          /**< Adresse des Knotens (Slaves) */
-                          uint16_t offset,
-                          /**< Physikalische Speicheradresse im Slave */
-                          size_t data_size,
-                          /**< Länge der zu schreibenden Daten */
-                          const uint8_t *data
-                          /**< Zeiger auf Speicher mit zu schreibenden Daten */
-                          )
+int ec_command_npwr(ec_command_t *command,
+                    /**< EtherCAT-Rahmen */
+                    uint16_t node_address,
+                    /**< Adresse des Knotens (Slaves) */
+                    uint16_t offset,
+                    /**< Physikalische Speicheradresse im Slave */
+                    size_t data_size
+                    /**< Länge der zu schreibenden Daten */
+                    )
 {
     if (unlikely(node_address == 0x0000))
         EC_WARN("Using node address 0x0000!\n");
 
     EC_FUNC_HEADER;
-
     command->type = EC_CMD_NPWR;
     command->address.physical.slave = node_address;
     command->address.physical.mem = offset;
-
-    EC_FUNC_WRITE_FOOTER;
+    EC_FUNC_FOOTER;
 }
 
 /*****************************************************************************/
@@ -99,23 +146,21 @@
    Autoincrement physical read.
 */
 
-void ec_command_init_aprd(ec_command_t *command,
-                          /**< EtherCAT-Rahmen */
-                          uint16_t ring_position,
-                          /**< Position des Slaves im Bus */
-                          uint16_t offset,
-                          /**< Physikalische Speicheradresse im Slave */
-                          size_t data_size
-                          /**< Länge der zu lesenden Daten */
-                          )
-{
-    EC_FUNC_HEADER;
-
+int ec_command_aprd(ec_command_t *command,
+                    /**< EtherCAT-Rahmen */
+                    uint16_t ring_position,
+                    /**< Position des Slaves im Bus */
+                    uint16_t offset,
+                    /**< Physikalische Speicheradresse im Slave */
+                    size_t data_size
+                    /**< Länge der zu lesenden Daten */
+                    )
+{
+    EC_FUNC_HEADER;
     command->type = EC_CMD_APRD;
     command->address.physical.slave = (int16_t) ring_position * (-1);
     command->address.physical.mem = offset;
-
-    EC_FUNC_READ_FOOTER;
+    EC_FUNC_FOOTER;
 }
 
 /*****************************************************************************/
@@ -126,25 +171,21 @@
    Autoincrement physical write.
 */
 
-void ec_command_init_apwr(ec_command_t *command,
-                          /**< EtherCAT-Rahmen */
-                          uint16_t ring_position,
-                          /**< Position des Slaves im Bus */
-                          uint16_t offset,
-                          /**< Physikalische Speicheradresse im Slave */
-                          size_t data_size,
-                          /**< Länge der zu schreibenden Daten */
-                          const uint8_t *data
-                          /**< Zeiger auf Speicher mit zu schreibenden Daten */
-                          )
-{
-    EC_FUNC_HEADER;
-
+int ec_command_apwr(ec_command_t *command,
+                    /**< EtherCAT-Rahmen */
+                    uint16_t ring_position,
+                    /**< Position des Slaves im Bus */
+                    uint16_t offset,
+                    /**< Physikalische Speicheradresse im Slave */
+                    size_t data_size
+                    /**< Länge der zu schreibenden Daten */
+                    )
+{
+    EC_FUNC_HEADER;
     command->type = EC_CMD_APWR;
     command->address.physical.slave = (int16_t) ring_position * (-1);
     command->address.physical.mem = offset;
-
-    EC_FUNC_WRITE_FOOTER;
+    EC_FUNC_FOOTER;
 }
 
 /*****************************************************************************/
@@ -155,21 +196,19 @@
    Broadcast read.
 */
 
-void ec_command_init_brd(ec_command_t *command,
-                         /**< EtherCAT-Rahmen */
-                         uint16_t offset,
-                         /**< Physikalische Speicheradresse im Slave */
-                         size_t data_size
-                         /**< Länge der zu lesenden Daten */
-                         )
-{
-    EC_FUNC_HEADER;
-
+int ec_command_brd(ec_command_t *command,
+                   /**< EtherCAT-Rahmen */
+                   uint16_t offset,
+                   /**< Physikalische Speicheradresse im Slave */
+                   size_t data_size
+                   /**< Länge der zu lesenden Daten */
+                   )
+{
+    EC_FUNC_HEADER;
     command->type = EC_CMD_BRD;
     command->address.physical.slave = 0x0000;
     command->address.physical.mem = offset;
-
-    EC_FUNC_READ_FOOTER;
+    EC_FUNC_FOOTER;
 }
 
 /*****************************************************************************/
@@ -180,23 +219,19 @@
    Broadcast write.
 */
 
-void ec_command_init_bwr(ec_command_t *command,
-                         /**< EtherCAT-Rahmen */
-                         uint16_t offset,
-                         /**< Physikalische Speicheradresse im Slave */
-                         size_t data_size,
-                         /**< Länge der zu schreibenden Daten */
-                         const uint8_t *data
-                         /**< Zeiger auf Speicher mit zu schreibenden Daten */
-                         )
-{
-    EC_FUNC_HEADER;
-
+int ec_command_bwr(ec_command_t *command,
+                   /**< EtherCAT-Rahmen */
+                   uint16_t offset,
+                   /**< Physikalische Speicheradresse im Slave */
+                   size_t data_size
+                   /**< Länge der zu schreibenden Daten */
+                   )
+{
+    EC_FUNC_HEADER;
     command->type = EC_CMD_BWR;
     command->address.physical.slave = 0x0000;
     command->address.physical.mem = offset;
-
-    EC_FUNC_WRITE_FOOTER;
+    EC_FUNC_FOOTER;
 }
 
 /*****************************************************************************/
@@ -207,22 +242,18 @@
    Logical read write.
 */
 
-void ec_command_init_lrw(ec_command_t *command,
-                         /**< EtherCAT-Rahmen */
-                         uint32_t offset,
-                         /**< Logische Startadresse */
-                         size_t data_size,
-                         /**< Länge der zu lesenden/schreibenden Daten */
-                         uint8_t *data
-                         /**< Zeiger auf die Daten */
-                         )
-{
-    EC_FUNC_HEADER;
-
+int ec_command_lrw(ec_command_t *command,
+                   /**< EtherCAT-Rahmen */
+                   uint32_t offset,
+                   /**< Logische Startadresse */
+                   size_t data_size
+                   /**< Länge der zu lesenden/schreibenden Daten */
+                   )
+{
+    EC_FUNC_HEADER;
     command->type = EC_CMD_LRW;
     command->address.logical = offset;
-
-    EC_FUNC_WRITE_FOOTER;
+    EC_FUNC_FOOTER;
 }
 
 /*****************************************************************************/
--- a/master/command.h	Sun Apr 02 09:26:56 2006 +0000
+++ b/master/command.h	Mon Apr 03 10:03:34 2006 +0000
@@ -84,10 +84,12 @@
 
 typedef struct
 {
-    struct list_head list; /**< Nötig für Liste */
+    struct list_head list; /**< Kommando-Listeneintrag */
+    struct list_head queue; /**< Master-Kommando-Queue */
     ec_command_type_t type; /**< Typ des Kommandos (APRD, NPWR, etc) */
     ec_address_t address; /**< Adresse des/der Empfänger */
-    uint8_t data[EC_MAX_DATA_SIZE]; /**< Kommandodaten */
+    uint8_t *data; /**< Kommandodaten */
+    size_t mem_size; /**< Größe des Speichers */
     size_t data_size; /**< Länge der zu sendenden und/oder empfangenen Daten */
     uint8_t index; /**< Kommando-Index, wird vom Master beim Senden gesetzt. */
     uint16_t working_counter; /**< Working-Counter */
@@ -97,15 +99,16 @@
 
 /*****************************************************************************/
 
-void ec_command_init_nprd(ec_command_t *, uint16_t, uint16_t, size_t);
-void ec_command_init_npwr(ec_command_t *, uint16_t, uint16_t, size_t,
-                          const uint8_t *);
-void ec_command_init_aprd(ec_command_t *, uint16_t, uint16_t, size_t);
-void ec_command_init_apwr(ec_command_t *, uint16_t, uint16_t, size_t,
-                          const uint8_t *);
-void ec_command_init_brd(ec_command_t *, uint16_t, size_t);
-void ec_command_init_bwr(ec_command_t *, uint16_t, size_t, const uint8_t *);
-void ec_command_init_lrw(ec_command_t *, uint32_t, size_t, uint8_t *);
+void ec_command_init(ec_command_t *);
+void ec_command_clear(ec_command_t *);
+
+int ec_command_nprd(ec_command_t *, uint16_t, uint16_t, size_t);
+int ec_command_npwr(ec_command_t *, uint16_t, uint16_t, size_t);
+int ec_command_aprd(ec_command_t *, uint16_t, uint16_t, size_t);
+int ec_command_apwr(ec_command_t *, uint16_t, uint16_t, size_t);
+int ec_command_brd(ec_command_t *, uint16_t, size_t);
+int ec_command_bwr(ec_command_t *, uint16_t, size_t);
+int ec_command_lrw(ec_command_t *, uint32_t, size_t);
 
 /*****************************************************************************/
 
--- a/master/domain.c	Sun Apr 02 09:26:56 2006 +0000
+++ b/master/domain.c	Mon Apr 03 10:03:34 2006 +0000
@@ -25,14 +25,12 @@
                     )
 {
     domain->master = master;
-    domain->data = NULL;
     domain->data_size = 0;
-    domain->commands = NULL;
-    domain->command_count = 0;
     domain->base_address = 0;
     domain->response_count = 0xFFFFFFFF;
 
     INIT_LIST_HEAD(&domain->field_regs);
+    INIT_LIST_HEAD(&domain->commands);
 }
 
 /*****************************************************************************/
@@ -43,8 +41,12 @@
 
 void ec_domain_clear(ec_domain_t *domain /**< Domäne */)
 {
-    if (domain->data) kfree(domain->data);
-    if (domain->commands) kfree(domain->commands);
+    ec_command_t *command, *next;
+
+    list_for_each_entry_safe(command, next, &domain->commands, list) {
+        ec_command_clear(command);
+        kfree(command);
+    }
 
     ec_domain_clear_field_regs(domain);
 }
@@ -66,8 +68,8 @@
 {
     ec_field_reg_t *field_reg;
 
-    if (!(field_reg = (ec_field_reg_t *) kmalloc(sizeof(ec_field_reg_t),
-                                                 GFP_KERNEL))) {
+    if (!(field_reg =
+          (ec_field_reg_t *) kmalloc(sizeof(ec_field_reg_t), GFP_KERNEL))) {
         EC_ERR("Failed to allocate field registration.\n");
         return -1;
     }
@@ -107,6 +109,35 @@
 /*****************************************************************************/
 
 /**
+   Alloziert ein Prozessdatenkommando und fügt es in die Liste ein.
+*/
+
+int ec_domain_add_command(ec_domain_t *domain, /**< Domäne */
+                          uint32_t offset, /**< Logisches Offset */
+                          size_t data_size /**< Größe der Kommando-Daten */
+                          )
+{
+    ec_command_t *command;
+
+    if (!(command = kmalloc(sizeof(ec_command_t), GFP_KERNEL))) {
+        EC_ERR("Failed to allocate domain command!\n");
+        return -1;
+    }
+
+    ec_command_init(command);
+
+    if (ec_command_lrw(command, offset, data_size)) {
+        kfree(command);
+        return -1;
+    }
+
+    list_add_tail(&command->list, &domain->commands);
+    return 0;
+}
+
+/*****************************************************************************/
+
+/**
    Erzeugt eine Domäne.
 
    Reserviert den Speicher einer Domäne, berechnet die logischen Adressen der
@@ -122,19 +153,19 @@
     ec_field_reg_t *field_reg;
     ec_slave_t *slave;
     ec_fmmu_t *fmmu;
-    unsigned int i, j;
-    uint32_t data_offset;
-
-    if (domain->data) {
-        EC_ERR("Domain already allocated!\n");
-        return -1;
-    }
+    unsigned int i, j, cmd_count;
+    uint32_t field_off, field_off_cmd;
+    uint32_t cmd_offset;
+    size_t cmd_data_size;
+    ec_command_t *command;
 
     domain->base_address = base_address;
 
-    // Größe der Prozessdaten berechnen
-    // und logische Adressen der FMMUs setzen
+    // Größe der Prozessdaten berechnen und Kommandos allozieren
     domain->data_size = 0;
+    cmd_offset = base_address;
+    cmd_data_size = 0;
+    cmd_count = 0;
     for (i = 0; i < domain->master->slave_count; i++) {
         slave = &domain->master->slaves[i];
         for (j = 0; j < slave->fmmu_count; j++) {
@@ -142,49 +173,57 @@
             if (fmmu->domain == domain) {
                 fmmu->logical_start_address = base_address + domain->data_size;
                 domain->data_size += fmmu->sync->size;
+                if (cmd_data_size + fmmu->sync->size > EC_MAX_DATA_SIZE) {
+                    if (ec_domain_add_command(domain, cmd_offset,
+                                              cmd_data_size)) return -1;
+                    cmd_offset += cmd_data_size;
+                    cmd_data_size = 0;
+                    cmd_count++;
+                }
+                cmd_data_size += fmmu->sync->size;
             }
         }
     }
 
-    if (!domain->data_size) {
+    // Letztes Kommando allozieren
+    if (cmd_data_size) {
+        if (ec_domain_add_command(domain, cmd_offset, cmd_data_size))
+            return -1;
+        cmd_count++;
+    }
+
+    if (!cmd_count) {
         EC_WARN("Domain 0x%08X contains no data!\n", (u32) domain);
         ec_domain_clear_field_regs(domain);
         return 0;
     }
 
-    // Prozessdaten allozieren
-    if (!(domain->data = kmalloc(domain->data_size, GFP_KERNEL))) {
-        EC_ERR("Failed to allocate domain data!\n");
-        return -1;
-    }
-
-    // Prozessdaten mit Nullen vorbelegen
-    memset(domain->data, 0x00, domain->data_size);
-
     // Alle Prozessdatenzeiger setzen
     list_for_each_entry(field_reg, &domain->field_regs, list) {
         for (i = 0; i < field_reg->slave->fmmu_count; i++) {
             fmmu = &field_reg->slave->fmmus[i];
             if (fmmu->domain == domain && fmmu->sync == field_reg->sync) {
-                data_offset = fmmu->logical_start_address - base_address
-                    + field_reg->field_offset;
-                *field_reg->data_ptr = domain->data + data_offset;
+                field_off = fmmu->logical_start_address +
+                    field_reg->field_offset;
+                // Kommando suchen
+                list_for_each_entry(command, &domain->commands, list) {
+                    field_off_cmd = field_off - command->address.logical;
+                    if (field_off >= command->address.logical &&
+                        field_off_cmd < command->mem_size) {
+                        *field_reg->data_ptr = command->data + field_off_cmd;
+                    }
+                }
+                if (!field_reg->data_ptr) {
+                    EC_ERR("Failed to assign data pointer!\n");
+                    return -1;
+                }
                 break;
             }
         }
     }
 
-    // Kommando-Array erzeugen
-    domain->command_count = domain->data_size / EC_MAX_DATA_SIZE + 1;
-    if (!(domain->commands = (ec_command_t *) kmalloc(sizeof(ec_command_t)
-                                                      * domain->command_count,
-                                                      GFP_KERNEL))) {
-        EC_ERR("Failed to allocate domain command array!\n");
-        return -1;
-    }
-
     EC_INFO("Domain %X - Allocated %i bytes in %i command(s)\n",
-            (u32) domain, domain->data_size, domain->command_count);
+            (u32) domain, domain->data_size, cmd_count);
 
     ec_domain_clear_field_regs(domain);
 
@@ -346,19 +385,10 @@
 
 void ecrt_domain_queue(ec_domain_t *domain /**< Domäne */)
 {
-    unsigned int i;
-    size_t size;
-    off_t offset;
-
-    offset = 0;
-    for (i = 0; i < domain->command_count; i++) {
-        size = domain->data_size - offset;
-        if (size > EC_MAX_DATA_SIZE) size = EC_MAX_DATA_SIZE;
-        ec_command_init_lrw(domain->commands + i,
-                            domain->base_address + offset, size,
-                            domain->data + offset);
-        ec_master_queue_command(domain->master, domain->commands + i);
-        offset += size;
+    ec_command_t *command;
+
+    list_for_each_entry(command, &domain->commands, list) {
+        ec_master_queue_command(domain->master, command);
     }
 }
 
@@ -370,27 +400,15 @@
 
 void ecrt_domain_process(ec_domain_t *domain /**< Domäne */)
 {
-    unsigned int working_counter_sum, i;
+    unsigned int working_counter_sum;
     ec_command_t *command;
-    size_t size;
-    off_t offset;
 
     working_counter_sum = 0;
 
-    offset = 0;
-    for (i = 0; i < domain->command_count; i++) {
-        command = domain->commands + i;
-        size = domain->data_size - offset;
-        if (size > EC_MAX_DATA_SIZE) size = EC_MAX_DATA_SIZE;
+    list_for_each_entry(command, &domain->commands, list) {
         if (command->state == EC_CMD_RECEIVED) {
-            // Daten vom Kommando- in den Prozessdatenspeicher kopieren
-            memcpy(domain->data + offset, command->data, size);
             working_counter_sum += command->working_counter;
         }
-        else if (unlikely(domain->master->debug_level)) {
-            EC_DBG("process data command not received!\n");
-        }
-        offset += size;
     }
 
     ec_domain_response_count(domain, working_counter_sum);
@@ -406,11 +424,9 @@
 
 int ecrt_domain_state(ec_domain_t *domain /**< Domäne */)
 {
-    unsigned int i;
     ec_command_t *command;
 
-    for (i = 0; i < domain->command_count; i++) {
-        command = domain->commands + i;
+    list_for_each_entry(command, &domain->commands, list) {
         if (command->state != EC_CMD_RECEIVED) return -1;
     }
 
--- a/master/domain.h	Sun Apr 02 09:26:56 2006 +0000
+++ b/master/domain.h	Mon Apr 03 10:03:34 2006 +0000
@@ -46,10 +46,8 @@
 {
     struct list_head list; /**< Listenkopf */
     ec_master_t *master; /**< EtherCAT-Master, zu der die Domäne gehört. */
-    uint8_t *data; /**< Prozessdaten */
     size_t data_size; /**< Größe der Prozessdaten */
-    ec_command_t *commands; /**< EtherCAT-Kommandos für die Prozessdaten */
-    unsigned int command_count; /**< Anzahl allozierter Kommandos */
+    struct list_head commands; /**< EtherCAT-Kommandos für die Prozessdaten */
     uint32_t base_address; /**< Logische Basisaddresse der Domain */
     unsigned int response_count; /**< Anzahl antwortender Slaves */
     struct list_head field_regs; /**< Liste der Datenfeldregistrierungen */
--- a/master/master.c	Sun Apr 02 09:26:56 2006 +0000
+++ b/master/master.c	Mon Apr 03 10:03:34 2006 +0000
@@ -33,9 +33,12 @@
     master->slaves = NULL;
     master->device = NULL;
 
-    INIT_LIST_HEAD(&master->commands);
+    INIT_LIST_HEAD(&master->command_queue);
     INIT_LIST_HEAD(&master->domains);
 
+    ec_command_init(&master->simple_command);
+    ec_command_init(&master->watch_command);
+
     ec_master_reset(master);
 }
 
@@ -56,6 +59,9 @@
         ec_device_clear(master->device);
         kfree(master->device);
     }
+
+    ec_command_clear(&master->simple_command);
+    ec_command_clear(&master->watch_command);
 }
 
 /*****************************************************************************/
@@ -72,8 +78,8 @@
                      )
 {
     unsigned int i;
-    ec_command_t *command, *next_command;
-    ec_domain_t *domain, *next_domain;
+    ec_command_t *command, *next_c;
+    ec_domain_t *domain, *next_d;
 
     // Alle Slaves entfernen
     if (master->slaves) {
@@ -86,13 +92,13 @@
     master->slave_count = 0;
 
     // Kommando-Warteschlange leeren
-    list_for_each_entry_safe(command, next_command, &master->commands, list) {
+    list_for_each_entry_safe(command, next_c, &master->command_queue, queue) {
         command->state = EC_CMD_ERROR;
-        list_del_init(&command->list);
+        list_del_init(&command->queue);
     }
 
     // Domain-Liste leeren
-    list_for_each_entry_safe(domain, next_domain, &master->domains, list) {
+    list_for_each_entry_safe(domain, next_d, &master->domains, list) {
         list_del(&domain->list);
         ec_domain_clear(domain);
         kfree(domain);
@@ -166,7 +172,7 @@
     ec_command_t *queued_command;
 
     // Ist das Kommando schon in der Warteschlange?
-    list_for_each_entry(queued_command, &master->commands, list) {
+    list_for_each_entry(queued_command, &master->command_queue, queue) {
         if (queued_command == command) {
             command->state = EC_CMD_QUEUED;
             if (unlikely(master->debug_level))
@@ -175,7 +181,7 @@
         }
     }
 
-    list_add_tail(&command->list, &master->commands);
+    list_add_tail(&command->queue, &master->command_queue);
     command->state = EC_CMD_QUEUED;
 }
 
@@ -206,7 +212,7 @@
     follows_word = NULL;
 
     // Aktuellen Frame mit Kommandos füllen
-    list_for_each_entry(command, &master->commands, list) {
+    list_for_each_entry(command, &master->command_queue, queue) {
         if (command->state != EC_CMD_QUEUED) continue;
 
         // Passt das aktuelle Kommando noch in den aktuellen Rahmen?
@@ -238,7 +244,7 @@
         cur_data += command->data_size;
 
         // EtherCAT command footer
-        EC_WRITE_U16(cur_data, command->working_counter);
+        EC_WRITE_U16(cur_data, 0x0000); // Working counter
         cur_data += EC_COMMAND_FOOTER_SIZE;
     }
 
@@ -323,7 +329,7 @@
 
         // Suche passendes Kommando in der Liste
         matched = 0;
-        list_for_each_entry(command, &master->commands, list) {
+        list_for_each_entry(command, &master->command_queue, queue) {
             if (command->state == EC_CMD_SENT
                 && command->type == command_type
                 && command->index == command_index
@@ -349,9 +355,9 @@
         command->working_counter = EC_READ_U16(cur_data);
         cur_data += EC_COMMAND_FOOTER_SIZE;
 
-        // Kommando aus der Liste entfernen
+        // Kommando aus der Warteschlange entfernen
         command->state = EC_CMD_RECEIVED;
-        list_del_init(&command->list);
+        list_del_init(&command->queue);
     }
 }
 
@@ -366,13 +372,13 @@
    \return 0 bei Erfolg, sonst < 0
 */
 
-int ec_master_simple_io(ec_master_t *master, /**< EtherCAT-Master */
-                        ec_command_t *command /**< Kommando */
-                        )
+int ec_master_simple_io(ec_master_t *master /**< EtherCAT-Master */)
 {
     unsigned int response_tries_left;
+    ec_command_t *command;
 
     response_tries_left = 10;
+    command = &master->simple_command;
 
     while (1)
     {
@@ -415,21 +421,22 @@
 
 int ec_master_bus_scan(ec_master_t *master /**< EtherCAT-Master */)
 {
-    ec_command_t command;
     ec_slave_t *slave;
     ec_slave_ident_t *ident;
     unsigned int i;
-    uint8_t data[2];
+    ec_command_t *command;
 
     if (master->slaves || master->slave_count) {
         EC_ERR("Slave scan already done!\n");
         return -1;
     }
 
+    command = &master->simple_command;
+
     // Determine number of slaves on bus
-    ec_command_init_brd(&command, 0x0000, 4);
-    if (unlikely(ec_master_simple_io(master, &command))) return -1;
-    master->slave_count = command.working_counter;
+    if (ec_command_brd(command, 0x0000, 4)) return -1;
+    if (unlikely(ec_master_simple_io(master))) return -1;
+    master->slave_count = command->working_counter;
     EC_INFO("Found %i slaves on bus.\n", master->slave_count);
 
     if (!master->slave_count) return 0;
@@ -455,10 +462,10 @@
         slave = master->slaves + i;
 
         // Write station address
-        EC_WRITE_U16(data, slave->station_address);
-        ec_command_init_apwr(&command, slave->ring_position,
-                             0x0010, sizeof(uint16_t), data);
-        if (unlikely(ec_master_simple_io(master, &command))) {
+        if (ec_command_apwr(command, slave->ring_position,
+                            0x0010, sizeof(uint16_t))) return -1;
+        EC_WRITE_U16(command->data, slave->station_address);
+        if (unlikely(ec_master_simple_io(master))) {
             EC_ERR("Writing station address failed on slave %i!\n", i);
             return -1;
         }
@@ -713,6 +720,8 @@
 {
     unsigned int first;
 
+    if (unlikely(master->watch_command.state == EC_CMD_INIT)) return;
+
     first = 1;
 
     if (master->watch_command.working_counter != master->slaves_responding ||
@@ -789,15 +798,21 @@
 {
     unsigned int i, j;
     ec_slave_t *slave;
-    ec_command_t command;
+    ec_command_t *command;
     const ec_sync_t *sync;
     const ec_slave_type_t *type;
     const ec_fmmu_t *fmmu;
-    uint8_t data[256];
     uint32_t domain_offset;
     ec_domain_t *domain;
     ec_eeprom_sync_t *eeprom_sync;
 
+    command = &master->simple_command;
+
+    if (ec_command_brd(&master->watch_command, 0x130, 2)) {
+        EC_ERR("Failed to allocate watchdog command!\n");
+        return -1;
+    }
+
     // Domains erstellen
     domain_offset = 0;
     list_for_each_entry(domain, &master->domains, list) {
@@ -826,10 +841,11 @@
 
         // Resetting FMMUs
         if (slave->base_fmmu_count) {
-            memset(data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count);
-            ec_command_init_npwr(&command, slave->station_address, 0x0600,
-                                 EC_FMMU_SIZE * slave->base_fmmu_count, data);
-            if (unlikely(ec_master_simple_io(master, &command))) {
+            if (ec_command_npwr(command, slave->station_address, 0x0600,
+                                EC_FMMU_SIZE * slave->base_fmmu_count))
+                return -1;
+            memset(command->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count);
+            if (unlikely(ec_master_simple_io(master))) {
                 EC_ERR("Resetting FMMUs failed on slave %i!\n",
                        slave->ring_position);
                 return -1;
@@ -838,10 +854,11 @@
 
         // Resetting Sync Manager channels
         if (slave->base_sync_count) {
-            memset(data, 0x00, EC_SYNC_SIZE * slave->base_sync_count);
-            ec_command_init_npwr(&command, slave->station_address, 0x0800,
-                                 EC_SYNC_SIZE * slave->base_sync_count, data);
-            if (unlikely(ec_master_simple_io(master, &command))) {
+            if (ec_command_npwr(command, slave->station_address, 0x0800,
+                                EC_SYNC_SIZE * slave->base_sync_count))
+                return -1;
+            memset(command->data, 0x00, EC_SYNC_SIZE * slave->base_sync_count);
+            if (unlikely(ec_master_simple_io(master))) {
                 EC_ERR("Resetting sync managers failed on slave %i!\n",
                        slave->ring_position);
                 return -1;
@@ -853,11 +870,11 @@
             for (j = 0; type->sync_managers[j] && j < EC_MAX_SYNC; j++)
             {
                 sync = type->sync_managers[j];
-                ec_sync_config(sync, data);
-                ec_command_init_npwr(&command, slave->station_address,
-                                     0x0800 + j * EC_SYNC_SIZE, EC_SYNC_SIZE,
-                                     data);
-                if (unlikely(ec_master_simple_io(master, &command))) {
+                if (ec_command_npwr(command, slave->station_address,
+                                    0x0800 + j * EC_SYNC_SIZE, EC_SYNC_SIZE))
+                    return -1;
+                ec_sync_config(sync, command->data);
+                if (unlikely(ec_master_simple_io(master))) {
                     EC_ERR("Setting sync manager %i failed on slave %i!\n",
                            j, slave->ring_position);
                     return -1;
@@ -866,11 +883,11 @@
         }
         else if (slave->sii_mailbox_protocols) { // Unknown slave, has mailbox
             list_for_each_entry(eeprom_sync, &slave->eeprom_syncs, list) {
-                ec_eeprom_sync_config(eeprom_sync, data);
-                ec_command_init_npwr(&command, slave->station_address,
-                                     0x800 + eeprom_sync->index * EC_SYNC_SIZE,
-                                     EC_SYNC_SIZE, data);
-                if (unlikely(ec_master_simple_io(master, &command))) {
+                if (ec_command_npwr(command, slave->station_address,
+                                    0x800 + eeprom_sync->index * EC_SYNC_SIZE,
+                                    EC_SYNC_SIZE)) return -1;
+                ec_eeprom_sync_config(eeprom_sync, command->data);
+                if (unlikely(ec_master_simple_io(master))) {
                     EC_ERR("Setting sync manager %i failed on slave %i!\n",
                            eeprom_sync->index, slave->ring_position);
                     return -1;
@@ -896,12 +913,11 @@
         for (j = 0; j < slave->fmmu_count; j++)
         {
             fmmu = &slave->fmmus[j];
-
-            ec_fmmu_config(fmmu, data);
-            ec_command_init_npwr(&command, slave->station_address,
-                                 0x0600 + j * EC_FMMU_SIZE, EC_FMMU_SIZE,
-                                 data);
-            if (unlikely(ec_master_simple_io(master, &command))) {
+            if (ec_command_npwr(command, slave->station_address,
+                                0x0600 + j * EC_FMMU_SIZE, EC_FMMU_SIZE))
+                return -1;
+            ec_fmmu_config(fmmu, command->data);
+            if (unlikely(ec_master_simple_io(master))) {
                 EC_ERR("Setting FMMU %i failed on slave %i!\n",
                        j, slave->ring_position);
                 return -1;
@@ -980,31 +996,17 @@
 
 void ecrt_master_sync_io(ec_master_t *master)
 {
-    ec_command_t *command, *next;
+    ec_command_t *command, *n;
     unsigned int commands_sent;
     cycles_t t_start, t_end, t_timeout;
 
-    ec_master_output_stats(master);
-
-    if (unlikely(!master->device->link_state)) {
-        // Link DOWN, keines der Kommandos kann gesendet werden.
-        list_for_each_entry_safe(command, next, &master->commands, list) {
-            command->state = EC_CMD_ERROR;
-            list_del_init(&command->list);
-        }
-
-        // Device-Zustand abfragen
-        ec_device_call_isr(master->device);
-        return;
-    }
-
-    // Rahmen senden
-    ec_master_send_commands(master);
+    // Kommandos senden
+    ecrt_master_async_send(master);
 
     t_start = get_cycles(); // Sendezeit nehmen
     t_timeout = (cycles_t) master->timeout * (cpu_khz / 1000);
 
-    while (1)
+    while (1) // Aktiv auf Empfang warten
     {
         ec_device_call_isr(master->device);
 
@@ -1012,9 +1014,9 @@
         if (t_end - t_start >= t_timeout) break; // Timeout
 
         commands_sent = 0;
-        list_for_each_entry_safe(command, next, &master->commands, list) {
+        list_for_each_entry_safe(command, n, &master->command_queue, queue) {
             if (command->state == EC_CMD_RECEIVED)
-                list_del_init(&command->list);
+                list_del_init(&command->queue);
             else if (command->state == EC_CMD_SENT)
                 commands_sent++;
         }
@@ -1023,7 +1025,7 @@
     }
 
     // Zeit abgelaufen. Alle verbleibenden Kommandos entfernen.
-    list_for_each_entry_safe(command, next, &master->commands, list) {
+    list_for_each_entry_safe(command, n, &master->command_queue, queue) {
         switch (command->state) {
             case EC_CMD_SENT:
             case EC_CMD_QUEUED:
@@ -1038,7 +1040,7 @@
             default:
                 break;
         }
-        list_del_init(&command->list);
+        list_del_init(&command->queue);
     }
 }
 
@@ -1050,15 +1052,13 @@
 
 void ecrt_master_async_send(ec_master_t *master)
 {
-    ec_command_t *command, *next;
-
-    ec_master_output_stats(master);
+    ec_command_t *command, *n;
 
     if (unlikely(!master->device->link_state)) {
         // Link DOWN, keines der Kommandos kann gesendet werden.
-        list_for_each_entry_safe(command, next, &master->commands, list) {
+        list_for_each_entry_safe(command, n, &master->command_queue, queue) {
             command->state = EC_CMD_ERROR;
-            list_del_init(&command->list);
+            list_del_init(&command->queue);
         }
 
         // Device-Zustand abfragen
@@ -1066,10 +1066,6 @@
         return;
     }
 
-    // Watch-Kommando hinzufügen
-    ec_command_init_brd(&master->watch_command, 0x130, 2);
-    ec_master_queue_command(master, &master->watch_command);
-
     // Rahmen senden
     ec_master_send_commands(master);
 }
@@ -1087,12 +1083,11 @@
     ec_device_call_isr(master->device);
 
     // Alle empfangenen Kommandos aus der Liste entfernen
-    list_for_each_entry_safe(command, next, &master->commands, list)
-        if (command->state == EC_CMD_RECEIVED)
-            list_del_init(&command->list);
+    list_for_each_entry_safe(command, next, &master->command_queue, queue)
+        if (command->state == EC_CMD_RECEIVED) list_del_init(&command->queue);
 
     // Alle verbleibenden Kommandos entfernen.
-    list_for_each_entry_safe(command, next, &master->commands, list) {
+    list_for_each_entry_safe(command, next, &master->command_queue, queue) {
         switch (command->state) {
             case EC_CMD_SENT:
             case EC_CMD_QUEUED:
@@ -1103,14 +1098,8 @@
             default:
                 break;
         }
-        list_del_init(&command->list);
-    }
-
-    // Watch-Kommando verarbeiten
-    ec_master_process_watch_command(master);
-
-    // Statistiken ausgeben
-    ec_master_output_stats(master);
+        list_del_init(&command->queue);
+    }
 }
 
 /*****************************************************************************/
@@ -1128,7 +1117,7 @@
     ec_domain_t *domain;
     cycles_t t_start, t_end, t_timeout;
 
-    // Alle empfangenen Kommandos aus der Liste entfernen
+    // Kommandos aller Domains in die Warteschlange setzen
     list_for_each_entry(domain, &master->domains, list)
         ecrt_domain_queue(domain);
 
@@ -1147,6 +1136,22 @@
 /*****************************************************************************/
 
 /**
+   Führt Routinen im zyklischen Betrieb aus.
+*/
+
+void ecrt_master_run(ec_master_t *master /**< EtherCAT-Master */)
+{
+    // Statistiken ausgeben
+    ec_master_output_stats(master);
+
+    // Watchdog-Kommando
+    ec_master_process_watch_command(master);
+    ec_master_queue_command(master, &master->watch_command);
+}
+
+/*****************************************************************************/
+
+/**
    Setzt die Debug-Ebene des Masters.
 
    Folgende Debug-Level sind definiert:
@@ -1198,6 +1203,7 @@
 EXPORT_SYMBOL(ecrt_master_sync_io);
 EXPORT_SYMBOL(ecrt_master_async_send);
 EXPORT_SYMBOL(ecrt_master_async_receive);
+EXPORT_SYMBOL(ecrt_master_run);
 EXPORT_SYMBOL(ecrt_master_debug);
 EXPORT_SYMBOL(ecrt_master_print);
 EXPORT_SYMBOL(ecrt_master_get_slave);
--- a/master/master.h	Sun Apr 02 09:26:56 2006 +0000
+++ b/master/master.h	Mon Apr 03 10:03:34 2006 +0000
@@ -47,9 +47,10 @@
     ec_slave_t *slaves; /**< Array von Slaves auf dem Bus */
     unsigned int slave_count; /**< Anzahl Slaves auf dem Bus */
     ec_device_t *device; /**< EtherCAT-Gerät */
-    struct list_head commands; /**< Kommando-Liste */
+    struct list_head command_queue; /**< Kommando-Warteschlange */
     uint8_t command_index; /**< Aktueller Kommando-Index */
     struct list_head domains; /**< Liste der Prozessdatendomänen */
+    ec_command_t simple_command; /**< Kommando für Initialisierungsphase */
     ec_command_t watch_command; /**< Kommando zum Überwachen der Slaves */
     unsigned int slaves_responding; /**< Anzahl antwortender Slaves */
     ec_slave_state_t slave_states; /**< Zustände der antwortenden Slaves */
@@ -68,7 +69,7 @@
 // IO
 void ec_master_receive(ec_master_t *, const uint8_t *, size_t);
 void ec_master_queue_command(ec_master_t *, ec_command_t *);
-int ec_master_simple_io(ec_master_t *, ec_command_t *);
+int ec_master_simple_io(ec_master_t *);
 
 // Registration of devices
 int ec_master_open(ec_master_t *);
--- a/master/slave.c	Sun Apr 02 09:26:56 2006 +0000
+++ b/master/slave.c	Mon Apr 03 10:03:34 2006 +0000
@@ -141,36 +141,38 @@
 
 int ec_slave_fetch(ec_slave_t *slave /**< EtherCAT-Slave */)
 {
-    ec_command_t command;
+    ec_command_t *command;
     unsigned int i;
     uint16_t dl_status;
 
+    command = &slave->master->simple_command;
+
     // Read base data
-    ec_command_init_nprd(&command, slave->station_address, 0x0000, 6);
-    if (unlikely(ec_master_simple_io(slave->master, &command))) {
+    if (ec_command_nprd(command, slave->station_address, 0x0000, 6)) return -1;
+    if (unlikely(ec_master_simple_io(slave->master))) {
         EC_ERR("Reading base data from slave %i failed!\n",
                slave->ring_position);
         return -1;
     }
 
-    slave->base_type =       EC_READ_U8 (command.data);
-    slave->base_revision =   EC_READ_U8 (command.data + 1);
-    slave->base_build =      EC_READ_U16(command.data + 2);
-    slave->base_fmmu_count = EC_READ_U8 (command.data + 4);
-    slave->base_sync_count = EC_READ_U8 (command.data + 5);
+    slave->base_type =       EC_READ_U8 (command->data);
+    slave->base_revision =   EC_READ_U8 (command->data + 1);
+    slave->base_build =      EC_READ_U16(command->data + 2);
+    slave->base_fmmu_count = EC_READ_U8 (command->data + 4);
+    slave->base_sync_count = EC_READ_U8 (command->data + 5);
 
     if (slave->base_fmmu_count > EC_MAX_FMMUS)
         slave->base_fmmu_count = EC_MAX_FMMUS;
 
     // Read DL status
-    ec_command_init_nprd(&command, slave->station_address, 0x0110, 2);
-    if (unlikely(ec_master_simple_io(slave->master, &command))) {
+    if (ec_command_nprd(command, slave->station_address, 0x0110, 2)) return -1;
+    if (unlikely(ec_master_simple_io(slave->master))) {
         EC_ERR("Reading DL status from slave %i failed!\n",
                slave->ring_position);
         return -1;
     }
 
-    dl_status = EC_READ_U16(command.data);
+    dl_status = EC_READ_U16(command->data);
     for (i = 0; i < 2; i++) {
         slave->dl_status_link[i] = dl_status & (1 << (4 + i)) ? 1 : 0;
         slave->dl_status_loop[i] = dl_status & (1 << (8 + i * 2)) ? 1 : 0;
@@ -224,18 +226,17 @@
                         /**< Speicher für Wert (16-Bit) */
                         )
 {
-    ec_command_t command;
-    uint8_t data[10];
+    ec_command_t *command;
     cycles_t start, end, timeout;
 
+    command = &slave->master->simple_command;
+
     // Initiate read operation
-
-    EC_WRITE_U8 (data,     0x00); // read-only access
-    EC_WRITE_U8 (data + 1, 0x01); // request read operation
-    EC_WRITE_U32(data + 2, offset);
-
-    ec_command_init_npwr(&command, slave->station_address, 0x502, 6, data);
-    if (unlikely(ec_master_simple_io(slave->master, &command))) {
+    if (ec_command_npwr(command, slave->station_address, 0x502, 6)) return -1;
+    EC_WRITE_U8 (command->data,     0x00); // read-only access
+    EC_WRITE_U8 (command->data + 1, 0x01); // request read operation
+    EC_WRITE_U32(command->data + 2, offset);
+    if (unlikely(ec_master_simple_io(slave->master))) {
         EC_ERR("SII-read failed on slave %i!\n", slave->ring_position);
         return -1;
     }
@@ -251,8 +252,9 @@
     {
         udelay(10);
 
-        ec_command_init_nprd(&command, slave->station_address, 0x502, 10);
-        if (unlikely(ec_master_simple_io(slave->master, &command))) {
+        if (ec_command_nprd(command, slave->station_address, 0x502, 10))
+            return -1;
+        if (unlikely(ec_master_simple_io(slave->master))) {
             EC_ERR("Getting SII-read status failed on slave %i!\n",
                    slave->ring_position);
             return -1;
@@ -260,8 +262,8 @@
 
         end = get_cycles();
 
-        if (likely((EC_READ_U8(command.data + 1) & 0x81) == 0)) {
-            *target = EC_READ_U16(command.data + 6);
+        if (likely((EC_READ_U8(command->data + 1) & 0x81) == 0)) {
+            *target = EC_READ_U16(command->data + 6);
             return 0;
         }
 
@@ -289,18 +291,17 @@
                         /**< Speicher für Wert (32-Bit) */
                         )
 {
-    ec_command_t command;
-    uint8_t data[10];
+    ec_command_t *command;
     cycles_t start, end, timeout;
 
+    command = &slave->master->simple_command;
+
     // Initiate read operation
-
-    EC_WRITE_U8 (data,     0x00); // read-only access
-    EC_WRITE_U8 (data + 1, 0x01); // request read operation
-    EC_WRITE_U32(data + 2, offset);
-
-    ec_command_init_npwr(&command, slave->station_address, 0x502, 6, data);
-    if (unlikely(ec_master_simple_io(slave->master, &command))) {
+    if (ec_command_npwr(command, slave->station_address, 0x502, 6)) return -1;
+    EC_WRITE_U8 (command->data,     0x00); // read-only access
+    EC_WRITE_U8 (command->data + 1, 0x01); // request read operation
+    EC_WRITE_U32(command->data + 2, offset);
+    if (unlikely(ec_master_simple_io(slave->master))) {
         EC_ERR("SII-read failed on slave %i!\n", slave->ring_position);
         return -1;
     }
@@ -316,8 +317,9 @@
     {
         udelay(10);
 
-        ec_command_init_nprd(&command, slave->station_address, 0x502, 10);
-        if (unlikely(ec_master_simple_io(slave->master, &command))) {
+        if (ec_command_nprd(command, slave->station_address, 0x502, 10))
+            return -1;
+        if (unlikely(ec_master_simple_io(slave->master))) {
             EC_ERR("Getting SII-read status failed on slave %i!\n",
                    slave->ring_position);
             return -1;
@@ -325,8 +327,8 @@
 
         end = get_cycles();
 
-        if (likely((EC_READ_U8(command.data + 1) & 0x81) == 0)) {
-            *target = EC_READ_U32(command.data + 6);
+        if (likely((EC_READ_U8(command->data + 1) & 0x81) == 0)) {
+            *target = EC_READ_U32(command->data + 6);
             return 0;
         }
 
@@ -354,22 +356,21 @@
                          /**< Zu schreibender Wert */
                          )
 {
-    ec_command_t command;
-    uint8_t data[8];
+    ec_command_t *command;
     cycles_t start, end, timeout;
 
+    command = &slave->master->simple_command;
+
     EC_INFO("SII-write (slave %i, offset 0x%04X, value 0x%04X)\n",
             slave->ring_position, offset, value);
 
     // Initiate write operation
-
-    EC_WRITE_U8 (data,     0x01); // enable write access
-    EC_WRITE_U8 (data + 1, 0x02); // request write operation
-    EC_WRITE_U32(data + 2, offset);
-    EC_WRITE_U16(data + 6, value);
-
-    ec_command_init_npwr(&command, slave->station_address, 0x502, 8, data);
-    if (unlikely(ec_master_simple_io(slave->master, &command))) {
+    if (ec_command_npwr(command, slave->station_address, 0x502, 8)) return -1;
+    EC_WRITE_U8 (command->data,     0x01); // enable write access
+    EC_WRITE_U8 (command->data + 1, 0x02); // request write operation
+    EC_WRITE_U32(command->data + 2, offset);
+    EC_WRITE_U16(command->data + 6, value);
+    if (unlikely(ec_master_simple_io(slave->master))) {
         EC_ERR("SII-write failed on slave %i!\n", slave->ring_position);
         return -1;
     }
@@ -385,8 +386,9 @@
     {
         udelay(10);
 
-        ec_command_init_nprd(&command, slave->station_address, 0x502, 2);
-        if (unlikely(ec_master_simple_io(slave->master, &command))) {
+        if (ec_command_nprd(command, slave->station_address, 0x502, 2))
+            return -1;
+        if (unlikely(ec_master_simple_io(slave->master))) {
             EC_ERR("Getting SII-write status failed on slave %i!\n",
                    slave->ring_position);
             return -1;
@@ -394,8 +396,8 @@
 
         end = get_cycles();
 
-        if (likely((EC_READ_U8(command.data + 1) & 0x82) == 0)) {
-            if (EC_READ_U8(command.data + 1) & 0x40) {
+        if (likely((EC_READ_U8(command->data + 1) & 0x82) == 0)) {
+            if (EC_READ_U8(command->data + 1) & 0x40) {
                 EC_ERR("SII-write failed!\n");
                 return -1;
             }
@@ -717,14 +719,14 @@
                         /**< Alter Zustand */
                         )
 {
-    ec_command_t command;
-    uint8_t data[2];
+    ec_command_t *command;
     cycles_t start, end, timeout;
 
-    EC_WRITE_U16(data, state | EC_ACK);
-
-    ec_command_init_npwr(&command, slave->station_address, 0x0120, 2, data);
-    if (unlikely(ec_master_simple_io(slave->master, &command))) {
+    command = &slave->master->simple_command;
+
+    if (ec_command_npwr(command, slave->station_address, 0x0120, 2)) return;
+    EC_WRITE_U16(command->data, state | EC_ACK);
+    if (unlikely(ec_master_simple_io(slave->master))) {
         EC_WARN("State %02X acknowledge failed on slave %i!\n",
                 state, slave->ring_position);
         return;
@@ -737,8 +739,9 @@
     {
         udelay(100); // Dem Slave etwas Zeit lassen...
 
-        ec_command_init_nprd(&command, slave->station_address, 0x0130, 2);
-        if (unlikely(ec_master_simple_io(slave->master, &command))) {
+        if (ec_command_nprd(command, slave->station_address, 0x0130, 2))
+            return;
+        if (unlikely(ec_master_simple_io(slave->master))) {
             EC_WARN("State %02X acknowledge checking failed on slave %i!\n",
                     state, slave->ring_position);
             return;
@@ -746,14 +749,14 @@
 
         end = get_cycles();
 
-        if (unlikely(EC_READ_U8(command.data) != state)) {
+        if (unlikely(EC_READ_U8(command->data) != state)) {
             EC_WARN("Could not acknowledge state %02X on slave %i (code"
                     " %02X)!\n", state, slave->ring_position,
-                    EC_READ_U8(command.data));
+                    EC_READ_U8(command->data));
             return;
         }
 
-        if (likely(EC_READ_U8(command.data) == state)) {
+        if (likely(EC_READ_U8(command->data) == state)) {
             EC_INFO("Acknowleged state %02X on slave %i.\n", state,
                     slave->ring_position);
             return;
@@ -781,14 +784,14 @@
                           /**< Neuer Zustand */
                           )
 {
-    ec_command_t command;
-    uint8_t data[2];
+    ec_command_t *command;
     cycles_t start, end, timeout;
 
-    EC_WRITE_U16(data, state);
-
-    ec_command_init_npwr(&command, slave->station_address, 0x0120, 2, data);
-    if (unlikely(ec_master_simple_io(slave->master, &command))) {
+    command = &slave->master->simple_command;
+
+    if (ec_command_npwr(command, slave->station_address, 0x0120, 2)) return -1;
+    EC_WRITE_U16(command->data, state);
+    if (unlikely(ec_master_simple_io(slave->master))) {
         EC_ERR("Failed to set state %02X on slave %i!\n",
                state, slave->ring_position);
         return -1;
@@ -801,8 +804,9 @@
     {
         udelay(100); // Dem Slave etwas Zeit lassen...
 
-        ec_command_init_nprd(&command, slave->station_address, 0x0130, 2);
-        if (unlikely(ec_master_simple_io(slave->master, &command))) {
+        if (ec_command_nprd(command, slave->station_address, 0x0130, 2))
+            return -1;
+        if (unlikely(ec_master_simple_io(slave->master))) {
             EC_ERR("Failed to check state %02X on slave %i!\n",
                    state, slave->ring_position);
             return -1;
@@ -810,15 +814,15 @@
 
         end = get_cycles();
 
-        if (unlikely(EC_READ_U8(command.data) & 0x10)) { // State change error
+        if (unlikely(EC_READ_U8(command->data) & 0x10)) { // State change error
             EC_ERR("Could not set state %02X - Slave %i refused state change"
                    " (code %02X)!\n", state, slave->ring_position,
-                   EC_READ_U8(command.data));
-            ec_slave_state_ack(slave, EC_READ_U8(command.data) & 0x0F);
-            return -1;
-        }
-
-        if (likely(EC_READ_U8(command.data) == (state & 0x0F))) {
+                   EC_READ_U8(command->data));
+            ec_slave_state_ack(slave, EC_READ_U8(command->data) & 0x0F);
+            return -1;
+        }
+
+        if (likely(EC_READ_U8(command->data) == (state & 0x0F))) {
             // State change successful
             return 0;
         }
@@ -1040,44 +1044,45 @@
 
 int ec_slave_check_crc(ec_slave_t *slave /**< EtherCAT-Slave */)
 {
-    ec_command_t command;
-    uint8_t data[4];
-
-    ec_command_init_nprd(&command, slave->station_address, 0x0300, 4);
-    if (unlikely(ec_master_simple_io(slave->master, &command))) {
+    ec_command_t *command;
+
+    command = &slave->master->simple_command;
+
+    if (ec_command_nprd(command, slave->station_address, 0x0300, 4)) return -1;
+    if (unlikely(ec_master_simple_io(slave->master))) {
         EC_WARN("Reading CRC fault counters failed on slave %i!\n",
                 slave->ring_position);
         return -1;
     }
 
     // No CRC faults.
-    if (!EC_READ_U32(command.data)) return 0;
-
-    if (EC_READ_U8(command.data))
+    if (!EC_READ_U32(command->data)) return 0;
+
+    if (EC_READ_U8(command->data))
         EC_WARN("%3i RX-error%s on slave %i, channel A.\n",
-                EC_READ_U8(command.data),
-                EC_READ_U8(command.data) == 1 ? "" : "s",
+                EC_READ_U8(command->data),
+                EC_READ_U8(command->data) == 1 ? "" : "s",
                 slave->ring_position);
-    if (EC_READ_U8(command.data + 1))
+    if (EC_READ_U8(command->data + 1))
         EC_WARN("%3i invalid frame%s on slave %i, channel A.\n",
-                EC_READ_U8(command.data + 1),
-                EC_READ_U8(command.data + 1) == 1 ? "" : "s",
+                EC_READ_U8(command->data + 1),
+                EC_READ_U8(command->data + 1) == 1 ? "" : "s",
                 slave->ring_position);
-    if (EC_READ_U8(command.data + 2))
+    if (EC_READ_U8(command->data + 2))
         EC_WARN("%3i RX-error%s on slave %i, channel B.\n",
-                EC_READ_U8(command.data + 2),
-                EC_READ_U8(command.data + 2) == 1 ? "" : "s",
+                EC_READ_U8(command->data + 2),
+                EC_READ_U8(command->data + 2) == 1 ? "" : "s",
                 slave->ring_position);
-    if (EC_READ_U8(command.data + 3))
+    if (EC_READ_U8(command->data + 3))
         EC_WARN("%3i invalid frame%s on slave %i, channel B.\n",
-                EC_READ_U8(command.data + 3),
-                EC_READ_U8(command.data + 3) == 1 ? "" : "s",
+                EC_READ_U8(command->data + 3),
+                EC_READ_U8(command->data + 3) == 1 ? "" : "s",
                 slave->ring_position);
 
     // Reset CRC counters
-    EC_WRITE_U32(data, 0x00000000);
-    ec_command_init_npwr(&command, slave->station_address, 0x0300, 4, data);
-    if (unlikely(ec_master_simple_io(slave->master, &command))) {
+    if (ec_command_npwr(command, slave->station_address, 0x0300, 4)) return -1;
+    EC_WRITE_U32(command->data, 0x00000000);
+    if (unlikely(ec_master_simple_io(slave->master))) {
         EC_WARN("Resetting CRC fault counters failed on slave %i!\n",
                 slave->ring_position);
         return -1;
@@ -1089,74 +1094,60 @@
 /*****************************************************************************/
 
 /**
-   Sendet ein Mailbox-Kommando.
+   Bereitet ein Mailbox-Send-Kommando vor.
  */
 
-int ec_slave_mailbox_send(ec_slave_t *slave, /**< EtherCAT-Slave */
-                          uint8_t type, /**< Unterliegendes Protokoll */
-                          const uint8_t *prot_data, /**< Protokoll-Daten */
-                          size_t size /**< Datengröße */
-                          )
+uint8_t *ec_slave_prepare_mailbox_send(ec_slave_t *slave, /**< Slave */
+                                       uint8_t type, /**< Mailbox-Protokoll */
+                                       size_t size /**< Datengröße */
+                                       )
 {
     size_t total_size;
-    uint8_t *data;
-    ec_command_t command;
+    ec_command_t *command;
 
     if (unlikely(!slave->sii_mailbox_protocols)) {
         EC_ERR("Slave %i does not support mailbox communication!\n",
                slave->ring_position);
-        return -1;
+        return NULL;
     }
 
     total_size = size + 6;
     if (unlikely(total_size > slave->sii_rx_mailbox_size)) {
         EC_ERR("Data size does not fit in mailbox!\n");
-        return -1;
-    }
-
-    if (!(data = kmalloc(slave->sii_rx_mailbox_size, GFP_KERNEL))) {
-        EC_ERR("Failed to allocate %i bytes of memory for mailbox data!\n",
-               slave->sii_rx_mailbox_size);
-        return -1;
-    }
-
-    memset(data, 0x00, slave->sii_rx_mailbox_size);
-    EC_WRITE_U16(data,      size); // Length of the Mailbox service data
-    EC_WRITE_U16(data + 2,  slave->station_address); // Station address
-    EC_WRITE_U8 (data + 4,  0x00); // Channel & priority
-    EC_WRITE_U8 (data + 5,  type); // Underlying protocol type
-    memcpy(data + 6, prot_data, size);
-
-    ec_command_init_npwr(&command, slave->station_address,
-                         slave->sii_rx_mailbox_offset,
-                         slave->sii_rx_mailbox_size, data);
-    if (unlikely(ec_master_simple_io(slave->master, &command))) {
-        EC_ERR("Mailbox sending failed on slave %i!\n", slave->ring_position);
-        kfree(data);
-        return -1;
-    }
-
-    kfree(data);
-    return 0;
-}
-
-/*****************************************************************************/
-
-/**
-   Sendet ein Mailbox-Kommando.
+        return NULL;
+    }
+
+    command = &slave->master->simple_command;
+
+    if (ec_command_npwr(command, slave->station_address,
+                        slave->sii_rx_mailbox_offset,
+                        slave->sii_rx_mailbox_size)) return NULL;
+    EC_WRITE_U16(command->data,     size); // Mailbox service data length
+    EC_WRITE_U16(command->data + 2, slave->station_address); // Station address
+    EC_WRITE_U8 (command->data + 4, 0x00); // Channel & priority
+    EC_WRITE_U8 (command->data + 5, type); // Underlying protocol type
+
+    return command->data + 6;
+}
+
+/*****************************************************************************/
+
+/**
+   Empfängt ein Mailbox-Kommando.
  */
 
-int ec_slave_mailbox_receive(ec_slave_t *slave, /**< EtherCAT-Slave */
-                             uint8_t type, /**< Unterliegendes Protokoll */
-                             uint8_t *prot_data, /**< Protokoll-Daten */
-                             size_t *size /**< Datengröße des Puffers, später
-                                             Größe der gelesenen Daten */
-                             )
-{
-    ec_command_t command;
+uint8_t *ec_slave_mailbox_receive(ec_slave_t *slave, /**< Slave */
+                                  uint8_t type, /**< Protokoll */
+                                  size_t *size /**< Größe der gelesenen
+                                                  Daten */
+                                  )
+{
+    ec_command_t *command;
     size_t data_size;
     cycles_t start, end, timeout;
 
+    command = &slave->master->simple_command;
+
     // Read "written bit" of Sync-Manager
     start = get_cycles();
     timeout = (cycles_t) 100 * cpu_khz; // 100ms
@@ -1164,59 +1155,54 @@
     while (1)
     {
         // FIXME: Zweiter Sync-Manager nicht immer TX-Mailbox?
-        ec_command_init_nprd(&command, slave->station_address, 0x808, 8);
-        if (unlikely(ec_master_simple_io(slave->master, &command))) {
+        if (ec_command_nprd(command, slave->station_address, 0x808, 8))
+            return NULL;
+        if (unlikely(ec_master_simple_io(slave->master))) {
             EC_ERR("Mailbox checking failed on slave %i!\n",
                    slave->ring_position);
-            return -1;
+            return NULL;
         }
 
         end = get_cycles();
 
-        if (EC_READ_U8(command.data + 5) & 8)
+        if (EC_READ_U8(command->data + 5) & 8)
             break; // Proceed with received data
 
         if ((end - start) >= timeout) {
             EC_ERR("Mailbox check - Slave %i timed out.\n",
                    slave->ring_position);
-            return -1;
+            return NULL;
         }
 
         udelay(100);
     }
 
-    ec_command_init_nprd(&command, slave->station_address,
-                         slave->sii_tx_mailbox_offset,
-                         slave->sii_tx_mailbox_size);
-    if (unlikely(ec_master_simple_io(slave->master, &command))) {
+    if (ec_command_nprd(command, slave->station_address,
+                        slave->sii_tx_mailbox_offset,
+                        slave->sii_tx_mailbox_size)) return NULL;
+    if (unlikely(ec_master_simple_io(slave->master))) {
         EC_ERR("Mailbox receiving failed on slave %i!\n",
                slave->ring_position);
-        return -1;
-    }
-
-    if ((EC_READ_U8(command.data + 5) & 0x0F) != type) {
+        return NULL;
+    }
+
+    if ((EC_READ_U8(command->data + 5) & 0x0F) != type) {
         EC_ERR("Unexpected mailbox protocol 0x%02X (exp.: 0x%02X) at"
-               " slave %i!\n", EC_READ_U8(command.data + 5), type,
+               " slave %i!\n", EC_READ_U8(command->data + 5), type,
                slave->ring_position);
-        return -1;
+        return NULL;
     }
 
     if (unlikely(slave->master->debug_level) > 1)
         EC_DBG("Mailbox receive took %ius.\n", ((u32) (end - start) * 1000
                                                 / cpu_khz));
 
-    if ((data_size = EC_READ_U16(command.data)) > *size) {
-        EC_ERR("Mailbox service data does not fit into buffer (%i > %i).\n",
-               data_size, *size);
-        return -1;
-    }
-
-    if (data_size > slave->sii_tx_mailbox_size - 6) {
+    if ((data_size = EC_READ_U16(command->data)) >
+        slave->sii_tx_mailbox_size - 6) {
         EC_ERR("Currupt mailbox response detected!\n");
-        return -1;
-    }
-
-    memcpy(prot_data, command.data + 6, data_size);
+        return NULL;
+    }
+
     *size = data_size;
     return 0;
 }
--- a/master/slave.h	Sun Apr 02 09:26:56 2006 +0000
+++ b/master/slave.h	Mon Apr 03 10:03:34 2006 +0000
@@ -248,8 +248,8 @@
 int ec_slave_set_fmmu(ec_slave_t *, const ec_domain_t *, const ec_sync_t *);
 
 // Mailbox
-int ec_slave_mailbox_send(ec_slave_t *, uint8_t, const uint8_t *, size_t);
-int ec_slave_mailbox_receive(ec_slave_t *, uint8_t, uint8_t *, size_t *);
+uint8_t *ec_slave_prepare_mailbox_send(ec_slave_t *, uint8_t, size_t);
+uint8_t *ec_slave_mailbox_receive(ec_slave_t *, uint8_t, size_t *);
 
 // CANopen over EtherCAT
 int ec_slave_fetch_sdo_list(ec_slave_t *);
--- a/rt/msr_module.c	Sun Apr 02 09:26:56 2006 +0000
+++ b/rt/msr_module.c	Mon Apr 03 10:03:34 2006 +0000
@@ -99,6 +99,7 @@
     k_preio = (uint32_t) (get_cycles() - offset) * 1e6 / cpu_khz;
 
 #ifdef ASYNC
+
     // Empfangen
     ecrt_master_async_receive(master);
     ecrt_domain_process(domain1);
@@ -113,10 +114,14 @@
 
     // Senden
     ecrt_domain_queue(domain1);
+    ecrt_master_run(master);
     ecrt_master_async_send(master);
-#else
+
+#else // ASYNC
+
     // Senden und empfangen
     ecrt_domain_queue(domain1);
+    ecrt_master_run(master);
     ecrt_master_sync_io(master);
     ecrt_domain_process(domain1);
 
@@ -184,9 +189,11 @@
 int __init init_rt_module(void)
 {
     struct ipipe_domain_attr attr; //ipipe
+#ifdef BLOCK1
     uint8_t string[20];
     size_t size;
     ec_slave_t *slave;
+#endif
 
     // Als allererstes die RT-Lib initialisieren
     if (msr_rtlib_init(1, MSR_ABTASTFREQUENZ, 10, &msr_globals_register) < 0) {
@@ -286,8 +293,10 @@
     ipipe_register_domain(&this_domain, &attr);
     return 0;
 
+#ifdef BLOCK1
  out_deactivate:
     ecrt_master_deactivate(master);
+#endif
  out_release_master:
     ecrt_release_master(master);
  out_msr_cleanup:
--- a/todo.txt	Sun Apr 02 09:26:56 2006 +0000
+++ b/todo.txt	Mon Apr 03 10:03:34 2006 +0000
@@ -3,8 +3,6 @@
 
 $Id$
 
-- Kommandos mit dynamischem Speicher
-- Master mit eigener State-Machine; run() bzw. in send()
 - Verteilen von empfangenen Mailbox-Daten?
 - Ethernet over EtherCAT (EoE)
 - Anzahl Frames, die die Karte Puffern kann