VERSION 1.1: New realtime interface, only state machines.
authorFlorian Pose <fp@igh-essen.com>
Thu, 03 Aug 2006 12:51:17 +0000
changeset 325 7833cf70c4f2
parent 324 9aa51cbdbfae
child 326 ddb48b173680
VERSION 1.1: New realtime interface, only state machines.
TODO
examples/mini/mini.c
examples/msr/msr_sample.c
examples/rtai/rtai_sample.c
include/ecdb.h
include/ecrt.h
master/Makefile
master/canopen.c
master/datagram.c
master/datagram.h
master/domain.c
master/domain.h
master/ethernet.c
master/ethernet.h
master/fsm.c
master/fsm.h
master/globals.h
master/mailbox.c
master/master.c
master/master.h
master/module.c
master/slave.c
master/slave.h
master/types.c
master/types.h
script/ethercat.sh
script/lsec.pl
--- a/TODO	Wed Aug 02 23:16:10 2006 +0000
+++ b/TODO	Thu Aug 03 12:51:17 2006 +0000
@@ -8,12 +8,6 @@
 
 Important things to do:
 
-* New SDO-Configuration interface
-
-* Remove slave type information from master / New RT Interface
-
-* Always use state machines / remove simple IO code
-
 * SysFS interface
   - Add secondary slave address
   - Add SDO dictionary
--- a/examples/mini/mini.c	Wed Aug 02 23:16:10 2006 +0000
+++ b/examples/mini/mini.c	Thu Aug 03 12:51:17 2006 +0000
@@ -42,8 +42,8 @@
 #include <linux/interrupt.h>
 
 #include "../../include/ecrt.h" // EtherCAT realtime interface
+#include "../../include/ecdb.h" // EtherCAT slave database
 
-#define ASYNC
 #define FREQUENCY 100
 
 /*****************************************************************************/
@@ -56,16 +56,14 @@
 spinlock_t master_lock = SPIN_LOCK_UNLOCKED;
 
 // data fields
-//void *r_ssi_input, *r_ssi_status, *r_4102[3];
-void *r_kbus_in, *r_kbus_out;
+void *r_ana_out;
 
 // channels
 uint32_t k_pos;
 uint8_t k_stat;
 
-ec_field_init_t domain1_fields[] = {
-    //{&r_kbus_out, "0", "Beckhoff", "BK1120", "Outputs", 0},
-    //{&r_kbus_in,  "0", "Beckhoff", "BK1120", "Inputs",  0},
+ec_pdo_reg_t domain1_pdos[] = {
+    {"1", Beckhoff_EL4132_Output1, &r_ana_out},
     {}
 };
 
@@ -74,31 +72,19 @@
 void run(unsigned long data)
 {
     static unsigned int counter = 0;
-    unsigned int i;
 
     spin_lock(&master_lock);
 
-#ifdef ASYNC
     // receive
-    ecrt_master_async_receive(master);
+    ecrt_master_receive(master);
     ecrt_domain_process(domain1);
-#else
-    // send and receive
-    ecrt_domain_queue(domain1);
-    ecrt_master_run(master);
-    ecrt_master_sync_io(master);
-    ecrt_domain_process(domain1);
-#endif
 
     // process data
     //k_pos = EC_READ_U32(r_ssi);
 
-#ifdef ASYNC
     // send
-    ecrt_domain_queue(domain1);
     ecrt_master_run(master);
-    ecrt_master_async_send(master);
-#endif
+    ecrt_master_send(master);
 
     spin_unlock(&master_lock);
 
@@ -107,9 +93,10 @@
     }
     else {
         counter = FREQUENCY;
-        printk(KERN_INFO "input = ");
-        for (i = 0; i < 22; i++) printk("%02X ", *((uint8_t *) r_kbus_in + i));
-        printk("\n");
+        //printk(KERN_INFO "input = ");
+        //for (i = 0; i < 22; i++)
+        //    printk("%02X ", *((uint8_t *) r_kbus_in + i));
+        //printk("\n");
     }
 
     // restart timer
@@ -136,8 +123,6 @@
 
 int __init init_mini_module(void)
 {
-    ec_slave_t *slave;
-
     printk(KERN_INFO "=== Starting Minimal EtherCAT environment... ===\n");
 
     if ((master = ecrt_request_master(0)) == NULL) {
@@ -154,69 +139,19 @@
         goto out_release_master;
     }
 
-    printk(KERN_INFO "Registering domain fields...\n");
-    if (ecrt_domain_register_field_list(domain1, domain1_fields)) {
-        printk(KERN_ERR "Field registration failed!\n");
+    printk(KERN_INFO "Registering PDOs...\n");
+    if (ecrt_domain_register_pdo_list(domain1, domain1_pdos)) {
+        printk(KERN_ERR "PDO registration failed!\n");
         goto out_release_master;
     }
 
-#if 1
-    printk(KERN_INFO "Setting variable data field sizes...\n");
-    if (!(slave = ecrt_master_get_slave(master, "0"))) {
-        printk(KERN_ERR "Failed to get slave!\n");
-        goto out_deactivate;
-    }
-    ecrt_slave_field_size(slave, "Outputs", 0, 0x16);
-    ecrt_slave_field_size(slave, "Inputs", 0, 0x16);
-#endif
-
     printk(KERN_INFO "Activating master...\n");
     if (ecrt_master_activate(master)) {
         printk(KERN_ERR "Failed to activate master!\n");
         goto out_release_master;
     }
 
-#if 1
-    if (ecrt_master_fetch_sdo_lists(master)) {
-        printk(KERN_ERR "Failed to fetch SDO lists!\n");
-        goto out_deactivate;
-    }
-    ecrt_master_print(master, 2);
-#else
-    ecrt_master_print(master, 0);
-#endif
-
-#if 0
-    if (!(slave = ecrt_master_get_slave(master, "5"))) {
-        printk(KERN_ERR "Failed to get slave 5!\n");
-        goto out_deactivate;
-    }
-
-    if (ecrt_slave_sdo_write_exp8(slave, 0x4061, 1,  0) ||
-        ecrt_slave_sdo_write_exp8(slave, 0x4061, 2,  1) ||
-        ecrt_slave_sdo_write_exp8(slave, 0x4061, 3,  1) ||
-        ecrt_slave_sdo_write_exp8(slave, 0x4066, 0,  0) ||
-        ecrt_slave_sdo_write_exp8(slave, 0x4067, 0,  4) ||
-        ecrt_slave_sdo_write_exp8(slave, 0x4068, 0,  0) ||
-        ecrt_slave_sdo_write_exp8(slave, 0x4069, 0, 25) ||
-        ecrt_slave_sdo_write_exp8(slave, 0x406A, 0, 25) ||
-        ecrt_slave_sdo_write_exp8(slave, 0x406B, 0, 50)) {
-        printk(KERN_ERR "Failed to configure SSI slave!\n");
-        goto out_deactivate;
-    }
-#endif
-
-#ifdef ASYNC
-    // send once and wait...
-    ecrt_master_prepare_async_io(master);
-#endif
-
-#if 1
-    if (ecrt_master_start_eoe(master)) {
-        printk(KERN_ERR "Failed to start EoE processing!\n");
-        goto out_deactivate;
-    }
-#endif
+    ecrt_master_prepare(master);
 
     printk("Starting cyclic sample thread.\n");
     init_timer(&timer);
@@ -227,10 +162,6 @@
     printk(KERN_INFO "=== Minimal EtherCAT environment started. ===\n");
     return 0;
 
-#if 1
- out_deactivate:
-    ecrt_master_deactivate(master);
-#endif
  out_release_master:
     ecrt_release_master(master);
  out_return:
--- a/examples/msr/msr_sample.c	Wed Aug 02 23:16:10 2006 +0000
+++ b/examples/msr/msr_sample.c	Thu Aug 03 12:51:17 2006 +0000
@@ -48,8 +48,7 @@
 
 // EtherCAT
 #include "../../include/ecrt.h"
-
-#define ASYNC
+#include "../../include/ecdb.h"
 
 #define HZREDUCTION (MSR_ABTASTFREQUENZ / HZ)
 #define TIMERTICKS (1000000000 / MSR_ABTASTFREQUENZ)
@@ -66,16 +65,13 @@
 ec_domain_t *domain1 = NULL;
 
 // raw process data
-void *r_ssi;
-void *r_ssi_st;
+void *r_ana_out;
 
 // Channels
-uint32_t k_ssi;
-uint32_t k_ssi_st;
-
-ec_field_init_t domain1_fields[] = {
-    {&r_ssi,    "0:3", "Beckhoff", "EL5001", "InputValue", 0},
-    {&r_ssi_st, "0:3", "Beckhoff", "EL5001", "Status",     0},
+double k_ana_out;
+
+ec_pdo_reg_t domain1_pdos[] = {
+    {"3", Beckhoff_EL4132_Output1, &r_ana_out},
     {}
 };
 
@@ -85,28 +81,16 @@
 {
     rt_sem_wait(&master_sem);
 
-#ifdef ASYNC
-    // Empfangen
-    ecrt_master_async_receive(master);
+    // receive
+    ecrt_master_receive(master);
     ecrt_domain_process(domain1);
-#else
-    // Senden und empfangen
-    ecrt_domain_queue(domain1);
+
+    // Process data
+    EC_WRITE_S16(r_ana_out, k_ana_out / 10.0 * 0x7FFF);
+
+    // Send
     ecrt_master_run(master);
-    ecrt_master_sync_io(master);
-    ecrt_domain_process(domain1);
-#endif
-
-    // Prozessdaten verarbeiten
-    k_ssi    = EC_READ_U32(r_ssi);
-    k_ssi_st = EC_READ_U8 (r_ssi_st);
-
-#ifdef ASYNC
-    // Senden
-    ecrt_domain_queue(domain1);
-    ecrt_master_run(master);
-    ecrt_master_async_send(master);
-#endif
+    ecrt_master_send(master);
 
     rt_sem_signal(&master_sem);
 
@@ -128,8 +112,7 @@
 
 int msr_reg(void)
 {
-    msr_reg_kanal("/ssi_position", "", &k_ssi,    TUINT);
-    msr_reg_kanal("/ssi_status",   "", &k_ssi_st, TUINT);
+    msr_reg_kanal("/ana_out", "", &k_ana_out, TDBL);
     return 0;
 }
 
@@ -157,9 +140,6 @@
 int __init init_mod(void)
 {
     RTIME ticks;
-#if 0
-    ec_slave_t *slave;
-#endif
 
     printk(KERN_INFO "=== Starting EtherCAT RTAI MSR sample module... ===\n");
 
@@ -171,7 +151,7 @@
         goto out_return;
     }
 
-    if ((master = ecrt_request_master(0)) == NULL) {
+    if (!(master = ecrt_request_master(0))) {
         printk(KERN_ERR "Failed to request master 0!\n");
         goto out_msr_cleanup;
     }
@@ -184,9 +164,9 @@
         goto out_release_master;
     }
 
-    printk(KERN_INFO "Registering domain fields...\n");
-    if (ecrt_domain_register_field_list(domain1, domain1_fields)) {
-        printk(KERN_ERR "Failed to register domain fields.\n");
+    printk(KERN_INFO "Registering PDOs...\n");
+    if (ecrt_domain_register_pdo_list(domain1, domain1_pdos)) {
+        printk(KERN_ERR "Failed to register PDOs.\n");
         goto out_release_master;
     }
 
@@ -196,59 +176,7 @@
         goto out_release_master;
     }
 
-#if 0
-    if (ecrt_master_fetch_sdo_lists(master)) {
-        printk(KERN_ERR "Failed to fetch SDO lists!\n");
-        goto out_deactivate;
-    }
-    ecrt_master_print(master, 2);
-#else
-    ecrt_master_print(master, 0);
-#endif
-
-#if 0
-    if (!(slave = ecrt_master_get_slave(master, "0:3"))) {
-        printk(KERN_ERR "Failed to get slave!\n");
-        goto out_deactivate;
-    }
-
-    if (
-        ecrt_slave_sdo_write_exp8(slave, 0x4061, 1,  1) || // disable frame error bit
-        ecrt_slave_sdo_write_exp8(slave, 0x4061, 2,  0) || // power failure bit
-        ecrt_slave_sdo_write_exp8(slave, 0x4061, 3,  1) || // inhibit time
-        ecrt_slave_sdo_write_exp8(slave, 0x4061, 4,  0) || // test mode
-        ecrt_slave_sdo_write_exp8(slave, 0x4066, 0,  0) || // graycode
-        ecrt_slave_sdo_write_exp8(slave, 0x4067, 0,  5) || // 125kbaud
-        ecrt_slave_sdo_write_exp8(slave, 0x4068, 0,  0) || // single-turn
-        ecrt_slave_sdo_write_exp8(slave, 0x4069, 0, 25) || // frame size
-        ecrt_slave_sdo_write_exp8(slave, 0x406A, 0, 25) || // data length
-        ecrt_slave_sdo_write_exp16(slave, 0x406B, 0, 50) // inhibit time in us
-        ) {
-        printk(KERN_ERR "Failed to configure SSI slave!\n");
-        goto out_deactivate;
-    }
-#endif
-
-#if 0
-    if (!(slave = ecrt_master_get_slave(master, "1:0"))) {
-        printk(KERN_ERR "Failed to get slave!\n");
-        goto out_deactivate;
-    }
-    if (ecrt_slave_write_alias(slave, 0x5678)) {
-        printk(KERN_ERR "Failed to write alias!\n");
-        goto out_deactivate;
-    }
-#endif
-
-#ifdef ASYNC
-    // Einmal senden und warten...
-    ecrt_master_prepare_async_io(master);
-#endif
-
-    if (ecrt_master_start_eoe(master)) {
-        printk(KERN_ERR "Failed to start EoE processing!\n");
-        goto out_deactivate;
-    }
+    ecrt_master_prepare(master);
 
     printk("Starting cyclic sample thread...\n");
     ticks = start_rt_timer(nano2count(TIMERTICKS));
@@ -268,7 +196,6 @@
     rt_task_delete(&task);
  out_stop_timer:
     stop_rt_timer();
- out_deactivate:
     ecrt_master_deactivate(master);
  out_release_master:
     ecrt_release_master(master);
--- a/examples/rtai/rtai_sample.c	Wed Aug 02 23:16:10 2006 +0000
+++ b/examples/rtai/rtai_sample.c	Thu Aug 03 12:51:17 2006 +0000
@@ -42,6 +42,7 @@
 
 // EtherCAT
 #include "../../include/ecrt.h"
+#include "../../include/ecdb.h"
 
 /*****************************************************************************/
 
@@ -51,12 +52,8 @@
 
 /*****************************************************************************/
 
-// comment this for synchronous IO
-#define ASYNC
-
 // RTAI task frequency in Hz
 #define FREQUENCY 10000
-
 #define TIMERTICKS (1000000000 / FREQUENCY)
 
 /*****************************************************************************/
@@ -64,22 +61,20 @@
 // RTAI
 RT_TASK task;
 SEM master_sem;
-cycles_t t_last_start = 0;
-cycles_t t_critical;
+cycles_t t_last_start = 0, t_critical;
 
 // EtherCAT
 ec_master_t *master = NULL;
 ec_domain_t *domain1 = NULL;
 
 // data fields
-void *r_ssi_input;
+void *r_ana_out;
 
 // channels
 uint32_t k_pos;
 
-ec_field_init_t domain1_fields[] = {
-    {&r_ssi_input, "3", "Beckhoff", "EL5001", "InputValue",   0},
-    {NULL,         "2", "Beckhoff", "EL4132", "OutputValue",  0},
+ec_pdo_reg_t domain1_pdos[] = {
+    {"2", Beckhoff_EL4132_Output1, &r_ana_out},
     {}
 };
 
@@ -92,27 +87,14 @@
         t_last_start = get_cycles();
         rt_sem_wait(&master_sem);
 
-#ifdef ASYNC
-        // receive
-        ecrt_master_async_receive(master);
+        ecrt_master_receive(master);
         ecrt_domain_process(domain1);
-#else
-        // send and receive
-        ecrt_domain_queue(domain1);
+
+        // process data
+        //k_pos = EC_READ_U32(r_ssi_input);
+
         ecrt_master_run(master);
-        ecrt_master_sync_io(master);
-        ecrt_domain_process(domain1);
-#endif
-
-        // process data
-        k_pos = EC_READ_U32(r_ssi_input);
-
-#ifdef ASYNC
-        // send
-        ecrt_domain_queue(domain1);
-        ecrt_master_run(master);
-        ecrt_master_async_send(master);
-#endif
+        ecrt_master_send(master);
 
         rt_sem_signal(&master_sem);
         rt_task_wait_period();
@@ -158,15 +140,14 @@
     ecrt_master_callbacks(master, request_lock, release_lock, NULL);
 
     printk(KERN_INFO "Registering domain...\n");
-    if (!(domain1 = ecrt_master_create_domain(master)))
-    {
+    if (!(domain1 = ecrt_master_create_domain(master))) {
         printk(KERN_ERR "Domain creation failed!\n");
         goto out_release_master;
     }
 
-    printk(KERN_INFO "Registering domain fields...\n");
-    if (ecrt_domain_register_field_list(domain1, domain1_fields)) {
-        printk(KERN_ERR "Field registration failed!\n");
+    printk(KERN_INFO "Registering PDOs...\n");
+    if (ecrt_domain_register_pdo_list(domain1, domain1_pdos)) {
+        printk(KERN_ERR "PDO registration failed!\n");
         goto out_release_master;
     }
 
@@ -176,53 +157,7 @@
         goto out_release_master;
     }
 
-#if 0
-    if (ecrt_master_fetch_sdo_lists(master)) {
-        printk(KERN_ERR "Failed to fetch SDO lists!\n");
-        goto out_deactivate;
-    }
-    ecrt_master_print(master, 2);
-#else
-    ecrt_master_print(master, 0);
-#endif
-
-#if 0
-    if (!(slave = ecrt_master_get_slave(master, "5"))) {
-        printk(KERN_ERR "Failed to get slave 5!\n");
-        goto out_deactivate;
-    }
-
-    if (ecrt_slave_sdo_write_exp8(slave, 0x4061, 1,  0) ||
-        ecrt_slave_sdo_write_exp8(slave, 0x4061, 2,  1) ||
-        ecrt_slave_sdo_write_exp8(slave, 0x4061, 3,  1) ||
-        ecrt_slave_sdo_write_exp8(slave, 0x4066, 0,  0) ||
-        ecrt_slave_sdo_write_exp8(slave, 0x4067, 0,  4) ||
-        ecrt_slave_sdo_write_exp8(slave, 0x4068, 0,  0) ||
-        ecrt_slave_sdo_write_exp8(slave, 0x4069, 0, 25) ||
-        ecrt_slave_sdo_write_exp8(slave, 0x406A, 0, 25) ||
-        ecrt_slave_sdo_write_exp8(slave, 0x406B, 0, 50)) {
-        printk(KERN_ERR "Failed to configure SSI slave!\n");
-        goto out_deactivate;
-    }
-#endif
-
-#if 0
-    printk(KERN_INFO "Writing alias...\n");
-    if (ecrt_slave_sdo_write_exp16(slave, 0xBEEF)) {
-        printk(KERN_ERR "Failed to write alias!\n");
-        goto out_deactivate;
-    }
-#endif
-
-#ifdef ASYNC
-    // send once and wait...
-    ecrt_master_prepare_async_io(master);
-#endif
-
-    if (ecrt_master_start_eoe(master)) {
-        printk(KERN_ERR "Failed to start EoE processing!\n");
-        goto out_deactivate;
-    }
+    ecrt_master_prepare(master);
 
     printk("Starting cyclic sample thread...\n");
     requested_ticks = nano2count(TIMERTICKS);
@@ -248,7 +183,6 @@
     rt_task_delete(&task);
  out_stop_timer:
     stop_rt_timer();
- out_deactivate:
     ecrt_master_deactivate(master);
  out_release_master:
     ecrt_release_master(master);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/ecdb.h	Thu Aug 03 12:51:17 2006 +0000
@@ -0,0 +1,51 @@
+/******************************************************************************
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2006  Florian Pose, Ingenieurgemeinschaft IgH
+ *
+ *  This file is part of the IgH EtherCAT Master.
+ *
+ *  The IgH EtherCAT Master is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2 of the
+ *  License, or (at your option) any later version.
+ *
+ *  The IgH EtherCAT Master is distributed in the hope that it will be
+ *  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with the IgH EtherCAT Master; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ *  The right to use EtherCAT Technology is granted and comes free of
+ *  charge under condition of compatibility of product made by
+ *  Licensee. People intending to distribute/sell products based on the
+ *  code, have to sign an agreement to guarantee that products using
+ *  software based on IgH EtherCAT master stay compatible with the actual
+ *  EtherCAT specification (which are released themselves as an open
+ *  standard) as the (only) precondition to have the right to use EtherCAT
+ *  Technology, IP and trade marks.
+ *
+ *****************************************************************************/
+
+/**
+   \file
+   EtherCAT Slave Database.
+*/
+
+/*****************************************************************************/
+
+#ifndef __ECDB_H__
+#define __ECDB_H__
+
+/*****************************************************************************/
+
+#define Beckhoff_EL4132_Output1 0x00000002, 0x10243052, 0x6411, 1
+#define Beckhoff_EL4132_Output2 0x00000002, 0x10243052, 0x6411, 2
+
+/*****************************************************************************/
+
+#endif
--- a/include/ecrt.h	Wed Aug 02 23:16:10 2006 +0000
+++ b/include/ecrt.h	Thu Aug 03 12:51:17 2006 +0000
@@ -69,23 +69,22 @@
 typedef struct ec_slave ec_slave_t; /**< \see ec_slave */
 
 /**
-   Initialization type for field registrations.
-   This type is used as a parameter for the ec_domain_register_field_list()
+   Initialization type for PDO registrations.
+   This type is used as a parameter for the ec_domain_register_pdo_list()
    function.
 */
 
 typedef struct
 {
-    void **data_ptr; /**< address of the process data pointer */
     const char *slave_address; /**< slave address string (see
                                   ecrt_master_get_slave()) */
-    const char *vendor_name; /**< vendor name */
-    const char *product_name; /**< product name */
-    const char *field_name; /**< data field name */
-    unsigned int field_index; /**< index in data fields with same name */
-    unsigned int field_count; /**< number of data fields with same name */
+    uint32_t vendor_id; /**< vendor ID */
+    uint32_t product_code; /**< product code */
+    uint16_t pdo_index; /**< PDO index */
+    uint8_t pdo_subindex; /**< PDO subindex */
+    void **data_ptr; /**< address of the process data pointer */
 }
-ec_field_init_t;
+ec_pdo_reg_t;
 
 /******************************************************************************
  *  Master request functions
@@ -106,66 +105,47 @@
 int ecrt_master_activate(ec_master_t *master);
 void ecrt_master_deactivate(ec_master_t *master);
 
-int ecrt_master_fetch_sdo_lists(ec_master_t *master);
-
-void ecrt_master_sync_io(ec_master_t *master);
-void ecrt_master_async_send(ec_master_t *master);
-void ecrt_master_async_receive(ec_master_t *master);
-void ecrt_master_prepare_async_io(ec_master_t *master);
+void ecrt_master_prepare(ec_master_t *master);
+
+void ecrt_master_send(ec_master_t *master);
+void ecrt_master_receive(ec_master_t *master);
 
 void ecrt_master_run(ec_master_t *master);
 
-int ecrt_master_start_eoe(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);
-
 ec_slave_t *ecrt_master_get_slave(const ec_master_t *, const char *);
 
+int ecrt_master_state(const ec_master_t *master);
+
 /******************************************************************************
  *  Domain Methods
  *****************************************************************************/
 
-ec_slave_t *ecrt_domain_register_field(ec_domain_t *domain,
-                                       const char *address,
-                                       const char *vendor_name,
-                                       const char *product_name,
-                                       void **data_ptr, const char *field_name,
-                                       unsigned int field_index,
-                                       unsigned int field_count);
-int ecrt_domain_register_field_list(ec_domain_t *domain,
-                                    const ec_field_init_t *fields);
-
-void ecrt_domain_queue(ec_domain_t *domain);
+ec_slave_t *ecrt_domain_register_pdo(ec_domain_t *domain,
+                                     const char *address,
+                                     uint32_t vendor_id,
+                                     uint32_t product_code,
+                                     uint16_t pdo_index,
+                                     uint8_t pdo_subindex,
+                                     void **data_ptr);
+int ecrt_domain_register_pdo_list(ec_domain_t *domain,
+                                  const ec_pdo_reg_t *pdos);
+
 void ecrt_domain_process(ec_domain_t *domain);
-
-int ecrt_domain_state(ec_domain_t *domain);
+int ecrt_domain_state(const ec_domain_t *domain);
 
 /******************************************************************************
  *  Slave Methods
  *****************************************************************************/
 
-/* there SDO functions are deprecated! */
-
-int ecrt_slave_sdo_read_exp8(ec_slave_t *slave, uint16_t sdo_index,
-                              uint8_t sdo_subindex, uint8_t *value);
-int ecrt_slave_sdo_read_exp16(ec_slave_t *slave, uint16_t sdo_index,
-                              uint8_t sdo_subindex, uint16_t *value);
-int ecrt_slave_sdo_read_exp32(ec_slave_t *slave, uint16_t sdo_index,
-                              uint8_t sdo_subindex, uint32_t *value);
-int ecrt_slave_sdo_write_exp8(ec_slave_t *slave, uint16_t sdo_index,
-                              uint8_t sdo_subindex, uint8_t value);
-int ecrt_slave_sdo_write_exp16(ec_slave_t *slave, uint16_t sdo_index,
-                               uint8_t sdo_subindex, uint16_t value);
-int ecrt_slave_sdo_write_exp32(ec_slave_t *slave, uint16_t sdo_index,
-                               uint8_t sdo_subindex, uint32_t value);
-int ecrt_slave_sdo_read(ec_slave_t *slave, uint16_t sdo_index,
-                        uint8_t sdo_subindex, uint8_t *data, size_t *size);
-
-int ecrt_slave_write_alias(ec_slave_t *slave, uint16_t alias); // deprecated!
-
-int ecrt_slave_field_size(ec_slave_t *slave, const char *field_name,
-                          unsigned int field_index, size_t size);
+int ecrt_slave_conf_sdo8(ec_slave_t *slave, uint16_t sdo_index,
+                         uint8_t sdo_subindex, uint8_t value);
+int ecrt_slave_conf_sdo16(ec_slave_t *slave, uint16_t sdo_index,
+                          uint8_t sdo_subindex, uint16_t value);
+int ecrt_slave_conf_sdo32(ec_slave_t *slave, uint16_t sdo_index,
+                          uint8_t sdo_subindex, uint32_t value);
+
+int ecrt_slave_pdo_size(ec_slave_t *slave, uint16_t pdo_index,
+                        uint8_t pdo_subindex, size_t size);
 
 /******************************************************************************
  *  Bitwise read/write macros
--- a/master/Makefile	Wed Aug 02 23:16:10 2006 +0000
+++ b/master/Makefile	Thu Aug 03 12:51:17 2006 +0000
@@ -42,8 +42,8 @@
 
 obj-m := ec_master.o
 
-ec_master-objs := module.o master.o device.o slave.o datagram.o types.o \
-		domain.o mailbox.o canopen.o ethernet.o debug.o fsm.o
+ec_master-objs := module.o master.o device.o slave.o datagram.o \
+		domain.o mailbox.o ethernet.o debug.o fsm.o
 
 REV := $(shell svnversion $(src) 2>/dev/null || echo "unknown")
 
--- a/master/canopen.c	Wed Aug 02 23:16:10 2006 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,726 +0,0 @@
-/******************************************************************************
- *
- *  $Id$
- *
- *  Copyright (C) 2006  Florian Pose, Ingenieurgemeinschaft IgH
- *
- *  This file is part of the IgH EtherCAT Master.
- *
- *  The IgH EtherCAT Master is free software; you can redistribute it
- *  and/or modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2 of the
- *  License, or (at your option) any later version.
- *
- *  The IgH EtherCAT Master is distributed in the hope that it will be
- *  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with the IgH EtherCAT Master; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- *  The right to use EtherCAT Technology is granted and comes free of
- *  charge under condition of compatibility of product made by
- *  Licensee. People intending to distribute/sell products based on the
- *  code, have to sign an agreement to guarantee that products using
- *  software based on IgH EtherCAT master stay compatible with the actual
- *  EtherCAT specification (which are released themselves as an open
- *  standard) as the (only) precondition to have the right to use EtherCAT
- *  Technology, IP and trade marks.
- *
- *****************************************************************************/
-
-/**
-   \file
-   Canopen-over-EtherCAT functions.
-*/
-
-/*****************************************************************************/
-
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-
-#include "master.h"
-#include "mailbox.h"
-
-/*****************************************************************************/
-
-void ec_canopen_abort_msg(uint32_t);
-int ec_slave_fetch_sdo_descriptions(ec_slave_t *, ec_datagram_t *);
-int ec_slave_fetch_sdo_entries(ec_slave_t *, ec_datagram_t *,
-                               ec_sdo_t *, uint8_t);
-
-/*****************************************************************************/
-
-/**
-   Reads 32 bit of a CANopen SDO in expedited mode.
-   \return 0 in case of success, else < 0
-*/
-
-int ec_slave_sdo_read_exp(ec_slave_t *slave, /**< EtherCAT slave */
-                          uint16_t sdo_index, /**< SDO index */
-                          uint8_t sdo_subindex, /**< SDO subindex */
-                          uint8_t *target /**< 4-byte memory */
-                          )
-{
-    ec_datagram_t datagram;
-    size_t rec_size;
-    uint8_t *data;
-
-    ec_datagram_init(&datagram);
-
-    if (!(data = ec_slave_mbox_prepare_send(slave, &datagram, 0x03, 6)))
-        goto err;
-
-    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 (!(data = ec_slave_mbox_simple_io(slave, &datagram, &rec_size)))
-        goto err;
-
-    if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
-        EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
-        EC_ERR("SDO upload 0x%04X:%X aborted on slave %i.\n",
-               sdo_index, sdo_subindex, slave->ring_position);
-        ec_canopen_abort_msg(EC_READ_U32(data + 6));
-        goto err;
-    }
-
-    if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
-        EC_READ_U8 (data + 2) >> 5 != 0x2 || // upload response
-        EC_READ_U16(data + 3) != sdo_index || // index
-        EC_READ_U8 (data + 5) != sdo_subindex) { // subindex
-        EC_ERR("SDO upload 0x%04X:%X failed:\n", sdo_index, sdo_subindex);
-        EC_ERR("Invalid SDO upload response at slave %i!\n",
-               slave->ring_position);
-        ec_print_data(data, rec_size);
-        goto err;
-    }
-
-    memcpy(target, data + 6, 4);
-
-    ec_datagram_clear(&datagram);
-    return 0;
- err:
-    ec_datagram_clear(&datagram);
-    return -1;
-}
-
-/*****************************************************************************/
-
-/**
-   Writes a CANopen SDO using expedited mode.
-   \return 0 in case of success, else < 0
-*/
-
-int ec_slave_sdo_write_exp(ec_slave_t *slave, /**< EtherCAT slave */
-                           uint16_t sdo_index, /**< SDO index */
-                           uint8_t sdo_subindex, /**< SDO subindex */
-                           const uint8_t *sdo_data, /**< new value */
-                           size_t size /**< Data size in bytes (1 - 4) */
-                           )
-{
-    uint8_t *data;
-    size_t rec_size;
-    ec_datagram_t datagram;
-
-    ec_datagram_init(&datagram);
-
-    if (size == 0 || size > 4) {
-        EC_ERR("Invalid data size!\n");
-        goto err;
-    }
-
-    if (!(data = ec_slave_mbox_prepare_send(slave, &datagram, 0x03, 0x0A)))
-        goto err;
-
-    EC_WRITE_U16(data, 0x2 << 12); // SDO request
-    EC_WRITE_U8 (data + 2, (0x1 // size specified
-                            | 0x1 << 1 // expedited transfer
-                            | (4 - size) << 2 // data set size
-                            | 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);
-
-    if (!(data = ec_slave_mbox_simple_io(slave, &datagram, &rec_size)))
-        goto err;
-
-    if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
-        EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
-        EC_ERR("SDO download 0x%04X:%X (%i bytes) aborted on slave %i.\n",
-               sdo_index, sdo_subindex, size, slave->ring_position);
-        ec_canopen_abort_msg(EC_READ_U32(data + 6));
-        return -1;
-    }
-
-    if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
-        EC_READ_U8 (data + 2) >> 5 != 0x3 || // download response
-        EC_READ_U16(data + 3) != sdo_index || // index
-        EC_READ_U8 (data + 5) != sdo_subindex) { // subindex
-        EC_ERR("SDO download 0x%04X:%X (%i bytes) failed:\n",
-               sdo_index, sdo_subindex, size);
-        EC_ERR("Invalid SDO download response at slave %i!\n",
-               slave->ring_position);
-        ec_print_data(data, rec_size);
-        return -1;
-    }
-
-    ec_datagram_clear(&datagram);
-    return 0;
- err:
-    ec_datagram_clear(&datagram);
-    return -1;
-}
-
-/*****************************************************************************/
-
-/**
-   Reads a CANopen SDO in normal mode.
-   \return 0 in case of success, else < 0
-   \ingroup RealtimeInterface
-   \todo Make size non-pointer.
-*/
-
-int ecrt_slave_sdo_read(ec_slave_t *slave, /**< EtherCAT slave */
-                        uint16_t sdo_index, /**< SDO index */
-                        uint8_t sdo_subindex, /**< SDO subindex */
-                        uint8_t *target, /**< memory for value */
-                        size_t *size /**< target memory size */
-                        )
-{
-    uint8_t *data;
-    size_t rec_size, data_size;
-    uint32_t complete_size;
-    ec_datagram_t datagram;
-
-    ec_datagram_init(&datagram);
-
-    if (!(data = ec_slave_mbox_prepare_send(slave, &datagram, 0x03, 6)))
-        goto err;
-
-    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 (!(data = ec_slave_mbox_simple_io(slave, &datagram, &rec_size)))
-        goto err;
-
-    if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
-        EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
-        EC_ERR("SDO upload 0x%04X:%X aborted on slave %i.\n",
-               sdo_index, sdo_subindex, slave->ring_position);
-        ec_canopen_abort_msg(EC_READ_U32(data + 6));
-        goto err;
-    }
-
-    if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
-        EC_READ_U8 (data + 2) >> 5 != 0x2 || // initiate upload response
-        EC_READ_U16(data + 3) != sdo_index || // index
-        EC_READ_U8 (data + 5) != sdo_subindex) { // subindex
-        EC_ERR("SDO upload 0x%04X:%X failed:\n", sdo_index, sdo_subindex);
-        EC_ERR("Invalid SDO upload response at slave %i!\n",
-               slave->ring_position);
-        ec_print_data(data, rec_size);
-        goto err;
-    }
-
-    if (rec_size < 10) {
-        EC_ERR("Received currupted SDO upload response!\n");
-        ec_print_data(data, rec_size);
-        goto err;
-    }
-
-    if ((complete_size = EC_READ_U32(data + 6)) > *size) {
-        EC_ERR("SDO data does not fit into buffer (%i / %i)!\n",
-               complete_size, *size);
-        goto err;
-    }
-
-    data_size = rec_size - 10;
-
-    if (data_size != complete_size) {
-        EC_ERR("SDO data incomplete - Fragmenting not implemented.\n");
-        goto err;
-    }
-
-    memcpy(target, data + 10, data_size);
-
-    ec_datagram_clear(&datagram);
-    return 0;
- err:
-    ec_datagram_clear(&datagram);
-    return -1;
-}
-
-/*****************************************************************************/
-
-/**
-   Fetches the SDO dictionary of a slave.
-   \return 0 in case of success, else < 0
-*/
-
-int ec_slave_fetch_sdo_list(ec_slave_t *slave /**< EtherCAT slave */)
-{
-    uint8_t *data;
-    size_t rec_size;
-    unsigned int i, sdo_count;
-    ec_sdo_t *sdo;
-    uint16_t sdo_index;
-    ec_datagram_t datagram;
-
-    ec_datagram_init(&datagram);
-
-    if (!(data = ec_slave_mbox_prepare_send(slave, &datagram, 0x03, 8)))
-        goto err;
-
-    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 (unlikely(ec_master_simple_io(slave->master, &datagram))) {
-        EC_ERR("Mailbox checking failed on slave %i!\n", slave->ring_position);
-        goto err;
-    }
-
-    do {
-        if (!(data = ec_slave_mbox_simple_receive(slave, &datagram,
-                                                  0x03, &rec_size)))
-            goto err;
-
-        if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
-            (EC_READ_U8(data + 2) & 0x7F) == 0x07) { // error response
-            EC_ERR("SDO information error response at slave %i!\n",
-                   slave->ring_position);
-            ec_canopen_abort_msg(EC_READ_U32(data + 6));
-            goto err;
-        }
-
-        if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
-            (EC_READ_U8 (data + 2) & 0x7F) != 0x02) { // Get OD List response
-            EC_ERR("Invalid SDO list response at slave %i!\n",
-                   slave->ring_position);
-            ec_print_data(data, rec_size);
-            goto err;
-        }
-
-        if (rec_size < 8) {
-            EC_ERR("Invalid data size!\n");
-            ec_print_data(data, rec_size);
-            goto err;
-        }
-
-        sdo_count = (rec_size - 8) / 2;
-        for (i = 0; i < sdo_count; i++) {
-            sdo_index = EC_READ_U16(data + 8 + i * 2);
-            if (!sdo_index) continue; // sometimes index is 0... ???
-
-            if (!(sdo = (ec_sdo_t *) kmalloc(sizeof(ec_sdo_t), GFP_KERNEL))) {
-                EC_ERR("Failed to allocate memory for SDO!\n");
-                goto err;
-            }
-
-            // Initialize SDO object
-            sdo->index = sdo_index;
-            //sdo->unkown = 0x0000;
-            sdo->object_code = 0x00;
-            sdo->name = NULL;
-            INIT_LIST_HEAD(&sdo->entries);
-
-            list_add_tail(&sdo->list, &slave->sdo_dictionary);
-        }
-    }
-    while (EC_READ_U8(data + 2) & 0x80);
-
-    // Fetch all SDO descriptions
-    if (ec_slave_fetch_sdo_descriptions(slave, &datagram)) goto err;
-
-    ec_datagram_clear(&datagram);
-    return 0;
- err:
-    ec_datagram_clear(&datagram);
-    return -1;
-}
-
-/*****************************************************************************/
-
-/**
-   Fetches the SDO descriptions for the known SDOs.
-   \return 0 in case of success, else < 0
-*/
-
-int ec_slave_fetch_sdo_descriptions(ec_slave_t *slave, /**< EtherCAT slave */
-                                    ec_datagram_t *datagram /**< datagram */
-                                    )
-{
-    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_mbox_prepare_send(slave, datagram, 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 (!(data = ec_slave_mbox_simple_io(slave, datagram, &rec_size)))
-            return -1;
-
-        if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
-            (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response
-            EC_ERR("SDO information error response at slave %i while"
-                   " fetching SDO 0x%04X!\n", slave->ring_position,
-                   sdo->index);
-            ec_canopen_abort_msg(EC_READ_U32(data + 6));
-            return -1;
-        }
-
-        if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
-            (EC_READ_U8 (data + 2) & 0x7F) != 0x04 || // Object desc. response
-            EC_READ_U16(data + 6) != sdo->index) { // SDO index
-            EC_ERR("Invalid object description response at slave %i while"
-                   " fetching SDO 0x%04X!\n", slave->ring_position,
-                   sdo->index);
-            ec_print_data(data, rec_size);
-            return -1;
-        }
-
-        if (rec_size < 12) {
-            EC_ERR("Invalid data size!\n");
-            ec_print_data(data, rec_size);
-            return -1;
-        }
-
-#if 0
-        EC_DBG("object desc response:\n");
-        ec_print_data(data, rec_size);
-#endif
-
-        //sdo->unknown = EC_READ_U16(data + 8);
-        sdo->object_code = EC_READ_U8(data + 11);
-
-        name_size = rec_size - 12;
-        if (name_size) {
-            if (!(sdo->name = kmalloc(name_size + 1, GFP_KERNEL))) {
-                EC_ERR("Failed to allocate SDO name!\n");
-                return -1;
-            }
-
-            memcpy(sdo->name, data + 12, name_size);
-            sdo->name[name_size] = 0;
-        }
-
-        if (EC_READ_U8(data + 2) & 0x80) {
-            EC_ERR("Fragment follows (not implemented)!\n");
-            return -1;
-        }
-
-        // Fetch all entries (subindices)
-        if (ec_slave_fetch_sdo_entries(slave, datagram, sdo,
-                                       EC_READ_U8(data + 10)))
-            return -1;
-    }
-
-    return 0;
-}
-
-/*****************************************************************************/
-
-/**
-   Fetches all entries (subindices) to an SDO.
-   \return 0 in case of success, else < 0
-*/
-
-int ec_slave_fetch_sdo_entries(ec_slave_t *slave, /**< EtherCAT slave */
-                               ec_datagram_t *datagram, /**< datagram */
-                               ec_sdo_t *sdo, /**< SDO */
-                               uint8_t subindices /**< number of subindices */
-                               )
-{
-    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_mbox_prepare_send(slave, datagram, 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);
-        EC_WRITE_U16(data + 4, 0x0000);
-        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 (!(data = ec_slave_mbox_simple_io(slave, datagram, &rec_size)))
-            return -1;
-
-        if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
-            (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response
-            EC_ERR("SDO information error response at slave %i while"
-                   " fetching SDO entry 0x%04X:%i!\n", slave->ring_position,
-                   sdo->index, i);
-            ec_canopen_abort_msg(EC_READ_U32(data + 6));
-            return -1;
-        }
-
-        if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
-            (EC_READ_U8(data + 2) & 0x7F) != 0x06 || // Entry desc. response
-            EC_READ_U16(data + 6) != sdo->index || // SDO index
-            EC_READ_U8(data + 8) != i) { // SDO subindex
-            EC_ERR("Invalid entry description response at slave %i while"
-                   " fetching SDO entry 0x%04X:%i!\n", slave->ring_position,
-                   sdo->index, i);
-            ec_print_data(data, rec_size);
-            return -1;
-        }
-
-        if (rec_size < 16) {
-            EC_ERR("Invalid data size!\n");
-            ec_print_data(data, rec_size);
-            return -1;
-        }
-
-        if (!EC_READ_U16(data + 12)) // bit length = 0
-            continue;
-
-        data_size = rec_size - 16;
-
-        if (!(entry = (ec_sdo_entry_t *)
-              kmalloc(sizeof(ec_sdo_entry_t) + data_size + 1, GFP_KERNEL))) {
-            EC_ERR("Failed to allocate entry!\n");
-            return -1;
-        }
-
-        entry->subindex = i;
-        entry->data_type = EC_READ_U16(data + 10);
-        entry->bit_length = EC_READ_U16(data + 12);
-
-        // memory for name string appended to entry
-        entry->name = (uint8_t *) entry + sizeof(ec_sdo_entry_t);
-
-        memcpy(entry->name, data + 16, data_size);
-        entry->name[data_size] = 0;
-
-        list_add_tail(&entry->list, &sdo->entries);
-    }
-
-    return 0;
-}
-
-/*****************************************************************************/
-
-/**
-   SDO abort messages.
-   The "abort SDO transfer request" supplies an abort code,
-   which can be translated to clear text. This table does
-   the mapping of the codes and messages.
-*/
-
-const ec_code_msg_t sdo_abort_messages[] = {
-    {0x05030000, "Toggle bit not changed"},
-    {0x05040000, "SDO protocol timeout"},
-    {0x05040001, "Client/Server command specifier not valid or unknown"},
-    {0x05040005, "Out of memory"},
-    {0x06010000, "Unsupported access to an object"},
-    {0x06010001, "Attempt to read a write-only object"},
-    {0x06010002, "Attempt to write a read-only object"},
-    {0x06020000, "This object does not exist in the object directory"},
-    {0x06040041, "The object cannot be mapped into the PDO"},
-    {0x06040042, "The number and length of the objects to be mapped would"
-     " exceed the PDO length"},
-    {0x06040043, "General parameter incompatibility reason"},
-    {0x06040047, "Gerneral internal incompatibility in device"},
-    {0x06060000, "Access failure due to a hardware error"},
-    {0x06070010, "Data type does not match, length of service parameter does"
-     " not match"},
-    {0x06070012, "Data type does not match, length of service parameter too"
-     " high"},
-    {0x06070013, "Data type does not match, length of service parameter too"
-     " low"},
-    {0x06090011, "Subindex does not exist"},
-    {0x06090030, "Value range of parameter exceeded"},
-    {0x06090031, "Value of parameter written too high"},
-    {0x06090032, "Value of parameter written too low"},
-    {0x06090036, "Maximum value is less than minimum value"},
-    {0x08000000, "General error"},
-    {0x08000020, "Data cannot be transferred or stored to the application"},
-    {0x08000021, "Data cannot be transferred or stored to the application"
-     " because of local control"},
-    {0x08000022, "Data cannot be transferred or stored to the application"
-     " because of the present device state"},
-    {0x08000023, "Object dictionary dynamic generation fails or no object"
-     " dictionary is present"},
-    {}
-};
-
-/*****************************************************************************/
-
-/**
-   Outputs an SDO abort message.
-*/
-
-void ec_canopen_abort_msg(uint32_t abort_code)
-{
-    const ec_code_msg_t *abort_msg;
-
-    for (abort_msg = sdo_abort_messages; abort_msg->code; abort_msg++) {
-        if (abort_msg->code == abort_code) {
-            EC_ERR("SDO abort message 0x%08X: \"%s\".\n",
-                   abort_msg->code, abort_msg->message);
-            return;
-        }
-    }
-
-    EC_ERR("Unknown SDO abort code 0x%08X.\n", abort_code);
-}
-
-/******************************************************************************
- *  Realtime interface
- *****************************************************************************/
-
-/**
-   Reads an 8-bit SDO in expedited mode.
-   See ec_slave_sdo_read_exp()
-   \return 0 in case of success, else < 0
-   \ingroup RealtimeInterface
-*/
-
-int ecrt_slave_sdo_read_exp8(ec_slave_t *slave, /**< EtherCAT slave */
-                             uint16_t sdo_index, /**< SDO index */
-                             uint8_t sdo_subindex, /**< SDO subindex */
-                             uint8_t *target /**< memory for read value */
-                             )
-{
-    uint8_t data[4];
-    if (ec_slave_sdo_read_exp(slave, sdo_index, sdo_subindex, data)) return -1;
-    *target = EC_READ_U8(data);
-    return 0;
-}
-
-/*****************************************************************************/
-
-/**
-   Reads a 16-bit SDO in expedited mode.
-   See ec_slave_sdo_read_exp()
-   \return 0 in case of success, else < 0
-   \ingroup RealtimeInterface
-*/
-
-int ecrt_slave_sdo_read_exp16(ec_slave_t *slave, /**< EtherCAT slave */
-                              uint16_t sdo_index, /**< SDO index */
-                              uint8_t sdo_subindex, /**< SDO subindex */
-                              uint16_t *target /**< memory for read value */
-                              )
-{
-    uint8_t data[4];
-    if (ec_slave_sdo_read_exp(slave, sdo_index, sdo_subindex, data)) return -1;
-    *target = EC_READ_U16(data);
-    return 0;
-}
-
-/*****************************************************************************/
-
-/**
-   Reads a 32-bit SDO in expedited mode.
-   See ec_slave_sdo_read_exp()
-   \return 0 in case of success, else < 0
-   \ingroup RealtimeInterface
-*/
-
-int ecrt_slave_sdo_read_exp32(ec_slave_t *slave, /**< EtherCAT slave */
-                              uint16_t sdo_index, /**< SDO index */
-                              uint8_t sdo_subindex, /**< SDO subindex */
-                              uint32_t *target /**< memory for read value */
-                              )
-{
-    uint8_t data[4];
-    if (ec_slave_sdo_read_exp(slave, sdo_index, sdo_subindex, data)) return -1;
-    *target = EC_READ_U32(data);
-    return 0;
-}
-
-/*****************************************************************************/
-
-/**
-   Writes an 8-bit SDO in expedited mode.
-   \return 0 in case of success, else < 0
-   \ingroup RealtimeInterface
-*/
-
-int ecrt_slave_sdo_write_exp8(ec_slave_t *slave, /**< EtherCAT slave */
-                              uint16_t sdo_index, /**< SDO index */
-                              uint8_t sdo_subindex, /**< SDO subindex */
-                              uint8_t value /**< new value */
-                              )
-{
-    return ec_slave_sdo_write_exp(slave, sdo_index, sdo_subindex, &value, 1);
-}
-
-/*****************************************************************************/
-
-/**
-   Writes a 16-bit SDO in expedited mode.
-   \return 0 in case of success, else < 0
-   \ingroup RealtimeInterface
-*/
-
-int ecrt_slave_sdo_write_exp16(ec_slave_t *slave, /**< EtherCAT slave */
-                               uint16_t sdo_index, /**< SDO index */
-                               uint8_t sdo_subindex, /**< SDO subindex */
-                               uint16_t value /**< new value */
-                               )
-{
-    uint8_t data[2];
-    EC_WRITE_U16(data, value);
-    return ec_slave_sdo_write_exp(slave, sdo_index, sdo_subindex, data, 2);
-}
-
-/*****************************************************************************/
-
-/**
-   Writes a 32-bit SDO in expedited mode.
-   \return 0 in case of success, else < 0
-   \ingroup RealtimeInterface
-*/
-
-int ecrt_slave_sdo_write_exp32(ec_slave_t *slave, /**< EtherCAT slave */
-                               uint16_t sdo_index, /**< SDO index */
-                               uint8_t sdo_subindex, /**< SDO subindex */
-                               uint32_t value /**< new value */
-                               )
-{
-    uint8_t data[4];
-    EC_WRITE_U32(data, value);
-    return ec_slave_sdo_write_exp(slave, sdo_index, sdo_subindex, data, 4);
-}
-
-/*****************************************************************************/
-
-/** \cond */
-
-EXPORT_SYMBOL(ecrt_slave_sdo_read_exp8);
-EXPORT_SYMBOL(ecrt_slave_sdo_read_exp16);
-EXPORT_SYMBOL(ecrt_slave_sdo_read_exp32);
-EXPORT_SYMBOL(ecrt_slave_sdo_write_exp8);
-EXPORT_SYMBOL(ecrt_slave_sdo_write_exp16);
-EXPORT_SYMBOL(ecrt_slave_sdo_write_exp32);
-EXPORT_SYMBOL(ecrt_slave_sdo_read);
-
-/** \endcond */
-
-/*****************************************************************************/
--- a/master/datagram.c	Wed Aug 02 23:16:10 2006 +0000
+++ b/master/datagram.c	Thu Aug 03 12:51:17 2006 +0000
@@ -52,7 +52,7 @@
         return -1; \
     datagram->index = 0; \
     datagram->working_counter = 0; \
