Minor changes in fsm.c and slave.c
authorFlorian Pose <fp@igh-essen.com>
Tue, 27 Jun 2006 20:24:32 +0000
changeset 292 2cf6ae0a2419
parent 291 0b1f877cf3f1
child 293 14aeb79aa992
Minor changes in fsm.c and slave.c
master/fsm.c
master/slave.c
--- a/master/fsm.c	Tue Jun 27 20:08:15 2006 +0000
+++ b/master/fsm.c	Tue Jun 27 20:24:32 2006 +0000
@@ -57,7 +57,7 @@
 void ec_fsm_master_eeprom(ec_fsm_t *);
 
 void ec_fsm_slave_start_reading(ec_fsm_t *);
-void ec_fsm_slave_read_status(ec_fsm_t *);
+void ec_fsm_slave_read_state(ec_fsm_t *);
 void ec_fsm_slave_read_base(ec_fsm_t *);
 void ec_fsm_slave_read_dl(ec_fsm_t *);
 void ec_fsm_slave_eeprom_size(ec_fsm_t *);
@@ -99,7 +99,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;
@@ -109,7 +109,7 @@
 
     ec_command_init(&fsm->command);
     if (ec_command_prealloc(&fsm->command, EC_MAX_DATA_SIZE)) {
-        EC_ERR("FSM failed to allocate FSM command.\n");
+        EC_ERR("Failed to allocate FSM command.\n");
         return -1;
     }
 
@@ -290,36 +290,35 @@
     ec_slave_t *slave = fsm->slave;
 
     // have all states been read?
-    if (slave->list.next == &master->slaves) {
-
-        // check, if a bus validation has to be done
-        if (fsm->master_validation) {
-            fsm->master_validation = 0;
-            list_for_each_entry(slave, &master->slaves, list) {
-                if (slave->online) continue;
-
-                // At least one slave is offline. validate!
-                EC_INFO("Validating bus.\n");
-                fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
-                fsm->master_state = ec_fsm_master_validate_vendor;
-                fsm->sii_offset = 0x0008; // vendor ID
-                fsm->sii_mode = 0;
-                fsm->sii_state = ec_fsm_sii_start_reading;
-                fsm->sii_state(fsm); // execute immediately
-                return;
-            }
+    if (slave->list.next != &master->slaves) {
+        // process next slave
+        fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
+        ec_command_nprd(&fsm->command, fsm->slave->station_address, 0x0130, 2);
+        ec_master_queue_command(master, &fsm->command);
+        fsm->master_state = ec_fsm_master_states;
+        return;
+    }
+
+    // all slave stated read; check, if a bus validation has to be done
+    if (fsm->master_validation) {
+        fsm->master_validation = 0;
+        list_for_each_entry(slave, &master->slaves, list) {
+            if (slave->online) continue;
+
+            // At least one slave is offline. validate!
+            EC_INFO("Validating bus.\n");
+            fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
+            fsm->master_state = ec_fsm_master_validate_vendor;
+            fsm->sii_offset = 0x0008; // vendor ID
+            fsm->sii_mode = 0;
+            fsm->sii_state = ec_fsm_sii_start_reading;
+            fsm->sii_state(fsm); // execute immediately
+            return;
         }
-
-        fsm->master_state = ec_fsm_master_proc_states;
-        fsm->master_state(fsm); // execute immediately
-        return;
-    }
-
-    // process next slave
-    fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
-    ec_command_nprd(&fsm->command, fsm->slave->station_address, 0x0130, 2);
-    ec_master_queue_command(master, &fsm->command);
-    fsm->master_state = ec_fsm_master_states;
+    }
+
+    fsm->master_state = ec_fsm_master_proc_states;
+    fsm->master_state(fsm); // execute immediately
 }
 
 /*****************************************************************************/
