Mit neuer Schnittstelle wieder lauff?hig.
authorFlorian Pose <fp@igh-essen.com>
Fri, 20 Jan 2006 13:32:31 +0000
changeset 55 059a9e712aa7
parent 54 7506e67dd122
child 56 36d1fa37f5e1
Mit neuer Schnittstelle wieder lauff?hig.
devices/8139too.c
include/EtherCAT_dev.h
include/EtherCAT_rt.h
master/master.c
master/master.h
master/module.c
master/slave.c
master/slave.h
master/types.c
master/types.h
mini/mini.c
rt/msr_module.c
--- a/devices/8139too.c	Tue Jan 17 18:28:15 2006 +0000
+++ b/devices/8139too.c	Fri Jan 20 13:32:31 2006 +0000
@@ -2982,7 +2982,7 @@
  out_ec_dev:
     if (rtl_ec_dev) {
       printk(KERN_INFO "Unregistering RTL8139-EtherCAT device...\n");
-      EtherCAT_dev_unregister(ec_device_master_index);
+      EtherCAT_dev_unregister(ec_device_master_index, rtl_ec_dev);
       rtl_ec_dev = NULL;
     }
 
@@ -2998,14 +2998,14 @@
 
   printk(KERN_INFO "Cleaning up RTL8139-EtherCAT module...\n");
 
+  pci_unregister_driver(&rtl8139_pci_driver);
+
   if (rtl_ec_dev) {
     printk(KERN_INFO "Unregistering RTL8139-EtherCAT device...\n");
-    EtherCAT_dev_unregister(ec_device_master_index);
+    EtherCAT_dev_unregister(ec_device_master_index, rtl_ec_dev);
     rtl_ec_dev = NULL;
   }
 
-  pci_unregister_driver(&rtl8139_pci_driver);
-
   printk(KERN_INFO "RTL8139-EtherCAT module cleaned up.\n");
 
   /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
--- a/include/EtherCAT_dev.h	Tue Jan 17 18:28:15 2006 +0000
+++ b/include/EtherCAT_dev.h	Fri Jan 20 13:32:31 2006 +0000
@@ -32,7 +32,7 @@
                                    irqreturn_t (*)(int, void *,
                                                    struct pt_regs *),
                                    struct module *);
-void EtherCAT_dev_unregister(unsigned int);
+void EtherCAT_dev_unregister(unsigned int, ec_device_t *);
 int EtherCAT_dev_is_ec(ec_device_t *, struct net_device *);
 void EtherCAT_dev_state(ec_device_t *, ec_device_state_t);
 int EtherCAT_dev_receive(ec_device_t *, void *, unsigned int);
--- a/include/EtherCAT_rt.h	Tue Jan 17 18:28:15 2006 +0000
+++ b/include/EtherCAT_rt.h	Fri Jan 20 13:32:31 2006 +0000
@@ -14,22 +14,71 @@
 struct ec_master;
 typedef struct ec_master ec_master_t;
 
+struct ec_slave_type;
+typedef struct ec_slave_type ec_slave_type_t;
+
+struct ec_slave;
+typedef struct ec_slave ec_slave_t;
+
 /*****************************************************************************/
 
 ec_master_t *EtherCAT_rt_request_master(unsigned int master_index);
 
 void EtherCAT_rt_release_master(ec_master_t *master);
 
-void *EtherCAT_rt_register_slave(ec_master_t *master, unsigned int slave_index,
-                                 const char *vendor_name,
-                                 const char *product_name);
+ec_slave_t *EtherCAT_rt_register_slave(ec_master_t *master,
+                                       unsigned int slave_index,
+                                       const char *vendor_name,
+                                       const char *product_name,
+                                       unsigned int domain);
 
 int EtherCAT_rt_activate_slaves(ec_master_t *master);
 
 int EtherCAT_rt_deactivate_slaves(ec_master_t *master);
 
-int EtherCAT_rt_domain_cycle(ec_master_t *master, unsigned int domain,
-                             unsigned int timeout_us);
+int EtherCAT_rt_exchange_io(ec_master_t *master, unsigned int domain,
+                            unsigned int timeout_us);
+
+/*****************************************************************************/
+
+/**
+   EtherCAT-Slave
+*/
+
+struct ec_slave
+{
+    // Base data
+    unsigned char base_type; /**< Slave-Typ */
+    unsigned char base_revision; /**< Revision */
+    unsigned short base_build; /**< Build-Nummer */
+
+    // Addresses
+    short ring_position; /**< (Negative) Position des Slaves im Bus */
+    unsigned short station_address; /**< Konfigurierte Slave-Adresse */
+
+    // Slave information interface
+    unsigned int sii_vendor_id; /**< Identifikationsnummer des Herstellers */
+    unsigned int sii_product_code; /**< Herstellerspezifischer Produktcode */
+    unsigned int sii_revision_number; /**< Revisionsnummer */
+    unsigned int sii_serial_number; /**< Seriennummer der Klemme */
+
+    const ec_slave_type_t *type; /**< Zeiger auf die Beschreibung
+                                    des Slave-Typs */
+
+    unsigned int logical_address; /**< Konfigurierte, logische Adresse */
+
+    void *process_data; /**< Zeiger auf den Speicherbereich
+                           innerhalb eines Prozessdatenobjekts */
+    void *private_data; /**< Zeiger auf privaten Datenbereich */
+    int (*configure)(ec_slave_t *); /**< Zeiger auf die Funktion zur
+                                     Konfiguration */
+
+    unsigned char registered; /**< Der Slave wurde registriert */
+
+    unsigned int domain; /**< Prozessdatendomäne */
+
+    int error_reported; /**< Ein Zugriffsfehler wurde bereits gemeldet */
+};
 
 /*****************************************************************************/
 
--- a/master/master.c	Tue Jan 17 18:28:15 2006 +0000
+++ b/master/master.c	Fri Jan 20 13:32:31 2006 +0000
@@ -14,8 +14,11 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 
+#include "../include/EtherCAT_rt.h"
 #include "globals.h"
 #include "master.h"
