SII sync managers as array instead of list, removed sync manager
authorFlorian Pose <fp@igh-essen.com>
Tue, 06 Mar 2007 09:06:01 +0000
changeset 618 e4b89c862c43
parent 617 3c628bb7f68b
child 619 15becb1879fd
SII sync managers as array instead of list, removed sync manager
guessing, ignoring base_sync_count.
master/domain.c
master/fsm_slave.c
master/slave.c
master/slave.h
--- a/master/domain.c	Mon Mar 05 16:59:02 2007 +0000
+++ b/master/domain.c	Tue Mar 06 09:06:01 2007 +0000
@@ -199,23 +199,17 @@
     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;
+    unsigned int bit_offset, byte_offset;
 
     // 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) {
+    if (pdo->sync_index >= slave->sii_sync_count) {
         EC_ERR("No sync manager for PDO 0x%04X:%i.",
                pdo->index, entry->subindex);
         return -1;
     }
 
+    sync = &slave->sii_syncs[pdo->sync_index];
+
     // Calculate offset (in sync manager) for process data pointer
     bit_offset = 0;
     byte_offset = 0;
@@ -272,10 +266,10 @@
 {
     ec_data_reg_t *data_reg;
     ec_sii_sync_t *sync;
-    unsigned int sync_found, sync_index;
+    unsigned int sync_index;
     uint16_t sync_length;
 
-    switch (dir) {
+    switch (dir) { // FIXME
         case EC_DIR_OUTPUT: sync_index = 2; break;
         case EC_DIR_INPUT:  sync_index = 3; break;
         default:
@@ -283,21 +277,13 @@
             return -1;
     }
 
-    // Find sync manager
-    sync_found = 0;
-    list_for_each_entry(sync, &slave->sii_syncs, list) {
-        if (sync->index == sync_index) {
-            sync_found = 1;
-            break;
-        }
-    }
-
-    if (!sync_found) {
+    if (sync_index >= slave->sii_sync_count) {
         EC_ERR("No sync manager found for PDO range.\n");
         return -1;
     }
-
-     // Allocate memory for data registration object
+    sync = &slave->sii_syncs[sync_index];
+
+    // 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");
--- a/master/fsm_slave.c	Mon Mar 05 16:59:02 2007 +0000
+++ b/master/fsm_slave.c	Tue Mar 06 09:06:01 2007 +0000
@@ -319,7 +319,6 @@
     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;
@@ -661,8 +660,7 @@
     ec_master_t *master = fsm->slave->master;
     ec_slave_t *slave = fsm->slave;
     ec_datagram_t *datagram = fsm->datagram;
-    const ec_sii_sync_t *sync;
-    ec_sii_sync_t mbox_sync;
+    unsigned int i;
 
     // slave is now in INIT
     if (slave->current_state == slave->requested_state) {
@@ -674,51 +672,25 @@
         return;
     }
 
-    if (!slave->base_sync_count) { // no sync managers
+    if (!slave->sii_mailbox_protocols || slave->sii_sync_count < 2) {
+        // no mailbox sync managers to be configured
         ec_fsm_slave_conf_enter_preop(fsm);
         return;
     }
 
     if (master->debug_level) {
-        EC_DBG("Configuring sync managers of slave %i.\n",
+        EC_DBG("Configuring mailbox sync managers of slave %i.\n",
                slave->ring_position);
     }
 
     // configure sync managers
     ec_datagram_npwr(datagram, slave->station_address, 0x0800,
-                     EC_SYNC_SIZE * slave->base_sync_count);
-    memset(datagram->data, 0x00, EC_SYNC_SIZE * slave->base_sync_count);
-
-    if (list_empty(&slave->sii_syncs)) {
-        if (slave->sii_rx_mailbox_offset && slave->sii_tx_mailbox_offset) {
-            if (slave->master->debug_level)
-                EC_DBG("Guessing sync manager settings for slave %i.\n",
-                       slave->ring_position);
-            mbox_sync.index = 0;
-            mbox_sync.physical_start_address = slave->sii_tx_mailbox_offset;
-            mbox_sync.length = slave->sii_tx_mailbox_size;
-            mbox_sync.control_register = 0x26;
-            mbox_sync.enable = 0x01;
-            mbox_sync.est_length = 0;
-            ec_slave_sync_config(slave, &mbox_sync,
-                    datagram->data + EC_SYNC_SIZE * mbox_sync.index);
-            mbox_sync.index = 1;
-            mbox_sync.physical_start_address = slave->sii_rx_mailbox_offset;
-            mbox_sync.length = slave->sii_rx_mailbox_size;
-            mbox_sync.control_register = 0x22;
-            mbox_sync.enable = 0x01;
-            mbox_sync.est_length = 0;
-            ec_slave_sync_config(slave, &mbox_sync,
-                    datagram->data + EC_SYNC_SIZE * mbox_sync.index);
-        }
-    }
-    else if (slave->sii_mailbox_protocols) { // mailboxes present
-        list_for_each_entry(sync, &slave->sii_syncs, list) {
-            // only configure mailbox sync-managers
-            if (sync->index != 0 && sync->index != 1) continue;
-            ec_slave_sync_config(slave, sync,
-                    datagram->data + EC_SYNC_SIZE * sync->index);
-        }
+                     EC_SYNC_SIZE * slave->sii_sync_count);
+    memset(datagram->data, 0x00, EC_SYNC_SIZE * slave->sii_sync_count);
+
+    for (i = 0; i < 2; i++) {
+        ec_slave_sync_config(slave, &slave->sii_syncs[i],
+                datagram->data + EC_SYNC_SIZE * i);
     }
 
     ec_master_queue_datagram(fsm->slave->master, datagram);
@@ -820,21 +792,21 @@
 {
     ec_slave_t *slave = fsm->slave;
     ec_datagram_t *datagram = fsm->datagram;
-    ec_sii_sync_t *sync;
-
-    if (list_empty(&slave->sii_syncs)) {
+    unsigned int i;
+
+    if (!slave->sii_sync_count) {
         ec_fsm_slave_conf_enter_fmmu(fsm);
         return;
     }
 
     // configure sync managers for process data
     ec_datagram_npwr(datagram, slave->station_address, 0x0800,
-                     EC_SYNC_SIZE * slave->base_sync_count);
-    memset(datagram->data, 0x00, EC_SYNC_SIZE * slave->base_sync_count);
-
-    list_for_each_entry(sync, &slave->sii_syncs, list) {
-        ec_slave_sync_config(slave, sync,
-                datagram->data + EC_SYNC_SIZE * sync->index);
+                     EC_SYNC_SIZE * slave->sii_sync_count);
+    memset(datagram->data, 0x00, EC_SYNC_SIZE * slave->sii_sync_count);
+
+    for (i = 0; i < slave->sii_sync_count; i++) {
+        ec_slave_sync_config(slave, &slave->sii_syncs[i],
+                datagram->data + EC_SYNC_SIZE * i);
     }
 
     ec_master_queue_datagram(fsm->slave->master, datagram);
--- a/master/slave.c	Mon Mar 05 16:59:02 2007 +0000
+++ b/master/slave.c	Tue Mar 06 09:06:01 2007 +0000
@@ -127,7 +127,6 @@
     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;
@@ -149,7 +148,8 @@
     slave->sii_current_on_ebus = 0;
 
     INIT_LIST_HEAD(&slave->sii_strings);
-    INIT_LIST_HEAD(&slave->sii_syncs);
+    slave->sii_syncs = NULL;
+    slave->sii_sync_count = 0;
     INIT_LIST_HEAD(&slave->sii_pdos);
     INIT_LIST_HEAD(&slave->sdo_dictionary);
     INIT_LIST_HEAD(&slave->sdo_confs);
@@ -240,7 +240,6 @@
 {
     ec_slave_t *slave;
     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_data_t *sdodata, *next_sdodata;
@@ -254,10 +253,7 @@
     }
 
     // free all sync managers
-    list_for_each_entry_safe(sync, next_sync, &slave->sii_syncs, list) {
-        list_del(&sync->list);
-        kfree(sync);
-    }
+    if (slave->sii_syncs) kfree(slave->sii_syncs);
 
     // free all PDOs
     list_for_each_entry_safe(pdo, next_pdo, &slave->sii_pdos, list) {
@@ -309,7 +305,7 @@
 void ec_slave_reset(ec_slave_t *slave /**< EtherCAT slave */)
 {
     ec_sdo_data_t *sdodata, *next_sdodata;
-    ec_sii_sync_t *sync;
+    unsigned int i;
 
     // remove FMMU configurations
     slave->fmmu_count = 0;
@@ -323,8 +319,8 @@
     }
 
     // remove estimated sync manager sizes
-    list_for_each_entry(sync, &slave->sii_syncs, list) {
-        sync->est_length = 0;
+    for (i = 0; i < slave->sii_sync_count; i++) {
+        slave->sii_syncs[i].est_length = 0;
     }
 }
 
@@ -472,27 +468,28 @@
                         size_t word_count /**< number of words */
                         )
 {
-    unsigned int sync_count, i;
+    unsigned int i;
     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_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 manager struct is 4 words long
+    slave->sii_sync_count = word_count / 4;
+
+    if (!(slave->sii_syncs = kmalloc(sizeof(ec_sii_sync_t) *
+                    slave->sii_sync_count, GFP_ATOMIC))) {
+        EC_ERR("Failed to allocate Sync-Manager memory.\n");
+        return -1;
+    }
+    
+    for (i = 0; i < slave->sii_sync_count; i++, data += 8) {
+        sync = &slave->sii_syncs[i];
+
+        sync->index = i; 
         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);
-
+        
         sync->est_length = 0;
-
-        list_add_tail(&sync->list, &slave->sii_syncs);
     }
 
     return 0;
@@ -785,15 +782,16 @@
     if (slave->sii_order)
         off += sprintf(buffer + off, "  Order number: %s\n", slave->sii_order);
 
-    if (!list_empty(&slave->sii_syncs))
+    if (slave->sii_sync_count)
         off += sprintf(buffer + off, "\nSync-Managers:\n");
 
-    list_for_each_entry(sync, &slave->sii_syncs, list) {
+    for (i = 0; i < slave->sii_sync_count; i++) {
+        sync = &slave->sii_syncs[i];
         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");
+                " 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))
--- a/master/slave.h	Mon Mar 05 16:59:02 2007 +0000
+++ b/master/slave.h	Tue Mar 06 09:06:01 2007 +0000
@@ -116,7 +116,6 @@
 
 typedef struct
 {
-    struct list_head list; /**< list item */
     unsigned int index; /**< sync manager index */
     uint16_t physical_start_address; /**< physical start address */
     uint16_t length; /**< data length in bytes */
@@ -219,7 +218,6 @@
     uint8_t base_revision; /**< revision */
     uint16_t base_build; /**< build number */
     uint16_t base_fmmu_count; /**< number of supported FMMUs */
-    uint16_t base_sync_count; /**< number of supported sync managers */
 
     // data link status
     uint8_t dl_link[4]; /**< link detected */
@@ -243,7 +241,8 @@
     uint16_t sii_mailbox_protocols; /**< supported mailbox protocols */
     uint8_t sii_physical_layer[4]; /**< port media */
     struct list_head sii_strings; /**< EEPROM STRING categories */
-    struct list_head sii_syncs; /**< EEPROM SYNC MANAGER categories */
+    ec_sii_sync_t *sii_syncs; /**< EEPROM SYNC MANAGER categories */
+    unsigned int sii_sync_count; /**< number of sync managers in EEPROM */
     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 */