@@ -412,6 +411,14 @@
         list_for_each_entry(slave, &master->slaves, list) {
             if (!slave->new_eeprom_data) continue;
 
+            if (!slave->online || slave->error_flag) {
+                kfree(slave->new_eeprom_data);
+                slave->new_eeprom_data = NULL;
+                EC_ERR("Discarding EEPROM data, slave %i not ready.\n",
+                       slave->ring_position);
+                continue;
+            }
+
             // found pending EEPROM write operation. execute it!
             EC_INFO("Writing EEPROM of slave %i...\n", slave->ring_position);
             fsm->sii_offset = 0x0000;
@@ -444,7 +451,7 @@
     fsm->sii_state(fsm); // execute SII state machine
 
     if (fsm->sii_state == ec_fsm_sii_error) {
-	fsm->slave->error_flag = 1;
+        fsm->slave->error_flag = 1;
         EC_ERR("Failed to validate vendor ID of slave %i.\n",
                slave->ring_position);
         fsm->master_state = ec_fsm_master_start;
@@ -483,7 +490,7 @@
     fsm->sii_state(fsm); // execute SII state machine
 
     if (fsm->sii_state == ec_fsm_sii_error) {
-	fsm->slave->error_flag = 1;
+        fsm->slave->error_flag = 1;
         EC_ERR("Failed to validate product code of slave %i.\n",
                slave->ring_position);
         fsm->master_state = ec_fsm_master_start;
@@ -622,7 +629,7 @@
             }
 
             if (!slave->type) {
-                EC_WARN("FSM: Unknown slave device (vendor 0x%08X,"
+                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);
@@ -640,8 +647,8 @@
 
             // determine initial state.
             if ((slave->type &&
-		 (slave->type->special == EC_TYPE_BUS_COUPLER ||
-		  slave->type->special == EC_TYPE_INFRA))) {
+                 (slave->type->special == EC_TYPE_BUS_COUPLER ||
+                  slave->type->special == EC_TYPE_INFRA))) {
                 slave->requested_state = EC_SLAVE_STATE_OP;
             }
             else {
@@ -702,7 +709,7 @@
     fsm->sii_state(fsm); // execute SII state machine
 
     if (fsm->sii_state == ec_fsm_sii_error) {
-	fsm->slave->error_flag = 1;
+        fsm->slave->error_flag = 1;
         EC_ERR("Failed to write EEPROM contents to slave %i.\n",
                slave->ring_position);
         kfree(slave->new_eeprom_data);
@@ -751,7 +758,7 @@
     ec_command_apwr(command, fsm->slave->ring_position, 0x0010, 2);
     EC_WRITE_U16(command->data, fsm->slave->station_address);
     ec_master_queue_command(fsm->master, command);
-    fsm->slave_state = ec_fsm_slave_read_status;
+    fsm->slave_state = ec_fsm_slave_read_state;
 }
 
 /*****************************************************************************/
@@ -760,18 +767,19 @@
    Slave state: READ_STATUS.
 */
 
-void ec_fsm_slave_read_status(ec_fsm_t *fsm /**< finite state machine */)
+void ec_fsm_slave_read_state(ec_fsm_t *fsm /**< finite state machine */)
 {
     ec_command_t *command = &fsm->command;
 
     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
-        EC_ERR("FSM failed to write station address of slave %i.\n",
+        fsm->slave->error_flag = 1;
+        fsm->slave_state = ec_fsm_slave_end;
+        EC_ERR("Failed to write station address of slave %i.\n",
                fsm->slave->ring_position);
-        fsm->slave_state = ec_fsm_slave_end;
-        return;
-    }
-
-    // read AL status
+        return;
+    }
+
+    // Read AL state
     ec_command_nprd(command, fsm->slave->station_address, 0x0130, 2);
     ec_master_queue_command(fsm->master, command);
     fsm->slave_state = ec_fsm_slave_read_base;
@@ -790,15 +798,15 @@
 
     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
         fsm->slave->error_flag = 1;
-        EC_ERR("FSM failed to read AL status of slave %i.\n",
+        fsm->slave_state = ec_fsm_slave_end;
+        EC_ERR("Failed to read AL state of slave %i.\n",
                fsm->slave->ring_position);
-        fsm->slave_state = ec_fsm_slave_end;
         return;
     }
 
     slave->current_state = EC_READ_U8(command->data);
     if (slave->current_state & EC_ACK) {
-        EC_WARN("Slave %i has status error bit set (0x%02X)!\n",
+        EC_WARN("Slave %i has state error bit set (0x%02X)!\n",
                 slave->ring_position, slave->current_state);
         slave->current_state &= 0x0F;
     }
@@ -822,9 +830,9 @@
 
     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
         fsm->slave->error_flag = 1;
-        EC_ERR("FSM failed to read base data of slave %i.\n",
+        fsm->slave_state = ec_fsm_slave_end;
+        EC_ERR("Failed to read base data of slave %i.\n",
                slave->ring_position);
-        fsm->slave_state = ec_fsm_slave_end;
         return;
     }
 
@@ -859,9 +867,9 @@
 
     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
         fsm->slave->error_flag = 1;
-        EC_ERR("FSM failed to read DL status of slave %i.\n",
+        fsm->slave_state = ec_fsm_slave_end;
+        EC_ERR("Failed to read DL status of slave %i.\n",
                slave->ring_position);
-        fsm->slave_state = ec_fsm_slave_end;
         return;
     }
 
@@ -896,7 +904,7 @@
     fsm->sii_state(fsm);
 
     if (fsm->sii_state == ec_fsm_sii_error) {
-	fsm->slave->error_flag = 1;
+        fsm->slave->error_flag = 1;
         fsm->slave_state = ec_fsm_slave_end;
         EC_ERR("Failed to read EEPROM size of slave %i.\n",
                slave->ring_position);
@@ -926,9 +934,9 @@
     if (!(slave->eeprom_data =
           (uint8_t *) kmalloc(slave->eeprom_size, GFP_ATOMIC))) {
         fsm->slave->error_flag = 1;
+        fsm->slave_state = ec_fsm_slave_end;
         EC_ERR("Failed to allocate EEPROM data on slave %i.\n",
                slave->ring_position);
-        fsm->slave_state = ec_fsm_slave_end;
         return;
     }
 
@@ -956,7 +964,7 @@
     fsm->sii_state(fsm);
 
     if (fsm->sii_state == ec_fsm_sii_error) {
-	fsm->slave->error_flag = 1;
+        fsm->slave->error_flag = 1;
         fsm->slave_state = ec_fsm_slave_end;
         EC_ERR("Failed to fetch EEPROM contents of slave %i.\n",
                slave->ring_position);
@@ -1045,7 +1053,7 @@
         cat_word += cat_size + 2;
     }
 
- end:
+end:
     fsm->slave->error_flag = 1;
     fsm->slave_state = ec_fsm_slave_end;
 }
@@ -1065,7 +1073,7 @@
     fsm->change_state(fsm); // execute state change state machine
 
     if (fsm->change_state == ec_fsm_change_error) {
-	slave->error_flag = 1;
+        slave->error_flag = 1;
         fsm->slave_state = ec_fsm_slave_end;
         return;
     }
@@ -1074,7 +1082,7 @@
 
     // slave is now in INIT
     if (slave->current_state == slave->requested_state) {
-        fsm->slave_state = ec_fsm_slave_end;
+        fsm->slave_state = ec_fsm_slave_end; // successful
         return;
     }
 
@@ -1116,10 +1124,10 @@
     ec_eeprom_sync_t *eeprom_sync, mbox_sync;
 
     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
+        slave->error_flag = 1;
+        fsm->slave_state = ec_fsm_slave_end;
         EC_ERR("Failed to reset FMMUs of slave %i.\n",
                slave->ring_position);
-        slave->error_flag = 1;
-        fsm->slave_state = ec_fsm_slave_end;
         return;
     }
 
@@ -1149,9 +1157,9 @@
         if (!list_empty(&slave->eeprom_syncs)) {
             list_for_each_entry(eeprom_sync, &slave->eeprom_syncs, list) {
                 if (eeprom_sync->index >= slave->base_sync_count) {
-                    EC_ERR("Invalid sync manager configuration found!");
                     fsm->slave->error_flag = 1;
                     fsm->slave_state = ec_fsm_slave_end;
+                    EC_ERR("Invalid sync manager configuration found!");
                     return;
                 }
                 ec_eeprom_sync_config(eeprom_sync,
@@ -1199,10 +1207,10 @@
     ec_slave_t *slave = fsm->slave;
 
     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
+        slave->error_flag = 1;
+        fsm->slave_state = ec_fsm_slave_end;
         EC_ERR("Failed to set sync managers on slave %i.\n",
                slave->ring_position);
-        slave->error_flag = 1;
-        fsm->slave_state = ec_fsm_slave_end;
         return;
     }
 
@@ -1229,7 +1237,7 @@
     fsm->change_state(fsm); // execute state change state machine
 
     if (fsm->change_state == ec_fsm_change_error) {
-	slave->error_flag = 1;
+        slave->error_flag = 1;
         fsm->slave_state = ec_fsm_slave_end;
         return;
     }
@@ -1238,13 +1246,13 @@
 
     // slave is now in PREOP
     if (slave->current_state == slave->requested_state) {
-        fsm->slave_state = ec_fsm_slave_end;
+        fsm->slave_state = ec_fsm_slave_end; // successful
         return;
     }
 
     // stop activation here for slaves without type
     if (!slave->type) {
-        fsm->slave_state = ec_fsm_slave_end;
+        fsm->slave_state = ec_fsm_slave_end; // successful
         return;
     }
 
@@ -1280,10 +1288,10 @@
 
     if (fsm->slave->base_fmmu_count && (command->state != EC_CMD_RECEIVED ||
                                         command->working_counter != 1)) {
-        EC_ERR("FSM failed to set FMMUs on slave %i.\n",
-               fsm->slave->ring_position);
         fsm->slave->error_flag = 1;
         fsm->slave_state = ec_fsm_slave_end;
+        EC_ERR("Failed to set FMMUs on slave %i.\n",
+               fsm->slave->ring_position);
         return;
     }
 
@@ -1306,7 +1314,7 @@
     fsm->change_state(fsm); // execute state change state machine
 
     if (fsm->change_state == ec_fsm_change_error) {
-	fsm->slave->error_flag = 1;
+        fsm->slave->error_flag = 1;
         fsm->slave_state = ec_fsm_slave_end;
         return;
     }
@@ -1315,7 +1323,7 @@
 
     // slave is now in SAVEOP
     if (fsm->slave->current_state == fsm->slave->requested_state) {
-        fsm->slave_state = ec_fsm_slave_end;
+        fsm->slave_state = ec_fsm_slave_end; // successful
         return;
     }
 
@@ -1338,7 +1346,7 @@
     fsm->change_state(fsm); // execute state change state machine
 
     if (fsm->change_state == ec_fsm_change_error) {
-	fsm->slave->error_flag = 1;
+        fsm->slave->error_flag = 1;
         fsm->slave_state = ec_fsm_slave_end;
         return;
     }
@@ -1346,7 +1354,7 @@
     if (fsm->change_state != ec_fsm_change_end) return;
 
     // slave is now in OP
-    fsm->slave_state = ec_fsm_slave_end;
+    fsm->slave_state = ec_fsm_slave_end; // successful
 }
 
 /*****************************************************************************/
@@ -1609,16 +1617,16 @@
     ec_slave_t *slave = fsm->slave;
 
     if (command->state != EC_CMD_RECEIVED) {
+        fsm->change_state = ec_fsm_change_error;
         EC_ERR("Failed to send state command to slave %i!\n",
                fsm->slave->ring_position);
+        return;
+    }
+
+    if (command->working_counter != 1) {
         fsm->change_state = ec_fsm_change_error;
-        return;
-    }
-
-    if (command->working_counter != 1) {
         EC_ERR("Failed to set state 0x%02X on slave %i: Slave did not"
                " respond.\n", fsm->change_new, fsm->slave->ring_position);
-        fsm->change_state = ec_fsm_change_error;
         return;
     }
 
@@ -1642,9 +1650,9 @@
     ec_slave_t *slave = fsm->slave;
 
     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
+        fsm->change_state = ec_fsm_change_error;
         EC_ERR("Failed to check state 0x%02X on slave %i.\n",
                fsm->change_new, slave->ring_position);
-        fsm->change_state = ec_fsm_change_error;
         return;
     }
 
@@ -1722,8 +1730,8 @@
     const ec_code_msg_t *al_msg;
 
     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
+        fsm->change_state = ec_fsm_change_error;
         EC_ERR("Reception of AL status code command failed.\n");
-        fsm->change_state = ec_fsm_change_error;
         return;
     }
 
@@ -1757,8 +1765,8 @@
     ec_slave_t *slave = fsm->slave;
 
     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
+        fsm->change_state = ec_fsm_change_error;
         EC_ERR("Reception of state ack command failed.\n");
-        fsm->change_state = ec_fsm_change_error;
         return;
     }
 
@@ -1781,23 +1789,23 @@
     ec_slave_t *slave = fsm->slave;
 
     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
+        fsm->change_state = ec_fsm_change_error;
         EC_ERR("Reception of state ack check command failed.\n");
+        return;
+    }
+
+    slave->current_state = EC_READ_U8(command->data);
+
+    if (slave->current_state == fsm->change_new) {
         fsm->change_state = ec_fsm_change_error;
-        return;
-    }
-
-    slave->current_state = EC_READ_U8(command->data);
-
-    if (slave->current_state == fsm->change_new) {
         EC_INFO("Acknowleged state 0x%02X on slave %i.\n",
                 slave->current_state, slave->ring_position);
-        fsm->change_state = ec_fsm_change_error;
-        return;
-    }
-
+        return;
+    }
+
+    fsm->change_state = ec_fsm_change_error;
     EC_WARN("Failed to acknowledge state 0x%02X on slave %i"
             " - Timeout!\n", fsm->change_new, slave->ring_position);
