Limited EEPROM reading; added EC_FIRST_EEPROM_CATEGORY_HEADER define.
authorFlorian Pose <fp@igh-essen.com>
Fri, 10 Aug 2007 13:35:11 +0000
changeset 696 24fac09b5b26
parent 695 661ad8bd5ea1
child 697 6f658c2082fd
Limited EEPROM reading; added EC_FIRST_EEPROM_CATEGORY_HEADER define.
NEWS
TODO
master/fsm_slave.c
master/globals.h
master/slave.c
--- a/NEWS	Fri Aug 10 13:00:31 2007 +0000
+++ b/NEWS	Fri Aug 10 13:35:11 2007 +0000
@@ -46,6 +46,7 @@
 * Master state machine scheduled with timeout if idle, otherwise is executed
   as fast as possible (with schedule()).
 * Added dummy module for simulation purpuses.
+* Limited infinite EEPROM reading, if 0xffff limiter word is missing.
 * Removed EtherCAT line comments from 8139too drivers.
 
 -------------------------------------------------------------------------------
--- a/TODO	Fri Aug 10 13:00:31 2007 +0000
+++ b/TODO	Fri Aug 10 13:35:11 2007 +0000
@@ -8,7 +8,6 @@
 
 * Issues for release 1.3.0:
   - Take broadcast MAC address to register the first ethernet device.
-  - Limit EEPROM reading.
   - Implement ecrt_get_slave() with integer argument as ring position.
   - Handle missing rc_status in init script.
 
--- a/master/fsm_slave.c	Fri Aug 10 13:00:31 2007 +0000
+++ b/master/fsm_slave.c	Fri Aug 10 13:35:11 2007 +0000
@@ -366,7 +366,7 @@
 
     // Start fetching EEPROM size
 
-    fsm->sii_offset = 0x0040; // first category header
+    fsm->sii_offset = EC_FIRST_EEPROM_CATEGORY_OFFSET; // first category header
     ec_fsm_sii_read(&fsm->fsm_sii, slave, fsm->sii_offset, EC_FSM_SII_NODE);
     fsm->state = ec_fsm_slave_scan_state_eeprom_size;
     fsm->state(fsm); // execute state immediately
@@ -398,6 +398,13 @@
 
     if (cat_type != 0xFFFF) { // not the last category
         fsm->sii_offset += cat_size + 2;
+        if (fsm->sii_offset >= EC_MAX_EEPROM_SIZE) {
+            EC_WARN("EEPROM size of slave %i exceeds"
+                    " %i words (0xffff limiter missing?).\n",
+                    slave->ring_position, EC_MAX_EEPROM_SIZE);
+            slave->eeprom_size = EC_FIRST_EEPROM_CATEGORY_OFFSET * 2;
+            goto alloc_eeprom;
+        }
         ec_fsm_sii_read(&fsm->fsm_sii, slave, fsm->sii_offset,
                         EC_FSM_SII_NODE);
         ec_fsm_sii_exec(&fsm->fsm_sii); // execute state immediately
@@ -406,6 +413,7 @@
 
     slave->eeprom_size = (fsm->sii_offset + 1) * 2;
 
+alloc_eeprom:
     if (slave->eeprom_data) {
         EC_INFO("Freeing old EEPROM data on slave %i...\n",
                 slave->ring_position);
@@ -494,7 +502,7 @@
         EC_READ_U16(slave->eeprom_data + 2 * 0x001C);
 
     // evaluate category data
-    cat_word = (uint16_t *) slave->eeprom_data + 0x0040;
+    cat_word = (uint16_t *) slave->eeprom_data + EC_FIRST_EEPROM_CATEGORY_OFFSET;
     while (EC_READ_U16(cat_word) != 0xFFFF) {
         cat_type = EC_READ_U16(cat_word) & 0x7FFF;
         cat_size = EC_READ_U16(cat_word + 1);
--- a/master/globals.h	Fri Aug 10 13:00:31 2007 +0000
+++ b/master/globals.h	Fri Aug 10 13:35:11 2007 +0000
@@ -65,6 +65,9 @@
 /** minimum size of a buffer used with ec_state_string() */
 #define EC_STATE_STRING_SIZE 32
 
+/** maximum EEPROM size in words, to avoid infinite reading. */
+#define EC_MAX_EEPROM_SIZE 512
+
 /******************************************************************************
  *  EtherCAT protocol
  *****************************************************************************/
@@ -82,6 +85,9 @@
 #define EC_MAX_DATA_SIZE (ETH_DATA_LEN - EC_FRAME_HEADER_SIZE \
                           - EC_DATAGRAM_HEADER_SIZE - EC_DATAGRAM_FOOTER_SIZE)
 
+/** word offset of first EEPROM category. */
+#define EC_FIRST_EEPROM_CATEGORY_OFFSET 0x40
+
 /*****************************************************************************/
 
 /**
--- a/master/slave.c	Fri Aug 10 13:00:31 2007 +0000
+++ b/master/slave.c	Fri Aug 10 13:35:11 2007 +0000
@@ -925,7 +925,7 @@
         return -EINVAL;
     }
 
-    cat_header = request.words + 0x0040; // first category header
+    cat_header = request.words + EC_FIRST_EEPROM_CATEGORY_OFFSET;
     cat_type = EC_READ_U16(cat_header);
     while (cat_type != 0xFFFF) { // cycle through categories
         if (cat_header + 1 > request.words + request.size) {