+#include "slave.h"
+#include "types.h"
 #include "device.h"
 #include "command.h"
 
@@ -26,8 +29,7 @@
 int ec_simple_send(ec_master_t *, ec_command_t *);
 int ec_simple_receive(ec_master_t *, ec_command_t *);
 void ec_output_debug_data(const ec_master_t *);
-int ec_read_slave_information(ec_master_t *, unsigned short, unsigned short,
-                              unsigned int *);
+int ec_sii_read(ec_master_t *, unsigned short, unsigned short, unsigned int *);
 void ec_output_lost_frames(ec_master_t *);
 
 /*****************************************************************************/
@@ -354,7 +356,7 @@
 int ec_scan_for_slaves(ec_master_t *master)
 {
   ec_command_t cmd;
-  ec_slave_t *cur;
+  ec_slave_t *slave;
   unsigned int i, j;
   unsigned char data[2];
 
@@ -380,53 +382,71 @@
   // For every slave in the list
   for (i = 0; i < master->bus_slaves_count; i++)
   {
-    cur = master->bus_slaves + i;
-
-    ec_slave_init(cur);
+    slave = master->bus_slaves + i;
+
+    ec_slave_init(slave);
+
+    // Set ring position
+    slave->ring_position = -i;
+    slave->station_address = i + 1;
+
+    // Write station address
+
+    data[0] = slave->station_address & 0x00FF;
+    data[1] = (slave->station_address & 0xFF00) >> 8;
+
+    ec_command_position_write(&cmd, slave->ring_position, 0x0010, 2, data);
+
+    if (unlikely(ec_simple_send_receive(master, &cmd) < 0))
+      return -1;
+
+    if (unlikely(cmd.working_counter != 1)) {
+      printk(KERN_ERR "EtherCAT: Slave %i did not repond while writing"
+             " station address!\n", i);
+      return -1;
+    }
 
     // Read base data
 
-    ec_command_read(&cmd, cur->station_address, 0x0000, 4);
+    ec_command_read(&cmd, slave->station_address, 0x0000, 4);
 
     if (unlikely(ec_simple_send_receive(master, &cmd) < 0))
       return -1;
 
     if (unlikely(cmd.working_counter != 1)) {
-      printk(KERN_ERR "EtherCAT: Slave %i did not respond"
-             " while reading base data!\n", i);
+      printk(KERN_ERR "EtherCAT: Slave %i did not respond while reading base"
+             " data!\n", i);
       return -1;
     }
 
     // Get base data
 
-    cur->type = cmd.data[0];
-    cur->revision = cmd.data[1];
-    cur->build = cmd.data[2] | (cmd.data[3] << 8);
+    slave->base_type = cmd.data[0];
+    slave->base_revision = cmd.data[1];
+    slave->base_build = cmd.data[2] | (cmd.data[3] << 8);
 
     // Read identification from "Slave Information Interface" (SII)
 
-    if (unlikely(ec_read_slave_information(master, cur->station_address,
-                                           0x0008, &cur->vendor_id) != 0)) {
+    if (unlikely(ec_sii_read(master, slave->station_address, 0x0008,
+                             &slave->sii_vendor_id) != 0)) {
       printk(KERN_ERR "EtherCAT: Could not read SII vendor id!\n");
       return -1;
     }
 
-    if (unlikely(ec_read_slave_information(master, cur->station_address,
-                                           0x000A, &cur->product_code) != 0)) {
+    if (unlikely(ec_sii_read(master, slave->station_address, 0x000A,
+                             &slave->sii_product_code) != 0)) {
       printk(KERN_ERR "EtherCAT: Could not read SII product code!\n");
       return -1;
     }
 
-    if (unlikely(ec_read_slave_information(master, cur->station_address,
-                                           0x000C,
-                                           &cur->revision_number) != 0)) {
+    if (unlikely(ec_sii_read(master, slave->station_address, 0x000C,
+                             &slave->sii_revision_number) != 0)) {
       printk(KERN_ERR "EtherCAT: Could not read SII revision number!\n");
       return -1;
     }
 
-    if (unlikely(ec_read_slave_information(master, cur->station_address,
-                                           0x000E,
-                                           &cur->serial_number) != 0)) {
+    if (unlikely(ec_sii_read(master, slave->station_address, 0x000E,
+                             &slave->sii_serial_number) != 0)) {
       printk(KERN_ERR "EtherCAT: Could not read SII serial number!\n");
       return -1;
     }
@@ -435,37 +455,18 @@
 
     for (j = 0; j < slave_ident_count; j++)
     {
-      if (unlikely(slave_idents[j].vendor_id == cur->vendor_id
-                   && slave_idents[j].product_code == cur->product_code))
+      if (unlikely(slave_idents[j].vendor_id == slave->sii_vendor_id
+                   && slave_idents[j].product_code == slave->sii_product_code))
       {
-        cur->desc = slave_idents[j].desc;
+        slave->type = slave_idents[j].type;
         break;
       }
     }
 
-    if (unlikely(!cur->desc)) {
+    if (unlikely(!slave->type)) {
       printk(KERN_ERR "EtherCAT: Unknown slave device (vendor %X, code %X) at "
-             " position %i.\n", cur->vendor_id, cur->product_code, i);
-      return -1;
-    }
-
-    // Set ring position
-    cur->ring_position = -i;
-    cur->station_address = i + 1;
-
-    // Write station address
-
-    data[0] = cur->station_address & 0x00FF;
-    data[1] = (cur->station_address & 0xFF00) >> 8;
-
-    ec_command_position_write(&cmd, cur->ring_position, 0x0010, 2, data);
-
-    if (unlikely(ec_simple_send_receive(master, &cmd) < 0))
-      return -1;
-
-    if (unlikely(cmd.working_counter != 1)) {
-      printk(KERN_ERR "EtherCAT: Slave %i did not repond"
-             " while writing station address!\n", i);
+             " position %i.\n", slave->sii_vendor_id, slave->sii_product_code,
+             i);
       return -1;
     }
   }
@@ -488,10 +489,8 @@
    @return 0 bei Erfolg, sonst < 0
 */
 
-int ec_read_slave_information(ec_master_t *master,
-                              unsigned short int node_address,
-                              unsigned short int offset,
-                              unsigned int *target)
+int ec_sii_read(ec_master_t *master, unsigned short int node_address,
+                unsigned short int offset, unsigned int *target)
 {
   ec_command_t cmd;
   unsigned char data[10];
@@ -588,13 +587,11 @@
   }
 
   if (unlikely(cmd.working_counter != 1)) {
-    printk(KERN_ERR "EtherCAT: Could not set state %02X - Device \"%s %s\""
-           " (%d) did not respond!\n", state_and_ack, slave->desc->vendor_name,
-           slave->desc->product_name, slave->ring_position * (-1));
-    return -1;
-  }
-
-  slave->requested_state = state_and_ack & 0x0F;
+    printk(KERN_ERR "EtherCAT: Could not set state %02X - Device %i (%s %s)"
+           " did not respond!\n", state_and_ack, slave->ring_position * (-1),
+           slave->type->vendor_name, slave->type->product_name);
+    return -1;
+  }
 
   tries_left = 100;
   while (likely(tries_left))
@@ -635,8 +632,6 @@
     return -1;
   }
 
-  slave->current_state = state_and_ack & 0x0F;
-
   return 0;
 }
 
@@ -711,11 +706,14 @@
    @return 0 bei Erfolg, sonst < 0
 */
 
-void *EtherCAT_rt_register_slave(ec_master_t *master, unsigned int bus_index,
-                              const char *vendor_name,
-                              const char *product_name, unsigned int domain)
+ec_slave_t *EtherCAT_rt_register_slave(ec_master_t *master,
+                                       unsigned int bus_index,
+                                       const char *vendor_name,
+                                       const char *product_name,
+                                       unsigned int domain)
 {
   ec_slave_t *slave;
+  const ec_slave_type_t *type;
   ec_domain_t *dom;
   unsigned int j;
 
@@ -727,16 +725,18 @@
 
   slave = master->bus_slaves + bus_index;
 
-  if (slave->process_data) {
+  if (slave->registered) {
     printk(KERN_ERR "EtherCAT: Slave %i is already registered!\n", bus_index);
     return NULL;
   }
 
-  if (strcmp(vendor_name, slave->desc->vendor_name) ||
-      strcmp(product_name, slave->desc->product_name)) {
+  type = slave->type;
+
+  if (strcmp(vendor_name, type->vendor_name) ||
+      strcmp(product_name, type->product_name)) {
     printk(KERN_ERR "Invalid Slave Type! Requested: \"%s %s\", present: \"%s"
-           "%s\".\n", vendor_name, product_name, slave->desc->vendor_name,
-           slave->desc->product_name);
+           " %s\".\n", vendor_name, product_name, type->vendor_name,
+           type->product_name);
     return NULL;
   }
 
@@ -762,17 +762,18 @@
     master->domain_count++;
   }
 
-  if (dom->data_size + slave->desc->process_data_size > EC_FRAME_SIZE - 14) {
+  if (dom->data_size + type->process_data_size > EC_FRAME_SIZE - 14) {
     printk(KERN_ERR "EtherCAT: Oversized domain %i: %i / %i Bytes!\n",
-           dom->number, dom->data_size + slave->desc->process_data_size,
+           dom->number, dom->data_size + type->process_data_size,
            EC_FRAME_SIZE - 14);
     return NULL;
   }
 
   slave->process_data = dom->data + dom->data_size;
-  dom->data_size += slave->desc->process_data_size;
-
-  return slave->process_data;
+  dom->data_size += type->process_data_size;
+  slave->registered = 1;
+
+  return slave;
 }
 
 /*****************************************************************************/
@@ -795,14 +796,14 @@
   unsigned int i;
   ec_slave_t *slave;
   ec_command_t cmd;
-  const ec_slave_desc_t *desc;
+  const ec_slave_type_t *type;
   unsigned char fmmu[16];
   unsigned char data[256];
 
   for (i = 0; i < master->bus_slaves_count; i++)
   {
     slave = master->bus_slaves + i;
-    desc = slave->desc;
+    type = slave->type;
 
     if (unlikely(ec_state_change(master, slave, EC_SLAVE_STATE_INIT) != 0))
       return -1;
@@ -824,7 +825,7 @@
 
     // Resetting Sync Manager channels
 
-    if (desc->type != EC_NOSYNC_SLAVE)
+    if (type->features != EC_NOSYNC_SLAVE)
     {
       memset(data, 0x00, 256);
 
@@ -840,14 +841,21 @@
       }
     }
 
+    // Check if slave was registered...
+
+    if (!slave->registered) {
+      printk(KERN_INFO "EtherCAT: Slave %i (%s %s) was not registered.\n",
+             i, type->vendor_name, type->product_name);
+      continue;
+    }
+
     // Init Mailbox communication
 
-    if (desc->type == EC_MAILBOX_SLAVE)
+    if (type->features == EC_MAILBOX_SLAVE)
     {
-      if (desc->sm0)
+      if (type->sm0)
       {
-        ec_command_write(&cmd, slave->station_address, 0x0800, 8,
-                         desc->sm0);
+        ec_command_write(&cmd, slave->station_address, 0x0800, 8, type->sm0);
 
         if (unlikely(ec_simple_send_receive(master, &cmd) < 0))
           return -1;
@@ -859,10 +867,9 @@
         }
       }
 
-      if (desc->sm1)
+      if (type->sm1)
       {
-        ec_command_write(&cmd, slave->station_address, 0x0808, 8,
-                         desc->sm1);
+        ec_command_write(&cmd, slave->station_address, 0x0808, 8, type->sm1);
 
         if (unlikely(ec_simple_send_receive(master, &cmd) < 0))
           return -1;
@@ -883,7 +890,7 @@
 
     // Set FMMU's
 
-    if (desc->fmmu0)
+    if (type->fmmu0)
     {
       if (unlikely(!slave->process_data)) {
         printk(KERN_ERR "EtherCAT: Warning - Slave %04X is not assigned to any"
@@ -891,7 +898,7 @@
         return -1;
       }
 
-      memcpy(fmmu, desc->fmmu0, 16);
+      memcpy(fmmu, type->fmmu0, 16);
 
       fmmu[0] = slave->logical_address & 0x000000FF;
       fmmu[1] = (slave->logical_address & 0x0000FF00) >> 8;
@@ -912,12 +919,11 @@
 
     // Set Sync Managers
 
-    if (desc->type != EC_MAILBOX_SLAVE)
+    if (type->features != EC_MAILBOX_SLAVE)
     {
-      if (desc->sm0)
+      if (type->sm0)
       {
-        ec_command_write(&cmd, slave->station_address, 0x0800, 8,
-                         desc->sm0);
+        ec_command_write(&cmd, slave->station_address, 0x0800, 8, type->sm0);
 
         if (unlikely(ec_simple_send_receive(master, &cmd) < 0))
           return -1;
@@ -929,10 +935,9 @@
         }
       }
 
-      if (desc->sm1)
+      if (type->sm1)
       {
-        ec_command_write(&cmd, slave->station_address, 0x0808, 8,
-                         desc->sm1);
+        ec_command_write(&cmd, slave->station_address, 0x0808, 8, type->sm1);
 
         if (unlikely(ec_simple_send_receive(master, &cmd) < 0))
           return -1;
@@ -945,9 +950,9 @@
       }
     }
 
-    if (desc->sm2)
+    if (type->sm2)
     {
-      ec_command_write(&cmd, slave->station_address, 0x0810, 8, desc->sm2);
+      ec_command_write(&cmd, slave->station_address, 0x0810, 8, type->sm2);
 
       if (unlikely(ec_simple_send_receive(master, &cmd) < 0))
         return -1;
@@ -959,9 +964,9 @@
       }
     }
 
-    if (desc->sm3)
+    if (type->sm3)
     {
-      ec_command_write(&cmd, slave->station_address, 0x0818, 8, desc->sm3);
+      ec_command_write(&cmd, slave->station_address, 0x0818, 8, type->sm3);
 
       if (unlikely(ec_simple_send_receive(master, &cmd) < 0))
         return -1;
@@ -1024,8 +1029,8 @@
    @return 0 bei Erfolg, sonst < 0
 */
 
-int EtherCAT_rt_domain_cycle(ec_master_t *master, unsigned int domain,
-                             unsigned int timeout_us)
+int EtherCAT_rt_exchange_io(ec_master_t *master, unsigned int domain,
+                            unsigned int timeout_us)
 {
   unsigned int i;
   ec_domain_t *dom;
@@ -1103,7 +1108,7 @@
 EXPORT_SYMBOL(EtherCAT_rt_register_slave);
 EXPORT_SYMBOL(EtherCAT_rt_activate_slaves);
 EXPORT_SYMBOL(EtherCAT_rt_deactivate_slaves);
-EXPORT_SYMBOL(EtherCAT_rt_domain_cycle);
+EXPORT_SYMBOL(EtherCAT_rt_exchange_io);
 
 /*****************************************************************************/
 
--- a/master/master.h	Tue Jan 17 18:28:15 2006 +0000
+++ b/master/master.h	Fri Jan 20 13:32:31 2006 +0000
@@ -25,7 +25,7 @@
    dem zugewiesenen EtherCAT-Gerät.
 */
 
-typedef struct ec_master
+struct ec_master
 {
   ec_slave_t *bus_slaves; /**< Array von Slaves auf dem Bus */
   unsigned int bus_slaves_count; /**< Anzahl Slaves auf dem Bus */
@@ -46,8 +46,7 @@
   unsigned int frames_lost; /**< Anzahl verlorene Frames */
   unsigned long t_lost_output; /*<< Timer-Ticks bei der letzten Ausgabe von
                                  verlorenen Frames */
-}
-ec_master_t;
+};
 
 /*****************************************************************************/
 
--- a/master/module.c	Tue Jan 17 18:28:15 2006 +0000
+++ b/master/module.c	Fri Jan 20 13:32:31 2006 +0000
@@ -168,6 +168,7 @@
                                    struct module *module)
 {
   ec_device_t *ecd;
+  ec_master_t *master;
 
   if (master_index >= ec_master_count) {
     printk(KERN_ERR "EtherCAT: Master %i does not exist!\n", master_index);
@@ -179,13 +180,15 @@
     return NULL;
   }
 
-  if (ec_masters[master_index].device_registered) {
+  master = ec_masters + master_index;
+
+  if (master->device_registered) {
     printk(KERN_ERR "EtherCAT: Master %i already has a device!\n",
            master_index);
     return NULL;
   }
 
-  ecd = &ec_masters[master_index].device;
+  ecd = &master->device;
 
   if (ec_device_init(ecd) < 0) {
     return NULL;
@@ -197,6 +200,8 @@
   ecd->isr = isr;
   ecd->module = module;
 
+  master->device_registered = 1;
+
   return ecd;
 }
 
@@ -209,15 +214,24 @@
    @param device Das EtherCAT-Geraet
 */
 
-void EtherCAT_dev_unregister(unsigned int master_index)
-{
+void EtherCAT_dev_unregister(unsigned int master_index, ec_device_t *ecd)
+{
+  ec_master_t *master;
+
   if (master_index >= ec_master_count) {
     printk(KERN_WARNING "EtherCAT: Master %i does not exist!\n", master_index);
     return;
   }
 
-  ec_masters[master_index].device_registered = 0;
-  ec_device_clear(&ec_masters[master_index].device);
+  master = ec_masters + master_index;
+
+  if (!master->device_registered || &master->device != ecd) {
+    printk(KERN_ERR "EtherCAT: Unable to unregister device!\n");
+    return;
+  }
+
+  master->device_registered = 0;
+  ec_device_clear(ecd);
 }
 
 /******************************************************************************
@@ -235,7 +249,7 @@
    @returns Zeiger auf EtherCAT-Master oder NULL, wenn Parameter ungueltig.
 */
 
-ec_master_t *EtherCAT_rt_request_master(int index)
+ec_master_t *EtherCAT_rt_request_master(unsigned int index)
 {
   ec_master_t *master;
 
@@ -334,3 +348,9 @@
 EXPORT_SYMBOL(EtherCAT_rt_release_master);
 
 /*****************************************************************************/
+
+/* Emacs-Konfiguration
+;;; Local Variables: ***
+;;; c-basic-offset:2 ***
+;;; End: ***
+*/
--- a/master/slave.c	Tue Jan 17 18:28:15 2006 +0000
+++ b/master/slave.c	Fri Jan 20 13:32:31 2006 +0000
@@ -28,171 +28,27 @@
 
 void ec_slave_init(ec_slave_t *slave)
 {
-  slave->type = 0;
-  slave->revision = 0;
-  slave->build = 0;
+  slave->base_type = 0;
+  slave->base_revision = 0;
+  slave->base_build = 0;
   slave->ring_position = 0;
   slave->station_address = 0;
-  slave->vendor_id = 0;
-  slave->product_code = 0;
-  slave->revision_number = 0;
-  slave->serial_number = 0;
-  slave->desc = NULL;
+  slave->sii_vendor_id = 0;
+  slave->sii_product_code = 0;
+  slave->sii_revision_number = 0;
+  slave->sii_serial_number = 0;
+  slave->type = NULL;
   slave->logical_address = 0;
-  slave->current_state = EC_SLAVE_STATE_UNKNOWN;
-  slave->requested_state = EC_SLAVE_STATE_UNKNOWN;
   slave->process_data = NULL;
+  slave->private_data = NULL;
+  slave->configure = NULL;
+  slave->registered = 0;
   slave->domain = 0;
   slave->error_reported = 0;
 }
 
 /*****************************************************************************/
 
-#if 0
-/**
-   Liest einen bestimmten Kanal des Slaves als Integer-Wert.
-
-   Prüft zuerst, ob der entsprechende Slave eine
-   bekannte Beschreibung besitzt, ob dort eine
-   read()-Funktion hinterlegt ist und ob die angegebene
-   Kanalnummer gültig ist. Wenn ja, wird der dekodierte
-   Wert zurückgegeben, sonst ist der Wert 0.
-
-   @param slave EtherCAT-Slave
-   @param channel Kanalnummer
-
-   @return Gelesener Wert bzw. 0
-*/
-
-int EtherCAT_read_value(EtherCAT_slave_t *slave,
-                        unsigned int channel)
-{
-  if (unlikely(!slave->desc)) {
-    if (likely(slave->error_reported)) {
-      printk(KERN_WARNING "EtherCAT: Reading failed on slave %04X (addr %0X)"
-             " - Slave has no description.\n",
-             slave->station_address, (unsigned int) slave);
-      slave->error_reported = 1;
-    }
-    return 0;
-  }
-
-  if (unlikely(!slave->desc->read)) {
-    if (likely(slave->error_reported)) {
-      printk(KERN_WARNING "EtherCAT: Reading failed on slave %04X (addr %0X)"
-             " - Slave type (%s %s) has no read method.\n",
-             slave->station_address, (unsigned int) slave,
-             slave->desc->vendor_name, slave->desc->product_name);
-      slave->error_reported = 1;
-    }
-    return 0;
-  }
-
-  if (unlikely(channel >= slave->desc->channel_count)) {
-    if (likely(slave->error_reported)) {
-      printk(KERN_WARNING "EtherCAT: Reading failed on slave %4X (addr %0X)"
-             " - Type (%s %s) has no channel %i.\n",
-             slave->station_address, (unsigned int) slave,
-             slave->desc->vendor_name, slave->desc->product_name,
-             channel);
-      slave->error_reported = 1;
-    }
-    return 0;
-  }
-
-  if (unlikely(!slave->process_data)) {
-    if (likely(slave->error_reported)) {
-      printk(KERN_WARNING "EtherCAT: Reading failed on slave %4X (addr %0X)"
-             " - Slave does not belong to any process data object!\n",
-             slave->station_address, (unsigned int) slave);
-      slave->error_reported = 1;
-    }
-    return 0;
-  }
-
-  if (unlikely(slave->error_reported))
-    slave->error_reported = 0;
-
-  return slave->desc->read(slave->process_data, channel);
-}
-
-/*****************************************************************************/
-
-/**
-   Schreibt einen bestimmten Kanal des Slaves als Integer-Wert .
-
-   Prüft zuerst, ob der entsprechende Slave eine
-   bekannte Beschreibung besitzt, ob dort eine
-   write()-Funktion hinterlegt ist und ob die angegebene
-   Kanalnummer gültig ist. Wenn ja, wird der Wert entsprechend
-   kodiert und geschrieben.
-
-   @param slave EtherCAT-Slave
-   @param channel Kanalnummer
-   @param value Zu schreibender Wert
-*/
-
-void EtherCAT_write_value(EtherCAT_slave_t *slave,
-                          unsigned int channel,
-                          int value)
-{
-  if (unlikely(!slave->desc)) {
-    if (likely(slave->error_reported)) {
-      printk(KERN_WARNING "EtherCAT: Writing failed on slave %04X (addr %0X)"
-             " - Slave has no description.\n",
-             slave->station_address, (unsigned int) slave);
-      slave->error_reported = 1;
-    }
-    return;
-  }
-
-  if (unlikely(!slave->desc->write)) {
-    if (likely(slave->error_reported)) {
-      printk(KERN_WARNING "EtherCAT: Writing failed on slave %04X (addr %0X)"
-             " - Type (%s %s) has no write method.\n",
-             slave->station_address, (unsigned int) slave,
-             slave->desc->vendor_name, slave->desc->product_name);
-      slave->error_reported = 1;
-    }
-    return;
-  }
-
-  if (unlikely(channel >= slave->desc->channel_count)) {
-    if (likely(slave->error_reported)) {
-      printk(KERN_WARNING "EtherCAT: Writing failed on slave %4X (addr %0X)"
-             " - Type (%s %s) has no channel %i.\n",
-             slave->station_address, (unsigned int) slave,
-             slave->desc->vendor_name, slave->desc->product_name,
-             channel);
-      slave->error_reported = 1;
-    }
-    return;
-  }
-
-  if (unlikely(!slave->process_data)) {
-    if (likely(slave->error_reported)) {
-      printk(KERN_WARNING "EtherCAT: Writing failed on slave %4X (addr %0X)"
-             " - Slave does not belong to any process data object!\n",
-             slave->station_address, (unsigned int) slave);
-      slave->error_reported = 1;
-    }
-    return;
-  }
-
-  if (unlikely(slave->error_reported))
-    slave->error_reported = 0;
-
-  slave->desc->write(slave->process_data, channel, value);
-}
-
-/*****************************************************************************/
-
-EXPORT_SYMBOL(EtherCAT_write_value);
-EXPORT_SYMBOL(EtherCAT_read_value);
-#endif
-
-/*****************************************************************************/
-
 /* Emacs-Konfiguration
 ;;; Local Variables: ***
 ;;; c-basic-offset:2 ***
--- a/master/slave.h	Tue Jan 17 18:28:15 2006 +0000
+++ b/master/slave.h	Fri Jan 20 13:32:31 2006 +0000
@@ -15,59 +15,13 @@
 
 /*****************************************************************************/
 
-/**
-   EtherCAT-Slave
-
-   Achtung: Bei Änderungen dieser Struktur immer das Define
-   ECAT_INIT_SLAVE anpassen!
-*/
-
-typedef struct
-{
-  // Base data
-  unsigned char type; /**< Slave-Typ */
-  unsigned char revision; /**< Revision */
-  unsigned short build; /**< Build-Nummer */
-
-  // Addresses
-  short ring_position; /**< (Negative) Position des Slaves im Bus */
-  unsigned short station_address; /**< Konfigurierte Slave-Adresse */
-
-  // Slave information interface
-  unsigned int vendor_id; /**< Identifikationsnummer des Herstellers */
-  unsigned int product_code; /**< Herstellerspezifischer Produktcode */
-  unsigned int revision_number; /**< Revisionsnummer */
-  unsigned int serial_number; /**< Seriennummer der Klemme */
-
-  const ec_slave_desc_t *desc; /**< Zeiger auf die Beschreibung
-                                        des Slave-Typs */
-
-  unsigned int logical_address; /**< Konfigurierte, logische adresse */
-
-  ec_slave_state_t current_state; /**< Aktueller Zustand */
-  ec_slave_state_t requested_state; /**< Angeforderter Zustand */
-
-  unsigned char *process_data; /**< Zeiger auf den Speicherbereich
-                                  innerhalb eines Prozessdatenobjekts */
-  unsigned int domain; /**< Prozessdatendomäne */
-  int error_reported; /**< Ein Zugriffsfehler wurde bereits gemeldet */
-}
-ec_slave_t;
-
-#define EC_INIT_SLAVE(TYPE, DOMAIN) {0, 0, 0, 0, 0, 0, 0, 0, 0, \
-                                       TYPE, 0, ECAT_STATE_UNKNOWN, \
-                                       EC_STATE_UNKNOWN, NULL, DOMAIN, 0}
+// ec_slave_t ist in EtherCAT_rt.h ...
 
 /*****************************************************************************/
 
 // Slave construction and deletion
 void ec_slave_init(ec_slave_t *);
 
-#if 0
-int EtherCAT_read_value(EtherCAT_slave_t *, unsigned int);
-void EtherCAT_write_value(EtherCAT_slave_t *, unsigned int, int);
-#endif
-
 /*****************************************************************************/
 
 #endif
--- a/master/types.c	Tue Jan 17 18:28:15 2006 +0000
+++ b/master/types.c	Fri Jan 20 13:32:31 2006 +0000
@@ -45,116 +45,60 @@
 
 /*****************************************************************************/
 
-/* Lese- und Schreibfunktionen */
-
-int read_1014(unsigned char *data, unsigned int channel)
-{
-  return (data[0] >> channel) & 0x01;
-}
-
-void write_2004(unsigned char *data, unsigned int channel, int value)
-{
-  if (value) {
-    data[0] |= (1 << channel);
-  }
-  else {
-    data[0] &= ~(1 << channel);
-  }
-}
-
-int read_31xx(unsigned char *data, unsigned int channel)
-{
-  return (short int) ((data[channel * 3 + 2] << 8) | data[channel * 3 + 1]);
-}
-
-void write_41xx(unsigned char *data, unsigned int channel, int value)
-{
-  data[channel * 3 + 1] = (value & 0xFF00) >> 8;
-  data[channel * 3 + 2] = value & 0xFF;
-}
-
-/*****************************************************************************/
-
 /* Klemmen-Objekte */
 
-ec_slave_desc_t Beckhoff_EK1100[] =
+ec_slave_type_t Beckhoff_EK1100[] =
 {{
   "Beckhoff", "EK1100", "Bus Coupler",
-  EC_NOSYNC_SLAVE,
-  NULL, NULL, NULL, NULL,
-  NULL,
-  0, 0,
-  NULL, NULL
+  EC_NOSYNC_SLAVE, NULL, NULL, NULL, NULL, NULL, 0
 }};
 
-ec_slave_desc_t Beckhoff_EL1014[] =
+ec_slave_type_t Beckhoff_EK1110[] =
+{{
+  "Beckhoff", "EK1110", "Extension terminal",
+  EC_NOSYNC_SLAVE, NULL, NULL, NULL, NULL, NULL, 0
+}};
+
+ec_slave_type_t Beckhoff_EL1014[] =
 {{
   "Beckhoff", "EL1014", "4x Digital Input",
-  EC_SIMPLE_SLAVE,
-  sm0_1014, NULL, NULL, NULL,
-  fmmu0_1014,
-  1, 4,
-  read_1014, NULL
+  EC_SIMPLE_SLAVE, sm0_1014, NULL, NULL, NULL, fmmu0_1014, 1
 }};
 
-ec_slave_desc_t Beckhoff_EL2004[] =
+ec_slave_type_t Beckhoff_EL2004[] =
 {{
   "Beckhoff", "EL2004", "4x Digital Output",
-  EC_SIMPLE_SLAVE,
-  sm0_2004, NULL, NULL, NULL,
-  fmmu0_2004,
-  1, 4,
-  NULL, write_2004
+  EC_SIMPLE_SLAVE, sm0_2004, NULL, NULL, NULL, fmmu0_2004, 1
 }};
 
-ec_slave_desc_t Beckhoff_EL3102[] =
+ec_slave_type_t Beckhoff_EL3102[] =
 {{
   "Beckhoff", "EL3102", "2x Analog Input diff.",
-  EC_MAILBOX_SLAVE,
-  sm0_multi, sm1_multi, sm2_31xx, sm3_31xx,
-  fmmu0_31xx,
-  6, 2,
-  read_31xx, NULL
+  EC_MAILBOX_SLAVE, sm0_multi, sm1_multi, sm2_31xx, sm3_31xx, fmmu0_31xx, 6
 }};
 
-ec_slave_desc_t Beckhoff_EL3162[] =
+ec_slave_type_t Beckhoff_EL3162[] =
 {{
   "Beckhoff", "EL3162", "2x Analog Input",
-  EC_MAILBOX_SLAVE,
-  sm0_multi, sm1_multi, sm2_31xx, sm3_31xx,
-  fmmu0_31xx,
-  6, 2,
-  read_31xx, NULL
+  EC_MAILBOX_SLAVE, sm0_multi, sm1_multi, sm2_31xx, sm3_31xx, fmmu0_31xx, 6
 }};
 
-ec_slave_desc_t Beckhoff_EL4102[] =
+ec_slave_type_t Beckhoff_EL4102[] =
 {{
   "Beckhoff", "EL4102", "2x Analog Output",
-  EC_MAILBOX_SLAVE,
-  sm0_multi, sm1_multi, sm2_41xx, NULL,
-  fmmu0_41xx,
-  4, 2,
-  NULL, write_41xx
+  EC_MAILBOX_SLAVE, sm0_multi, sm1_multi, sm2_41xx, NULL, fmmu0_41xx, 4
 }};
 
-ec_slave_desc_t Beckhoff_EL4132[] =
+ec_slave_type_t Beckhoff_EL4132[] =
 {{
   "Beckhoff", "EL4132", "2x Analog Output diff.",
-  EC_MAILBOX_SLAVE,
-  sm0_multi, sm1_multi, sm2_41xx, NULL,
-  fmmu0_41xx,
-  4, 2,
-  NULL, write_41xx
+  EC_MAILBOX_SLAVE, sm0_multi, sm1_multi, sm2_41xx, NULL, fmmu0_41xx, 4
 }};
 
-ec_slave_desc_t Beckhoff_EL5001[] =
+ec_slave_type_t Beckhoff_EL5001[] =
 {{
-  "Beckhoff", "EL5001", "SSI-Interface",
-  EC_SIMPLE_SLAVE,
-  NULL, NULL, NULL, NULL, // Noch nicht eingepflegt...
-  NULL,
-  0, 0,
-  NULL, NULL
+  "Beckhoff", "EL5001", "SSI-Interface", // Noch nicht eingepflegt...
+  EC_SIMPLE_SLAVE, NULL, NULL, NULL, NULL, NULL, 0
 }};
 
 /*****************************************************************************/
@@ -171,6 +115,7 @@
 {
   {0x00000002, 0x03F63052, Beckhoff_EL1014},
   {0x00000002, 0x044C2C52, Beckhoff_EK1100},
+  {0x00000002, 0x04562C52, Beckhoff_EK1110},
   {0x00000002, 0x07D43052, Beckhoff_EL2004},
   {0x00000002, 0x0C1E3052, Beckhoff_EL3102},
   {0x00000002, 0x0C5A3052, Beckhoff_EL3162},
--- a/master/types.h	Tue Jan 17 18:28:15 2006 +0000
+++ b/master/types.h	Fri Jan 20 13:32:31 2006 +0000
@@ -11,12 +11,14 @@
 #ifndef _EC_TYPES_H_
 #define _EC_TYPES_H_
 
+#include "../include/EtherCAT_rt.h"
+
 /*****************************************************************************/
 
 /**
-   Typ eines EtherCAT-Slaves.
+   Features eines EtherCAT-Slaves.
 
-   Dieser Typ muss für die Konfiguration bekannt sein. Der
+   Diese Angabe muss für die Konfiguration bekannt sein. Der
    Master entscheidet danach, ober bspw. Mailboxes konfigurieren,
    oder Sync-Manager setzen soll.
 */
@@ -25,7 +27,7 @@
 {
   EC_SIMPLE_SLAVE, EC_MAILBOX_SLAVE, EC_NOSYNC_SLAVE
 }
-ec_slave_type_t;
+ec_slave_features_t;
 
 /*****************************************************************************/
 
@@ -37,13 +39,13 @@
    Slave-internen Sync-Manager und FMMU's.
 */
 
-typedef struct slave_desc
+struct ec_slave_type
 {
   const char *vendor_name; /**< Name des Herstellers */
   const char *product_name; /**< Name des Slaves-Typs */
   const char *product_desc; /**< Genauere Beschreibung des Slave-Typs */
 
-  const ec_slave_type_t type; /**< Art des Slave-Typs */
+  ec_slave_features_t features; /**< Features des Slave-Typs */
 
   const unsigned char *sm0; /**< Konfigurationsdaten des
                                ersten Sync-Managers */
@@ -57,16 +59,8 @@
   const unsigned char *fmmu0; /**< Konfigurationsdaten
                                  der ersten FMMU */
 
-  const unsigned int process_data_size; /**< Länge der Prozessdaten in Bytes */
-  const unsigned int channel_count; /**< Anzahl der Kanäle */
-
-  int (*read) (unsigned char *, unsigned int); /**< Funktion zum Dekodieren
-                                                  und Lesen der Kanaldaten */
-  void (*write) (unsigned char *, unsigned int, int); /**< Funktion zum
-                                                         Kodieren und Schreiben
-                                                         der Kanaldaten */
-}
-ec_slave_desc_t;
+  unsigned int process_data_size; /**< Länge der Prozessdaten in Bytes */
+};
 
 /*****************************************************************************/
 
@@ -79,10 +73,9 @@
 
 typedef struct slave_ident
 {
-  const unsigned int vendor_id; /**< Hersteller-Code */
-  const unsigned int product_code; /**< Herstellerspezifischer Produktcode */
-  const ec_slave_desc_t *desc; /**< Zeiger auf den dazugehörigen
-                                        Slave-Typ */
+  unsigned int vendor_id; /**< Hersteller-Code */
+  unsigned int product_code; /**< Herstellerspezifischer Produktcode */
+  const ec_slave_type_t *type; /**< Zeiger auf den entsprechenden Slave-Typ */
 }
 ec_slave_ident_t;
 
--- a/mini/mini.c	Tue Jan 17 18:28:15 2006 +0000
+++ b/mini/mini.c	Fri Jan 20 13:32:31 2006 +0000
@@ -59,7 +59,7 @@
 
     // Prozessdaten lesen und schreiben
     rdtscl(k);
-    EtherCAT_rt_domain_cycle(master, 1, 100);
+    EtherCAT_rt_exchange_io(master, 1, 100);
     firstrun = 0;
 
     timer.expires += HZ / 1000;
--- a/rt/msr_module.c	Tue Jan 17 18:28:15 2006 +0000
+++ b/rt/msr_module.c	Fri Jan 20 13:32:31 2006 +0000
@@ -55,23 +55,23 @@
 static unsigned int ecat_bus_time = 0;
 static unsigned int ecat_timeouts = 0;
 
-#if 0
-static ec_slave_t slaves[] =
-{
-    // Block 1
-    ECAT_INIT_SLAVE(Beckhoff_EK1100, 0),
-    ECAT_INIT_SLAVE(Beckhoff_EL3102, 0)
-};
-#endif
-
-#define ECAT_SLAVES_COUNT (sizeof(ecat_slaves) / sizeof(EtherCAT_slave_t))
-
-#define USE_MSR_LIB
-
-#ifdef USE_MSR_LIB
+ec_slave_t *s_controller;
+ec_slave_t *s_analog_in;
+
 double value;
 int dig1;
-#endif
+
+/*****************************************************************************/
+
+static int register_slaves(void)
+{
+    s_controller = EtherCAT_rt_register_slave(master, 0,
+                                              "Beckhoff", "EK1100", 0);
+    s_analog_in = EtherCAT_rt_register_slave(master, 1,
+                                             "Beckhoff", "EL3102", 0);
+
+    return !s_controller || !s_analog_in;
+}
 
 /******************************************************************************
  *
@@ -93,7 +93,7 @@
 #endif
 
     // Prozessdaten lesen und schreiben
-    EtherCAT_rt_domain_cycle(master, 0, 40);
+    EtherCAT_rt_exchange_io(master, 0, 40);
 
 #if 0
     if (debug_counter == 0) {
@@ -126,12 +126,10 @@
 {
     static int counter = 0;
 
-#ifdef USE_MSR_LIB
+    // Schreibe Kanal1 von Klemme X auf 1
+
     timeval_add(&process_time, &process_time, &msr_time_increment);
     MSR_ADEOS_INTERRUPT_CODE(msr_controller_run(); msr_write_kanal_list(););
-#else
-    msr_controller_run();
-#endif
 
     ipipe_control_irq(irq,0,IPIPE_ENABLE_MASK);  //Interrupt bestŽätigen
     if (counter++ > HZREDUCTION) {
@@ -169,10 +167,8 @@
 
 int msr_globals_register(void)
 {
-#ifdef USE_MSR_LIB
     msr_reg_kanal("/value", "V", &value, TDBL);
     msr_reg_kanal("/dig1", "", &dig1, TINT);
-#endif
 
     msr_reg_kanal("/Taskinfo/EtherCAT/BusTime", "us", &ecat_bus_time, TUINT);
     msr_reg_kanal("/Taskinfo/EtherCAT/Timeouts", "", &ecat_timeouts, TUINT);
@@ -189,29 +185,25 @@
     struct ipipe_domain_attr attr; //ipipe
 
     // Als allererstes die RT-lib initialisieren
-#ifdef USE_MSR_LIB
     if (msr_rtlib_init(1,MSR_ABTASTFREQUENZ,10,&msr_globals_register) < 0) {
         msr_print_warn("msr_modul: can't initialize rtlib!");
         goto out_return;
     }
-#endif
 
     msr_jitter_init();
 
     printk(KERN_INFO "=== Starting EtherCAT environment... ===\n");
 
     if ((master = EtherCAT_rt_request_master(0)) == NULL) {
-        printk(KERN_ERR "EtherCAT master 0 not available!\n");
+        printk(KERN_ERR "Error requesting master 0!\n");
         goto out_msr_cleanup;
     }
 
-#if 0
-    printk("Checking EtherCAT slaves.\n");
-    if (EtherCAT_check_slaves(master, ecat_slaves, ECAT_SLAVES_COUNT) != 0) {
+    printk("Registering EtherCAT slaves.\n");
+    if (register_slaves()) {
         printk(KERN_ERR "EtherCAT: Could not init slaves!\n");
         goto out_release_master;
     }
-#endif
 
     printk("Activating all EtherCAT slaves.\n");
 
@@ -266,9 +258,7 @@
         printk(KERN_INFO "=== EtherCAT environment stopped. ===\n");
     }
 
-#ifdef USE_MSR_LIB
     msr_rtlib_cleanup();
-#endif
 }
 
 /*****************************************************************************/
@@ -281,3 +271,9 @@
 module_exit(cleanup_rt_module);
 
 /*****************************************************************************/
+
+/* Emacs-Konfiguration
+;;; Local Variables: ***
+;;; c-basic-offset:4 ***
+;;; End: ***
+*/