-    fsm->change_state = ec_fsm_change_error;
 }
 
 /*****************************************************************************/
--- a/master/slave.c	Tue Jun 27 20:08:15 2006 +0000
+++ b/master/slave.c	Tue Jun 27 20:24:32 2006 +0000
@@ -1422,28 +1422,23 @@
     ec_slave_t *slave = container_of(kobj, ec_slave_t, kobj);
 
     if (attr == &attr_state) {
-        if (!strcmp(buffer, "INIT\n")) {
+        if (!strcmp(buffer, "INIT\n"))
             slave->requested_state = EC_SLAVE_STATE_INIT;
-            slave->error_flag = 0;
-            return size;
-        }
-        else if (!strcmp(buffer, "PREOP\n")) {
+        else if (!strcmp(buffer, "PREOP\n"))
             slave->requested_state = EC_SLAVE_STATE_PREOP;
-            slave->error_flag = 0;
-            return size;
-        }
-        else if (!strcmp(buffer, "SAVEOP\n")) {
+        else if (!strcmp(buffer, "SAVEOP\n"))
             slave->requested_state = EC_SLAVE_STATE_SAVEOP;
-            slave->error_flag = 0;
-            return size;
-        }
-        else if (!strcmp(buffer, "OP\n")) {
+        else if (!strcmp(buffer, "OP\n"))
             slave->requested_state = EC_SLAVE_STATE_OP;
-            slave->error_flag = 0;
-            return size;
-        }
-
-        EC_ERR("Failed to set slave state!\n");
+        else {
+            EC_ERR("Invalid slave state \"%s\"!\n", buffer);
+            return -EINVAL;
+        }
+
+        EC_INFO("Accepted new state %s for slave %i.\n",
+                buffer, slave->ring_position);
+        slave->error_flag = 0;
+        return size;
     }
     else if (attr == &attr_eeprom) {
         if (!ec_slave_write_eeprom(slave, buffer, size))