-    datagram->state = EC_CMD_INIT;
+    datagram->state = EC_DATAGRAM_INIT;
 
 #define EC_FUNC_FOOTER \
     datagram->data_size = data_size; \
@@ -69,14 +69,14 @@
 
 void ec_datagram_init(ec_datagram_t *datagram /**< EtherCAT datagram */)
 {
-    datagram->type = EC_CMD_NONE;
+    datagram->type = EC_DATAGRAM_NONE;
     datagram->address.logical = 0x00000000;
     datagram->data = NULL;
     datagram->mem_size = 0;
     datagram->data_size = 0;
     datagram->index = 0x00;
     datagram->working_counter = 0x00;
-    datagram->state = EC_CMD_INIT;
+    datagram->state = EC_DATAGRAM_INIT;
     datagram->t_sent = 0;
 }
 
@@ -142,7 +142,7 @@
         EC_WARN("Using node address 0x0000!\n");
 
     EC_FUNC_HEADER;
-    datagram->type = EC_CMD_NPRD;
+    datagram->type = EC_DATAGRAM_NPRD;
     datagram->address.physical.slave = node_address;
     datagram->address.physical.mem = offset;
     EC_FUNC_FOOTER;
@@ -170,7 +170,7 @@
         EC_WARN("Using node address 0x0000!\n");
 
     EC_FUNC_HEADER;
-    datagram->type = EC_CMD_NPWR;
+    datagram->type = EC_DATAGRAM_NPWR;
     datagram->address.physical.slave = node_address;
     datagram->address.physical.mem = offset;
     EC_FUNC_FOOTER;
@@ -195,7 +195,7 @@
                      )
 {
     EC_FUNC_HEADER;
-    datagram->type = EC_CMD_APRD;
+    datagram->type = EC_DATAGRAM_APRD;
     datagram->address.physical.slave = (int16_t) ring_position * (-1);
     datagram->address.physical.mem = offset;
     EC_FUNC_FOOTER;
@@ -220,7 +220,7 @@
                      )
 {
     EC_FUNC_HEADER;
-    datagram->type = EC_CMD_APWR;
+    datagram->type = EC_DATAGRAM_APWR;
     datagram->address.physical.slave = (int16_t) ring_position * (-1);
     datagram->address.physical.mem = offset;
     EC_FUNC_FOOTER;
@@ -243,7 +243,7 @@
                     )
 {
     EC_FUNC_HEADER;
-    datagram->type = EC_CMD_BRD;
+    datagram->type = EC_DATAGRAM_BRD;
     datagram->address.physical.slave = 0x0000;
     datagram->address.physical.mem = offset;
     EC_FUNC_FOOTER;
@@ -266,7 +266,7 @@
                     )
 {
     EC_FUNC_HEADER;
-    datagram->type = EC_CMD_BWR;
+    datagram->type = EC_DATAGRAM_BWR;
     datagram->address.physical.slave = 0x0000;
     datagram->address.physical.mem = offset;
     EC_FUNC_FOOTER;
@@ -289,7 +289,7 @@
                     )
 {
     EC_FUNC_HEADER;
-    datagram->type = EC_CMD_LRW;
+    datagram->type = EC_DATAGRAM_LRW;
     datagram->address.logical = offset;
     EC_FUNC_FOOTER;
 }
--- a/master/datagram.h	Wed Aug 02 23:16:10 2006 +0000
+++ b/master/datagram.h	Thu Aug 03 12:51:17 2006 +0000
@@ -55,14 +55,14 @@
 
 typedef enum
 {
-    EC_CMD_NONE = 0x00, /**< Dummy */
-    EC_CMD_APRD = 0x01, /**< Auto-increment physical read */
-    EC_CMD_APWR = 0x02, /**< Auto-increment physical write */
-    EC_CMD_NPRD = 0x04, /**< Node-addressed physical read */
-    EC_CMD_NPWR = 0x05, /**< Node-addressed physical write */
-    EC_CMD_BRD  = 0x07, /**< Broadcast read */
-    EC_CMD_BWR  = 0x08, /**< Broadcast write */
-    EC_CMD_LRW  = 0x0C  /**< Logical read/write */
+    EC_DATAGRAM_NONE = 0x00, /**< Dummy */
+    EC_DATAGRAM_APRD = 0x01, /**< Auto-increment physical read */
+    EC_DATAGRAM_APWR = 0x02, /**< Auto-increment physical write */
+    EC_DATAGRAM_NPRD = 0x04, /**< Node-addressed physical read */
+    EC_DATAGRAM_NPWR = 0x05, /**< Node-addressed physical write */
+    EC_DATAGRAM_BRD  = 0x07, /**< Broadcast read */
+    EC_DATAGRAM_BWR  = 0x08, /**< Broadcast write */
+    EC_DATAGRAM_LRW  = 0x0C  /**< Logical read/write */
 }
 ec_datagram_type_t;
 
@@ -72,12 +72,12 @@
 
 typedef enum
 {
-    EC_CMD_INIT, /**< new datagram */
-    EC_CMD_QUEUED, /**< datagram queued by master */
-    EC_CMD_SENT, /**< datagram has been sent */
-    EC_CMD_RECEIVED, /**< datagram has been received */
-    EC_CMD_TIMEOUT, /**< datagram timed out */
-    EC_CMD_ERROR /**< error while sending/receiving */
+    EC_DATAGRAM_INIT, /**< new datagram */
+    EC_DATAGRAM_QUEUED, /**< datagram queued by master */
+    EC_DATAGRAM_SENT, /**< datagram has been sent */
+    EC_DATAGRAM_RECEIVED, /**< datagram has been received */
+    EC_DATAGRAM_TIMED_OUT, /**< datagram timed out */
+    EC_DATAGRAM_ERROR /**< error while sending/receiving */
 }
 ec_datagram_state_t;
 
--- a/master/domain.c	Wed Aug 02 23:16:10 2006 +0000
+++ b/master/domain.c	Thu Aug 03 12:51:17 2006 +0000
@@ -46,7 +46,23 @@
 
 /*****************************************************************************/
 
-void ec_domain_clear_field_regs(ec_domain_t *);
+/**
+   Data registration type.
+*/
+
+typedef struct
+{
+    struct list_head list; /**< list item */
+    ec_slave_t *slave; /**< slave */
+    const ec_sii_sync_t *sync; /**< sync manager */
+    off_t sync_offset; /**< pdo offset */
+    void **data_ptr; /**< pointer to process data pointer(s) */
+}
+ec_data_reg_t;
+
+/*****************************************************************************/
+
+void ec_domain_clear_data_regs(ec_domain_t *);
 ssize_t ec_show_domain_attribute(struct kobject *, struct attribute *, char *);
 
 /*****************************************************************************/
@@ -91,7 +107,7 @@
     domain->base_address = 0;
     domain->response_count = 0xFFFFFFFF;
 
-    INIT_LIST_HEAD(&domain->field_regs);
+    INIT_LIST_HEAD(&domain->data_regs);
     INIT_LIST_HEAD(&domain->datagrams);
 
     // init kobject and add it to the hierarchy
@@ -127,7 +143,7 @@
         kfree(datagram);
     }
 
-    ec_domain_clear_field_regs(domain);
+    ec_domain_clear_data_regs(domain);
 
     kfree(domain);
 }
@@ -139,34 +155,70 @@
    \return 0 in case of success, else < 0
 */
 
