master/fsm_master.c
changeset 656 370aa8c2d1b1
parent 652 15cff76b66c7
child 661 bc1de1362efb
equal deleted inserted replaced
655:3702f0d6693b 656:370aa8c2d1b1
   219         fsm->slave_states = EC_READ_U8(datagram->data);
   219         fsm->slave_states = EC_READ_U8(datagram->data);
   220         ec_state_string(fsm->slave_states, states);
   220         ec_state_string(fsm->slave_states, states);
   221         EC_INFO("Slave states: %s.\n", states);
   221         EC_INFO("Slave states: %s.\n", states);
   222     }
   222     }
   223 
   223 
   224     // topology change in idle mode: clear all slaves and scan the bus
   224     if (fsm->topology_change_pending) {
   225     if (fsm->topology_change_pending &&
   225         down(&master->scan_sem);
   226             master->mode == EC_MASTER_MODE_IDLE) {
   226         if (!master->allow_scan) {
   227         fsm->topology_change_pending = 0;
   227             up(&master->scan_sem);
   228         fsm->tainted = 0;
   228         }
   229         fsm->idle = 0;
   229         else {
   230         fsm->scan_jiffies = jiffies;
   230             master->scan_state = EC_REQUEST_IN_PROGRESS;
   231 
   231             up(&master->scan_sem);
   232         ec_master_eoe_stop(master);
   232             
   233         ec_master_destroy_slaves(master);
   233             // topology change when scan is allowed:
   234 
   234             // clear all slaves and scan the bus
   235         master->slave_count = datagram->working_counter;
   235             fsm->topology_change_pending = 0;
   236 
   236             fsm->tainted = 0;
   237         if (!master->slave_count) {
   237             fsm->idle = 0;
   238             // no slaves present -> finish state machine.
   238             fsm->scan_jiffies = jiffies;
   239             fsm->state = ec_fsm_master_state_end;
   239 
   240             return;
   240             ec_master_eoe_stop(master);
   241         }
   241             ec_master_destroy_slaves(master);
   242 
   242 
   243         // init slaves
   243             master->slave_count = datagram->working_counter;
   244         for (i = 0; i < master->slave_count; i++) {
   244 
   245             if (!(slave = (ec_slave_t *) kmalloc(sizeof(ec_slave_t),
   245             if (!master->slave_count) {
   246                                                  GFP_ATOMIC))) {
   246                 // no slaves present -> finish state machine.
   247                 EC_ERR("Failed to allocate slave %i!\n", i);
   247                 master->scan_state = EC_REQUEST_COMPLETE;
   248                 ec_master_destroy_slaves(master);
   248                 wake_up_interruptible(&master->scan_queue);
   249                 fsm->state = ec_fsm_master_state_error;
   249                 fsm->state = ec_fsm_master_state_end;
   250                 return;
   250                 return;
   251             }
   251             }
   252 
   252 
   253             if (ec_slave_init(slave, master, i, i + 1)) {
   253             // init slaves
   254                 // freeing of "slave" already done
   254             for (i = 0; i < master->slave_count; i++) {
   255                 ec_master_destroy_slaves(master);
   255                 if (!(slave = (ec_slave_t *) kmalloc(sizeof(ec_slave_t),
   256                 fsm->state = ec_fsm_master_state_error;
   256                                 GFP_ATOMIC))) {
   257                 return;
   257                     EC_ERR("Failed to allocate slave %i!\n", i);
       
   258                     ec_master_destroy_slaves(master);
       
   259                     master->scan_state = EC_REQUEST_FAILURE;
       
   260                     wake_up_interruptible(&master->scan_queue);
       
   261                     fsm->state = ec_fsm_master_state_error;
       
   262                     return;
       
   263                 }
       
   264 
       
   265                 if (ec_slave_init(slave, master, i, i + 1)) {
       
   266                     // freeing of "slave" already done
       
   267                     ec_master_destroy_slaves(master);
       
   268                     master->scan_state = EC_REQUEST_FAILURE;
       
   269                     wake_up_interruptible(&master->scan_queue);
       
   270                     fsm->state = ec_fsm_master_state_error;
       
   271                     return;
       
   272                 }
       
   273 
       
   274                 list_add_tail(&slave->list, &master->slaves);
   258             }
   275             }
   259 
   276 
   260             list_add_tail(&slave->list, &master->slaves);
   277             EC_INFO("Scanning bus.\n");
   261         }
   278 
   262 
   279             // begin scanning of slaves
   263         EC_INFO("Scanning bus.\n");
   280             fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
   264 
   281             fsm->state = ec_fsm_master_state_scan_slaves;
   265         // begin scanning of slaves
   282             ec_fsm_slave_start_scan(&fsm->fsm_slave, fsm->slave);
   266         fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
   283             ec_fsm_slave_exec(&fsm->fsm_slave); // execute immediately
   267         fsm->state = ec_fsm_master_state_scan_slaves;
   284             return;
   268         ec_fsm_slave_start_scan(&fsm->fsm_slave, fsm->slave);
   285         }
   269         ec_fsm_slave_exec(&fsm->fsm_slave); // execute immediately
       
   270         return;
       
   271     }
   286     }
   272 
   287 
   273     // fetch state from each slave
   288     // fetch state from each slave
   274     fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
   289     fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
   275     ec_datagram_nprd(fsm->datagram, fsm->slave->station_address, 0x0130, 2);
   290     ec_datagram_nprd(fsm->datagram, fsm->slave->station_address, 0x0130, 2);
   390 }
   405 }
   391 
   406 
   392 /*****************************************************************************/
   407 /*****************************************************************************/
   393 
   408 
   394 /**
   409 /**
   395    Master action: PROC_STATES.
   410  */
   396    Processes the slave states.
   411 
   397 */
   412 int ec_fsm_master_action_configure(
   398 
   413         ec_fsm_master_t *fsm /**< master state machine */
   399 void ec_fsm_master_action_process_states(ec_fsm_master_t *fsm
   414         )
   400                                          /**< master state machine */
   415 {
   401                                          )
   416     ec_slave_t *slave;
   402 {
       
   403     ec_master_t *master = fsm->master;
   417     ec_master_t *master = fsm->master;
   404     ec_slave_t *slave;
       
   405     char old_state[EC_STATE_STRING_SIZE], new_state[EC_STATE_STRING_SIZE];
   418     char old_state[EC_STATE_STRING_SIZE], new_state[EC_STATE_STRING_SIZE];
   406 
   419 
   407     // check if any slaves are not in the state, they're supposed to be
   420     // check if any slaves are not in the state, they're supposed to be
       
   421     // FIXME do not check all slaves in every cycle...
   408     list_for_each_entry(slave, &master->slaves, list) {
   422     list_for_each_entry(slave, &master->slaves, list) {
   409         if (slave->error_flag
   423         if (slave->error_flag
   410             || slave->online_state == EC_SLAVE_OFFLINE
   424                 || slave->online_state == EC_SLAVE_OFFLINE
   411             || slave->requested_state == EC_SLAVE_STATE_UNKNOWN
   425                 || slave->requested_state == EC_SLAVE_STATE_UNKNOWN
   412             || (slave->current_state == slave->requested_state
   426                 || (slave->current_state == slave->requested_state
   413                 && slave->self_configured)) continue;
   427                     && slave->self_configured)) continue;
   414 
   428 
   415         if (master->debug_level) {
   429         if (master->debug_level) {
   416             ec_state_string(slave->current_state, old_state);
   430             ec_state_string(slave->current_state, old_state);
   417             if (slave->current_state != slave->requested_state) {
   431             if (slave->current_state != slave->requested_state) {
   418                 ec_state_string(slave->requested_state, new_state);
   432                 ec_state_string(slave->requested_state, new_state);
   419                 EC_DBG("Changing state of slave %i (%s -> %s).\n",
   433                 EC_DBG("Changing state of slave %i (%s -> %s).\n",
   420                        slave->ring_position, old_state, new_state);
   434                         slave->ring_position, old_state, new_state);
   421             }
   435             }
   422             else if (!slave->self_configured) {
   436             else if (!slave->self_configured) {
   423                 EC_DBG("Reconfiguring slave %i (%s).\n",
   437                 EC_DBG("Reconfiguring slave %i (%s).\n",
   424                        slave->ring_position, old_state);
   438                         slave->ring_position, old_state);
   425             }
   439             }
   426         }
   440         }
   427 
   441 
   428         fsm->idle = 0;
   442         fsm->idle = 0;
   429         fsm->slave = slave;
   443         fsm->slave = slave;
   430         fsm->state = ec_fsm_master_state_configure_slave;
   444         fsm->state = ec_fsm_master_state_configure_slave;
   431         ec_fsm_slave_start_conf(&fsm->fsm_slave, slave);
   445         ec_fsm_slave_start_conf(&fsm->fsm_slave, slave);
   432         ec_fsm_slave_exec(&fsm->fsm_slave); // execute immediately
   446         ec_fsm_slave_exec(&fsm->fsm_slave); // execute immediately
   433         return;
   447         return 1;
       
   448     }
       
   449 
       
   450     if (fsm->config_error)
       
   451         master->config_state = EC_REQUEST_FAILURE;
       
   452     else
       
   453         master->config_state = EC_REQUEST_COMPLETE;
       
   454     wake_up_interruptible(&master->config_queue);
       
   455     return 0;
       
   456 }
       
   457 
       
   458 /*****************************************************************************/
       
   459 
       
   460 /**
       
   461    Master action: PROC_STATES.
       
   462    Processes the slave states.
       
   463 */
       
   464 
       
   465 void ec_fsm_master_action_process_states(ec_fsm_master_t *fsm
       
   466                                          /**< master state machine */
       
   467                                          )
       
   468 {
       
   469     ec_master_t *master = fsm->master;
       
   470     ec_slave_t *slave;
       
   471 
       
   472     down(&master->config_sem);
       
   473     if (!master->allow_config) {
       
   474         up(&master->config_sem);
       
   475     }
       
   476     else {
       
   477         master->config_state = EC_REQUEST_IN_PROGRESS;
       
   478         fsm->config_error = 0;
       
   479         up(&master->config_sem);
       
   480         
       
   481         // check for pending slave configurations
       
   482         if (ec_fsm_master_action_configure(fsm))
       
   483             return;
   434     }
   484     }
   435 
   485 
   436     // Check, if EoE processing has to be started
   486     // Check, if EoE processing has to be started
   437     ec_master_eoe_start(master);
   487     ec_master_eoe_start(master);
   438 
   488 
   767         return;
   817         return;
   768     }
   818     }
   769 
   819 
   770     EC_INFO("Bus scanning completed in %u ms.\n",
   820     EC_INFO("Bus scanning completed in %u ms.\n",
   771             (u32) (jiffies - fsm->scan_jiffies) * 1000 / HZ);
   821             (u32) (jiffies - fsm->scan_jiffies) * 1000 / HZ);
   772 
   822     master->scan_state = EC_REQUEST_COMPLETE;
   773     // set initial states of all slaves to PREOP to make mailbox
   823     wake_up_interruptible(&master->scan_queue);
   774     // communication possible
       
   775     list_for_each_entry(slave, &master->slaves, list) {
       
   776         if (slave->requested_state == EC_SLAVE_STATE_UNKNOWN)
       
   777             ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP);
       
   778     }
       
   779 
   824 
   780     fsm->state = ec_fsm_master_state_end;
   825     fsm->state = ec_fsm_master_state_end;
   781 }
   826 }
   782 
   827 
   783 /*****************************************************************************/
   828 /*****************************************************************************/
   792                                    )
   837                                    )
   793 {
   838 {
   794     if (ec_fsm_slave_exec(&fsm->fsm_slave)) // execute slave's state machine
   839     if (ec_fsm_slave_exec(&fsm->fsm_slave)) // execute slave's state machine
   795         return;
   840         return;
   796 
   841 
   797     ec_fsm_master_action_process_states(fsm);
   842     if (!ec_fsm_slave_success(&fsm->fsm_slave))
       
   843         fsm->config_error = 1;
       
   844 
       
   845     // configure next slave, if necessary
       
   846     if (ec_fsm_master_action_configure(fsm))
       
   847         return;
       
   848 
       
   849     fsm->state = ec_fsm_master_state_end;
   798 }
   850 }
   799 
   851 
   800 /*****************************************************************************/
   852 /*****************************************************************************/
   801 
   853 
   802 /**
   854 /**