-int ec_domain_reg_field(ec_domain_t *domain, /**< EtherCAT domain */
-                        ec_slave_t *slave, /**< slave */
-                        const ec_sync_t *sync, /**< sync manager */
-                        uint32_t field_offset, /**< data field offset */
-                        void **data_ptr /**< pointer to the process data
-                                           pointer */
-                        )
-{
-    ec_field_reg_t *field_reg;
-
-    if (!(field_reg =
-          (ec_field_reg_t *) kmalloc(sizeof(ec_field_reg_t), GFP_KERNEL))) {
-        EC_ERR("Failed to allocate field registration.\n");
+int ec_domain_reg_pdo_entry(ec_domain_t *domain, /**< EtherCAT domain */
+                            ec_slave_t *slave, /**< slave */
+                            const ec_sii_pdo_t *pdo,
+                            const ec_sii_pdo_entry_t *entry,
+                            /**< PDO registration entry */
+                            void **data_ptr /**< pointer to the process data
+                                               pointer */
+                            )
+{
+    ec_data_reg_t *data_reg;
+    const ec_sii_sync_t *sync;
+    const ec_sii_pdo_t *other_pdo;
+    const ec_sii_pdo_entry_t *other_entry;
+    unsigned int bit_offset, byte_offset, sync_found;
+
+    // Find sync manager for PDO
+    sync_found = 0;
+    list_for_each_entry(sync, &slave->sii_syncs, list) {
+        if (sync->index == pdo->sync_index) {
+            sync_found = 1;
+            break;
+        }
+    }
+
+    if (!sync_found) {
+        EC_ERR("No sync manager for PDO 0x%04X:%i.",
+               pdo->index, entry->subindex);
+        return -1;
+    }
+
+    // Calculate offset for process data pointer
+    bit_offset = 0;
+    byte_offset = 0;
+    list_for_each_entry(other_pdo, &slave->sii_pdos, list) {
+        if (other_pdo->sync_index != sync->index) continue;
+
+        list_for_each_entry(other_entry, &pdo->entries, list) {
+            if (other_entry == entry) {
+                byte_offset = bit_offset / 8;
+                break;
+            }
+            bit_offset += other_entry->bit_length;
+        }
+    }
+
+    // Allocate memory for data registration object
+    if (!(data_reg =
+          (ec_data_reg_t *) kmalloc(sizeof(ec_data_reg_t), GFP_KERNEL))) {
+        EC_ERR("Failed to allocate data registration.\n");
         return -1;
     }
 
     if (ec_slave_prepare_fmmu(slave, domain, sync)) {
         EC_ERR("FMMU configuration failed.\n");
-        kfree(field_reg);
+        kfree(data_reg);
         return -1;
     }
 
-    field_reg->slave = slave;
-    field_reg->sync = sync;
-    field_reg->field_offset = field_offset;
-    field_reg->data_ptr = data_ptr;
-
-    list_add_tail(&field_reg->list, &domain->field_regs);
+    data_reg->slave = slave;
+    data_reg->sync = sync;
+    data_reg->sync_offset = byte_offset;
+    data_reg->data_ptr = data_ptr;
+
+    list_add_tail(&data_reg->list, &domain->data_regs);
     return 0;
 }
 
@@ -176,13 +228,13 @@
    Clears the list of the registered data fields.
 */
 
-void ec_domain_clear_field_regs(ec_domain_t *domain /**< EtherCAT domain */)
-{
-    ec_field_reg_t *field_reg, *next;
-
-    list_for_each_entry_safe(field_reg, next, &domain->field_regs, list) {
-        list_del(&field_reg->list);
-        kfree(field_reg);
+void ec_domain_clear_data_regs(ec_domain_t *domain /**< EtherCAT domain */)
+{
+    ec_data_reg_t *data_reg, *next;
+
+    list_for_each_entry_safe(data_reg, next, &domain->data_regs, list) {
+        list_del(&data_reg->list);
+        kfree(data_reg);
     }
 }
 
@@ -222,7 +274,7 @@
    Creates a domain.
    Reserves domain memory, calculates the logical addresses of the
    corresponding FMMUs and sets the process data pointer of the registered
-   data fields.
+   process data.
    \return 0 in case of success, else < 0
 */
 
@@ -230,22 +282,22 @@
                     uint32_t base_address /**< logical base address */
                     )
 {
-    ec_field_reg_t *field_reg;
+    ec_data_reg_t *data_reg;
     ec_slave_t *slave;
     ec_fmmu_t *fmmu;
-    unsigned int i, j, cmd_count;
-    uint32_t field_off, field_off_cmd;
-    uint32_t cmd_offset;
-    size_t cmd_data_size, sync_size;
+    unsigned int i, j, datagram_count;
+    uint32_t pdo_off, pdo_off_datagram;
+    uint32_t datagram_offset;
+    size_t datagram_data_size, sync_size;
     ec_datagram_t *datagram;
 
     domain->base_address = base_address;
 
     // calculate size of process data and allocate memory
     domain->data_size = 0;
-    cmd_offset = base_address;
-    cmd_data_size = 0;
-    cmd_count = 0;
+    datagram_offset = base_address;
+    datagram_data_size = 0;
+    datagram_count = 0;
     list_for_each_entry(slave, &domain->master->slaves, list) {
         for (j = 0; j < slave->fmmu_count; j++) {
             fmmu = &slave->fmmus[j];
@@ -253,47 +305,48 @@
                 fmmu->logical_start_address = base_address + domain->data_size;
                 sync_size = ec_slave_calc_sync_size(slave, fmmu->sync);
                 domain->data_size += sync_size;
-                if (cmd_data_size + sync_size > EC_MAX_DATA_SIZE) {
-                    if (ec_domain_add_datagram(domain, cmd_offset,
-                                               cmd_data_size)) return -1;
-                    cmd_offset += cmd_data_size;
-                    cmd_data_size = 0;
-                    cmd_count++;
+                if (datagram_data_size + sync_size > EC_MAX_DATA_SIZE) {
+                    if (ec_domain_add_datagram(domain, datagram_offset,
+                                               datagram_data_size)) return -1;
+                    datagram_offset += datagram_data_size;
+                    datagram_data_size = 0;
+                    datagram_count++;
                 }
-                cmd_data_size += sync_size;
+                datagram_data_size += sync_size;
             }
         }
     }
 
     // allocate last datagram
-    if (cmd_data_size) {
-        if (ec_domain_add_datagram(domain, cmd_offset, cmd_data_size))
+    if (datagram_data_size) {
+        if (ec_domain_add_datagram(domain, datagram_offset,
+                                   datagram_data_size))
             return -1;
-        cmd_count++;
-    }
-
-    if (!cmd_count) {
+        datagram_count++;
+    }
+
+    if (!datagram_count) {
         EC_WARN("Domain %i contains no data!\n", domain->index);
-        ec_domain_clear_field_regs(domain);
+        ec_domain_clear_data_regs(domain);
         return 0;
     }
 
     // set all process data pointers
-    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) {
-                field_off = fmmu->logical_start_address +
-                    field_reg->field_offset;
+    list_for_each_entry(data_reg, &domain->data_regs, list) {
+        for (i = 0; i < data_reg->slave->fmmu_count; i++) {
+            fmmu = &data_reg->slave->fmmus[i];
+            if (fmmu->domain == domain && fmmu->sync == data_reg->sync) {
+                pdo_off = fmmu->logical_start_address + data_reg->sync_offset;
                 // search datagram
                 list_for_each_entry(datagram, &domain->datagrams, list) {
-                    field_off_cmd = field_off - datagram->address.logical;
-                    if (field_off >= datagram->address.logical &&
-                        field_off_cmd < datagram->mem_size) {
-                        *field_reg->data_ptr = datagram->data + field_off_cmd;
+                    pdo_off_datagram = pdo_off - datagram->address.logical;
+                    if (pdo_off >= datagram->address.logical &&
+                        pdo_off_datagram < datagram->mem_size) {
+                        *data_reg->data_ptr = datagram->data +
+                            pdo_off_datagram;
                     }
                 }
-                if (!field_reg->data_ptr) {
+                if (!data_reg->data_ptr) {
                     EC_ERR("Failed to assign data pointer!\n");
                     return -1;
                 }
@@ -303,31 +356,26 @@
     }
 
     EC_INFO("Domain %i - Allocated %i bytes in %i datagram%s\n",
-            domain->index, domain->data_size, cmd_count,
-            cmd_count == 1 ? "" : "s");
-
-    ec_domain_clear_field_regs(domain);
-
-    return 0;
-}
-
-/*****************************************************************************/
-
-/**
-   Sets the number of responding slaves and outputs it on demand.
-   This number isn't really the number of responding slaves, but the sum of
-   the working counters of all domain datagrams. Some slaves increase the
-   working counter by 2, some by 1.
-*/
-
-void ec_domain_response_count(ec_domain_t *domain, /**< EtherCAT domain */
-                              unsigned int count /**< new WC sum */
-                              )
-{
-    if (count != domain->response_count) {
-        domain->response_count = count;
-        EC_INFO("Domain %i working counter change: %i\n", domain->index,
-                count);
+            domain->index, domain->data_size, datagram_count,
+            datagram_count == 1 ? "" : "s");
+
+    ec_domain_clear_data_regs(domain);
+
+    return 0;
+}
+
+/*****************************************************************************/
+
+/**
+   Places all process data datagrams in the masters datagram queue.
+*/
+
+void ec_domain_queue(ec_domain_t *domain /**< EtherCAT domain */)
+{
+    ec_datagram_t *datagram;
+
+    list_for_each_entry(datagram, &domain->datagrams, list) {
+        ec_master_queue_datagram(domain->master, datagram);
     }
 }
 
@@ -357,62 +405,45 @@
  *****************************************************************************/
 
 /**
-   Registers a data field in a domain.
-   - If \a data_ptr is NULL, the slave is only checked against its type.
-   - If \a field_count is 0, it is assumed that one data field is to be
-   registered.
-   - If \a field_count is greater then 1, it is assumed that \a data_ptr
-   is an array of the respective size.
+   Registers a PDO in a domain.
+   - If \a data_ptr is NULL, the slave is only validated.
    \return pointer to the slave on success, else NULL
    \ingroup RealtimeInterface
 */
 
-ec_slave_t *ecrt_domain_register_field(ec_domain_t *domain,
-                                       /**< EtherCAT domain */
-                                       const char *address,
-                                       /**< ASCII address of the slave,
-                                          see ecrt_master_get_slave() */
-                                       const char *vendor_name,
-                                       /**< vendor name */
-                                       const char *product_name,
-                                       /**< product name */
-                                       void **data_ptr,
-                                       /**< address of the process data
-                                          pointer */
-                                       const char *field_name,
-                                       /**< data field name */
-                                       unsigned int field_index,
-                                       /**< offset of data fields with
-                                          \a field_type  */
-                                       unsigned int field_count
-                                       /**< number of data fields (with
-                                          the same type) to register */
-                                       )
+ec_slave_t *ecrt_domain_register_pdo(ec_domain_t *domain,
+                                     /**< EtherCAT domain */
+                                     const char *address,
+                                     /**< ASCII address of the slave,
+                                        see ecrt_master_get_slave() */
+                                     uint32_t vendor_id,
+                                     /**< vendor ID */
+                                     uint32_t product_code,
+                                     /**< product code */
+                                     uint16_t pdo_index,
+                                     /**< PDO index */
+                                     uint8_t pdo_subindex,
+                                     /**< PDO subindex */
+                                     void **data_ptr
+                                     /**< address of the process data
+                                        pointer */
+                                     )
 {
     ec_slave_t *slave;
-    const ec_slave_type_t *type;
     ec_master_t *master;
-    const ec_sync_t *sync;
-    const ec_field_t *field;
-    unsigned int field_counter, i, j, orig_field_index, orig_field_count;
-    uint32_t field_offset;
+    const ec_sii_pdo_t *pdo;
+    const ec_sii_pdo_entry_t *entry;
 
     master = domain->master;
 
     // translate address
     if (!(slave = ecrt_master_get_slave(master, address))) return NULL;
 
-    if (!(type = slave->type)) {
-        EC_ERR("Slave \"%s\" (position %i) has unknown type!\n", address,
-               slave->ring_position);
-        return NULL;
-    }
-
-    if (strcmp(vendor_name, type->vendor_name) ||
-        strcmp(product_name, type->product_name)) {
-        EC_ERR("Invalid slave type at position %i - Requested: \"%s %s\","
-               " found: \"%s %s\".\n", slave->ring_position, vendor_name,
-               product_name, type->vendor_name, type->product_name);
+    if (vendor_id != slave->sii_vendor_id ||
+        product_code != slave->sii_product_code) {
+        EC_ERR("Invalid slave type at position %i - Requested: 0x%08X 0x%08X,"
+               " found: 0x%08X 0x%08X\".\n", slave->ring_position, vendor_id,
+               product_code, slave->sii_vendor_id, slave->sii_product_code);
         return NULL;
     }
 
@@ -421,32 +452,22 @@
         slave->registered = 1;
     }
 
-    if (!field_count) field_count = 1;
-    orig_field_index = field_index;
-    orig_field_count = field_count;
-
-    field_counter = 0;
-    for (i = 0; type->sync_managers[i]; i++) {
-        sync = type->sync_managers[i];
-        field_offset = 0;
-        for (j = 0; sync->fields[j]; j++) {
-            field = sync->fields[j];
-            if (!strcmp(field->name, field_name)) {
-                if (field_counter++ == field_index) {
-                    if (data_ptr)
-                        ec_domain_reg_field(domain, slave, sync, field_offset,
-                                            data_ptr++);
-                    if (!(--field_count)) return slave;
-                    field_index++;
-                }
+    list_for_each_entry(pdo, &slave->sii_pdos, list) {
+        list_for_each_entry(entry, &pdo->entries, list) {
+            if (entry->index != pdo_index
+                || entry->subindex != pdo_subindex) continue;
+
+            if (data_ptr) {
+                ec_domain_reg_pdo_entry(domain, slave, pdo, entry, data_ptr);
             }
-            field_offset += field->size;
+
+            return slave;
         }
     }
 
-    EC_ERR("Slave %i (\"%s %s\") registration mismatch: Field \"%s\","
-           " index %i, count %i.\n", slave->ring_position, vendor_name,
-           product_name, field_name, orig_field_index, orig_field_count);
+    EC_ERR("Slave %i does not provide PDO 0x%04X:%i.\n",
+           slave->ring_position, pdo_index, pdo_subindex);
+    slave->registered = 0;
     return NULL;
 }
 
@@ -459,20 +480,21 @@
    \ingroup RealtimeInterface
 */
 
-int ecrt_domain_register_field_list(ec_domain_t *domain,
-                                    /**< EtherCAT domain */
-                                    const ec_field_init_t *fields
-                                    /**< array of data field registrations */
-                                    )
-{
-    const ec_field_init_t *field;
-
-    for (field = fields; field->slave_address; field++)
-        if (!ecrt_domain_register_field(domain, field->slave_address,
-                                        field->vendor_name,
-                                        field->product_name, field->data_ptr,
-                                        field->field_name, field->field_index,
-                                        field->field_count))
+int ecrt_domain_register_pdo_list(ec_domain_t *domain,
+                                  /**< EtherCAT domain */
+                                  const ec_pdo_reg_t *pdos
+                                  /**< array of PDO registrations */
+                                  )
+{
+    const ec_pdo_reg_t *pdo;
+
+    for (pdo = pdos; pdo->slave_address; pdo++)
+        if (!ecrt_domain_register_pdo(domain, pdo->slave_address,
+                                      pdo->vendor_id,
+                                      pdo->product_code,
+                                      pdo->pdo_index,
+                                      pdo->pdo_subindex,
+                                      pdo->data_ptr))
             return -1;
 
     return 0;
@@ -481,23 +503,7 @@
 /*****************************************************************************/
 
 /**
-   Places all process data datagrams in the masters datagram queue.
-   \ingroup RealtimeInterface
-*/
-
-void ecrt_domain_queue(ec_domain_t *domain /**< EtherCAT domain */)
-{
-    ec_datagram_t *datagram;
-
-    list_for_each_entry(datagram, &domain->datagrams, list) {
-        ec_master_queue_datagram(domain->master, datagram);
-    }
-}
-
-/*****************************************************************************/
-
-/**
-   Processes received process data.
+   Processes received process data and requeues the domain datagram(s).
    \ingroup RealtimeInterface
 */
 
@@ -507,14 +513,19 @@
     ec_datagram_t *datagram;
 
     working_counter_sum = 0;
-
     list_for_each_entry(datagram, &domain->datagrams, list) {
-        if (datagram->state == EC_CMD_RECEIVED) {
+        if (datagram->state == EC_DATAGRAM_RECEIVED) {
             working_counter_sum += datagram->working_counter;
         }
     }
 
-    ec_domain_response_count(domain, working_counter_sum);
+    if (working_counter_sum != domain->response_count) {
+        domain->response_count = working_counter_sum;
+        EC_INFO("Domain %i working counter change: %i\n", domain->index,
+                domain->response_count);
+    }
+
+    ec_domain_queue(domain);
 }
 
 /*****************************************************************************/
@@ -525,12 +536,12 @@
    \ingroup RealtimeInterface
 */
 
-int ecrt_domain_state(ec_domain_t *domain /**< EtherCAT domain */)
+int ecrt_domain_state(const ec_domain_t *domain /**< EtherCAT domain */)
 {
     ec_datagram_t *datagram;
 
     list_for_each_entry(datagram, &domain->datagrams, list) {
-        if (datagram->state != EC_CMD_RECEIVED) return -1;
+        if (datagram->state != EC_DATAGRAM_RECEIVED) return -1;
     }
 
     return 0;
@@ -540,9 +551,8 @@
 
 /** \cond */
 
-EXPORT_SYMBOL(ecrt_domain_register_field);
-EXPORT_SYMBOL(ecrt_domain_register_field_list);
-EXPORT_SYMBOL(ecrt_domain_queue);
+EXPORT_SYMBOL(ecrt_domain_register_pdo);
+EXPORT_SYMBOL(ecrt_domain_register_pdo_list);
 EXPORT_SYMBOL(ecrt_domain_process);
 EXPORT_SYMBOL(ecrt_domain_state);
 
--- a/master/domain.h	Wed Aug 02 23:16:10 2006 +0000
+++ b/master/domain.h	Thu Aug 03 12:51:17 2006 +0000
@@ -45,24 +45,8 @@
 #include <linux/kobject.h>
 
 #include "globals.h"
-#include "slave.h"
 #include "datagram.h"
-
-/*****************************************************************************/
-
-/**
-   Data field registration type.
-*/
-
-typedef struct
-{
-    struct list_head list; /**< list item */
-    ec_slave_t *slave; /**< slave */
-    const ec_sync_t *sync; /**< sync manager */
-    uint32_t field_offset; /**< data field offset */
-    void **data_ptr; /**< pointer to process data pointer(s) */
-}
-ec_field_reg_t;
+#include "master.h"
 
 /*****************************************************************************/
 
@@ -82,7 +66,7 @@
     struct list_head datagrams; /**< process data datagrams */
     uint32_t base_address; /**< logical offset address of the process data */
     unsigned int response_count; /**< number of responding slaves */
-    struct list_head field_regs; /**< data field registrations */
+    struct list_head data_regs; /**< PDO data registrations */
 };
 
 /*****************************************************************************/
@@ -90,6 +74,7 @@
 int ec_domain_init(ec_domain_t *, ec_master_t *, unsigned int);
 void ec_domain_clear(struct kobject *);
 int ec_domain_alloc(ec_domain_t *, uint32_t);
+void ec_domain_queue(ec_domain_t *);
 
 /*****************************************************************************/
 
--- a/master/ethernet.c	Wed Aug 02 23:16:10 2006 +0000
+++ b/master/ethernet.c	Thu Aug 03 12:51:17 2006 +0000
@@ -155,10 +155,8 @@
 
 void ec_eoe_clear(ec_eoe_t *eoe /**< EoE handler */)
 {
-    if (eoe->dev) { // TODO: dev never NULL?
-        unregister_netdev(eoe->dev);
-        free_netdev(eoe->dev);
-    }
+    unregister_netdev(eoe->dev);
+    free_netdev(eoe->dev);
 
     // empty transmit queue
     ec_eoe_flush(eoe);
@@ -292,22 +290,6 @@
     return eoe->slave && eoe->opened;
 }
 
-/*****************************************************************************/
-
-/**
-   Prints EoE handler information.
-*/
-
-void ec_eoe_print(const ec_eoe_t *eoe /**< EoE handler */)
-{
-    EC_INFO("  EoE handler %s\n", eoe->dev->name);
-    EC_INFO("    State: %s\n", eoe->opened ? "opened" : "closed");
-    if (eoe->slave)
-        EC_INFO("    Coupled to slave %i.\n", eoe->slave->ring_position);
-    else
-        EC_INFO("    Not coupled.\n");
-}
-
 /******************************************************************************
  *  STATE PROCESSING FUNCTIONS
  *****************************************************************************/
@@ -338,7 +320,7 @@
 
 void ec_eoe_state_rx_check(ec_eoe_t *eoe /**< EoE handler */)
 {
-    if (eoe->datagram.state != EC_CMD_RECEIVED) {
+    if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) {
         eoe->stats.rx_errors++;
         eoe->state = ec_eoe_state_tx_start;
         return;
@@ -369,7 +351,7 @@
     uint8_t frame_number, fragment_offset, fragment_number;
     off_t offset;
 
-    if (eoe->datagram.state != EC_CMD_RECEIVED) {
+    if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) {
         eoe->stats.rx_errors++;
         eoe->state = ec_eoe_state_tx_start;
         return;
@@ -570,7 +552,7 @@
 
 void ec_eoe_state_tx_sent(ec_eoe_t *eoe /**< EoE handler */)
 {
-    if (eoe->datagram.state != EC_CMD_RECEIVED) {
+    if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) {
         eoe->stats.tx_errors++;
         eoe->state = ec_eoe_state_rx_start;
         return;
--- a/master/ethernet.h	Wed Aug 02 23:16:10 2006 +0000
+++ b/master/ethernet.h	Thu Aug 03 12:51:17 2006 +0000
@@ -98,6 +98,5 @@
 void ec_eoe_clear(ec_eoe_t *);
 void ec_eoe_run(ec_eoe_t *);
 unsigned int ec_eoe_active(const ec_eoe_t *);
-void ec_eoe_print(const ec_eoe_t *);
 
 /*****************************************************************************/
--- a/master/fsm.c	Wed Aug 02 23:16:10 2006 +0000
+++ b/master/fsm.c	Thu Aug 03 12:51:17 2006 +0000
@@ -54,6 +54,13 @@
 void ec_fsm_master_scan_slaves(ec_fsm_t *);
 void ec_fsm_master_write_eeprom(ec_fsm_t *);
 
+void ec_fsm_startup_start(ec_fsm_t *);
+void ec_fsm_startup_broadcast(ec_fsm_t *);
+void ec_fsm_startup_scan(ec_fsm_t *);
+
+void ec_fsm_configuration_start(ec_fsm_t *);
+void ec_fsm_configuration_conf(ec_fsm_t *);
+
 void ec_fsm_slavescan_start(ec_fsm_t *);
 void ec_fsm_slavescan_address(ec_fsm_t *);
 void ec_fsm_slavescan_state(ec_fsm_t *);
@@ -61,7 +68,6 @@
 void ec_fsm_slavescan_datalink(ec_fsm_t *);
 void ec_fsm_slavescan_eeprom_size(ec_fsm_t *);
 void ec_fsm_slavescan_eeprom_data(ec_fsm_t *);
-void ec_fsm_slavescan_end(ec_fsm_t *);
 
 void ec_fsm_slaveconf_init(ec_fsm_t *);
 void ec_fsm_slaveconf_sync(ec_fsm_t *);
@@ -69,7 +75,6 @@
 void ec_fsm_slaveconf_fmmu(ec_fsm_t *);
 void ec_fsm_slaveconf_saveop(ec_fsm_t *);
 void ec_fsm_slaveconf_op(ec_fsm_t *);
-void ec_fsm_slaveconf_end(ec_fsm_t *);
 
 void ec_fsm_sii_start_reading(ec_fsm_t *);
 void ec_fsm_sii_read_check(ec_fsm_t *);
@@ -77,8 +82,6 @@
 void ec_fsm_sii_start_writing(ec_fsm_t *);
 void ec_fsm_sii_write_check(ec_fsm_t *);
 void ec_fsm_sii_write_check2(ec_fsm_t *);
-void ec_fsm_sii_end(ec_fsm_t *);
-void ec_fsm_sii_error(ec_fsm_t *);
 
 void ec_fsm_change_start(ec_fsm_t *);
 void ec_fsm_change_check(ec_fsm_t *);
@@ -86,8 +89,9 @@
 void ec_fsm_change_code(ec_fsm_t *);
 void ec_fsm_change_ack(ec_fsm_t *);
 void ec_fsm_change_check_ack(ec_fsm_t *);
-void ec_fsm_change_end(ec_fsm_t *);
-void ec_fsm_change_error(ec_fsm_t *);
+
+void ec_fsm_end(ec_fsm_t *);
+void ec_fsm_error(ec_fsm_t *);
 
 /*****************************************************************************/
 
@@ -97,7 +101,7 @@
 
 int ec_fsm_init(ec_fsm_t *fsm, /**< finite state machine */
                 ec_master_t *master /**< EtherCAT master */
-    )
+                )
 {
     fsm->master = master;
     fsm->master_state = ec_fsm_master_start;
@@ -149,8 +153,224 @@
     fsm->master_state(fsm);
 }
 
+/*****************************************************************************/
+
+void ec_fsm_startup(ec_fsm_t *fsm)
+{
+    fsm->master_state = ec_fsm_startup_start;
+}
+
+/*****************************************************************************/
+
+int ec_fsm_startup_running(ec_fsm_t *fsm)
+{
+    return fsm->master_state != ec_fsm_end &&
+        fsm->master_state != ec_fsm_error;
+}
+
+/*****************************************************************************/
+
+int ec_fsm_startup_success(ec_fsm_t *fsm)
+{
+    return fsm->master_state == ec_fsm_end;
+}
+
+/*****************************************************************************/
+
+void ec_fsm_configuration(ec_fsm_t *fsm)
+{
+    fsm->master_state = ec_fsm_configuration_start;
+}
+
+/*****************************************************************************/
+
+int ec_fsm_configuration_running(ec_fsm_t *fsm)
+{
+    return fsm->master_state != ec_fsm_end &&
+        fsm->master_state != ec_fsm_error;
+}
+
+/*****************************************************************************/
+
+int ec_fsm_configuration_success(ec_fsm_t *fsm)
+{
+    return fsm->master_state == ec_fsm_end;
+}
+
 /******************************************************************************
- *  master state machine
+ *  master startup state machine
+ *****************************************************************************/
+
+/**
+   Master state: START.
+   Starts with getting slave count and slave states.
+*/
+
+void ec_fsm_startup_start(ec_fsm_t *fsm)
+{
+    ec_datagram_brd(&fsm->datagram, 0x0130, 2);
+    ec_master_queue_datagram(fsm->master, &fsm->datagram);
+    fsm->master_state = ec_fsm_startup_broadcast;
+}
+
+/*****************************************************************************/
+
+/**
+   Master state: BROADCAST.
+   Processes the broadcast read slave count and slaves states.
+*/
+
+void ec_fsm_startup_broadcast(ec_fsm_t *fsm /**< finite state machine */)
+{
+    ec_datagram_t *datagram = &fsm->datagram;
+    unsigned int i;
+    ec_slave_t *slave;
+    ec_master_t *master = fsm->master;
+
+    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+        EC_ERR("Failed tor receive broadcast datagram.\n");
+        fsm->master_state = ec_fsm_error;
+        return;
+    }
+
+    EC_INFO("Scanning bus.\n");
+
+    ec_master_clear_slaves(master);
+
+    master->slave_count = datagram->working_counter;
+
+    if (!master->slave_count) {
+        // no slaves present -> finish state machine.
+        fsm->master_state = ec_fsm_end;
+        return;
+    }
+
+    // init slaves
+    for (i = 0; i < master->slave_count; i++) {
+        if (!(slave = (ec_slave_t *) kmalloc(sizeof(ec_slave_t),
+                                             GFP_KERNEL))) {
+            EC_ERR("Failed to allocate slave %i!\n", i);
+            fsm->master_state = ec_fsm_error;
+            return;
+        }
+
+        if (ec_slave_init(slave, master, i, i + 1)) {
+            fsm->master_state = ec_fsm_error;
+            return;
+        }
+
+        if (kobject_add(&slave->kobj)) {
+            EC_ERR("Failed to add kobject.\n");
+            kobject_put(&slave->kobj); // free
+            fsm->master_state = ec_fsm_error;
+            return;
+        }
+
+        list_add_tail(&slave->list, &master->slaves);
+    }
+
+    // begin scanning of slaves
+    fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
+    fsm->slave_state = ec_fsm_slavescan_start;
+    fsm->master_state = ec_fsm_startup_scan;
+    fsm->master_state(fsm); // execute immediately
+    return;
+}
+
+/*****************************************************************************/
+
+/**
+   Master state: SCAN.
+   Executes the sub-statemachine for the scanning of a slave.
+*/
+
+void ec_fsm_startup_scan(ec_fsm_t *fsm /**< finite state machine */)
+{
+    ec_master_t *master = fsm->master;
+    ec_slave_t *slave = fsm->slave;
+
+    fsm->slave_state(fsm); // execute slave state machine
+
+    if (fsm->slave_state == ec_fsm_error) {
+        EC_ERR("Slave scanning failed.\n");
+        fsm->master_state = ec_fsm_error;
+        return;
+    }
+
+    if (fsm->slave_state != ec_fsm_end) return;
+
+    // another slave to scan?
+    if (slave->list.next != &master->slaves) {
+        fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
+        fsm->slave_state = ec_fsm_slavescan_start;
+        fsm->slave_state(fsm); // execute immediately
+        return;
+    }
+
+    EC_INFO("Bus scanning completed.\n");
+
+    ec_master_calc_addressing(master);
+
+    fsm->master_state = ec_fsm_end;
+}
+
+/******************************************************************************
+ *  master configuration state machine
+ *****************************************************************************/
+
+void ec_fsm_configuration_start(ec_fsm_t *fsm /**< finite state machine */)
+{
+    ec_master_t *master = fsm->master;
+
+    if (list_empty(&master->slaves)) {
+        fsm->master_state = ec_fsm_end;
+        return;
+    }
+
+    // begin configuring slaves
+    fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
+    fsm->slave_state = ec_fsm_slaveconf_init;
+    fsm->change_new = EC_SLAVE_STATE_INIT;
+    fsm->change_state = ec_fsm_change_start;
+    fsm->master_state = ec_fsm_configuration_conf;
+    fsm->master_state(fsm); // execute immediately
+}
+
+/*****************************************************************************/
+
+/**
+   Master state: CONF.
+*/
+
+void ec_fsm_configuration_conf(ec_fsm_t *fsm /**< finite state machine */)
+{
+    ec_master_t *master = fsm->master;
+    ec_slave_t *slave = fsm->slave;
+
+    fsm->slave_state(fsm); // execute slave's state machine
+
+    if (fsm->slave_state == ec_fsm_error) {
+        fsm->master_state = ec_fsm_error;
+        return;
+    }
+
+    if (fsm->slave_state != ec_fsm_end) return;
+
+    // another slave to configure?
+    if (slave->list.next != &master->slaves) {
+        fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
+        fsm->slave_state = ec_fsm_slaveconf_init;
+        fsm->change_new = EC_SLAVE_STATE_INIT;
+        fsm->change_state = ec_fsm_change_start;
+        fsm->master_state(fsm); // execute immediately
+        return;
+    }
+
+    fsm->master_state = ec_fsm_end;
+}
+
+/******************************************************************************
+ *  operation / idle state machine
  *****************************************************************************/
 
 /**
@@ -179,7 +399,7 @@
     ec_slave_t *slave;
     ec_master_t *master = fsm->master;
 
-    if (datagram->state != EC_CMD_RECEIVED) {
+    if (datagram->state != EC_DATAGRAM_RECEIVED) {
         if (!master->device->link_state) {
             fsm->master_slaves_responding = 0;
             list_for_each_entry(slave, &master->slaves, list) {
@@ -203,7 +423,7 @@
                 fsm->master_slaves_responding,
                 fsm->master_slaves_responding == 1 ? "" : "s");
 
-        if (master->mode == EC_MASTER_MODE_RUNNING) {
+        if (master->mode == EC_MASTER_MODE_OPERATION) {
             if (fsm->master_slaves_responding == master->slave_count) {
                 fsm->master_validation = 1; // start validation later
             }
@@ -214,9 +434,9 @@
     }
 
     if (states_change) {
-        EC_INFO("Slave states: ");
-        ec_print_states(fsm->master_slave_states);
-        printk(".\n");
+        char states[25];
+        ec_state_string(fsm->master_slave_states, states);
+        EC_INFO("Slave states: %s.\n", states);
     }
 
     // topology change in idle mode: clear all slaves and scan the bus
@@ -226,7 +446,9 @@
         ec_master_eoe_stop(master);
         ec_master_clear_slaves(master);
 
-        if (!fsm->master_slaves_responding) {
+        master->slave_count = datagram->working_counter;
+
+        if (!master->slave_count) {
             // no slaves present -> finish state machine.
             fsm->master_state = ec_fsm_master_start;
             fsm->master_state(fsm); // execute immediately
@@ -234,16 +456,19 @@
         }
 
         // init slaves
-        for (i = 0; i < fsm->master_slaves_responding; i++) {
+        for (i = 0; i < master->slave_count; i++) {
             if (!(slave = (ec_slave_t *) kmalloc(sizeof(ec_slave_t),
                                                  GFP_ATOMIC))) {
                 EC_ERR("Failed to allocate slave %i!\n", i);
+                ec_master_clear_slaves(master);
                 fsm->master_state = ec_fsm_master_start;
                 fsm->master_state(fsm); // execute immediately
                 return;
             }
 
             if (ec_slave_init(slave, master, i, i + 1)) {
+                // freeing of "slave" already done
+                ec_master_clear_slaves(master);
                 fsm->master_state = ec_fsm_master_start;
                 fsm->master_state(fsm); // execute immediately
                 return;
@@ -252,6 +477,7 @@
             if (kobject_add(&slave->kobj)) {
                 EC_ERR("Failed to add kobject.\n");
                 kobject_put(&slave->kobj); // free
+                ec_master_clear_slaves(master);
                 fsm->master_state = ec_fsm_master_start;
                 fsm->master_state(fsm); // execute immediately
                 return;
@@ -288,6 +514,7 @@
 {
     ec_master_t *master = fsm->master;
     ec_slave_t *slave;
+    char old_state[25], new_state[25];
 
     // check if any slaves are not in the state, they're supposed to be
     list_for_each_entry(slave, &master->slaves, list) {
@@ -296,11 +523,10 @@
             slave->requested_state == EC_SLAVE_STATE_UNKNOWN ||
             slave->current_state == slave->requested_state) continue;
 
-        EC_INFO("Changing state of slave %i from ", slave->ring_position);
-        ec_print_states(slave->current_state);
-        printk(" to ");
-        ec_print_states(slave->requested_state);
-        printk(".\n");
+        ec_state_string(slave->current_state, old_state);
+        ec_state_string(slave->requested_state, new_state);
+        EC_INFO("Changing state of slave %i from %s to %s.\n",
+                slave->ring_position, old_state, new_state);
 
         fsm->slave = slave;
         fsm->slave_state = ec_fsm_slaveconf_init;
@@ -311,6 +537,9 @@
         return;
     }
 
+    // Check, if EoE processing has to be started
+    ec_master_eoe_start(master);
+
     if (master->mode == EC_MASTER_MODE_IDLE) {
         // nothing to configure. check for pending EEPROM write operations.
         list_for_each_entry(slave, &master->slaves, list) {
@@ -401,7 +630,7 @@
     ec_datagram_t *datagram = &fsm->datagram;
     uint8_t new_state;
 
-    if (datagram->state != EC_CMD_RECEIVED) {
+    if (datagram->state != EC_DATAGRAM_RECEIVED) {
         fsm->master_state = ec_fsm_master_start;
         fsm->master_state(fsm); // execute immediately
         return;
@@ -420,19 +649,19 @@
     // slave responded
     new_state = EC_READ_U8(datagram->data);
     if (!slave->online) { // slave was offline before
+        char cur_state[25];
         slave->online = 1;
         slave->error_flag = 0; // clear error flag
         slave->current_state = new_state;
-        EC_INFO("Slave %i: online (", slave->ring_position);
-        ec_print_states(new_state);
-        printk(").\n");
+        ec_state_string(slave->current_state, cur_state);
+        EC_INFO("Slave %i: online (%s).\n", slave->ring_position, cur_state);
     }
     else if (new_state != slave->current_state) {
-        EC_INFO("Slave %i: ", slave->ring_position);
-        ec_print_states(slave->current_state);
-        printk(" -> ");
-        ec_print_states(new_state);
-        printk(".\n");
+        char old_state[25], cur_state[25];
+        ec_state_string(slave->current_state, old_state);
+        ec_state_string(new_state, cur_state);
+        EC_INFO("Slave %i: %s -> %s.\n",
+                slave->ring_position, old_state, cur_state);
         slave->current_state = new_state;
     }
 
@@ -452,7 +681,7 @@
 
     fsm->sii_state(fsm); // execute SII state machine
 
-    if (fsm->sii_state == ec_fsm_sii_error) {
+    if (fsm->sii_state == ec_fsm_error) {
         fsm->slave->error_flag = 1;
         EC_ERR("Failed to validate vendor ID of slave %i.\n",
                slave->ring_position);
@@ -461,7 +690,7 @@
         return;
     }
 
-    if (fsm->sii_state != ec_fsm_sii_end) return;
+    if (fsm->sii_state != ec_fsm_end) return;
 
     if (EC_READ_U32(fsm->sii_value) != slave->sii_vendor_id) {
         EC_ERR("Slave %i: invalid vendor ID!\n", slave->ring_position);
@@ -522,7 +751,7 @@
 
     fsm->sii_state(fsm); // execute SII state machine
 
-    if (fsm->sii_state == ec_fsm_sii_error) {
+    if (fsm->sii_state == ec_fsm_error) {
         fsm->slave->error_flag = 1;
         EC_ERR("Failed to validate product code of slave %i.\n",
                slave->ring_position);
@@ -531,7 +760,7 @@
         return;
     }
 
-    if (fsm->sii_state != ec_fsm_sii_end) return;
+    if (fsm->sii_state != ec_fsm_end) return;
 
     if (EC_READ_U32(fsm->sii_value) != slave->sii_product_code) {
         EC_ERR("Slave %i: invalid product code!\n", slave->ring_position);
@@ -573,7 +802,8 @@
     ec_slave_t *slave = fsm->slave;
     ec_datagram_t *datagram = &fsm->datagram;
 
-    if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
+    if (datagram->state != EC_DATAGRAM_RECEIVED
+        || datagram->working_counter != 1) {
         EC_ERR("Failed to write station address on slave %i.\n",
                slave->ring_position);
     }
@@ -601,89 +831,40 @@
 {
     ec_master_t *master = fsm->master;
     ec_slave_t *slave = fsm->slave;
-    uint16_t coupler_index, coupler_subindex;
-    uint16_t reverse_coupler_index, current_coupler_index;
-    ec_slave_ident_t *ident;
+
 
     fsm->slave_state(fsm); // execute slave state machine
 
-    if (fsm->slave_state != ec_fsm_slavescan_end) return;
-
-    // have all slaves been fetched?
-    if (slave->list.next == &master->slaves) {
-        EC_INFO("Bus scanning completed.\n");
-
-        // identify all slaves and calculate coupler addressing
-
-        coupler_index = 0;
-        reverse_coupler_index = 0xFFFF;
-        current_coupler_index = 0x3FFF;
-        coupler_subindex = 0;
-
-        list_for_each_entry(slave, &master->slaves, list)
-        {
-            // search for identification in "database"
-            ident = slave_idents;
-            while (ident->type) {
-                if (ident->vendor_id == slave->sii_vendor_id
-                    && ident->product_code == slave->sii_product_code) {
-                    slave->type = ident->type;
-                    break;
-                }
-                ident++;
-            }
-
-            if (!slave->type) {
-                EC_WARN("Unknown slave device (vendor 0x%08X,"
-                        " code 0x%08X) at position %i.\n",
-                        slave->sii_vendor_id, slave->sii_product_code,
-                        slave->ring_position);
-            }
-            else {
-                // if the slave is a bus coupler, change adressing base
-                if (slave->type->special == EC_TYPE_BUS_COUPLER) {
-                    if (slave->sii_alias)
-                        current_coupler_index = reverse_coupler_index--;
-                    else
-                        current_coupler_index = coupler_index++;
-                    coupler_subindex = 0;
-                }
-            }
-
-            // determine initial state.
-            if ((slave->type &&
-                 (slave->type->special == EC_TYPE_BUS_COUPLER ||
-                  slave->type->special == EC_TYPE_INFRA))) {
-                slave->requested_state = EC_SLAVE_STATE_OP;
-            }
-            else {
-                if (master->mode == EC_MASTER_MODE_RUNNING)
-                    slave->requested_state = EC_SLAVE_STATE_PREOP;
-                else
-                    slave->requested_state = EC_SLAVE_STATE_INIT;
-            }
-            slave->error_flag = 0;
-
-            // calculate coupler-based slave address
-            slave->coupler_index = current_coupler_index;
-            slave->coupler_subindex = coupler_subindex;
-            coupler_subindex++;
-        }
-
-        if (master->mode == EC_MASTER_MODE_IDLE) {
-            // start EoE processing
-            ec_master_eoe_start(master);
-        }
-
-        fsm->master_state = ec_fsm_master_start;
-        fsm->master_state(fsm); // execute immediately
-        return;
-    }
-
-    // process next slave
-    fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
-    fsm->slave_state = ec_fsm_slavescan_start;
-    fsm->slave_state(fsm); // execute immediately
+    if (fsm->slave_state != ec_fsm_end
+        && fsm->slave_state != ec_fsm_error) return;
+
+    // another slave to fetch?
+    if (slave->list.next != &master->slaves) {
+        fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
+        fsm->slave_state = ec_fsm_slavescan_start;
+        fsm->slave_state(fsm); // execute immediately
+        return;
+    }
+
+    EC_INFO("Bus scanning completed.\n");
+
+    ec_master_calc_addressing(master);
+
+    // determine initial states.
+    list_for_each_entry(slave, &master->slaves, list) {
+        if (ec_slave_is_coupler(slave)) {
+            slave->requested_state = EC_SLAVE_STATE_OP;
+        }
+        else {
+            if (master->mode == EC_MASTER_MODE_OPERATION)
+                slave->requested_state = EC_SLAVE_STATE_PREOP;
+            else
+                slave->requested_state = EC_SLAVE_STATE_INIT;
+        }
+    }
+
+    fsm->master_state = ec_fsm_master_start;
+    fsm->master_state(fsm); // execute immediately
 }
 
 /*****************************************************************************/
@@ -698,7 +879,9 @@
                                    )
 {
     fsm->slave_state(fsm); // execute slave's state machine
-    if (fsm->slave_state != ec_fsm_slaveconf_end) return;
+
+    if (fsm->slave_state != ec_fsm_end
+        && fsm->slave_state != ec_fsm_error) return;
 
     ec_fsm_master_action_process_states(fsm);
 }
@@ -715,7 +898,7 @@
 
     fsm->sii_state(fsm); // execute SII state machine
 
-    if (fsm->sii_state == ec_fsm_sii_error) {
+    if (fsm->sii_state == ec_fsm_error) {
         fsm->slave->error_flag = 1;
         EC_ERR("Failed to write EEPROM contents to slave %i.\n",
                slave->ring_position);
@@ -726,7 +909,7 @@
         return;
     }
 
-    if (fsm->sii_state != ec_fsm_sii_end) return;
+    if (fsm->sii_state != ec_fsm_end) return;
 
     fsm->sii_offset++;
     if (fsm->sii_offset < slave->new_eeprom_size) {
@@ -741,14 +924,16 @@
     kfree(slave->new_eeprom_data);
     slave->new_eeprom_data = NULL;
 
+    // TODO: Evaluate new EEPROM contents!
+
     // restart master state machine.
-    fsm->master_state = ec_fsm_master_start; // TODO: Evaluate new contents!
+    fsm->master_state = ec_fsm_master_start;
     fsm->master_state(fsm); // execute immediately
     return;
 }
 
 /******************************************************************************
- *  slave scan sub state machine
+ *  slave scan state machine
  *****************************************************************************/
 
 /**
@@ -778,9 +963,10 @@
 {
     ec_datagram_t *datagram = &fsm->datagram;
 
-    if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
+    if (datagram->state != EC_DATAGRAM_RECEIVED
+        || datagram->working_counter != 1) {
         fsm->slave->error_flag = 1;
-        fsm->slave_state = ec_fsm_slavescan_end;
+        fsm->slave_state = ec_fsm_error;
         EC_ERR("Failed to write station address of slave %i.\n",
                fsm->slave->ring_position);
         return;
@@ -803,9 +989,10 @@
     ec_datagram_t *datagram = &fsm->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
+    if (datagram->state != EC_DATAGRAM_RECEIVED
+        || datagram->working_counter != 1) {
         fsm->slave->error_flag = 1;
-        fsm->slave_state = ec_fsm_slavescan_end;
+        fsm->slave_state = ec_fsm_error;
         EC_ERR("Failed to read AL state of slave %i.\n",
                fsm->slave->ring_position);
         return;
@@ -835,9 +1022,10 @@
     ec_datagram_t *datagram = &fsm->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
+    if (datagram->state != EC_DATAGRAM_RECEIVED
+        || datagram->working_counter != 1) {
         fsm->slave->error_flag = 1;
-        fsm->slave_state = ec_fsm_slavescan_end;
+        fsm->slave_state = ec_fsm_error;
         EC_ERR("Failed to read base data of slave %i.\n",
                slave->ring_position);
         return;
@@ -871,9 +1059,10 @@
     uint16_t dl_status;
     unsigned int i;
 
-    if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
+    if (datagram->state != EC_DATAGRAM_RECEIVED
+        || datagram->working_counter != 1) {
         fsm->slave->error_flag = 1;
-        fsm->slave_state = ec_fsm_slavescan_end;
+        fsm->slave_state = ec_fsm_error;
         EC_ERR("Failed to read DL status of slave %i.\n",
                slave->ring_position);
         return;
@@ -909,15 +1098,15 @@
     // execute SII state machine
     fsm->sii_state(fsm);
 
-    if (fsm->sii_state == ec_fsm_sii_error) {
+    if (fsm->sii_state == ec_fsm_error) {
         fsm->slave->error_flag = 1;
-        fsm->slave_state = ec_fsm_slavescan_end;
+        fsm->slave_state = ec_fsm_error;
         EC_ERR("Failed to read EEPROM size of slave %i.\n",
                slave->ring_position);
         return;
     }
 
-    if (fsm->sii_state != ec_fsm_sii_end) return;
+    if (fsm->sii_state != ec_fsm_end) return;
 
     cat_type = EC_READ_U16(fsm->sii_value);
     cat_size = EC_READ_U16(fsm->sii_value + 2);
@@ -940,7 +1129,7 @@
     if (!(slave->eeprom_data =
           (uint8_t *) kmalloc(slave->eeprom_size, GFP_ATOMIC))) {
         fsm->slave->error_flag = 1;
-        fsm->slave_state = ec_fsm_slavescan_end;
+        fsm->slave_state = ec_fsm_error;
         EC_ERR("Failed to allocate EEPROM data on slave %i.\n",
                slave->ring_position);
         return;
@@ -969,15 +1158,15 @@
     // execute SII state machine
     fsm->sii_state(fsm);
 
-    if (fsm->sii_state == ec_fsm_sii_error) {
+    if (fsm->sii_state == ec_fsm_error) {
         fsm->slave->error_flag = 1;
-        fsm->slave_state = ec_fsm_slavescan_end;
+        fsm->slave_state = ec_fsm_error;
         EC_ERR("Failed to fetch EEPROM contents of slave %i.\n",
                slave->ring_position);
         return;
     }
 
-    if (fsm->sii_state != ec_fsm_sii_end) return;
+    if (fsm->sii_state != ec_fsm_end) return;
 
     // 2 words fetched
 
@@ -1031,8 +1220,7 @@
                     goto end;
                 break;
             case 0x001E:
-                if (ec_slave_fetch_general(slave, (uint8_t *) (cat_word + 2)))
-                    goto end;
+                ec_slave_fetch_general(slave, (uint8_t *) (cat_word + 2));
                 break;
             case 0x0028:
                 break;
@@ -1059,26 +1247,17 @@
         cat_word += cat_size + 2;
     }
 
-    fsm->slave_state = ec_fsm_slavescan_end;
+    fsm->slave_state = ec_fsm_end;
+    return;
 
 end:
+    EC_ERR("Failed to analyze category data.\n");
     fsm->slave->error_flag = 1;
-    fsm->slave_state = ec_fsm_slavescan_end;
-}
-
-/*****************************************************************************/
-
-/**
-   Slave state: END.
-   End state of the slave state machine.
-*/
-
-void ec_fsm_slavescan_end(ec_fsm_t *fsm /**< finite state machine */)
-{
+    fsm->slave_state = ec_fsm_error;
 }
 
 /******************************************************************************
- *  slave configuration sub state machine
+ *  slave configuration state machine
  *****************************************************************************/
 
 /**
@@ -1089,34 +1268,27 @@
 {
     ec_slave_t *slave = fsm->slave;
     ec_datagram_t *datagram = &fsm->datagram;
-    const ec_sync_t *sync;
-    ec_eeprom_sync_t *eeprom_sync, mbox_sync;
-    unsigned int j;
+    const ec_sii_sync_t *sync;
 
     fsm->change_state(fsm); // execute state change state machine
 
-    if (fsm->change_state == ec_fsm_change_error) {
+    if (fsm->change_state == ec_fsm_error) {
         slave->error_flag = 1;
-        fsm->slave_state = ec_fsm_slaveconf_end;
-        return;
-    }
-
-    if (fsm->change_state != ec_fsm_change_end) return;
+        fsm->slave_state = ec_fsm_error;
+        return;
+    }
+
+    if (fsm->change_state != ec_fsm_end) return;
 
     // slave is now in INIT
     if (slave->current_state == slave->requested_state) {
-        fsm->slave_state = ec_fsm_slaveconf_end; // successful
-        return;
-    }
-
-    // check for slave registration
-    if (!slave->type) {
-        EC_WARN("Slave %i has unknown type!\n", slave->ring_position);
+        fsm->slave_state = ec_fsm_end; // successful
+        return;
     }
 
     // check and reset CRC fault counters
     //ec_slave_check_crc(slave);
-    // TODO!
+    // TODO: Implement state machine for CRC checking.
 
     if (!slave->base_sync_count) { // no sync managers
         fsm->slave_state = ec_fsm_slaveconf_preop;
@@ -1131,50 +1303,15 @@
                      EC_SYNC_SIZE * slave->base_sync_count);
     memset(datagram->data, 0x00, EC_SYNC_SIZE * slave->base_sync_count);
 
-    // does the slave supply sync manager configurations in its EEPROM?
-    if (!list_empty(&slave->eeprom_syncs)) {
-        list_for_each_entry(eeprom_sync, &slave->eeprom_syncs, list) {
-            if (eeprom_sync->index >= slave->base_sync_count) {
-                fsm->slave->error_flag = 1;
-                fsm->slave_state = ec_fsm_slaveconf_end;
-                EC_ERR("Invalid sync manager configuration found!");
-                return;
-            }
-            ec_eeprom_sync_config(eeprom_sync, slave,
-                                  datagram->data + EC_SYNC_SIZE
-                                  * eeprom_sync->index);
-        }
-    }
-
-    // known slave type, take type's SM information
-    else if (slave->type) {
-        for (j = 0; slave->type->sync_managers[j] && j < EC_MAX_SYNC; j++) {
-            sync = slave->type->sync_managers[j];
-            ec_sync_config(sync, slave, datagram->data + EC_SYNC_SIZE * j);
-        }
-    }
-
-    // unknown type, but slave has mailbox
-    else if (slave->sii_mailbox_protocols)
-    {
-        // guess mailbox settings
-        mbox_sync.physical_start_address =
-            slave->sii_rx_mailbox_offset;
-        mbox_sync.length = slave->sii_rx_mailbox_size;
-        mbox_sync.control_register = 0x26;
-        mbox_sync.enable = 1;
-        ec_eeprom_sync_config(&mbox_sync, slave, datagram->data);
-
-        mbox_sync.physical_start_address =
-            slave->sii_tx_mailbox_offset;
-        mbox_sync.length = slave->sii_tx_mailbox_size;
-        mbox_sync.control_register = 0x22;
-        mbox_sync.enable = 1;
-        ec_eeprom_sync_config(&mbox_sync, slave,
-                              datagram->data + EC_SYNC_SIZE);
-
-        EC_INFO("Mailbox configured for unknown slave %i\n",
-                slave->ring_position);
+    list_for_each_entry(sync, &slave->sii_syncs, list) {
+        if (sync->index >= slave->base_sync_count) {
+            EC_ERR("Invalid sync manager configuration found!");
+            fsm->slave->error_flag = 1;
+            fsm->slave_state = ec_fsm_error;
+            return;
+        }
+        ec_sync_config(sync, slave,
+                       datagram->data + EC_SYNC_SIZE * sync->index);
     }
 
     ec_master_queue_datagram(fsm->master, datagram);
@@ -1192,9 +1329,10 @@
     ec_datagram_t *datagram = &fsm->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
+    if (datagram->state != EC_DATAGRAM_RECEIVED
+        || datagram->working_counter != 1) {
         slave->error_flag = 1;
-        fsm->slave_state = ec_fsm_slaveconf_end;
+        fsm->slave_state = ec_fsm_error;
         EC_ERR("Failed to set sync managers on slave %i.\n",
                slave->ring_position);
         return;
@@ -1221,23 +1359,17 @@
 
     fsm->change_state(fsm); // execute state change state machine
 
-    if (fsm->change_state == ec_fsm_change_error) {
+    if (fsm->change_state == ec_fsm_error) {
         slave->error_flag = 1;
-        fsm->slave_state = ec_fsm_slaveconf_end;
-        return;
-    }
-
-    if (fsm->change_state != ec_fsm_change_end) return;
+        fsm->slave_state = ec_fsm_error;
+        return;
+    }
+
+    if (fsm->change_state != ec_fsm_end) return;
 
     // slave is now in PREOP
     if (slave->current_state == slave->requested_state) {
-        fsm->slave_state = ec_fsm_slaveconf_end; // successful
-        return;
-    }
-
-    // stop activation here for slaves without type
-    if (!slave->type) {
-        fsm->slave_state = ec_fsm_slaveconf_end; // successful
+        fsm->slave_state = ec_fsm_end; // successful
         return;
     }
 
@@ -1272,9 +1404,10 @@
 {
     ec_datagram_t *datagram = &fsm->datagram;
 
-    if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
+    if (datagram->state != EC_DATAGRAM_RECEIVED
+        || datagram->working_counter != 1) {
         fsm->slave->error_flag = 1;
-        fsm->slave_state = ec_fsm_slaveconf_end;
+        fsm->slave_state = ec_fsm_error;
         EC_ERR("Failed to set FMMUs on slave %i.\n",
                fsm->slave->ring_position);
         return;
@@ -1297,17 +1430,17 @@
 {
     fsm->change_state(fsm); // execute state change state machine
 
-    if (fsm->change_state == ec_fsm_change_error) {
+    if (fsm->change_state == ec_fsm_error) {
         fsm->slave->error_flag = 1;
-        fsm->slave_state = ec_fsm_slaveconf_end;
-        return;
-    }
-
-    if (fsm->change_state != ec_fsm_change_end) return;
+        fsm->slave_state = ec_fsm_error;
+        return;
+    }
+
+    if (fsm->change_state != ec_fsm_end) return;
 
     // slave is now in SAVEOP
     if (fsm->slave->current_state == fsm->slave->requested_state) {
-        fsm->slave_state = ec_fsm_slaveconf_end; // successful
+        fsm->slave_state = ec_fsm_end; // successful
         return;
     }
 
@@ -1328,31 +1461,20 @@
 {
     fsm->change_state(fsm); // execute state change state machine
 
-    if (fsm->change_state == ec_fsm_change_error) {
+    if (fsm->change_state == ec_fsm_error) {
         fsm->slave->error_flag = 1;
-        fsm->slave_state = ec_fsm_slaveconf_end;
-        return;
-    }
-
-    if (fsm->change_state != ec_fsm_change_end) return;
+        fsm->slave_state = ec_fsm_error;
+        return;
+    }
+
+    if (fsm->change_state != ec_fsm_end) return;
 
     // slave is now in OP
-    fsm->slave_state = ec_fsm_slaveconf_end; // successful
-}
-
-/*****************************************************************************/
-
-/**
-   Slave state: END.
-   End state of the slave state machine.
-*/
-
-void ec_fsm_slaveconf_end(ec_fsm_t *fsm /**< finite state machine */)
-{
+    fsm->slave_state = ec_fsm_end; // successful
 }
 
 /******************************************************************************
- *  SII sub state machine
+ *  SII state machine
  *****************************************************************************/
 
 /**
@@ -1390,9 +1512,10 @@
 {
     ec_datagram_t *datagram = &fsm->datagram;
 
-    if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
+    if (datagram->state != EC_DATAGRAM_RECEIVED
+        || datagram->working_counter != 1) {
         EC_ERR("SII: Reception of read datagram failed.\n");
-        fsm->sii_state = ec_fsm_sii_error;
+        fsm->sii_state = ec_fsm_error;
         return;
     }
 
@@ -1421,9 +1544,10 @@
 {
     ec_datagram_t *datagram = &fsm->datagram;
 
-    if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
+    if (datagram->state != EC_DATAGRAM_RECEIVED
+        || datagram->working_counter != 1) {
         EC_ERR("SII: Reception of check/fetch datagram failed.\n");
-        fsm->sii_state = ec_fsm_sii_error;
+        fsm->sii_state = ec_fsm_error;
         return;
     }
 
@@ -1432,7 +1556,7 @@
         // still busy... timeout?
         if (get_cycles() - fsm->sii_start >= (cycles_t) 10 * cpu_khz) {
             EC_ERR("SII: Timeout.\n");
-            fsm->sii_state = ec_fsm_sii_error;
+            fsm->sii_state = ec_fsm_error;
 #if 0
             EC_DBG("SII busy: %02X %02X %02X %02X\n",
                    EC_READ_U8(datagram->data + 0),
@@ -1463,7 +1587,7 @@
 
     // SII value received.
     memcpy(fsm->sii_value, datagram->data + 6, 4);
-    fsm->sii_state = ec_fsm_sii_end;
+    fsm->sii_state = ec_fsm_end;
 }
 
 /*****************************************************************************/
@@ -1497,9 +1621,10 @@
 {
     ec_datagram_t *datagram = &fsm->datagram;
 
-    if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
+    if (datagram->state != EC_DATAGRAM_RECEIVED
+        || datagram->working_counter != 1) {
         EC_ERR("SII: Reception of write datagram failed.\n");
-        fsm->sii_state = ec_fsm_sii_error;
+        fsm->sii_state = ec_fsm_error;
         return;
     }
 
@@ -1521,9 +1646,10 @@
 {
     ec_datagram_t *datagram = &fsm->datagram;
 
-    if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
+    if (datagram->state != EC_DATAGRAM_RECEIVED
+        || datagram->working_counter != 1) {
         EC_ERR("SII: Reception of write check datagram failed.\n");
-        fsm->sii_state = ec_fsm_sii_error;
+        fsm->sii_state = ec_fsm_error;
         return;
     }
 
@@ -1531,7 +1657,7 @@
         // still busy... timeout?
         if (get_cycles() - fsm->sii_start >= (cycles_t) 10 * cpu_khz) {
             EC_ERR("SII: Write timeout.\n");
-            fsm->sii_state = ec_fsm_sii_error;
+            fsm->sii_state = ec_fsm_error;
         }
 
         // issue check/fetch datagram again
@@ -1539,37 +1665,15 @@
     }
     else if (EC_READ_U8(datagram->data + 1) & 0x40) {
         EC_ERR("SII: Write operation failed!\n");
-        fsm->sii_state = ec_fsm_sii_error;
+        fsm->sii_state = ec_fsm_error;
     }
     else { // success
-        fsm->sii_state = ec_fsm_sii_end;
-    }
-}
-
-/*****************************************************************************/
-
-/**
-   SII state: END.
-   End state of the slave SII state machine.
-*/
-
-void ec_fsm_sii_end(ec_fsm_t *fsm /**< finite state machine */)
-{
-}
-
-/*****************************************************************************/
-
-/**
-   SII state: ERROR.
-   End state of the slave SII state machine.
-*/
-
-void ec_fsm_sii_error(ec_fsm_t *fsm /**< finite state machine */)
-{
+        fsm->sii_state = ec_fsm_end;
+    }
 }
 
 /******************************************************************************
- *  state change sub state machine
+ *  state change state machine
  *****************************************************************************/
 
 /**
@@ -1581,6 +1685,8 @@
     ec_datagram_t *datagram = &fsm->datagram;
     ec_slave_t *slave = fsm->slave;
 
+    fsm->change_start = get_cycles();
+
     // write new state to slave
     ec_datagram_npwr(datagram, slave->station_address, 0x0120, 2);
     EC_WRITE_U16(datagram->data, fsm->change_new);
@@ -1599,17 +1705,25 @@
     ec_datagram_t *datagram = &fsm->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state != EC_CMD_RECEIVED) {
-        fsm->change_state = ec_fsm_change_error;
+    if (datagram->state != EC_DATAGRAM_RECEIVED) {
+        fsm->change_state = ec_fsm_error;
         EC_ERR("Failed to send state datagram to slave %i!\n",
                fsm->slave->ring_position);
         return;
     }
 
     if (datagram->working_counter != 1) {
-        fsm->change_state = ec_fsm_change_error;
-        EC_ERR("Failed to set state 0x%02X on slave %i: Slave did not"
-               " respond.\n", fsm->change_new, fsm->slave->ring_position);
+        if (get_cycles() - fsm->change_start >= (cycles_t) 100 * cpu_khz) {
+            fsm->change_state = ec_fsm_error;
+            EC_ERR("Failed to set state 0x%02X on slave %i: Slave did not"
+                   " respond.\n", fsm->change_new, fsm->slave->ring_position);
+            return;
+        }
+
+        // repeat writing new state to slave
+        ec_datagram_npwr(datagram, slave->station_address, 0x0120, 2);
+        EC_WRITE_U16(datagram->data, fsm->change_new);
+        ec_master_queue_datagram(fsm->master, datagram);
         return;
     }
 
@@ -1632,8 +1746,9 @@
     ec_datagram_t *datagram = &fsm->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
-        fsm->change_state = ec_fsm_change_error;
+    if (datagram->state != EC_DATAGRAM_RECEIVED
+        || datagram->working_counter != 1) {
+        fsm->change_state = ec_fsm_error;
         EC_ERR("Failed to check state 0x%02X on slave %i.\n",
                fsm->change_new, slave->ring_position);
         return;
@@ -1643,7 +1758,7 @@
 
     if (slave->current_state == fsm->change_new) {
         // state has been set successfully
-        fsm->change_state = ec_fsm_change_end;
+        fsm->change_state = ec_fsm_end;
         return;
     }
 
@@ -1662,7 +1777,7 @@
 
     if (get_cycles() - fsm->change_start >= (cycles_t) 10 * cpu_khz) {
         // timeout while checking
-        fsm->change_state = ec_fsm_change_error;
+        fsm->change_state = ec_fsm_error;
         EC_ERR("Timeout while setting state 0x%02X on slave %i.\n",
                fsm->change_new, slave->ring_position);
         return;
@@ -1726,8 +1841,9 @@
     uint32_t code;
     const ec_code_msg_t *al_msg;
 
-    if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
-        fsm->change_state = ec_fsm_change_error;
+    if (datagram->state != EC_DATAGRAM_RECEIVED
+        || datagram->working_counter != 1) {
+        fsm->change_state = ec_fsm_error;
         EC_ERR("Reception of AL status code datagram failed.\n");
         return;
     }
@@ -1761,8 +1877,9 @@
     ec_datagram_t *datagram = &fsm->datagram;
     ec_slave_t *slave = fsm->slave;
 
-    if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
-        fsm->change_state = ec_fsm_change_error;
+    if (datagram->state != EC_DATAGRAM_RECEIVED
+        || datagram->working_counter != 1) {
+        fsm->change_state = ec_fsm_error;
         EC_ERR("Reception of state ack datagram failed.\n");
         return;
     }
@@ -1787,8 +1904,9 @@
     ec_slave_t *slave = fsm->slave;
     ec_slave_state_t ack_state;
 
-    if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
-        fsm->change_state = ec_fsm_change_error;
+    if (datagram->state != EC_DATAGRAM_RECEIVED
+        || datagram->working_counter != 1) {
+        fsm->change_state = ec_fsm_error;
         EC_ERR("Reception of state ack check datagram failed.\n");
         return;
     }
@@ -1796,7 +1914,7 @@
     ack_state = EC_READ_U8(datagram->data);
 
     if (ack_state == slave->current_state) {
-        fsm->change_state = ec_fsm_change_error;
+        fsm->change_state = ec_fsm_error;
         EC_INFO("Acknowleged state 0x%02X on slave %i.\n",
                 slave->current_state, slave->ring_position);
         return;
@@ -1805,7 +1923,7 @@
     if (get_cycles() - fsm->change_start >= (cycles_t) 100 * cpu_khz) {
         // timeout while checking
         slave->current_state = EC_SLAVE_STATE_UNKNOWN;
-        fsm->change_state = ec_fsm_change_error;
+        fsm->change_state = ec_fsm_error;
         EC_ERR("Timeout while acknowleging state 0x%02X on slave %i.\n",
                fsm->change_new, slave->ring_position);
         return;
@@ -1819,21 +1937,21 @@
 /*****************************************************************************/
 
 /**
-   Change state: END.
-*/
-
-void ec_fsm_change_end(ec_fsm_t *fsm /**< finite state machine */)
-{
-}
-
-/*****************************************************************************/
-
-/**
-   Change state: ERROR.
-*/
-
-void ec_fsm_change_error(ec_fsm_t *fsm /**< finite state machine */)
-{
-}
-
-/*****************************************************************************/
+   State: ERROR.
+*/
+
+void ec_fsm_error(ec_fsm_t *fsm /**< finite state machine */)
+{
+}
+
+/*****************************************************************************/
+
+/**
+   State: END.
+*/
+
+void ec_fsm_end(ec_fsm_t *fsm /**< finite state machine */)
+{
+}
+
+/*****************************************************************************/
--- a/master/fsm.h	Wed Aug 02 23:16:10 2006 +0000
+++ b/master/fsm.h	Thu Aug 03 12:51:17 2006 +0000
@@ -41,6 +41,7 @@
 #ifndef __EC_STATES__
 #define __EC_STATES__
 
+#include "globals.h"
 #include "../include/ecrt.h"
 #include "datagram.h"
 #include "slave.h"
@@ -84,6 +85,14 @@
 void ec_fsm_reset(ec_fsm_t *);
 void ec_fsm_execute(ec_fsm_t *);
 
+void ec_fsm_startup(ec_fsm_t *);
+int ec_fsm_startup_running(ec_fsm_t *);
+int ec_fsm_startup_success(ec_fsm_t *);
+
+void ec_fsm_configuration(ec_fsm_t *);
+int ec_fsm_configuration_running(ec_fsm_t *);
+int ec_fsm_configuration_success(ec_fsm_t *);
+
 /*****************************************************************************/
 
 #endif
--- a/master/globals.h	Wed Aug 02 23:16:10 2006 +0000
+++ b/master/globals.h	Thu Aug 03 12:51:17 2006 +0000
@@ -51,7 +51,7 @@
 #define EC_MASTER_VERSION_MAIN  1
 
 /** master sub version (after the dot) */
-#define EC_MASTER_VERSION_SUB   0
+#define EC_MASTER_VERSION_SUB   1
 
 /** master extra version (just a string) */
 #define EC_MASTER_VERSION_EXTRA "trunk"
@@ -65,6 +65,9 @@
 /** clock frequency for the EoE state machines */
 #define EC_EOE_FREQUENCY 1000
 
+/** datagram timeout in microseconds */
+#define EC_IO_TIMEOUT 500
+
 /******************************************************************************
  *  EtherCAT protocol
  *****************************************************************************/
@@ -170,9 +173,9 @@
 
 /*****************************************************************************/
 
-extern void ec_print_data(const uint8_t *, size_t);
-extern void ec_print_data_diff(const uint8_t *, const uint8_t *, size_t);
-extern void ec_print_states(uint8_t);
+void ec_print_data(const uint8_t *, size_t);
+void ec_print_data_diff(const uint8_t *, const uint8_t *, size_t);
+size_t ec_state_string(uint8_t, char *);
 
 /*****************************************************************************/
 
@@ -192,4 +195,3 @@
 /*****************************************************************************/
 
 #endif
-
--- a/master/mailbox.c	Wed Aug 02 23:16:10 2006 +0000
+++ b/master/mailbox.c	Thu Aug 03 12:51:17 2006 +0000
@@ -165,83 +165,3 @@
 }
 
 /*****************************************************************************/
-
-/**
-   Sends a mailbox datagram and waits for its reception.
-   \return pointer to the received data
-*/
-
-uint8_t *ec_slave_mbox_simple_io(const ec_slave_t *slave, /**< slave */
-                                 ec_datagram_t *datagram, /**< datagram */
-                                 size_t *size /**< size of the received data */
-                                 )
-{
-    uint8_t type;
-
-    type = EC_READ_U8(datagram->data + 5);
-
-    if (unlikely(ec_master_simple_io(slave->master, datagram))) {
-        EC_ERR("Mailbox checking failed on slave %i!\n",
-               slave->ring_position);
-        return NULL;
-    }
-
-    return ec_slave_mbox_simple_receive(slave, datagram, type, size);
-}
-
-/*****************************************************************************/
-
-/**
-   Waits for the reception of a mailbox datagram.
-   \return pointer to the received data
-*/
-
-uint8_t *ec_slave_mbox_simple_receive(const ec_slave_t *slave, /**< slave */
-                                      ec_datagram_t *datagram, /**< datagram */
-                                      uint8_t type, /**< expected protocol */
-                                      size_t *size /**< received data size */
-                                      )
-{
-    cycles_t start, end, timeout;
-
-    start = get_cycles();
-    timeout = (cycles_t) 100 * cpu_khz; // 100ms
-
-    while (1)
-    {
-        if (ec_slave_mbox_prepare_check(slave, datagram)) return NULL;
-        if (unlikely(ec_master_simple_io(slave->master, datagram))) {
-            EC_ERR("Mailbox checking failed on slave %i!\n",
-                   slave->ring_position);
-            return NULL;
-        }
-
-        end = get_cycles();
-
-        if (ec_slave_mbox_check(datagram))
-            break; // proceed with receiving data
-
-        if ((end - start) >= timeout) {
-            EC_ERR("Mailbox check - Slave %i timed out.\n",
-                   slave->ring_position);
-            return NULL;
-        }
-
-        udelay(100);
-    }
-
-    if (ec_slave_mbox_prepare_fetch(slave, datagram)) return NULL;
-    if (unlikely(ec_master_simple_io(slave->master, datagram))) {
-        EC_ERR("Mailbox receiving failed on slave %i!\n",
-               slave->ring_position);
-        return NULL;
-    }
-
-    if (unlikely(slave->master->debug_level) > 1)
-        EC_DBG("Mailbox receive took %ius.\n",
-               ((unsigned int) (end - start) * 1000 / cpu_khz));
-
-    return ec_slave_mbox_fetch(slave, datagram, type, size);
-}
-
-/*****************************************************************************/
--- a/master/master.c	Wed Aug 02 23:16:10 2006 +0000
+++ b/master/master.c	Thu Aug 03 12:51:17 2006 +0000
@@ -48,13 +48,13 @@
 #include "globals.h"
 #include "master.h"
 #include "slave.h"
-#include "types.h"
 #include "device.h"
 #include "datagram.h"
 #include "ethernet.h"
 
 /*****************************************************************************/
 
+void ec_master_sync_io(ec_master_t *);
 void ec_master_idle_run(void *);
 void ec_master_eoe_run(unsigned long);
 ssize_t ec_show_master_attribute(struct kobject *, struct attribute *, char *);
@@ -115,7 +115,6 @@
     INIT_LIST_HEAD(&master->datagram_queue);
     INIT_LIST_HEAD(&master->domains);
     INIT_LIST_HEAD(&master->eoe_handlers);
-    ec_datagram_init(&master->simple_datagram);
     INIT_WORK(&master->idle_work, ec_master_idle_run, (void *) master);
     init_timer(&master->eoe_timer);
     master->eoe_timer.function = ec_master_eoe_run;
@@ -186,7 +185,6 @@
 
     ec_master_reset(master);
     ec_fsm_clear(&master->fsm);
-    ec_datagram_clear(&master->simple_datagram);
     destroy_workqueue(master->workqueue);
 
     // clear EoE objects
@@ -225,7 +223,7 @@
     list_for_each_entry_safe(datagram, next_c,
                              &master->datagram_queue, queue) {
         list_del_init(&datagram->queue);
-        datagram->state = EC_CMD_ERROR;
+        datagram->state = EC_DATAGRAM_ERROR;
     }
 
     // clear domains
@@ -237,7 +235,6 @@
 
     master->datagram_index = 0;
     master->debug_level = 0;
-    master->timeout = 500; // 500us
 
     master->stats.timeouts = 0;
     master->stats.delayed = 0;
@@ -289,7 +286,7 @@
     // check, if the datagram is already queued
     list_for_each_entry(queued_datagram, &master->datagram_queue, queue) {
         if (queued_datagram == datagram) {
-            datagram->state = EC_CMD_QUEUED;
+            datagram->state = EC_DATAGRAM_QUEUED;
             if (unlikely(master->debug_level))
                 EC_WARN("datagram already queued.\n");
             return;
@@ -297,7 +294,7 @@
     }
 
     list_add_tail(&datagram->queue, &master->datagram_queue);
-    datagram->state = EC_CMD_QUEUED;
+    datagram->state = EC_DATAGRAM_QUEUED;
 }
 
 /*****************************************************************************/
@@ -331,7 +328,7 @@
 
         // fill current frame with datagrams
         list_for_each_entry(datagram, &master->datagram_queue, queue) {
-            if (datagram->state != EC_CMD_QUEUED) continue;
+            if (datagram->state != EC_DATAGRAM_QUEUED) continue;
 
             // does the current datagram fit in the frame?
             datagram_size = EC_DATAGRAM_HEADER_SIZE + datagram->data_size
@@ -341,7 +338,7 @@
                 break;
             }
 
-            datagram->state = EC_CMD_SENT;
+            datagram->state = EC_DATAGRAM_SENT;
             datagram->t_sent = t_start;
             datagram->index = master->datagram_index++;
 
@@ -456,7 +453,7 @@
         // search for matching datagram in the queue
         matched = 0;
         list_for_each_entry(datagram, &master->datagram_queue, queue) {
-            if (datagram->state == EC_CMD_SENT
+            if (datagram->state == EC_DATAGRAM_SENT
                 && datagram->type == datagram_type
                 && datagram->index == datagram_index
                 && datagram->data_size == data_size) {
@@ -482,7 +479,7 @@
         cur_data += EC_DATAGRAM_FOOTER_SIZE;
 
         // dequeue the received datagram
-        datagram->state = EC_CMD_RECEIVED;
+        datagram->state = EC_DATAGRAM_RECEIVED;
         list_del_init(&datagram->queue);
     }
 }
@@ -490,50 +487,6 @@
 /*****************************************************************************/
 
 /**
-   Sends a single datagram and waits for its reception.
-   If the slave doesn't respond, the datagram is sent again.
-   \return 0 in case of success, else < 0
-*/
-
-int ec_master_simple_io(ec_master_t *master, /**< EtherCAT master */
-                        ec_datagram_t *datagram /**< datagram */
-                        )
-{
-    unsigned int response_tries_left;
-
-    response_tries_left = 10000;
-
-    while (1)
-    {
-        ec_master_queue_datagram(master, datagram);
-        ecrt_master_sync_io(master);
-
-        if (datagram->state == EC_CMD_RECEIVED) {
-            if (likely(datagram->working_counter))
-                return 0;
-        }
-        else if (datagram->state == EC_CMD_TIMEOUT) {
-            EC_ERR("Simple-IO TIMEOUT!\n");
-            return -1;
-        }
-        else if (datagram->state == EC_CMD_ERROR) {
-            EC_ERR("Simple-IO datagram error!\n");
-            return -1;
-        }
-
-        // no direct response, wait a little bit...
-        udelay(100);
-
-        if (unlikely(--response_tries_left)) {
-            EC_ERR("No response in simple-IO!\n");
-            return -1;
-        }
-    }
-}
-
-/*****************************************************************************/
-
-/**
    Scans the EtherCAT bus for slaves.
    Creates a list of slave structures for further processing.
    \return 0 in case of success, else < 0
@@ -541,102 +494,22 @@
 
 int ec_master_bus_scan(ec_master_t *master /**< EtherCAT master */)
 {
-    ec_slave_t *slave;
-    ec_slave_ident_t *ident;
-    ec_datagram_t *datagram;
-    unsigned int i;
-    uint16_t coupler_index, coupler_subindex;
-    uint16_t reverse_coupler_index, current_coupler_index;
-
-    if (!list_empty(&master->slaves)) {
-        EC_ERR("Slave scan already done!\n");
+    ec_fsm_t *fsm = &master->fsm;
+
+    ec_fsm_startup(fsm); // init startup state machine
+
+    do {
+        ec_fsm_execute(fsm);
+        ec_master_sync_io(master);
+    }
+    while (ec_fsm_startup_running(fsm));
+
+    if (!ec_fsm_startup_success(fsm)) {
+        ec_master_clear_slaves(master);
         return -1;
     }
 
-    datagram = &master->simple_datagram;
-
-    // determine number of slaves on bus
-    if (ec_datagram_brd(datagram, 0x0000, 4)) return -1;
-    if (unlikely(ec_master_simple_io(master, datagram))) return -1;
-    master->slave_count = datagram->working_counter;
-    EC_INFO("Found %i slaves on bus.\n", master->slave_count);
-
-    if (!master->slave_count) return 0;
-
-    // init slaves
-    for (i = 0; i < master->slave_count; i++) {
-        if (!(slave =
-              (ec_slave_t *) kmalloc(sizeof(ec_slave_t), GFP_KERNEL))) {
-            EC_ERR("Failed to allocate slave %i!\n", i);
-            goto out_free;
-        }
-
-        if (ec_slave_init(slave, master, i, i + 1)) goto out_free;
-
-        if (kobject_add(&slave->kobj)) {
-            EC_ERR("Failed to add kobject.\n");
-            kobject_put(&slave->kobj); // free
-            goto out_free;
-        }
-
-        list_add_tail(&slave->list, &master->slaves);
-    }
-
-    coupler_index = 0;
-    reverse_coupler_index = 0xFFFF;
-    current_coupler_index = 0x3FFF;
-    coupler_subindex = 0;
-
-    // for every slave on the bus
-    list_for_each_entry(slave, &master->slaves, list) {
-
-        // write station address
-        if (ec_datagram_apwr(datagram, slave->ring_position, 0x0010,
-                            sizeof(uint16_t))) goto out_free;
-        EC_WRITE_U16(datagram->data, slave->station_address);
-        if (unlikely(ec_master_simple_io(master, datagram))) {
-            EC_ERR("Writing station address failed on slave %i!\n",
-                   slave->ring_position);
-            goto out_free;
-        }
-
-        // fetch all slave information
-        if (ec_slave_fetch(slave)) goto out_free;
-
-        // search for identification in "database"
-        ident = slave_idents;
-        while (ident->type) {
-            if (unlikely(ident->vendor_id == slave->sii_vendor_id
-                         && ident->product_code == slave->sii_product_code)) {
-                slave->type = ident->type;
-                break;
-            }
-            ident++;
-        }
-
-        if (!slave->type) {
-            EC_WARN("Unknown slave device (vendor 0x%08X, code 0x%08X) at"
-                    " position %i.\n", slave->sii_vendor_id,
-                    slave->sii_product_code, slave->ring_position);
-        }
-        else if (slave->type->special == EC_TYPE_BUS_COUPLER) {
-            if (slave->sii_alias)
-                current_coupler_index = reverse_coupler_index--;
-            else
-                current_coupler_index = coupler_index++;
-            coupler_subindex = 0;
-        }
-
-        slave->coupler_index = current_coupler_index;
-        slave->coupler_subindex = coupler_subindex;
-        coupler_subindex++;
-    }
-
     return 0;
-
- out_free:
-    ec_master_clear_slaves(master);
-    return -1;
 }
 
 /*****************************************************************************/
@@ -682,7 +555,7 @@
 {
     if (master->mode == EC_MASTER_MODE_IDLE) return;
 
-    if (master->mode == EC_MASTER_MODE_RUNNING) {
+    if (master->mode == EC_MASTER_MODE_OPERATION) {
         EC_ERR("ec_master_idle_start: Master already running!\n");
         return;
     }
@@ -731,12 +604,12 @@
     // aquire master lock
     spin_lock_bh(&master->internal_lock);
 
-    ecrt_master_async_receive(master);
+    ecrt_master_receive(master);
 
     // execute master state machine
     ec_fsm_execute(&master->fsm);
 
-    ecrt_master_async_send(master);
+    ecrt_master_send(master);
 
     // release master lock
     spin_unlock_bh(&master->internal_lock);
@@ -748,11 +621,11 @@
 /*****************************************************************************/
 
 /**
-   Initializes a sync manager configuration page.
+   Initializes a sync manager configuration page with EEPROM data.
    The referenced memory (\a data) must be at least EC_SYNC_SIZE bytes.
 */
 
-void ec_sync_config(const ec_sync_t *sync, /**< sync manager */
+void ec_sync_config(const ec_sii_sync_t *sync, /**< sync manager */
                     const ec_slave_t *slave, /**< EtherCAT slave */
                     uint8_t *data /**> configuration memory */
                     )
@@ -761,29 +634,6 @@
 
     sync_size = ec_slave_calc_sync_size(slave, sync);
 
-    EC_WRITE_U16(data,     sync->physical_start_address);
-    EC_WRITE_U16(data + 2, sync_size);
-    EC_WRITE_U8 (data + 4, sync->control_byte);
-    EC_WRITE_U8 (data + 5, 0x00); // status byte (read only)
-    EC_WRITE_U16(data + 6, 0x0001); // enable
-}
-
-/*****************************************************************************/
-
-/**
-   Initializes a sync manager configuration page with EEPROM data.
-   The referenced memory (\a data) must be at least EC_SYNC_SIZE bytes.
-*/
-
-void ec_eeprom_sync_config(const ec_eeprom_sync_t *sync, /**< sync manager */
-                           const ec_slave_t *slave, /**< EtherCAT slave */
-                           uint8_t *data /**> configuration memory */
-                           )
-{
-    size_t sync_size;
-
-    sync_size = ec_slave_calc_eeprom_sync_size(slave, sync);
-
     if (slave->master->debug_level) {
         EC_INFO("Slave %i, sync manager %i:\n", slave->ring_position,
                 sync->index);
@@ -821,7 +671,8 @@
     EC_WRITE_U8 (data + 7,  0x07); // logical end bit
     EC_WRITE_U16(data + 8,  fmmu->sync->physical_start_address);
     EC_WRITE_U8 (data + 10, 0x00); // physical start bit
-    EC_WRITE_U8 (data + 11, (fmmu->sync->control_byte & 0x04) ? 0x02 : 0x01);
+    EC_WRITE_U8 (data + 11, ((fmmu->sync->control_register & 0x04)
+                             ? 0x02 : 0x01));
     EC_WRITE_U16(data + 12, 0x0001); // enable
     EC_WRITE_U16(data + 14, 0x0000); // reserved
 }
@@ -849,8 +700,8 @@
                 return sprintf(buffer, "ORPHANED\n");
             case EC_MASTER_MODE_IDLE:
                 return sprintf(buffer, "IDLE\n");
-            case EC_MASTER_MODE_RUNNING:
-                return sprintf(buffer, "RUNNING\n");
+            case EC_MASTER_MODE_OPERATION:
+                return sprintf(buffer, "OPERATION\n");
         }
     }
     else if (attr == &attr_debug_level) {
@@ -922,7 +773,7 @@
 /*****************************************************************************/
 
 /**
-   Starts Ethernet-over-EtherCAT processing for all EoE-capable slaves.
+   Starts/Stops Ethernet-over-EtherCAT processing on demand.
 */
 
 void ec_master_eoe_start(ec_master_t *master /**< EtherCAT master */)
@@ -933,12 +784,17 @@
 
     if (master->eoe_running) return;
 
+    // if the locking callbacks are not set in operation mode,
+    // the EoE timer my not be started.
+    if (master->mode == EC_MASTER_MODE_OPERATION
+        && (!master->request_cb || !master->release_cb)) return;
+
     // decouple all EoE handlers
     list_for_each_entry(eoe, &master->eoe_handlers, list)
         eoe->slave = NULL;
+
+    // couple a free EoE handler to every EoE-capable slave
     coupled = 0;
-
-    // couple a free EoE handler to every EoE-capable slave
     list_for_each_entry(slave, &master->slaves, list) {
         if (!(slave->sii_mailbox_protocols & EC_MBOX_EOE)) continue;
 
@@ -950,12 +806,8 @@
             coupled++;
             EC_INFO("Coupling device %s to slave %i.\n",
                     eoe->dev->name, slave->ring_position);
-            if (eoe->opened) {
-                slave->requested_state = EC_SLAVE_STATE_OP;
-            }
-            else {
-                slave->requested_state = EC_SLAVE_STATE_INIT;
-            }
+            if (eoe->opened) slave->requested_state = EC_SLAVE_STATE_OP;
+            else slave->requested_state = EC_SLAVE_STATE_INIT;
             slave->error_flag = 0;
             break;
         }
@@ -1026,7 +878,7 @@
     if (!active) goto queue_timer;
 
     // aquire master lock...
-    if (master->mode == EC_MASTER_MODE_RUNNING) {
+    if (master->mode == EC_MASTER_MODE_OPERATION) {
         // request_cb must return 0, if the lock has been aquired!
         if (master->request_cb(master->cb_data))
             goto queue_timer;
@@ -1038,14 +890,14 @@
         goto queue_timer;
 
     // actual EoE stuff
-    ecrt_master_async_receive(master);
+    ecrt_master_receive(master);
     list_for_each_entry(eoe, &master->eoe_handlers, list) {
         ec_eoe_run(eoe);
     }
-    ecrt_master_async_send(master);
+    ecrt_master_send(master);
 
     // release lock...
-    if (master->mode == EC_MASTER_MODE_RUNNING) {
+    if (master->mode == EC_MASTER_MODE_OPERATION) {
         master->release_cb(master->cb_data);
     }
     else if (master->mode == EC_MASTER_MODE_IDLE) {
@@ -1057,6 +909,38 @@
     add_timer(&master->eoe_timer);
 }
 
+/*****************************************************************************/
+
+/**
+   Calculates Advanced Position Adresses.
+*/
+
+void ec_master_calc_addressing(ec_master_t *master /**< EtherCAT master */)
+{
+    uint16_t coupler_index, coupler_subindex;
+    uint16_t reverse_coupler_index, current_coupler_index;
+    ec_slave_t *slave;
+
+    coupler_index = 0;
+    reverse_coupler_index = 0xFFFF;
+    current_coupler_index = 0x0000;
+    coupler_subindex = 0;
+
+    list_for_each_entry(slave, &master->slaves, list) {
+        if (ec_slave_is_coupler(slave)) {
+            if (slave->sii_alias)
+                current_coupler_index = reverse_coupler_index--;
+            else
+                current_coupler_index = coupler_index++;
+            coupler_subindex = 0;
+        }
+
+        slave->coupler_index = current_coupler_index;
+        slave->coupler_subindex = coupler_subindex;
+        coupler_subindex++;
+    }
+}
+
 /******************************************************************************
  *  Realtime interface
  *****************************************************************************/
@@ -1115,17 +999,10 @@
 
 int ecrt_master_activate(ec_master_t *master /**< EtherCAT master */)
 {
-    unsigned int j;
-    ec_slave_t *slave;
-    ec_datagram_t *datagram;
-    const ec_sync_t *sync;
-    const ec_slave_type_t *type;
-    const ec_fmmu_t *fmmu;
     uint32_t domain_offset;
     ec_domain_t *domain;
-    ec_eeprom_sync_t *eeprom_sync, mbox_sync;
-
-    datagram = &master->simple_datagram;
+    ec_fsm_t *fsm = &master->fsm;
+    ec_slave_t *slave;
 
     // allocate all domains
     domain_offset = 0;
@@ -1137,149 +1014,29 @@
         domain_offset += domain->data_size;
     }
 
-    // configure and activate slaves
+    // determine initial states.
     list_for_each_entry(slave, &master->slaves, list) {
-
-        // change state to INIT
-        if (unlikely(ec_slave_state_change(slave, EC_SLAVE_STATE_INIT)))
-            return -1;
-
-        // check for slave registration
-        type = slave->type;
-        if (!type)
-            EC_WARN("Slave %i has unknown type!\n", slave->ring_position);
-
-        // check and reset CRC fault counters
-        ec_slave_check_crc(slave);
-
-        // reset FMMUs
-        if (slave->base_fmmu_count) {
-            if (ec_datagram_npwr(datagram, slave->station_address, 0x0600,
-                                 EC_FMMU_SIZE * slave->base_fmmu_count))
-                return -1;
-            memset(datagram->data, 0x00,
-                   EC_FMMU_SIZE * slave->base_fmmu_count);
-            if (unlikely(ec_master_simple_io(master, datagram))) {
-                EC_ERR("Resetting FMMUs failed on slave %i!\n",
-                       slave->ring_position);
-                return -1;
-            }
-        }
-
-        // reset sync managers
-        if (slave->base_sync_count) {
-            if (ec_datagram_npwr(datagram, slave->station_address, 0x0800,
-                                EC_SYNC_SIZE * slave->base_sync_count))
-                return -1;
-            memset(datagram->data, 0x00,
-                   EC_SYNC_SIZE * slave->base_sync_count);
-            if (unlikely(ec_master_simple_io(master, datagram))) {
-                EC_ERR("Resetting sync managers failed on slave %i!\n",
-                       slave->ring_position);
-                return -1;
-            }
-        }
-
-        // configure sync managers
-
-        // does the slave provide sync manager information?
-        if (!list_empty(&slave->eeprom_syncs)) {
-            list_for_each_entry(eeprom_sync, &slave->eeprom_syncs, list) {
-                if (ec_datagram_npwr(datagram, slave->station_address,
-                                     0x800 + eeprom_sync->index *
-                                     EC_SYNC_SIZE,
-                                     EC_SYNC_SIZE)) return -1;
-                ec_eeprom_sync_config(eeprom_sync, slave, datagram->data);
-                if (unlikely(ec_master_simple_io(master, datagram))) {
-                    EC_ERR("Setting sync manager %i failed on slave %i!\n",
-                           eeprom_sync->index, slave->ring_position);
-                    return -1;
-                }
-            }
-        }
-
-        else if (type) { // known slave type, take type's SM information
-            for (j = 0; type->sync_managers[j] && j < EC_MAX_SYNC; j++) {
-                sync = type->sync_managers[j];
-                if (ec_datagram_npwr(datagram, slave->station_address,
-                                     0x0800 + j * EC_SYNC_SIZE, EC_SYNC_SIZE))
-                    return -1;
-                ec_sync_config(sync, slave, datagram->data);
-                if (unlikely(ec_master_simple_io(master, datagram))) {
-                    EC_ERR("Setting sync manager %i failed on slave %i!\n",
-                           j, slave->ring_position);
-                    return -1;
-                }
-            }
-        }
-
-        // no sync manager information; guess mailbox settings
-        else if (slave->sii_mailbox_protocols) { 
-            mbox_sync.physical_start_address =
-                slave->sii_rx_mailbox_offset;
-            mbox_sync.length = slave->sii_rx_mailbox_size;
-            mbox_sync.control_register = 0x26;
-            mbox_sync.enable = 1;
-            if (ec_datagram_npwr(datagram, slave->station_address,
-                                 0x800,EC_SYNC_SIZE)) return -1;
-            ec_eeprom_sync_config(&mbox_sync, slave, datagram->data);
-            if (unlikely(ec_master_simple_io(master, datagram))) {
-                EC_ERR("Setting sync manager 0 failed on slave %i!\n",
-                       slave->ring_position);
-                return -1;
-            }
-
-            mbox_sync.physical_start_address =
-                slave->sii_tx_mailbox_offset;
-            mbox_sync.length = slave->sii_tx_mailbox_size;
-            mbox_sync.control_register = 0x22;
-            mbox_sync.enable = 1;
-            if (ec_datagram_npwr(datagram, slave->station_address,
-                                 0x808, EC_SYNC_SIZE)) return -1;
-            ec_eeprom_sync_config(&mbox_sync, slave, datagram->data);
-            if (unlikely(ec_master_simple_io(master, datagram))) {
-		    EC_ERR("Setting sync manager 1 failed on slave %i!\n",
-			   slave->ring_position);
-		    return -1;
-            }
-        }
-
-        // change state to PREOP
-        if (unlikely(ec_slave_state_change(slave, EC_SLAVE_STATE_PREOP)))
-            return -1;
-
-        // stop activation here for slaves without type
-        if (!type) continue;
-
-        // slaves that are not registered are only brought into PREOP
-        // state -> nice blinking and mailbox communication possible
-        if (!slave->registered && !slave->type->special) {
-            EC_WARN("Slave %i was not registered!\n", slave->ring_position);
-            continue;
-        }
-
-        // configure FMMUs
-        for (j = 0; j < slave->fmmu_count; j++) {
-            fmmu = &slave->fmmus[j];
-            if (ec_datagram_npwr(datagram, slave->station_address,
-                                 0x0600 + j * EC_FMMU_SIZE, EC_FMMU_SIZE))
-                return -1;
-            ec_fmmu_config(fmmu, slave, datagram->data);
-            if (unlikely(ec_master_simple_io(master, datagram))) {
-                EC_ERR("Setting FMMU %i failed on slave %i!\n",
-                       j, slave->ring_position);
-                return -1;
-            }
-        }
-
-        // change state to SAVEOP
-        if (unlikely(ec_slave_state_change(slave, EC_SLAVE_STATE_SAVEOP)))
-            return -1;
-
-        // change state to OP
-        if (unlikely(ec_slave_state_change(slave, EC_SLAVE_STATE_OP)))
-            return -1;
-    }
+        if (ec_slave_is_coupler(slave) || slave->registered) {
+            slave->requested_state = EC_SLAVE_STATE_OP;
+        }
+        else {
+            slave->requested_state = EC_SLAVE_STATE_PREOP;
+        }
+    }
+
+    ec_fsm_configuration(fsm); // init configuration state machine
+
+    do {
+        ec_fsm_execute(fsm);
+        ec_master_sync_io(master);
+    }
+    while (ec_fsm_configuration_running(fsm));
+
+    if (!ec_fsm_configuration_success(fsm)) {
+        return -1;
+    }
+
+    ec_fsm_reset(&master->fsm); // prepare for operation state machine
 
     return 0;
 }
@@ -1293,59 +1050,39 @@
 
 void ecrt_master_deactivate(ec_master_t *master /**< EtherCAT master */)
 {
+    ec_fsm_t *fsm = &master->fsm;
     ec_slave_t *slave;
 
     list_for_each_entry(slave, &master->slaves, list) {
-        ec_slave_check_crc(slave);
-        ec_slave_state_change(slave, EC_SLAVE_STATE_INIT);
-    }
-}
-
-
-/*****************************************************************************/
-
-/**
-   Fetches the SDO dictionaries of all slaves.
-   Slaves that do not support the CoE protocol are left out.
-   \return 0 in case of success, else < 0
-   \ingroup RealtimeInterface
-*/
-
-int ecrt_master_fetch_sdo_lists(ec_master_t *master /**< EtherCAT master */)
-{
-    ec_slave_t *slave;
-
-    list_for_each_entry(slave, &master->slaves, list) {
-        if (slave->sii_mailbox_protocols & EC_MBOX_COE) {
-            if (unlikely(ec_slave_fetch_sdo_list(slave))) {
-                EC_ERR("Failed to fetch SDO list on slave %i!\n",
-                       slave->ring_position);
-                return -1;
-            }
-        }
-    }
-
-    return 0;
+        slave->requested_state = EC_SLAVE_STATE_INIT;
+    }
+
+    ec_fsm_configuration(fsm); // init configuration state machine
+
+    do {
+        ec_fsm_execute(fsm);
+        ec_master_sync_io(master);
+    }
+    while (ec_fsm_configuration_running(fsm));
 }
 
 /*****************************************************************************/
 
 /**
    Sends queued datagrams and waits for their reception.
-   \ingroup RealtimeInterface
-*/
-
-void ecrt_master_sync_io(ec_master_t *master /**< EtherCAT master */)
+*/
+
+void ec_master_sync_io(ec_master_t *master /**< EtherCAT master */)
 {
     ec_datagram_t *datagram, *n;
     unsigned int datagrams_sent;
     cycles_t t_start, t_end, t_timeout;
 
     // send datagrams
-    ecrt_master_async_send(master);
+    ecrt_master_send(master);
 
     t_start = get_cycles(); // measure io time
-    t_timeout = (cycles_t) master->timeout * (cpu_khz / 1000);
+    t_timeout = (cycles_t) EC_IO_TIMEOUT * (cpu_khz / 1000);
 
     while (1) { // active waiting
         ec_device_call_isr(master->device);
@@ -1355,9 +1092,9 @@
 
         datagrams_sent = 0;
         list_for_each_entry_safe(datagram, n, &master->datagram_queue, queue) {
-            if (datagram->state == EC_CMD_RECEIVED)
+            if (datagram->state == EC_DATAGRAM_RECEIVED)
                 list_del_init(&datagram->queue);
-            else if (datagram->state == EC_CMD_SENT)
+            else if (datagram->state == EC_DATAGRAM_SENT)
                 datagrams_sent++;
         }
 
@@ -1367,13 +1104,13 @@
     // timeout; dequeue all datagrams
     list_for_each_entry_safe(datagram, n, &master->datagram_queue, queue) {
         switch (datagram->state) {
-            case EC_CMD_SENT:
-            case EC_CMD_QUEUED:
-                datagram->state = EC_CMD_TIMEOUT;
+            case EC_DATAGRAM_SENT:
+            case EC_DATAGRAM_QUEUED:
+                datagram->state = EC_DATAGRAM_TIMED_OUT;
                 master->stats.timeouts++;
                 ec_master_output_stats(master);
                 break;
-            case EC_CMD_RECEIVED:
+            case EC_DATAGRAM_RECEIVED:
                 master->stats.delayed++;
                 ec_master_output_stats(master);
                 break;
@@ -1391,14 +1128,14 @@
    \ingroup RealtimeInterface
 */
 
-void ecrt_master_async_send(ec_master_t *master /**< EtherCAT master */)
+void ecrt_master_send(ec_master_t *master /**< EtherCAT master */)
 {
     ec_datagram_t *datagram, *n;
 
     if (unlikely(!master->device->link_state)) {
         // link is down, no datagram can be sent
         list_for_each_entry_safe(datagram, n, &master->datagram_queue, queue) {
-            datagram->state = EC_CMD_ERROR;
+            datagram->state = EC_DATAGRAM_ERROR;
             list_del_init(&datagram->queue);
         }
 
@@ -1418,7 +1155,7 @@
    \ingroup RealtimeInterface
 */
 
-void ecrt_master_async_receive(ec_master_t *master /**< EtherCAT master */)
+void ecrt_master_receive(ec_master_t *master /**< EtherCAT master */)
 {
     ec_datagram_t *datagram, *next;
     cycles_t t_received, t_timeout;
@@ -1426,21 +1163,21 @@
     ec_device_call_isr(master->device);
 
     t_received = get_cycles();
-    t_timeout = (cycles_t) master->timeout * (cpu_khz / 1000);
+    t_timeout = (cycles_t) EC_IO_TIMEOUT * (cpu_khz / 1000);
 
     // dequeue all received datagrams
     list_for_each_entry_safe(datagram, next, &master->datagram_queue, queue)
-        if (datagram->state == EC_CMD_RECEIVED)
+        if (datagram->state == EC_DATAGRAM_RECEIVED)
             list_del_init(&datagram->queue);
 
     // dequeue all datagrams that timed out
     list_for_each_entry_safe(datagram, next, &master->datagram_queue, queue) {
         switch (datagram->state) {
-            case EC_CMD_SENT:
-            case EC_CMD_QUEUED:
+            case EC_DATAGRAM_SENT:
+            case EC_DATAGRAM_QUEUED:
                 if (t_received - datagram->t_sent > t_timeout) {
                     list_del_init(&datagram->queue);
-                    datagram->state = EC_CMD_TIMEOUT;
+                    datagram->state = EC_DATAGRAM_TIMED_OUT;
                     master->stats.timeouts++;
                     ec_master_output_stats(master);
                 }
@@ -1456,23 +1193,23 @@
 /**
    Prepares synchronous IO.
    Queues all domain datagrams and sends them. Then waits a certain time, so
-   that ecrt_master_sasync_receive() can be called securely.
+   that ecrt_master_receive() can be called securely.
    \ingroup RealtimeInterface
 */
 
-void ecrt_master_prepare_async_io(ec_master_t *master /**< EtherCAT master */)
+void ecrt_master_prepare(ec_master_t *master /**< EtherCAT master */)
 {
     ec_domain_t *domain;
     cycles_t t_start, t_end, t_timeout;
 
     // queue datagrams of all domains
     list_for_each_entry(domain, &master->domains, list)
-        ecrt_domain_queue(domain);
-
-    ecrt_master_async_send(master);
+        ec_domain_queue(domain);
+
+    ecrt_master_send(master);
 
     t_start = get_cycles(); // take sending time
-    t_timeout = (cycles_t) master->timeout * (cpu_khz / 1000);
+    t_timeout = (cycles_t) EC_IO_TIMEOUT * (cpu_khz / 1000);
 
     // active waiting
     while (1) {
@@ -1576,8 +1313,7 @@
         }
 
         if (alias_requested) {
-            if (!alias_slave->type ||
-                alias_slave->type->special != EC_TYPE_BUS_COUPLER) {
+            if (!ec_slave_is_coupler(alias_slave)) {
                 EC_ERR("Slave address \"%s\": Alias slave must be bus coupler"
                        " in colon mode.\n", address);
                 return NULL;
@@ -1628,92 +1364,16 @@
 
 /*****************************************************************************/
 
-/**
-   Starts Ethernet-over-EtherCAT processing for all EoE-capable slaves.
-   \ingroup RealtimeInterface
-*/
-
-int ecrt_master_start_eoe(ec_master_t *master /**< EtherCAT master */)
-{
-    if (!master->request_cb || !master->release_cb) {
-        EC_ERR("EoE requires master callbacks to be set!\n");
-        return -1;
-    }
-
-    ec_master_eoe_start(master);
-    return 0;
-}
-
-/*****************************************************************************/
-
-/**
-   Sets the debug level of the master.
-   The following levels are valid:
-   - 1: only output positions marks and basic data
-   - 2: additional frame data output
-   \ingroup RealtimeInterface
-*/
-
-void ecrt_master_debug(ec_master_t *master, /**< EtherCAT master */
-                       int level /**< debug level */
-                       )
-{
-    if (level != master->debug_level) {
-        master->debug_level = level;
-        EC_INFO("Master debug level set to %i.\n", level);
-    }
-}
-
-/*****************************************************************************/
-
-/**
-   Outputs all master information.
-   Verbosity:
-   - 0: Only slave types and positions
-   - 1: with EEPROM contents
-   - >1: with SDO dictionaries
-   \ingroup RealtimeInterface
-*/
-
-void ecrt_master_print(const ec_master_t *master, /**< EtherCAT master */
-                       unsigned int verbosity /**< verbosity level */
-                       )
-{
-    ec_slave_t *slave;
-    ec_eoe_t *eoe;
-
-    EC_INFO("*** Begin master information ***\n");
-    if (master->slave_count) {
-        EC_INFO("Slave list:\n");
-        list_for_each_entry(slave, &master->slaves, list)
-            ec_slave_print(slave, verbosity);
-    }
-    if (!list_empty(&master->eoe_handlers)) {
-        EC_INFO("Ethernet-over-EtherCAT (EoE) objects:\n");
-        list_for_each_entry(eoe, &master->eoe_handlers, list) {
-            ec_eoe_print(eoe);
-        }
-    }
-    EC_INFO("*** End master information ***\n");
-}
-
-/*****************************************************************************/
-
 /** \cond */
 
 EXPORT_SYMBOL(ecrt_master_create_domain);
 EXPORT_SYMBOL(ecrt_master_activate);
 EXPORT_SYMBOL(ecrt_master_deactivate);
-EXPORT_SYMBOL(ecrt_master_fetch_sdo_lists);
-EXPORT_SYMBOL(ecrt_master_prepare_async_io);
-EXPORT_SYMBOL(ecrt_master_sync_io);
-EXPORT_SYMBOL(ecrt_master_async_send);
-EXPORT_SYMBOL(ecrt_master_async_receive);
+EXPORT_SYMBOL(ecrt_master_prepare);
+EXPORT_SYMBOL(ecrt_master_send);
+EXPORT_SYMBOL(ecrt_master_receive);
 EXPORT_SYMBOL(ecrt_master_run);
 EXPORT_SYMBOL(ecrt_master_callbacks);
-EXPORT_SYMBOL(ecrt_master_start_eoe);
-EXPORT_SYMBOL(ecrt_master_debug);
-EXPORT_SYMBOL(ecrt_master_print);
 EXPORT_SYMBOL(ecrt_master_get_slave);
 
 /** \endcond */
--- a/master/master.h	Wed Aug 02 23:16:10 2006 +0000
+++ b/master/master.h	Thu Aug 03 12:51:17 2006 +0000
@@ -59,7 +59,7 @@
 {
     EC_MASTER_MODE_ORPHANED,
     EC_MASTER_MODE_IDLE,
-    EC_MASTER_MODE_RUNNING
+    EC_MASTER_MODE_OPERATION
 }
 ec_master_mode_t;
 
@@ -104,10 +104,6 @@
 
     struct list_head domains; /**< list of domains */
 
-    ec_datagram_t simple_datagram; /**< datagram structure for
-                                      initialization */
-    unsigned int timeout; /**< timeout in synchronous IO */
-
     int debug_level; /**< master debug level */
     ec_stats_t stats; /**< cyclic statistics */
 
@@ -145,18 +141,18 @@
 // IO
 void ec_master_receive(ec_master_t *, const uint8_t *, size_t);
 void ec_master_queue_datagram(ec_master_t *, ec_datagram_t *);
-int ec_master_simple_io(ec_master_t *, ec_datagram_t *);
 
 // slave management
 int ec_master_bus_scan(ec_master_t *);
 
 // misc.
+void ec_master_output_stats(ec_master_t *);
 void ec_master_clear_slaves(ec_master_t *);
-void ec_sync_config(const ec_sync_t *, const ec_slave_t *, uint8_t *);
-void ec_eeprom_sync_config(const ec_eeprom_sync_t *, const ec_slave_t *,
-                           uint8_t *);
+
+// other methods
+void ec_sync_config(const ec_sii_sync_t *, const ec_slave_t *, uint8_t *);
 void ec_fmmu_config(const ec_fmmu_t *, const ec_slave_t *, uint8_t *);
-void ec_master_output_stats(ec_master_t *);
+void ec_master_calc_addressing(ec_master_t *);
 
 /*****************************************************************************/
 
--- a/master/module.c	Wed Aug 02 23:16:10 2006 +0000
+++ b/master/module.c	Thu Aug 03 12:51:17 2006 +0000
@@ -237,33 +237,38 @@
    Prints slave states in clear text.
 */
 
-void ec_print_states(const uint8_t states /**< slave states */)
-{
+size_t ec_state_string(uint8_t states, /**< slave states */
+                       char *buffer /**< target buffer (min. 25 bytes) */
+                       )
+{
+    off_t off = 0;
     unsigned int first = 1;
 
     if (!states) {
-        printk("(unknown)");
-        return;
+        off += sprintf(buffer + off, "(unknown)");
+        return off;
     }
 
     if (states & EC_SLAVE_STATE_INIT) {
-        printk("INIT");
+        off += sprintf(buffer + off, "INIT");
         first = 0;
     }
     if (states & EC_SLAVE_STATE_PREOP) {
-        if (!first) printk(", ");
-        printk("PREOP");
+        if (!first) off += sprintf(buffer + off, ", ");
+        off += sprintf(buffer + off, "PREOP");
         first = 0;
     }
     if (states & EC_SLAVE_STATE_SAVEOP) {
-        if (!first) printk(", ");
-        printk("SAVEOP");
+        if (!first) off += sprintf(buffer + off, ", ");
+        off += sprintf(buffer + off, "SAVEOP");
         first = 0;
     }
     if (states & EC_SLAVE_STATE_OP) {
-        if (!first) printk(", ");
-        printk("OP");
-    }
+        if (!first) off += sprintf(buffer + off, ", ");
+        off += sprintf(buffer + off, "OP");
+    }
+
+    return off;
 }
 
 /******************************************************************************
@@ -426,7 +431,7 @@
 
     ec_master_idle_stop(master);
     ec_master_reset(master);
-    master->mode = EC_MASTER_MODE_RUNNING;
+    master->mode = EC_MASTER_MODE_OPERATION;
 
     if (!master->device->link_state) EC_WARN("Link is DOWN.\n");
 
--- a/master/slave.c	Wed Aug 02 23:16:10 2006 +0000
+++ b/master/slave.c	Thu Aug 03 12:51:17 2006 +0000
@@ -52,7 +52,6 @@
 
 /*****************************************************************************/
 
-int ec_slave_fetch_categories(ec_slave_t *);
 ssize_t ec_show_slave_attribute(struct kobject *, struct attribute *, char *);
 ssize_t ec_store_slave_attribute(struct kobject *, struct attribute *,
                                  const char *, size_t);
@@ -61,24 +60,12 @@
 
 /** \cond */
 
-EC_SYSFS_READ_ATTR(ring_position);
-EC_SYSFS_READ_ATTR(advanced_position);
-EC_SYSFS_READ_ATTR(vendor_name); // deprecated
-EC_SYSFS_READ_ATTR(product_name); // deprecated
-EC_SYSFS_READ_ATTR(product_desc); // deprecated
-EC_SYSFS_READ_ATTR(name);
-EC_SYSFS_READ_ATTR(type); // deprecated
+EC_SYSFS_READ_ATTR(info);
 EC_SYSFS_READ_WRITE_ATTR(state);
 EC_SYSFS_READ_WRITE_ATTR(eeprom);
 
 static struct attribute *def_attrs[] = {
-    &attr_ring_position,
-    &attr_advanced_position,
-    &attr_vendor_name,
-    &attr_product_name,
-    &attr_product_desc,
-    &attr_name,
-    &attr_type,
+    &attr_info,
     &attr_state,
     &attr_eeprom,
     NULL,
@@ -127,13 +114,28 @@
     }
 
     slave->master = master;
+
+    slave->requested_state = EC_SLAVE_STATE_UNKNOWN;
+    slave->current_state = EC_SLAVE_STATE_UNKNOWN;
+    slave->error_flag = 0;
+    slave->online = 1;
+    slave->fmmu_count = 0;
+    slave->registered = 0;
+
     slave->coupler_index = 0;
     slave->coupler_subindex = 0xFFFF;
+
     slave->base_type = 0;
     slave->base_revision = 0;
     slave->base_build = 0;
     slave->base_fmmu_count = 0;
     slave->base_sync_count = 0;
+
+    slave->eeprom_data = NULL;
+    slave->eeprom_size = 0;
+    slave->new_eeprom_data = NULL;
+    slave->new_eeprom_size = 0;
+
     slave->sii_alias = 0;
     slave->sii_vendor_id = 0;
     slave->sii_product_code = 0;
@@ -144,25 +146,14 @@
     slave->sii_tx_mailbox_offset = 0;
     slave->sii_tx_mailbox_size = 0;
     slave->sii_mailbox_protocols = 0;
-    slave->type = NULL;
-    slave->registered = 0;
-    slave->fmmu_count = 0;
-    slave->eeprom_data = NULL;
-    slave->eeprom_size = 0;
-    slave->eeprom_group = NULL;
-    slave->eeprom_image = NULL;
-    slave->eeprom_order = NULL;
-    slave->eeprom_name = NULL;
-    slave->requested_state = EC_SLAVE_STATE_UNKNOWN;
-    slave->current_state = EC_SLAVE_STATE_UNKNOWN;
-    slave->error_flag = 0;
-    slave->online = 1;
-    slave->new_eeprom_data = NULL;
-    slave->new_eeprom_size = 0;
-
-    INIT_LIST_HEAD(&slave->eeprom_strings);
-    INIT_LIST_HEAD(&slave->eeprom_syncs);
-    INIT_LIST_HEAD(&slave->eeprom_pdos);
+    slave->sii_group = NULL;
+    slave->sii_image = NULL;
+    slave->sii_order = NULL;
+    slave->sii_name = NULL;
+
+    INIT_LIST_HEAD(&slave->sii_strings);
+    INIT_LIST_HEAD(&slave->sii_syncs);
+    INIT_LIST_HEAD(&slave->sii_pdos);
     INIT_LIST_HEAD(&slave->sdo_dictionary);
     INIT_LIST_HEAD(&slave->varsize_fields);
 
@@ -185,10 +176,10 @@
 void ec_slave_clear(struct kobject *kobj /**< kobject of the slave */)
 {
     ec_slave_t *slave;
-    ec_eeprom_string_t *string, *next_str;
-    ec_eeprom_sync_t *sync, *next_sync;
-    ec_eeprom_pdo_t *pdo, *next_pdo;
-    ec_eeprom_pdo_entry_t *entry, *next_ent;
+    ec_sii_string_t *string, *next_str;
+    ec_sii_sync_t *sync, *next_sync;
+    ec_sii_pdo_t *pdo, *next_pdo;
+    ec_sii_pdo_entry_t *entry, *next_ent;
     ec_sdo_t *sdo, *next_sdo;
     ec_sdo_entry_t *en, *next_en;
     ec_varsize_t *var, *next_var;
@@ -196,19 +187,19 @@
     slave = container_of(kobj, ec_slave_t, kobj);
 
     // free all string objects
-    list_for_each_entry_safe(string, next_str, &slave->eeprom_strings, list) {
+    list_for_each_entry_safe(string, next_str, &slave->sii_strings, list) {
         list_del(&string->list);
         kfree(string);
     }
 
     // free all sync managers
-    list_for_each_entry_safe(sync, next_sync, &slave->eeprom_syncs, list) {
+    list_for_each_entry_safe(sync, next_sync, &slave->sii_syncs, list) {
         list_del(&sync->list);
         kfree(sync);
     }
 
     // free all PDOs
-    list_for_each_entry_safe(pdo, next_pdo, &slave->eeprom_pdos, list) {
+    list_for_each_entry_safe(pdo, next_pdo, &slave->sii_pdos, list) {
         list_del(&pdo->list);
         if (pdo->name) kfree(pdo->name);
 
@@ -222,10 +213,10 @@
         kfree(pdo);
     }
 
-    if (slave->eeprom_group) kfree(slave->eeprom_group);
-    if (slave->eeprom_image) kfree(slave->eeprom_image);
-    if (slave->eeprom_order) kfree(slave->eeprom_order);
-    if (slave->eeprom_name) kfree(slave->eeprom_name);
+    if (slave->sii_group) kfree(slave->sii_group);
+    if (slave->sii_image) kfree(slave->sii_image);
+    if (slave->sii_order) kfree(slave->sii_order);
+    if (slave->sii_name) kfree(slave->sii_name);
 
     // free all SDOs
     list_for_each_entry_safe(sdo, next_sdo, &slave->sdo_dictionary, list) {
@@ -253,371 +244,6 @@
 /*****************************************************************************/
 
 /**
-   Reads all necessary information from a slave.
-   \return 0 in case of success, else < 0
-*/
-
-int ec_slave_fetch(ec_slave_t *slave /**< EtherCAT slave */)
-{
-    ec_datagram_t *datagram;
-    unsigned int i;
-    uint16_t dl_status;
-
-    datagram = &slave->master->simple_datagram;
-
-    // read base data
-    if (ec_datagram_nprd(datagram, slave->station_address, 0x0000, 6))
-        return -1;
-    if (unlikely(ec_master_simple_io(slave->master, datagram))) {
-        EC_ERR("Reading base data from slave %i failed!\n",
-               slave->ring_position);
-        return -1;
-    }
-
-    slave->base_type =       EC_READ_U8 (datagram->data);
-    slave->base_revision =   EC_READ_U8 (datagram->data + 1);
-    slave->base_build =      EC_READ_U16(datagram->data + 2);
-    slave->base_fmmu_count = EC_READ_U8 (datagram->data + 4);
-    slave->base_sync_count = EC_READ_U8 (datagram->data + 5);
-
-    if (slave->base_fmmu_count > EC_MAX_FMMUS)
-        slave->base_fmmu_count = EC_MAX_FMMUS;
-
-    // read data link status
-    if (ec_datagram_nprd(datagram, slave->station_address, 0x0110, 2))
-        return -1;
-    if (unlikely(ec_master_simple_io(slave->master, datagram))) {
-        EC_ERR("Reading DL status from slave %i failed!\n",
-               slave->ring_position);
-        return -1;
-    }
-
-    dl_status = EC_READ_U16(datagram->data);
-    for (i = 0; i < 4; i++) {
-        slave->dl_link[i] = dl_status & (1 << (4 + i)) ? 1 : 0;
-        slave->dl_loop[i] = dl_status & (1 << (8 + i * 2)) ? 1 : 0;
-        slave->dl_signal[i] = dl_status & (1 << (9 + i * 2)) ? 1 : 0;
-    }
-
-    // read EEPROM data
-    if (ec_slave_sii_read16(slave, 0x0004, &slave->sii_alias))
-        return -1;
-    if (ec_slave_sii_read32(slave, 0x0008, &slave->sii_vendor_id))
-        return -1;
-    if (ec_slave_sii_read32(slave, 0x000A, &slave->sii_product_code))
-        return -1;
-    if (ec_slave_sii_read32(slave, 0x000C, &slave->sii_revision_number))
-        return -1;
-    if (ec_slave_sii_read32(slave, 0x000E, &slave->sii_serial_number))
-        return -1;
-    if (ec_slave_sii_read16(slave, 0x0018, &slave->sii_rx_mailbox_offset))
-        return -1;
-    if (ec_slave_sii_read16(slave, 0x0019, &slave->sii_rx_mailbox_size))
-        return -1;
-    if (ec_slave_sii_read16(slave, 0x001A, &slave->sii_tx_mailbox_offset))
-        return -1;
-    if (ec_slave_sii_read16(slave, 0x001B, &slave->sii_tx_mailbox_size))
-        return -1;
-    if (ec_slave_sii_read16(slave, 0x001C, &slave->sii_mailbox_protocols))
-        return -1;
-
-    if (unlikely(ec_slave_fetch_categories(slave))) {
-        EC_ERR("Failed to fetch category data!\n");
-        return -1;
-    }
-
-    return 0;
-}
-
-/*****************************************************************************/
-
-/**
-   Reads 16 bit from the slave information interface (SII).
-   \return 0 in case of success, else < 0
-*/
-
-int ec_slave_sii_read16(ec_slave_t *slave,
-                        /**< EtherCAT slave */
-                        uint16_t offset,
-                        /**< address of the SII register to read */
-                        uint16_t *target
-                        /**< target memory */
-                        )
-{
-    ec_datagram_t *datagram;
-    cycles_t start, end, timeout;
-
-    datagram = &slave->master->simple_datagram;
-
-    // initiate read operation
-    if (ec_datagram_npwr(datagram, slave->station_address, 0x502, 6))
-        return -1;
-    EC_WRITE_U8 (datagram->data,     0x00); // read-only access
-    EC_WRITE_U8 (datagram->data + 1, 0x01); // request read operation
-    EC_WRITE_U32(datagram->data + 2, offset);
-    if (unlikely(ec_master_simple_io(slave->master, datagram))) {
-        EC_ERR("SII-read failed on slave %i!\n", slave->ring_position);
-        return -1;
-    }
-
-    start = get_cycles();
-    timeout = (cycles_t) 100 * cpu_khz; // 100ms
-
-    while (1)
-    {
-        udelay(10);
-
-        if (ec_datagram_nprd(datagram, slave->station_address, 0x502, 10))
-            return -1;
-        if (unlikely(ec_master_simple_io(slave->master, datagram))) {
-            EC_ERR("Getting SII-read status failed on slave %i!\n",
-                   slave->ring_position);
-            return -1;
-        }
-
-        end = get_cycles();
-
-        // check for "busy bit"
-        if (likely((EC_READ_U8(datagram->data + 1) & 0x81) == 0)) {
-            *target = EC_READ_U16(datagram->data + 6);
-            return 0;
-        }
-
-        if (unlikely((end - start) >= timeout)) {
-            EC_ERR("SII-read. Slave %i timed out!\n", slave->ring_position);
-            return -1;
-        }
-    }
-}
-
-/*****************************************************************************/
-
-/**
-   Reads 32 bit from the slave information interface (SII).
-   \return 0 in case of success, else < 0
-*/
-
-int ec_slave_sii_read32(ec_slave_t *slave,
-                        /**< EtherCAT slave */
-                        uint16_t offset,
-                        /**< address of the SII register to read */
-                        uint32_t *target
-                        /**< target memory */
-                        )
-{
-    ec_datagram_t *datagram;
-    cycles_t start, end, timeout;
-
-    datagram = &slave->master->simple_datagram;
-
-    // initiate read operation
-    if (ec_datagram_npwr(datagram, slave->station_address, 0x502, 6))
-        return -1;
-    EC_WRITE_U8 (datagram->data,     0x00); // read-only access
-    EC_WRITE_U8 (datagram->data + 1, 0x01); // request read operation
-    EC_WRITE_U32(datagram->data + 2, offset);
-    if (unlikely(ec_master_simple_io(slave->master, datagram))) {
-        EC_ERR("SII-read failed on slave %i!\n", slave->ring_position);
-        return -1;
-    }
-
-    start = get_cycles();
-    timeout = (cycles_t) 100 * cpu_khz; // 100ms
-
-    while (1)
-    {
-        udelay(10);
-
-        if (ec_datagram_nprd(datagram, slave->station_address, 0x502, 10))
-            return -1;
-        if (unlikely(ec_master_simple_io(slave->master, datagram))) {
-            EC_ERR("Getting SII-read status failed on slave %i!\n",
-                   slave->ring_position);
-            return -1;
-        }
-
-        end = get_cycles();
-
-        // check "busy bit"
-        if (likely((EC_READ_U8(datagram->data + 1) & 0x81) == 0)) {
-            *target = EC_READ_U32(datagram->data + 6);
-            return 0;
-        }
-
-        if (unlikely((end - start) >= timeout)) {
-            EC_ERR("SII-read. Slave %i timed out!\n", slave->ring_position);
-            return -1;
-        }
-    }
-}
-
-/*****************************************************************************/
-
-/**
-   Writes 16 bit of data to the slave information interface (SII).
-   \return 0 in case of success, else < 0
-*/
-
-int ec_slave_sii_write16(ec_slave_t *slave,
-                         /**< EtherCAT slave */
-                         uint16_t offset,
-                         /**< address of the SII register to write */
-                         uint16_t value
-                         /**< new value */
-                         )
-{
-    ec_datagram_t *datagram;
-    cycles_t start, end, timeout;
-
-    datagram = &slave->master->simple_datagram;
-
-    EC_INFO("SII-write (slave %i, offset 0x%04X, value 0x%04X)\n",
-            slave->ring_position, offset, value);
-
-    // initiate write operation
-    if (ec_datagram_npwr(datagram, slave->station_address, 0x502, 8))
-        return -1;
-    EC_WRITE_U8 (datagram->data,     0x01); // enable write access
-    EC_WRITE_U8 (datagram->data + 1, 0x02); // request write operation
-    EC_WRITE_U32(datagram->data + 2, offset);
-    EC_WRITE_U16(datagram->data + 6, value);
-    if (unlikely(ec_master_simple_io(slave->master, datagram))) {
-        EC_ERR("SII-write failed on slave %i!\n", slave->ring_position);
-        return -1;
-    }
-
-    start = get_cycles();
-    timeout = (cycles_t) 100 * cpu_khz; // 100ms
-
-    while (1)
-    {
-        udelay(10);
-
-        if (ec_datagram_nprd(datagram, slave->station_address, 0x502, 2))
-            return -1;
-        if (unlikely(ec_master_simple_io(slave->master, datagram))) {
-            EC_ERR("Getting SII-write status failed on slave %i!\n",
-                   slave->ring_position);
-            return -1;
-        }
-
-        end = get_cycles();
-
-        // check "busy bit"
-        if (likely((EC_READ_U8(datagram->data + 1) & 0x82) == 0)) {
-            if (EC_READ_U8(datagram->data + 1) & 0x40) {
-                EC_ERR("SII-write failed!\n");
-                return -1;
-            }
-            else {
-                EC_INFO("SII-write succeeded!\n");
-                return 0;
-            }
-        }
-
-        if (unlikely((end - start) >= timeout)) {
-            EC_ERR("SII-write: Slave %i timed out!\n", slave->ring_position);
-            return -1;
-        }
-    }
-}
-
-/*****************************************************************************/
-
-/**
-   Fetches data from slave's EEPROM.
-   \return 0 in case of success, else < 0
-   \todo memory allocation
-*/
-
-int ec_slave_fetch_categories(ec_slave_t *slave /**< EtherCAT slave */)
-{
-    uint16_t word_offset, cat_type, word_count;
-    uint32_t value;
-    uint8_t *cat_data;
-    unsigned int i;
-
-    word_offset = 0x0040;
-
-    if (!(cat_data = (uint8_t *) kmalloc(0x10000, GFP_ATOMIC))) {
-        EC_ERR("Failed to allocate 64k bytes for category data.\n");
-        return -1;
-    }
-
-    while (1) {
-        // read category type
-        if (ec_slave_sii_read32(slave, word_offset, &value)) {
-            EC_ERR("Unable to read category header.\n");
-            goto out_free;
-        }
-
-        // last category?
-        if ((value & 0xFFFF) == 0xFFFF) break;
-
-        cat_type = value & 0x7FFF;
-        word_count = (value >> 16) & 0xFFFF;
-
-        // fetch category data
-        for (i = 0; i < word_count; i++) {
-            if (ec_slave_sii_read32(slave, word_offset + 2 + i, &value)) {
-                EC_ERR("Unable to read category data word %i.\n", i);
-                goto out_free;
-            }
-
-            cat_data[i * 2]     = (value >> 0) & 0xFF;
-            cat_data[i * 2 + 1] = (value >> 8) & 0xFF;
-
-            // read second word "on the fly"
-            if (i + 1 < word_count) {
-                i++;
-                cat_data[i * 2]     = (value >> 16) & 0xFF;
-                cat_data[i * 2 + 1] = (value >> 24) & 0xFF;
-            }
-        }
-
-        switch (cat_type)
-        {
-            case 0x000A:
-                if (ec_slave_fetch_strings(slave, cat_data))
-                    goto out_free;
-                break;
-            case 0x001E:
-                if (ec_slave_fetch_general(slave, cat_data))
-                    goto out_free;
-                break;
-            case 0x0028:
-                break;
-            case 0x0029:
-                if (ec_slave_fetch_sync(slave, cat_data, word_count))
-                    goto out_free;
-                break;
-            case 0x0032:
-                if (ec_slave_fetch_pdo(slave, cat_data, word_count, EC_TX_PDO))
-                    goto out_free;
-                break;
-            case 0x0033:
-                if (ec_slave_fetch_pdo(slave, cat_data, word_count, EC_RX_PDO))
-                    goto out_free;
-                break;
-            default:
-                EC_WARN("Unknown category type 0x%04X in slave %i.\n",
-                        cat_type, slave->ring_position);
-        }
-
-        word_offset += 2 + word_count;
-    }
-
-    kfree(cat_data);
-    return 0;
-
- out_free:
-    kfree(cat_data);
-    return -1;
-}
-
-/*****************************************************************************/
-
-/**
    Fetches data from a STRING category.
    \return 0 in case of success, else < 0
 */
@@ -629,24 +255,24 @@
     unsigned int string_count, i;
     size_t size;
     off_t offset;
-    ec_eeprom_string_t *string;
+    ec_sii_string_t *string;
 
     string_count = data[0];
     offset = 1;
     for (i = 0; i < string_count; i++) {
         size = data[offset];
         // allocate memory for string structure and data at a single blow
-        if (!(string = (ec_eeprom_string_t *)
-              kmalloc(sizeof(ec_eeprom_string_t) + size + 1, GFP_ATOMIC))) {
+        if (!(string = (ec_sii_string_t *)
+              kmalloc(sizeof(ec_sii_string_t) + size + 1, GFP_ATOMIC))) {
             EC_ERR("Failed to allocate string memory.\n");
             return -1;
         }
         string->size = size;
         // string memory appended to string structure
-        string->data = (char *) string + sizeof(ec_eeprom_string_t);
+        string->data = (char *) string + sizeof(ec_sii_string_t);
         memcpy(string->data, data + offset + 1, size);
         string->data[size] = 0x00;
-        list_add_tail(&string->list, &slave->eeprom_strings);
+        list_add_tail(&string->list, &slave->sii_strings);
         offset += 1 + size;
     }
 
@@ -660,26 +286,20 @@
    \return 0 in case of success, else < 0
 */
 
-int ec_slave_fetch_general(ec_slave_t *slave, /**< EtherCAT slave */
-                           const uint8_t *data /**< category data */
-                           )
+void ec_slave_fetch_general(ec_slave_t *slave, /**< EtherCAT slave */
+                            const uint8_t *data /**< category data */
+                            )
 {
     unsigned int i;
 
-    if (ec_slave_locate_string(slave, data[0], &slave->eeprom_group))
-        return -1;
-    if (ec_slave_locate_string(slave, data[1], &slave->eeprom_image))
-        return -1;
-    if (ec_slave_locate_string(slave, data[2], &slave->eeprom_order))
-        return -1;
-    if (ec_slave_locate_string(slave, data[3], &slave->eeprom_name))
-        return -1;
+    ec_slave_locate_string(slave, data[0], &slave->sii_group);
+    ec_slave_locate_string(slave, data[1], &slave->sii_image);
+    ec_slave_locate_string(slave, data[2], &slave->sii_order);
+    ec_slave_locate_string(slave, data[3], &slave->sii_name);
 
     for (i = 0; i < 4; i++)
         slave->sii_physical_layer[i] =
             (data[4] & (0x03 << (i * 2))) >> (i * 2);
-
-    return 0;
 }
 
 /*****************************************************************************/
@@ -695,24 +315,24 @@
                         )
 {
     unsigned int sync_count, i;
-    ec_eeprom_sync_t *sync;
+    ec_sii_sync_t *sync;
 
     sync_count = word_count / 4; // sync manager struct is 4 words long
 
     for (i = 0; i < sync_count; i++, data += 8) {
-        if (!(sync = (ec_eeprom_sync_t *)
-              kmalloc(sizeof(ec_eeprom_sync_t), GFP_ATOMIC))) {
+        if (!(sync = (ec_sii_sync_t *)
+              kmalloc(sizeof(ec_sii_sync_t), GFP_ATOMIC))) {
             EC_ERR("Failed to allocate Sync-Manager memory.\n");
             return -1;
         }
 
         sync->index = i;
-        sync->physical_start_address = *((uint16_t *) (data + 0));
-        sync->length                 = *((uint16_t *) (data + 2));
-        sync->control_register       = data[4];
-        sync->enable                 = data[6];
-
-        list_add_tail(&sync->list, &slave->eeprom_syncs);
+        sync->physical_start_address = EC_READ_U16(data);
+        sync->length                 = EC_READ_U16(data + 2);
+        sync->control_register       = EC_READ_U8 (data + 4);
+        sync->enable                 = EC_READ_U8 (data + 6);
+
+        list_add_tail(&sync->list, &slave->sii_syncs);
     }
 
     return 0;
@@ -728,16 +348,16 @@
 int ec_slave_fetch_pdo(ec_slave_t *slave, /**< EtherCAT slave */
                        const uint8_t *data, /**< category data */
                        size_t word_count, /**< number of words */
-                       ec_pdo_type_t pdo_type /**< PDO type */
+                       ec_sii_pdo_type_t pdo_type /**< PDO type */
                        )
 {
-    ec_eeprom_pdo_t *pdo;
-    ec_eeprom_pdo_entry_t *entry;
+    ec_sii_pdo_t *pdo;
+    ec_sii_pdo_entry_t *entry;
     unsigned int entry_count, i;
 
     while (word_count >= 4) {
-        if (!(pdo = (ec_eeprom_pdo_t *)
-              kmalloc(sizeof(ec_eeprom_pdo_t), GFP_ATOMIC))) {
+        if (!(pdo = (ec_sii_pdo_t *)
+              kmalloc(sizeof(ec_sii_pdo_t), GFP_ATOMIC))) {
             EC_ERR("Failed to allocate PDO memory.\n");
             return -1;
         }
@@ -745,29 +365,29 @@
         INIT_LIST_HEAD(&pdo->entries);
         pdo->type = pdo_type;
 
-        pdo->index = *((uint16_t *) data);
-        entry_count = data[2];
-        pdo->sync_manager = data[3];
+        pdo->index = EC_READ_U16(data);
+        entry_count = EC_READ_U8(data + 2);
+        pdo->sync_index = EC_READ_U8(data + 3);
         pdo->name = NULL;
-        ec_slave_locate_string(slave, data[5], &pdo->name);
-
-        list_add_tail(&pdo->list, &slave->eeprom_pdos);
+        ec_slave_locate_string(slave, EC_READ_U8(data + 5), &pdo->name);
+
+        list_add_tail(&pdo->list, &slave->sii_pdos);
 
         word_count -= 4;
         data += 8;
 
         for (i = 0; i < entry_count; i++) {
-            if (!(entry = (ec_eeprom_pdo_entry_t *)
-                  kmalloc(sizeof(ec_eeprom_pdo_entry_t), GFP_ATOMIC))) {
+            if (!(entry = (ec_sii_pdo_entry_t *)
+                  kmalloc(sizeof(ec_sii_pdo_entry_t), GFP_ATOMIC))) {
                 EC_ERR("Failed to allocate PDO entry memory.\n");
                 return -1;
             }
 
-            entry->index = *((uint16_t *) data);
-            entry->subindex = data[2];
+            entry->index = EC_READ_U16(data);
+            entry->subindex = EC_READ_U8(data + 2);
             entry->name = NULL;
-            ec_slave_locate_string(slave, data[3], &entry->name);
-            entry->bit_length = data[5];
+            ec_slave_locate_string(slave, EC_READ_U8(data + 3), &entry->name);
+            entry->bit_length = EC_READ_U8(data + 5);
 
             list_add_tail(&entry->list, &pdo->entries);
 
@@ -792,7 +412,7 @@
                            char **ptr /**< Address of the string pointer */
                            )
 {
-    ec_eeprom_string_t *string;
+    ec_sii_string_t *string;
     char *err_string;
 
     // Erst alten Speicher freigeben
@@ -805,7 +425,7 @@
     if (!index) return 0;
 
     // EEPROM-String mit Index finden und kopieren
-    list_for_each_entry(string, &slave->eeprom_strings, list) {
+    list_for_each_entry(string, &slave->sii_strings, list) {
         if (--index) continue;
 
         if (!(*ptr = (char *) kmalloc(string->size + 1, GFP_ATOMIC))) {
@@ -821,7 +441,7 @@
     err_string = "(string not found)";
 
     if (!(*ptr = (char *) kmalloc(strlen(err_string) + 1, GFP_ATOMIC))) {
-        EC_ERR("Unable to allocate string memory.\n");
+        EC_WARN("Unable to allocate string memory.\n");
         return -1;
     }
 
@@ -832,174 +452,11 @@
 /*****************************************************************************/
 
 /**
-   Acknowledges an error after a state transition.
-*/
-
-void ec_slave_state_ack(ec_slave_t *slave, /**< EtherCAT slave */
-                        uint8_t state /**< previous state */
-                        )
-{
-    ec_datagram_t *datagram;
-    cycles_t start, end, timeout;
-
-    datagram = &slave->master->simple_datagram;
-
-    if (ec_datagram_npwr(datagram, slave->station_address, 0x0120, 2)) return;
-    EC_WRITE_U16(datagram->data, state | EC_ACK);
-    if (unlikely(ec_master_simple_io(slave->master, datagram))) {
-        EC_WARN("Acknowledge sending failed on slave %i!\n",
-                slave->ring_position);
-        return;
-    }
-
-    start = get_cycles();
-    timeout = (cycles_t) 100 * cpu_khz; // 100ms
-
-    while (1) {
-        udelay(100); // wait a little bit...
-
-        if (ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2))
-            return;
-        if (unlikely(ec_master_simple_io(slave->master, datagram))) {
-            slave->current_state = EC_SLAVE_STATE_UNKNOWN;
-            EC_WARN("Acknowledge checking failed on slave %i!\n",
-                    slave->ring_position);
-            return;
-        }
-
-        end = get_cycles();
-
-        if (EC_READ_U8(datagram->data) == state) {
-            slave->current_state = state;
-            EC_INFO("Acknowleged state 0x%02X on slave %i.\n", state,
-                    slave->ring_position);
-            return;
-        }
-
-        if (end - start >= timeout) {
-            slave->current_state = EC_SLAVE_STATE_UNKNOWN;
-            EC_WARN("Failed to acknowledge state 0x%02X on slave %i"
-                    " - Timeout!\n", state, slave->ring_position);
-            return;
-        }
-    }
-}
-
-/*****************************************************************************/
-
-/**
-   Reads the AL status code of a slave and displays it.
-   If the AL status code is not supported, or if no error occurred (both
-   resulting in code = 0), nothing is displayed.
-*/
-
-void ec_slave_read_al_status_code(ec_slave_t *slave /**< EtherCAT slave */)
-{
-    ec_datagram_t *datagram;
-    uint16_t code;
-    const ec_code_msg_t *al_msg;
-
-    datagram = &slave->master->simple_datagram;
-
-    if (ec_datagram_nprd(datagram, slave->station_address, 0x0134, 2)) return;
-    if (unlikely(ec_master_simple_io(slave->master, datagram))) {
-        EC_WARN("Failed to read AL status code on slave %i!\n",
-                slave->ring_position);
-        return;
-    }
-
-    if (!(code = EC_READ_U16(datagram->data))) return;
-
-    for (al_msg = al_status_messages; al_msg->code; al_msg++) {
-        if (al_msg->code == code) {
-            EC_ERR("AL status message 0x%04X: \"%s\".\n",
-                   al_msg->code, al_msg->message);
-            return;
-        }
-    }
-
-    EC_ERR("Unknown AL status code 0x%04X.\n", code);
-}
-
-/*****************************************************************************/
-
-/**
-   Does a state transition.
-   \return 0 in case of success, else < 0
-*/
-
-int ec_slave_state_change(ec_slave_t *slave, /**< EtherCAT slave */
-                          uint8_t state /**< new state */
-                          )
-{
-    ec_datagram_t *datagram;
-    cycles_t start, end, timeout;
-
-    datagram = &slave->master->simple_datagram;
-
-    slave->requested_state = state;
-
-    if (ec_datagram_npwr(datagram, slave->station_address, 0x0120, 2))
-        return -1;
-    EC_WRITE_U16(datagram->data, state);
-    if (unlikely(ec_master_simple_io(slave->master, datagram))) {
-        EC_ERR("Failed to set state 0x%02X on slave %i!\n",
-               state, slave->ring_position);
-        return -1;
-    }
-
-    start = get_cycles();
-    timeout = (cycles_t) 10 * cpu_khz; // 10ms
-
-    while (1)
-    {
-        udelay(100); // wait a little bit
-
-        if (ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2))
-            return -1;
-        if (unlikely(ec_master_simple_io(slave->master, datagram))) {
-            slave->current_state = EC_SLAVE_STATE_UNKNOWN;
-            EC_ERR("Failed to check state 0x%02X on slave %i!\n",
-                   state, slave->ring_position);
-            return -1;
-        }
-
-        end = get_cycles();
-
-        if (unlikely(EC_READ_U8(datagram->data) & 0x10)) {
-            // state change error
-            EC_ERR("Failed to set state 0x%02X - Slave %i refused state change"
-                   " (code 0x%02X)!\n", state, slave->ring_position,
-                   EC_READ_U8(datagram->data));
-            slave->current_state = EC_READ_U8(datagram->data);
-            state = slave->current_state & 0x0F;
-            ec_slave_read_al_status_code(slave);
-            ec_slave_state_ack(slave, state);
-            return -1;
-        }
-
-        if (likely(EC_READ_U8(datagram->data) == (state & 0x0F))) {
-            slave->current_state = state;
-            return 0; // state change successful
-        }
-
-        if (unlikely((end - start) >= timeout)) {
-            slave->current_state = EC_SLAVE_STATE_UNKNOWN;
-            EC_ERR("Failed to check state 0x%02X of slave %i - Timeout!\n",
-                   state, slave->ring_position);
-            return -1;
-        }
-    }
-}
-
-/*****************************************************************************/
-
-/**
    Prepares an FMMU configuration.
    Configuration data for the FMMU is saved in the slave structure and is
    written to the slave in ecrt_master_activate().
    The FMMU configuration is done in a way, that the complete data range
-   of the corresponding sync manager is covered. Seperate FMMUs arce configured
+   of the corresponding sync manager is covered. Seperate FMMUs are configured
    for each domain.
    If the FMMU configuration is already prepared, the function returns with
    success.
@@ -1008,7 +465,7 @@
 
 int ec_slave_prepare_fmmu(ec_slave_t *slave, /**< EtherCAT slave */
                           const ec_domain_t *domain, /**< domain */
-                          const ec_sync_t *sync  /**< sync manager */
+                          const ec_sii_sync_t *sync  /**< sync manager */
                           )
 {
     unsigned int i;
@@ -1038,171 +495,152 @@
 
 /**
    Outputs all information about a certain slave.
-   Verbosity:
-   - 0: Only slave types and addresses
-   - 1: with EEPROM information
-   - >1: with SDO dictionaries
-*/
-
-void ec_slave_print(const ec_slave_t *slave, /**< EtherCAT slave */
-                    unsigned int verbosity /**< verbosity level */
-                    )
-{
-    ec_eeprom_sync_t *sync;
-    ec_eeprom_pdo_t *pdo;
-    ec_eeprom_pdo_entry_t *pdo_entry;
-    ec_sdo_t *sdo;
-    ec_sdo_entry_t *sdo_entry;
+*/
+
+size_t ec_slave_info(const ec_slave_t *slave, /**< EtherCAT slave */
+                     char *buffer /**< Output buffer */
+                     )
+{
+    off_t off = 0;
+    ec_sii_sync_t *sync;
+    ec_sii_pdo_t *pdo;
+    ec_sii_pdo_entry_t *pdo_entry;
     int first, i;
 
-    if (slave->type) {
-        EC_INFO("%i) %s %s: %s\n", slave->ring_position,
-                slave->type->vendor_name, slave->type->product_name,
-                slave->type->description);
-    }
-    else {
-        EC_INFO("%i) UNKNOWN SLAVE: vendor 0x%08X, product 0x%08X\n",
-                slave->ring_position, slave->sii_vendor_id,
-                slave->sii_product_code);
-    }
-
-    if (!verbosity) return;
-
-    EC_INFO("  Station address: 0x%04X\n", slave->station_address);
-
-    EC_INFO("  Data link status:\n");
+    off += sprintf(buffer + off, "\nName: ");
+
+    if (slave->sii_name)
+        off += sprintf(buffer + off, "%s", slave->sii_name);
+
+    off += sprintf(buffer + off, "\n\nVendor ID: 0x%08X\n",
+                   slave->sii_vendor_id);
+    off += sprintf(buffer + off, "Product code: 0x%08X\n\n",
+                   slave->sii_product_code);
+
+    off += sprintf(buffer + off, "Ring position: %i\n", slave->ring_position);
+    off += sprintf(buffer + off, "Advanced position: %i:%i\n\n",
+                   slave->coupler_index, slave->coupler_subindex);
+
+    off += sprintf(buffer + off, "State: ");
+    off += ec_state_string(slave->current_state, buffer + off);
+    off += sprintf(buffer + off, "\n\n");
+
+    off += sprintf(buffer + off, "Data link status:\n");
     for (i = 0; i < 4; i++) {
-        EC_INFO("    Port %i (", i);
+        off += sprintf(buffer + off, "  Port %i (", i);
         switch (slave->sii_physical_layer[i]) {
             case 0x00:
-                printk("EBUS");
+                off += sprintf(buffer + off, "EBUS");
                 break;
             case 0x01:
-                printk("100BASE-TX");
+                off += sprintf(buffer + off, "100BASE-TX");
                 break;
             case 0x02:
-                printk("100BASE-FX");
+                off += sprintf(buffer + off, "100BASE-FX");
                 break;
             default:
-                printk("unknown");
-        }
-        printk(")\n");
-        EC_INFO("      link %s, loop %s, %s\n",
-                slave->dl_link[i] ? "up" : "down",
-                slave->dl_loop[i] ? "closed" : "open",
-                slave->dl_signal[i] ? "signal detected" : "no signal");
-    }
-
-    EC_INFO("  Base information:\n");
-    EC_INFO("    Type %u, revision %i, build %i\n",
-            slave->base_type, slave->base_revision, slave->base_build);
-    EC_INFO("    Supported FMMUs: %i, sync managers: %i\n",
-            slave->base_fmmu_count, slave->base_sync_count);
+                off += sprintf(buffer + off, "unknown (%i)",
+                               slave->sii_physical_layer[i]);
+        }
+        off += sprintf(buffer + off, ") Link %s, Loop %s, %s\n",
+                       slave->dl_link[i] ? "up" : "down",
+                       slave->dl_loop[i] ? "closed" : "open",
+                       slave->dl_signal[i] ? "Signal detected" : "No signal");
+    }
 
     if (slave->sii_mailbox_protocols) {
-        EC_INFO("  Mailbox communication:\n");
-        EC_INFO("    RX mailbox: 0x%04X/%i, TX mailbox: 0x%04X/%i\n",
-                slave->sii_rx_mailbox_offset, slave->sii_rx_mailbox_size,
-                slave->sii_tx_mailbox_offset, slave->sii_tx_mailbox_size);
-        EC_INFO("    Supported protocols: ");
+        off += sprintf(buffer + off, "\nMailboxes:\n");
+        off += sprintf(buffer + off, "  RX mailbox: 0x%04X/%i,"
+                       " TX mailbox: 0x%04X/%i\n",
+                       slave->sii_rx_mailbox_offset,
+                       slave->sii_rx_mailbox_size,
+                       slave->sii_tx_mailbox_offset,
+                       slave->sii_tx_mailbox_size);
+        off += sprintf(buffer + off, "  Supported protocols: ");
 
         first = 1;
         if (slave->sii_mailbox_protocols & EC_MBOX_AOE) {
-            printk("AoE");
+            off += sprintf(buffer + off, "AoE");
             first = 0;
         }
         if (slave->sii_mailbox_protocols & EC_MBOX_EOE) {
-            if (!first) printk(", ");
-            printk("EoE");
+            if (!first) off += sprintf(buffer + off, ", ");
+            off += sprintf(buffer + off, "EoE");
             first = 0;
         }
         if (slave->sii_mailbox_protocols & EC_MBOX_COE) {
-            if (!first) printk(", ");
-            printk("CoE");
+            if (!first) off += sprintf(buffer + off, ", ");
+            off += sprintf(buffer + off, "CoE");
             first = 0;
         }
         if (slave->sii_mailbox_protocols & EC_MBOX_FOE) {
-            if (!first) printk(", ");
-            printk("FoE");
+            if (!first) off += sprintf(buffer + off, ", ");
+            off += sprintf(buffer + off, "FoE");
             first = 0;
         }
         if (slave->sii_mailbox_protocols & EC_MBOX_SOE) {
-            if (!first) printk(", ");
-            printk("SoE");
+            if (!first) off += sprintf(buffer + off, ", ");
+            off += sprintf(buffer + off, "SoE");
             first = 0;
         }
         if (slave->sii_mailbox_protocols & EC_MBOX_VOE) {
-            if (!first) printk(", ");
-            printk("VoE");
-        }
-        printk("\n");
-    }
-
-    EC_INFO("  EEPROM data:\n");
-
-    EC_INFO("    EEPROM content size: %i Bytes\n", slave->eeprom_size);
+            if (!first) off += sprintf(buffer + off, ", ");
+            off += sprintf(buffer + off, "VoE");
+        }
+        off += sprintf(buffer + off, "\n");
+    }
+
+    if (slave->sii_alias || slave->sii_group
+        || slave->sii_image || slave->sii_order)
+        off += sprintf(buffer + off, "\nSII data:\n");
 
     if (slave->sii_alias)
-        EC_INFO("    Configured station alias: 0x%04X (%i)\n",
-                slave->sii_alias, slave->sii_alias);
-
-    EC_INFO("    Vendor-ID: 0x%08X, Product code: 0x%08X\n",
-            slave->sii_vendor_id, slave->sii_product_code);
-    EC_INFO("    Revision number: 0x%08X, Serial number: 0x%08X\n",
-            slave->sii_revision_number, slave->sii_serial_number);
-
-    if (slave->eeprom_group)
-        EC_INFO("    Group: %s\n", slave->eeprom_group);
-    if (slave->eeprom_image)
-        EC_INFO("    Image: %s\n", slave->eeprom_image);
-    if (slave->eeprom_order)
-        EC_INFO("    Order#: %s\n", slave->eeprom_order);
-    if (slave->eeprom_name)
-        EC_INFO("    Name: %s\n", slave->eeprom_name);
-
-    if (!list_empty(&slave->eeprom_syncs)) {
-        EC_INFO("    Sync-Managers:\n");
-        list_for_each_entry(sync, &slave->eeprom_syncs, list) {
-            EC_INFO("      %i: 0x%04X, length %i, control 0x%02X, %s\n",
-                    sync->index, sync->physical_start_address,
-                    sync->length, sync->control_register,
-                    sync->enable ? "enable" : "disable");
-        }
-    }
-
-    list_for_each_entry(pdo, &slave->eeprom_pdos, list) {
-        EC_INFO("    %s \"%s\" (0x%04X), -> Sync-Manager %i\n",
-                pdo->type == EC_RX_PDO ? "RXPDO" : "TXPDO",
-                pdo->name ? pdo->name : "???",
-                pdo->index, pdo->sync_manager);
+        off += sprintf(buffer + off, "  Configured station alias:"
+                       " 0x%04X (%i)\n", slave->sii_alias, slave->sii_alias);
+    if (slave->sii_group)
+        off += sprintf(buffer + off, "  Group: %s\n", slave->sii_group);
+    if (slave->sii_image)
+        off += sprintf(buffer + off, "  Image: %s\n", slave->sii_image);
+    if (slave->sii_order)
+        off += sprintf(buffer + off, "  Order#: %s\n", slave->sii_order);
+
+    if (!list_empty(&slave->sii_syncs))
+        off += sprintf(buffer + off, "\nSync-Managers:\n");
+
+    list_for_each_entry(sync, &slave->sii_syncs, list) {
+        off += sprintf(buffer + off, "  %i: 0x%04X, length %i,"
+                       " control 0x%02X, %s\n",
+                       sync->index, sync->physical_start_address,
+                       sync->length, sync->control_register,
+                       sync->enable ? "enable" : "disable");
+    }
+
+    if (!list_empty(&slave->sii_pdos))
+        off += sprintf(buffer + off, "\nPDOs:\n");
+
+    list_for_each_entry(pdo, &slave->sii_pdos, list) {
+        off += sprintf(buffer + off,
+                       "  %s \"%s\" (0x%04X), -> Sync-Manager %i\n",
+                       pdo->type == EC_RX_PDO ? "RXPDO" : "TXPDO",
+                       pdo->name ? pdo->name : "???",
+                       pdo->index, pdo->sync_index);
 
         list_for_each_entry(pdo_entry, &pdo->entries, list) {
-            EC_INFO("      \"%s\" 0x%04X:%X, %i Bit\n",
-                    pdo_entry->name ? pdo_entry->name : "???",
-                    pdo_entry->index, pdo_entry->subindex,
-                    pdo_entry->bit_length);
-        }
-    }
-
-    if (verbosity < 2) return;
-
-    if (!list_empty(&slave->sdo_dictionary)) {
-        EC_INFO("    SDO-Dictionary:\n");
-        list_for_each_entry(sdo, &slave->sdo_dictionary, list) {
-            EC_INFO("      0x%04X \"%s\"\n", sdo->index,
-                    sdo->name ? sdo->name : "");
-            EC_INFO("        Object code: 0x%02X\n", sdo->object_code);
-            list_for_each_entry(sdo_entry, &sdo->entries, list) {
-                EC_INFO("        0x%04X:%i \"%s\", type 0x%04X, %i bits\n",
-                        sdo->index, sdo_entry->subindex,
-                        sdo_entry->name ? sdo_entry->name : "",
-                        sdo_entry->data_type, sdo_entry->bit_length);
-            }
-        }
-    }
-}
-
-/*****************************************************************************/
+            off += sprintf(buffer + off, "    \"%s\" 0x%04X:%X, %i Bit\n",
+                           pdo_entry->name ? pdo_entry->name : "???",
+                           pdo_entry->index, pdo_entry->subindex,
+                           pdo_entry->bit_length);
+        }
+    }
+
+    off += sprintf(buffer + off, "\n");
+
+    return off;
+}
+
+/*****************************************************************************/
+
+#if 0
 
 /**
    Outputs the values of the CRC faoult counters and resets them.
@@ -1259,6 +697,8 @@
     return 0;
 }
 
+#endif
+
 /*****************************************************************************/
 
 /**
@@ -1350,38 +790,8 @@
 {
     ec_slave_t *slave = container_of(kobj, ec_slave_t, kobj);
 
-    if (attr == &attr_ring_position) {
-        return sprintf(buffer, "%i\n", slave->ring_position);
-    }
-    else if (attr == &attr_advanced_position) {
-        return sprintf(buffer, "%i:%i\n", slave->coupler_index,
-                       slave->coupler_subindex);
-    }
-    else if (attr == &attr_vendor_name) {
-        if (slave->type)
-            return sprintf(buffer, "%s\n", slave->type->vendor_name);
-    }
-    else if (attr == &attr_product_name) {
-        if (slave->type)
-            return sprintf(buffer, "%s\n", slave->type->product_name);
-    }
-    else if (attr == &attr_product_desc) {
-        if (slave->type)
-            return sprintf(buffer, "%s\n", slave->type->description);
-    }
-    else if (attr == &attr_name) {
-        if (slave->eeprom_name)
-            return sprintf(buffer, "%s\n", slave->eeprom_name);
-    }
-    else if (attr == &attr_type) {
-        if (slave->type) {
-            if (slave->type->special == EC_TYPE_BUS_COUPLER)
-                return sprintf(buffer, "coupler\n");
-	    else if (slave->type->special == EC_TYPE_INFRA)
-                return sprintf(buffer, "infrastructure\n");
-            else
-                return sprintf(buffer, "normal\n");
-        }
+    if (attr == &attr_info) {
+        return ec_slave_info(slave, buffer);
     }
     else if (attr == &attr_state) {
         switch (slave->current_state) {
@@ -1459,62 +869,25 @@
 /*****************************************************************************/
 
 /**
-   \return size of sync manager contents
-*/
-
-size_t ec_slave_calc_sync_size(const ec_slave_t *slave, /**< EtherCAT slave */
-                               const ec_sync_t *sync /**< sync manager */
-                               )
-{
-    unsigned int i, found;
-    const ec_field_t *field;
-    const ec_varsize_t *var;
-    size_t size;
-
-    // if size is specified, return size
-    if (sync->size) return sync->size;
-
-    // sync manager has variable size (size == 0).
-
-    size = 0;
-    for (i = 0; (field = sync->fields[i]); i++) {
-        found = 0;
-        list_for_each_entry(var, &slave->varsize_fields, list) {
-            if (var->field != field) continue;
-            size += var->size;
-            found = 1;
-        }
-
-        if (!found) {
-            EC_WARN("Variable data field \"%s\" of slave %i has no size"
-                    " information!\n", field->name, slave->ring_position);
-        }
-    }
-    return size;
-}
-
-/*****************************************************************************/
-
-/**
    Calculates the size of a sync manager by evaluating PDO sizes.
    \return sync manager size
 */
 
-uint16_t ec_slave_calc_eeprom_sync_size(const ec_slave_t *slave,
-                                        /**< EtherCAT slave */
-                                        const ec_eeprom_sync_t *sync
-                                        /**< sync manager */
-                                        )
-{
-    ec_eeprom_pdo_t *pdo;
-    ec_eeprom_pdo_entry_t *pdo_entry;
+uint16_t ec_slave_calc_sync_size(const ec_slave_t *slave,
+                                 /**< EtherCAT slave */
+                                 const ec_sii_sync_t *sync
+                                 /**< sync manager */
+                                 )
+{
+    ec_sii_pdo_t *pdo;
+    ec_sii_pdo_entry_t *pdo_entry;
     unsigned int bit_size;
 
     if (sync->length) return sync->length;
 
     bit_size = 0;
-    list_for_each_entry(pdo, &slave->eeprom_pdos, list) {
-        if (pdo->sync_manager != sync->index) continue;
+    list_for_each_entry(pdo, &slave->sii_pdos, list) {
+        if (pdo->sync_index != sync->index) continue;
 
         list_for_each_entry(pdo_entry, &pdo->entries, list) {
             bit_size += pdo_entry->bit_length;
@@ -1527,39 +900,41 @@
         return bit_size / 8;
 }
 
+/*****************************************************************************/
+
+/**
+   \return non-zero if slave is a bus coupler
+*/
+
+int ec_slave_is_coupler(const ec_slave_t *slave)
+{
+    // TODO: Better bus coupler criterion
+    return slave->sii_vendor_id == 0x00000002
+        && slave->sii_product_code == 0x044C2C52;
+}
+
 /******************************************************************************
  *  Realtime interface
  *****************************************************************************/
 
 /**
-   Writes the "configured station alias" to the slave's EEPROM.
    \return 0 in case of success, else < 0
    \ingroup RealtimeInterface
 */
 
-int ecrt_slave_write_alias(ec_slave_t *slave, /**< EtherCAT slave */
-                           uint16_t alias /**< new alias */
-                           )
-{
-    return ec_slave_sii_write16(slave, 0x0004, alias);
-}
-
-/*****************************************************************************/
-
-/**
-   \return 0 in case of success, else < 0
-   \ingroup RealtimeInterface
-*/
-
-int ecrt_slave_field_size(ec_slave_t *slave, /**< EtherCAT slave */
-                          const char *field_name, /**< data field name */
-                          unsigned int field_index, /**< data field index */
-                          size_t size /**< new data field size */
-                          )
-{
+int ecrt_slave_pdo_size(ec_slave_t *slave, /**< EtherCAT slave */
+                        uint16_t pdo_index, /**< PDO index */
+                        uint8_t pdo_subindex, /**< PDO subindex */
+                        size_t size /**< new PDO size */
+                        )
+{
+    EC_WARN("ecrt_slave_pdo_size() currently not available.\n");
+    return -1;
+
+#if 0
     unsigned int i, j, field_counter;
-    const ec_sync_t *sync;
-    const ec_field_t *field;
+    const ec_sii_sync_t *sync;
+    const ec_pdo_t *pdo;
     ec_varsize_t *var;
 
     if (!slave->type) {
@@ -1607,14 +982,14 @@
            slave->ring_position, slave->type->vendor_name,
            slave->type->product_name, field_name, field_index);
     return -1;
+#endif
 }
 
 /*****************************************************************************/
 
 /**< \cond */
 
-EXPORT_SYMBOL(ecrt_slave_write_alias);
-EXPORT_SYMBOL(ecrt_slave_field_size);
+EXPORT_SYMBOL(ecrt_slave_pdo_size);
 
 /**< \endcond */
 
--- a/master/slave.h	Wed Aug 02 23:16:10 2006 +0000
+++ b/master/slave.h	Thu Aug 03 12:51:17 2006 +0000
@@ -44,9 +44,10 @@
 #include <linux/list.h>
 #include <linux/kobject.h>
 
+#include "../include/ecrt.h"
+
 #include "globals.h"
 #include "datagram.h"
-#include "types.h"
 
 /*****************************************************************************/
 
@@ -90,20 +91,6 @@
 /*****************************************************************************/
 
 /**
-   FMMU configuration.
-*/
-
-typedef struct
-{
-    const ec_domain_t *domain; /**< domain */
-    const ec_sync_t *sync; /**< sync manager */
-    uint32_t logical_start_address; /**< logical start address */
-}
-ec_fmmu_t;
-
-/*****************************************************************************/
-
-/**
    String object (EEPROM).
 */
 
@@ -113,7 +100,7 @@
     size_t size; /**< size in bytes */
     char *data; /**< string data */
 }
-ec_eeprom_string_t;
+ec_sii_string_t;
 
 /*****************************************************************************/
 
@@ -130,7 +117,7 @@
     uint8_t control_register; /**< control register value */
     uint8_t enable; /**< enable bit */
 }
-ec_eeprom_sync_t;
+ec_sii_sync_t;
 
 /*****************************************************************************/
 
@@ -143,7 +130,7 @@
     EC_RX_PDO, /**< Reveive PDO */
     EC_TX_PDO /**< Transmit PDO */
 }
-ec_pdo_type_t;
+ec_sii_pdo_type_t;
 
 /*****************************************************************************/
 
@@ -154,13 +141,13 @@
 typedef struct
 {
     struct list_head list; /**< list item */
-    ec_pdo_type_t type; /**< PDO type */
+    ec_sii_pdo_type_t type; /**< PDO type */
     uint16_t index; /**< PDO index */
-    uint8_t sync_manager; /**< assigned sync manager */
+    uint8_t sync_index; /**< assigned sync manager */
     char *name; /**< PDO name */
     struct list_head entries; /**< entry list */
 }
-ec_eeprom_pdo_t;
+ec_sii_pdo_t;
 
 /*****************************************************************************/
 
@@ -176,7 +163,7 @@
     char *name; /**< entry name */
     uint8_t bit_length; /**< entry length in bit */
 }
-ec_eeprom_pdo_entry_t;
+ec_sii_pdo_entry_t;
 
 /*****************************************************************************/
 
@@ -188,7 +175,6 @@
 {
     struct list_head list; /**< list item */
     uint16_t index; /**< SDO index */
-    //uint16_t type;
     uint8_t object_code; /**< object code */
     char *name; /**< SDO name */
     struct list_head entries; /**< entry list */
@@ -214,13 +200,27 @@
 /*****************************************************************************/
 
 /**
+   FMMU configuration.
+*/
+
+typedef struct
+{
+    const ec_domain_t *domain; /**< domain */
+    const ec_sii_sync_t *sync; /**< sync manager */
+    uint32_t logical_start_address; /**< logical start address */
+}
+ec_fmmu_t;
+
+/*****************************************************************************/
+
+/**
    Variable-sized field information.
 */
 
 typedef struct
 {
     struct list_head list; /**< list item */
-    const ec_field_t *field; /**< data field */
+    const ec_sii_pdo_t *pdo; /**< PDO */
     size_t size; /**< field size */
 }
 ec_varsize_t;
@@ -237,6 +237,12 @@
     struct kobject kobj; /**< kobject */
     ec_master_t *master; /**< master owning the slave */
 
+    ec_slave_state_t requested_state; /**< requested slave state */
+    ec_slave_state_t current_state; /**< current slave state */
+    unsigned int error_flag; /**< stop processing after an error */
+    unsigned int online; /**< non-zero, if the slave responds. */
+    uint8_t registered; /**< true, if slave has been registered */
+
     // addresses
     uint16_t ring_position; /**< ring position */
     uint16_t station_address; /**< configured station address */
@@ -255,6 +261,12 @@
     uint8_t dl_loop[4]; /**< loop closed */
     uint8_t dl_signal[4]; /**< detected signal on RX port */
 
+    // EEPROM
+    uint8_t *eeprom_data; /**< Complete EEPROM image */
+    uint16_t eeprom_size; /**< size of the EEPROM contents in byte */
+    uint16_t *new_eeprom_data; /**< new EEPROM data to write */
+    uint16_t new_eeprom_size; /**< size of new EEPROM data in words */
+
     // slave information interface
     uint16_t sii_alias; /**< configured station alias */
     uint32_t sii_vendor_id; /**< vendor id */
@@ -267,34 +279,19 @@
     uint16_t sii_tx_mailbox_size; /**< mailbox size (slave to master) */
     uint16_t sii_mailbox_protocols; /**< supported mailbox protocols */
     uint8_t sii_physical_layer[4]; /**< port media */
-
-    const ec_slave_type_t *type; /**< pointer to slave type object */
-
-    uint8_t registered; /**< true, if slave has been registered */
+    struct list_head sii_strings; /**< EEPROM STRING categories */
+    struct list_head sii_syncs; /**< EEPROM SYNC MANAGER categories */
+    struct list_head sii_pdos; /**< EEPROM [RT]XPDO categories */
+    char *sii_group; /**< slave group acc. to EEPROM */
+    char *sii_image; /**< slave image name acc. to EEPROM */
+    char *sii_order; /**< slave order number acc. to EEPROM */
+    char *sii_name; /**< slave name acc. to EEPROM */
 
     ec_fmmu_t fmmus[EC_MAX_FMMUS]; /**< FMMU configurations */
     uint8_t fmmu_count; /**< number of FMMUs used */
 
-    uint8_t *eeprom_data; /**< Complete EEPROM image */
-    uint16_t eeprom_size; /**< size of the EEPROM contents in byte */
-    struct list_head eeprom_strings; /**< EEPROM STRING categories */
-    struct list_head eeprom_syncs; /**< EEPROM SYNC MANAGER categories */
-    struct list_head eeprom_pdos; /**< EEPROM [RT]XPDO categories */
-    char *eeprom_group; /**< slave group acc. to EEPROM */
-    char *eeprom_image; /**< slave image name acc. to EEPROM */
-    char *eeprom_order; /**< slave order number acc. to EEPROM */
-    char *eeprom_name; /**< slave name acc. to EEPROM */
-
-    uint16_t *new_eeprom_data; /**< new EEPROM data to write */
-    size_t new_eeprom_size; /**< size of new EEPROM data in words */
-
     struct list_head sdo_dictionary; /**< SDO directory list */
 
-    ec_slave_state_t requested_state; /**< requested slave state */
-    ec_slave_state_t current_state; /**< current slave state */
-    unsigned int error_flag; /**< stop processing after an error */
-    unsigned int online; /**< non-zero, if the slave responds. */
-
     struct list_head varsize_fields; /**< size information for variable-sized
                                         data fields. */
 };
@@ -305,32 +302,27 @@
 int ec_slave_init(ec_slave_t *, ec_master_t *, uint16_t, uint16_t);
 void ec_slave_clear(struct kobject *);
 
-// slave control
-int ec_slave_fetch(ec_slave_t *);
-int ec_slave_sii_read16(ec_slave_t *, uint16_t, uint16_t *);
-int ec_slave_sii_read32(ec_slave_t *, uint16_t, uint32_t *);
-int ec_slave_sii_write16(ec_slave_t *, uint16_t, uint16_t);
-int ec_slave_state_change(ec_slave_t *, uint8_t);
 int ec_slave_prepare_fmmu(ec_slave_t *, const ec_domain_t *,
-                          const ec_sync_t *);
+                          const ec_sii_sync_t *);
 
 // CoE
-int ec_slave_fetch_sdo_list(ec_slave_t *);
-
-// state machine
+//int ec_slave_fetch_sdo_list(ec_slave_t *);
+
+// SII categories
 int ec_slave_fetch_strings(ec_slave_t *, const uint8_t *);
-int ec_slave_fetch_general(ec_slave_t *, const uint8_t *);
+void ec_slave_fetch_general(ec_slave_t *, const uint8_t *);
 int ec_slave_fetch_sync(ec_slave_t *, const uint8_t *, size_t);
-int ec_slave_fetch_pdo(ec_slave_t *, const uint8_t *, size_t, ec_pdo_type_t);
+int ec_slave_fetch_pdo(ec_slave_t *, const uint8_t *, size_t,
+                       ec_sii_pdo_type_t);
 int ec_slave_locate_string(ec_slave_t *, unsigned int, char **);
 
 // misc.
-size_t ec_slave_calc_sync_size(const ec_slave_t *, const ec_sync_t *);
-uint16_t ec_slave_calc_eeprom_sync_size(const ec_slave_t *,
-                                        const ec_eeprom_sync_t *);
+uint16_t ec_slave_calc_sync_size(const ec_slave_t *,
+                                 const ec_sii_sync_t *);
 
 void ec_slave_print(const ec_slave_t *, unsigned int);
-int ec_slave_check_crc(ec_slave_t *);
+int ec_slave_is_coupler(const ec_slave_t *);
+//int ec_slave_check_crc(ec_slave_t *);
 
 /*****************************************************************************/
 
--- a/master/types.c	Wed Aug 02 23:16:10 2006 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,280 +0,0 @@
-/******************************************************************************
- *
- *  $Id$
- *
- *  Copyright (C) 2006  Florian Pose, Ingenieurgemeinschaft IgH
- *
- *  This file is part of the IgH EtherCAT Master.
- *
- *  The IgH EtherCAT Master is free software; you can redistribute it
- *  and/or modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2 of the
- *  License, or (at your option) any later version.
- *
- *  The IgH EtherCAT Master is distributed in the hope that it will be
- *  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with the IgH EtherCAT Master; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- *  The right to use EtherCAT Technology is granted and comes free of
- *  charge under condition of compatibility of product made by
- *  Licensee. People intending to distribute/sell products based on the
- *  code, have to sign an agreement to guarantee that products using
- *  software based on IgH EtherCAT master stay compatible with the actual
- *  EtherCAT specification (which are released themselves as an open
- *  standard) as the (only) precondition to have the right to use EtherCAT
- *  Technology, IP and trade marks.
- *
- *****************************************************************************/
-
-/**
-   \file
-   EtherCAT slave descriptions.
-   \cond
-*/
-
-/*****************************************************************************/
-
-#include <linux/module.h>
-
-#include "globals.h"
-#include "types.h"
-
-/*****************************************************************************/
-
-const ec_sync_t mailbox_sm0 = {0x1800, 246, 0x26, {NULL}};
-const ec_sync_t mailbox_sm1 = {0x18F6, 246, 0x22, {NULL}};
-
-/******************************************************************************
- *  slave objects
- *****************************************************************************/
-
-const ec_slave_type_t Beckhoff_EK1100 = {
-    "Beckhoff", "EK1100", "Bus Coupler", EC_TYPE_BUS_COUPLER,
-    {NULL} // no sync managers
-};
-
-/*****************************************************************************/
-
-const ec_slave_type_t Beckhoff_EK1110 = {
-    "Beckhoff", "EK1110", "Extension terminal", EC_TYPE_INFRA,
-    {NULL} // no sync managers
-};
-
-/*****************************************************************************/
-
-const ec_field_t bk1120_out = {"Outputs", 0}; // variable size
-const ec_field_t bk1120_in = {"Inputs", 0}; // variable size
-
-const ec_sync_t bk1120_sm0 = {0x1C00, 264, 0x26, {NULL}};
-const ec_sync_t bk1120_sm1 = {0x1E00, 264, 0x22, {NULL}};
-
-const ec_sync_t bk1120_sm2 = { // outputs
-    0x1000, 0, 0x24, // variable size
-    {&bk1120_out, NULL}
-};
-
-const ec_sync_t bk1120_sm3 = { // inputs
-    0x1600, 0, 0x00, // variable size
-    {&bk1120_in, NULL}
-};
-
-const ec_slave_type_t Beckhoff_BK1120 = {
-    "Beckhoff", "BK1120", "KBUS Coupler", EC_TYPE_NORMAL,
-    {&bk1120_sm0, &bk1120_sm1, &bk1120_sm2, &bk1120_sm3, NULL}
-};
-
-/*****************************************************************************/
-
-const ec_field_t el1004_in = {"InputValue", 1};
-
-const ec_sync_t el1004_sm0 = { // inputs
-    0x1000, 1, 0x00,
-    {&el1004_in, NULL}
-};
-
-const ec_slave_type_t Beckhoff_EL1004 = {
-    "Beckhoff", "EL1004", "4x Digital Input, 3ms", EC_TYPE_NORMAL,
-    {&el1004_sm0, NULL}
-};
-
-/*****************************************************************************/
-
-const ec_field_t el1014_in = {"InputValue", 1};
-
-const ec_sync_t el1014_sm0 = { // inputs
-    0x1000, 1, 0x00,
-    {&el1014_in, NULL}
-};
-
-const ec_slave_type_t Beckhoff_EL1014 = {
-    "Beckhoff", "EL1014", "4x Digital Input, 10us", EC_TYPE_NORMAL,
-    {&el1014_sm0, NULL}
-};
-
-/*****************************************************************************/
-
-const ec_field_t el20XX_out = {"OutputValue", 1};
-
-const ec_sync_t el20XX_sm0 = {
-    0x0F00, 1, 0x46,
-    {&el20XX_out, NULL}
-};
-
-const ec_slave_type_t Beckhoff_EL2004 = {
-    "Beckhoff", "EL2004", "4x Digital Output", EC_TYPE_NORMAL,
-    {&el20XX_sm0, NULL}
-};
-
-const ec_slave_type_t Beckhoff_EL2032 = {
-    "Beckhoff", "EL2032", "2x Digital Output (2A)", EC_TYPE_NORMAL,
-    {&el20XX_sm0, NULL}
-};
-
-/*****************************************************************************/
-
-const ec_field_t el31X2_st1 = {"Status",     1};
-const ec_field_t el31X2_ip1 = {"InputValue", 2};
-const ec_field_t el31X2_st2 = {"Status",     1};
-const ec_field_t el31X2_ip2 = {"InputValue", 2};
-
-const ec_sync_t el31X2_sm2 = {0x1000, 4, 0x24, {NULL}};
-
-const ec_sync_t el31X2_sm3 = {
-    0x1100, 6, 0x20,
-    {&el31X2_st1, &el31X2_ip1, &el31X2_st2, &el31X2_ip2, NULL}
-};
-
-const ec_slave_type_t Beckhoff_EL3102 = {
-    "Beckhoff", "EL3102", "2x Analog Input diff.", EC_TYPE_NORMAL,
-    {&mailbox_sm0, &mailbox_sm1, &el31X2_sm2, &el31X2_sm3, NULL}
-};
-
-const ec_slave_type_t Beckhoff_EL3162 = {
-    "Beckhoff", "EL3162", "2x Analog Input", EC_TYPE_NORMAL,
-    {&mailbox_sm0, &mailbox_sm1, &el31X2_sm2, &el31X2_sm3, NULL}
-};
-
-/*****************************************************************************/
-
-const ec_field_t el41X2_op = {"OutputValue", 2};
-
-const ec_sync_t el41X2_sm2 = {
-    0x1000, 4, 0x24,
-    {&el41X2_op, &el41X2_op, NULL}
-};
-
-const ec_slave_type_t Beckhoff_EL4102 = {
-    "Beckhoff", "EL4102", "2x Analog Output", EC_TYPE_NORMAL,
-    {&mailbox_sm0, &mailbox_sm1, &el41X2_sm2, NULL}
-};
-
-const ec_slave_type_t Beckhoff_EL4132 = {
-    "Beckhoff", "EL4132", "2x Analog Output diff.", EC_TYPE_NORMAL,
-    {&mailbox_sm0, &mailbox_sm1, &el41X2_sm2, NULL}
-};
-
-/*****************************************************************************/
-
-const ec_field_t el5001_st = {"Status",     1};
-const ec_field_t el5001_ip = {"InputValue", 4};
-
-const ec_sync_t el5001_sm2 = {
-    0x1000, 4, 0x24,
-    {NULL}
-};
-
-const ec_sync_t el5001_sm3 = {
-    0x1100, 5, 0x20,
-    {&el5001_st, &el5001_ip, NULL}
-};
-
-const ec_slave_type_t Beckhoff_EL5001 = {
-    "Beckhoff", "EL5001", "SSI-Interface", EC_TYPE_NORMAL,
-    {&mailbox_sm0, &mailbox_sm1, &el5001_sm2, &el5001_sm3, NULL}
-};
-
-/*****************************************************************************/
-
-const ec_field_t el5101_ct = {"Control",     1};
-const ec_field_t el5101_op = {"OutputValue", 2};
-const ec_field_t el5101_st = {"Status",      1};
-const ec_field_t el5101_ip = {"InputValue",  2};
-const ec_field_t el5101_la = {"LatchValue",  2};
-
-const ec_sync_t el5101_sm2 = {
-    0x1000, 3, 0x24,
-    {&el5101_ct, &el5101_op, NULL}
-};
-
-const ec_sync_t el5101_sm3 = {
-    0x1100, 5, 0x20,
-    {&el5101_st, &el5101_ip, &el5101_la, NULL}
-};
-
-const ec_slave_type_t Beckhoff_EL5101 = {
-    "Beckhoff", "EL5101", "Incremental Encoder Interface", EC_TYPE_NORMAL,
-    {&mailbox_sm0, &mailbox_sm1, &el5101_sm2, &el5101_sm3, NULL}
-};
-
-/*****************************************************************************/
-
-const ec_sync_t el6601_sm0 = {0x1800, 522, 0x26, {NULL}};
-const ec_sync_t el6601_sm1 = {0x1C00, 522, 0x22, {NULL}};
-
-const ec_slave_type_t Beckhoff_EL6601 = {
-    "Beckhoff", "EL6601", "1-Port Ethernet Switch Terminal", EC_TYPE_EOE,
-    {&el6601_sm0, &el6601_sm1, NULL, NULL, NULL}
-};
-
-/*****************************************************************************/
-
-const ec_field_t trlinenc2_st = {"Status",     1};
-const ec_field_t trlinenc2_ip = {"InputValue", 4};
-
-const ec_sync_t trlinenc2_sm0 = {0x1800, 192, 0x26, {NULL}};
-const ec_sync_t trlinenc2_sm1 = {0x1C00, 192, 0x22, {NULL}};
-const ec_sync_t trlinenc2_sm2 = {0x1000,   4, 0x24, {NULL}};
-
-const ec_sync_t trlinenc2_sm3 = {
-    0x1100, 5, 0x20,
-    {&trlinenc2_st, &trlinenc2_ip, NULL}
-};
-
-const ec_slave_type_t TR_Electronic_LinEnc2 = {
-    "TR-Electronic", "LinEnc2", "SSI-Encoder", EC_TYPE_NORMAL,
-    {&trlinenc2_sm0, &trlinenc2_sm1, &trlinenc2_sm2, &trlinenc2_sm3, NULL}
-};
-
-/** \endcond */
-
-/*****************************************************************************/
-
-/**
-   Mapping between vendor IDs and product codes <=> slave objects.
-*/
-
-ec_slave_ident_t slave_idents[] = {
-    {0x00000002, 0x03EC3052, &Beckhoff_EL1004},
-    {0x00000002, 0x03F63052, &Beckhoff_EL1014},
-    {0x00000002, 0x044C2C52, &Beckhoff_EK1100},
-    {0x00000002, 0x04562C52, &Beckhoff_EK1110},
-    {0x00000002, 0x04602C22, &Beckhoff_BK1120},
-    {0x00000002, 0x07D43052, &Beckhoff_EL2004},
-    {0x00000002, 0x07F03052, &Beckhoff_EL2032},
-    {0x00000002, 0x0C1E3052, &Beckhoff_EL3102},
-    {0x00000002, 0x0C5A3052, &Beckhoff_EL3162},
-    {0x00000002, 0x10063052, &Beckhoff_EL4102},
-    {0x00000002, 0x10243052, &Beckhoff_EL4132},
-    {0x00000002, 0x13893052, &Beckhoff_EL5001},
-    {0x00000002, 0x13ED3052, &Beckhoff_EL5101},
-    {0x00000002, 0x19C93052, &Beckhoff_EL6601},
-    {0x000000D4, 0x00000017, &TR_Electronic_LinEnc2},
-    {}
-};
-
-/*****************************************************************************/
--- a/master/types.h	Wed Aug 02 23:16:10 2006 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,130 +0,0 @@
-/******************************************************************************
- *
- *  $Id$
- *
- *  Copyright (C) 2006  Florian Pose, Ingenieurgemeinschaft IgH
- *
- *  This file is part of the IgH EtherCAT Master.
- *
- *  The IgH EtherCAT Master is free software; you can redistribute it
- *  and/or modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2 of the
- *  License, or (at your option) any later version.
- *
- *  The IgH EtherCAT Master is distributed in the hope that it will be
- *  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with the IgH EtherCAT Master; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- *  The right to use EtherCAT Technology is granted and comes free of
- *  charge under condition of compatibility of product made by
- *  Licensee. People intending to distribute/sell products based on the
- *  code, have to sign an agreement to guarantee that products using
- *  software based on IgH EtherCAT master stay compatible with the actual
- *  EtherCAT specification (which are released themselves as an open
- *  standard) as the (only) precondition to have the right to use EtherCAT
- *  Technology, IP and trade marks.
- *
- *****************************************************************************/
-
-/**
-   \file
-   EtherCAT slave types.
-*/
-
-/*****************************************************************************/
-
-#ifndef _EC_TYPES_H_
-#define _EC_TYPES_H_
-
-#include <linux/types.h>
-
-#include "../include/ecrt.h"
-
-/*****************************************************************************/
-
-#define EC_MAX_FIELDS 10 /**< maximal number of data fields per sync manager */
-#define EC_MAX_SYNC   16 /**< maximal number of sync managers per type */
-
-/*****************************************************************************/
-
-/**
-   Special slaves.
-*/
-
-typedef enum
-{
-    EC_TYPE_NORMAL, /**< no special slave */
-    EC_TYPE_BUS_COUPLER, /**< slave is a bus coupler */
-    EC_TYPE_INFRA, /**< infrastructure slaves, that contain no process data */
-    EC_TYPE_EOE /**< slave is an EoE switch */
-}
-ec_special_type_t;
-
-/*****************************************************************************/
-
-/**
-   Process data field.
-*/
-
-typedef struct
-{
-    const char *name; /**< field name */
-    size_t size; /**< field size in bytes */
-}
-ec_field_t;
-
-/*****************************************************************************/
-
-/**
-   Sync manager.
-*/
-
-typedef struct
-{
-    uint16_t physical_start_address; /**< physical start address */
-    uint16_t size; /**< size in bytes */
-    uint8_t control_byte; /**< control register value */
-    const ec_field_t *fields[EC_MAX_FIELDS]; /**< field array */
-}
-ec_sync_t;
-
-/*****************************************************************************/
-
-/**
-   Slave description type.
-*/
-
-typedef struct ec_slave_type
-{
-    const char *vendor_name; /**< vendor name*/
-    const char *product_name; /**< product name */
-    const char *description; /**< free description */
-    ec_special_type_t special; /**< special slave type? */
-    const ec_sync_t *sync_managers[EC_MAX_SYNC]; /**< sync managers */
-}
-ec_slave_type_t;
-
-/*****************************************************************************/
-
-/**
-   Slave type identification.
-*/
-
-typedef struct
-{
-    uint32_t vendor_id; /**< vendor id */
-    uint32_t product_code; /**< product code */
-    const ec_slave_type_t *type; /**< associated slave description object */
-}
-ec_slave_ident_t;
-
-extern ec_slave_ident_t slave_idents[]; /**< array with slave descriptions */
-
-/*****************************************************************************/
-
-#endif
--- a/script/ethercat.sh	Wed Aug 02 23:16:10 2006 +0000
+++ b/script/ethercat.sh	Thu Aug 03 12:51:17 2006 +0000
@@ -163,7 +163,7 @@
 		fi
 
 	    # unload conflicting modules at first
-		for mod in 8139too 8139cp; do
+		for mod in 8139too; do
 			if lsmod | grep "^$mod " > /dev/null; then
 				if ! rmmod $mod; then
 					/bin/false
@@ -175,6 +175,7 @@
 
 	    # load master module
 		if ! modprobe ec_master ec_eoeif_count=$EOE_INTERFACES; then
+			modprobe 8139too
 			/bin/false
 			rc_status -v
 			rc_exit
@@ -182,6 +183,8 @@
 
         # load device module
 		if ! modprobe ec_8139too ec_device_index=$DEVICE_INDEX; then
+			rmmod ec_master
+			modprobe 8139too
 			/bin/false
 			rc_status -v
 			rc_exit
--- a/script/lsec.pl	Wed Aug 02 23:16:10 2006 +0000
+++ b/script/lsec.pl	Thu Aug 03 12:51:17 2006 +0000
@@ -42,7 +42,6 @@
 
 my $master_index;
 my $master_dir;
-my $show_sii_naming;
 
 #------------------------------------------------------------------------------
 
@@ -63,45 +62,43 @@
 sub query_slaves
 {
     my $dirhandle;
-    my $slave_dir;
     my $entry;
-    my $slave_index;
-    my $file_name;
-    my $vendor_name;
     my @slaves;
     my $slave;
     my $abs;
+	my $line;
 
     unless (opendir $dirhandle, $master_dir) {
-	print "Failed to open directory \"$master_dir\".\n";
-	exit 1;
+		print "Failed to open directory \"$master_dir\".\n";
+		exit 1;
     }
 
     while ($entry = readdir $dirhandle) {
         next unless $entry =~ /^slave(\d+)$/;
-	$slave_dir = $master_dir . "/" . $entry;
 
-	$slave = {};
-	$slave->{'ring_position'} =
-	    &read_integer("$slave_dir/ring_position");
-	$slave->{'advanced_position'} =
-	    &read_string("$slave_dir/advanced_position");
-	unless ($show_sii_naming) {
-	    $slave->{'vendor_name'} =
-		&read_string("$slave_dir/vendor_name");
-	    $slave->{'product_name'} =
-		&read_string("$slave_dir/product_name");
-	    $slave->{'product_desc'} =
-		&read_string("$slave_dir/product_desc");
-	}
-	else {
-	    $slave->{'name'} =
-		&read_string("$slave_dir/name");
-	}
-	$slave->{'type'} =
-	    &read_string("$slave_dir/type");
+		$slave = {};
 
-	push @slaves, $slave;
+		open INFO, "$master_dir/$entry/info" or die
+			"ERROR: Failed to open $master_dir/$entry/info";
+
+		while ($line = <INFO>) {
+			if ($line =~ /^Name: (.*)$/) {
+				$slave->{'name'} = $1;
+			}
+			elsif ($line =~ /^Ring position: (\d+)$/) {
+				$slave->{'ring_position'} = $1;
+			}
+			elsif ($line =~ /^Advanced position: (\d+:\d+)$/) {
+				$slave->{'advanced_position'} = $1;
+			}
+			elsif ($line =~ /^State: (.+)$/) {
+				$slave->{'state'} = $1;
+			}
+		}
+
+		close INFO;
+
+		push @slaves, $slave;
     }
     closedir $dirhandle;
 
@@ -109,82 +106,40 @@
 
     print "EtherCAT bus listing for master $master_index:\n";
     for $slave (@slaves) {
-	if ($slave->{'type'} eq "coupler") {
-	    print "--------------------------------------------------------\n";
-	}
-
-	$abs = sprintf "%i", $slave->{'ring_position'};
-	printf(" %3s %8s   ", $abs, $slave->{'advanced_position'});
-	unless ($show_sii_naming) {
-	    printf("%-12s %-10s %s\n", $slave->{'vendor_name'},
-		   $slave->{'product_name'}, $slave->{'product_desc'});
-	}
-	else {
-	    printf("%s\n", $slave->{'name'});
-	}
+		$abs = sprintf "%i", $slave->{'ring_position'};
+		printf(" %3s %8s  %-6s  %s\n",
+			   $abs, $slave->{'advanced_position'},
+			   $slave->{'state'}, $slave->{'name'});
     }
 }
 
 #------------------------------------------------------------------------------
 
-sub read_string
-{
-    (my $file_name) = @_;
-    my $data;
-
-    $data = `cat $file_name 2>/dev/null`;
-    if ($?) {
-	print "ERROR: Unable to read string $file_name!\n";
-	exit 1;
-    }
-
-    chomp $data;
-    return $data;
-}
-
-#------------------------------------------------------------------------------
-
-sub read_integer
-{
-    (my $file_name) = @_;
-
-    if (`cat $file_name 2>/dev/null` !~ /^(\d+)$/) {
-	print "ERROR: Unable to read integer $file_name!\n";
-	exit 1;
-    }
-
-    return int $1;
-}
-
-#------------------------------------------------------------------------------
-
 sub get_options
 {
     my %opt;
     my $optret;
 
-    $optret = getopts "m:sh", \%opt;
+    $optret = getopts "m:h", \%opt;
 
     &print_usage if defined $opt{'h'} or $#ARGV > -1 or !$optret;
 
     if (defined $opt{'m'}) {
-	$master_index = $opt{'m'};
+		$master_index = $opt{'m'};
     }
     else {
-	$master_index = 0;
+		$master_index = 0;
     }
-
-    $show_sii_naming = defined $opt{'s'};
 }
 
 #------------------------------------------------------------------------------
 
 sub print_usage
 {
-    print "Usage: $0 [OPTIONS]\n";
+	my $cmd = `basename $0`;
+	chomp $cmd;
+    print "Usage: $cmd [OPTIONS]\n";
     print "        -m <IDX>    Query master <IDX>.\n";
-    print "        -s          Show EEPROM name instead of";
-    print " vendor/product/description.\n";
     print "        -h          Show this help.\n";
     exit 0;
 }