master/fsm_master.c
changeset 900 f8b5c6d21705
parent 880 f6212c54a5e3
child 904 ba6f222aa06e
equal deleted inserted replaced
899:e82e2e4cdc9b 900:f8b5c6d21705
    52 
    52 
    53 void ec_fsm_master_state_start(ec_fsm_master_t *);
    53 void ec_fsm_master_state_start(ec_fsm_master_t *);
    54 void ec_fsm_master_state_broadcast(ec_fsm_master_t *);
    54 void ec_fsm_master_state_broadcast(ec_fsm_master_t *);
    55 void ec_fsm_master_state_read_states(ec_fsm_master_t *);
    55 void ec_fsm_master_state_read_states(ec_fsm_master_t *);
    56 void ec_fsm_master_state_acknowledge(ec_fsm_master_t *);
    56 void ec_fsm_master_state_acknowledge(ec_fsm_master_t *);
    57 void ec_fsm_master_state_validate_vendor(ec_fsm_master_t *);
       
    58 void ec_fsm_master_state_validate_product(ec_fsm_master_t *);
       
    59 void ec_fsm_master_state_rewrite_addresses(ec_fsm_master_t *);
       
    60 void ec_fsm_master_state_configure_slave(ec_fsm_master_t *);
    57 void ec_fsm_master_state_configure_slave(ec_fsm_master_t *);
    61 void ec_fsm_master_state_clear_addresses(ec_fsm_master_t *);
    58 void ec_fsm_master_state_clear_addresses(ec_fsm_master_t *);
    62 void ec_fsm_master_state_scan_slaves(ec_fsm_master_t *);
    59 void ec_fsm_master_state_scan_slaves(ec_fsm_master_t *);
    63 void ec_fsm_master_state_write_sii(ec_fsm_master_t *);
    60 void ec_fsm_master_state_write_sii(ec_fsm_master_t *);
    64 void ec_fsm_master_state_sdodict(ec_fsm_master_t *);
    61 void ec_fsm_master_state_sdodict(ec_fsm_master_t *);
    82     fsm->state = ec_fsm_master_state_start;
    79     fsm->state = ec_fsm_master_state_start;
    83     fsm->idle = 0;
    80     fsm->idle = 0;
    84     fsm->slaves_responding = 0;
    81     fsm->slaves_responding = 0;
    85     fsm->topology_change_pending = 0;
    82     fsm->topology_change_pending = 0;
    86     fsm->slave_states = EC_SLAVE_STATE_UNKNOWN;
    83     fsm->slave_states = EC_SLAVE_STATE_UNKNOWN;
    87     fsm->validate = 0;
       
    88     fsm->tainted = 0;
       
    89 
    84 
    90     // init sub-state-machines
    85     // init sub-state-machines
    91     ec_fsm_slave_config_init(&fsm->fsm_slave_config, fsm->datagram);
    86     ec_fsm_slave_config_init(&fsm->fsm_slave_config, fsm->datagram);
    92     ec_fsm_slave_scan_init(&fsm->fsm_slave_scan, fsm->datagram,
    87     ec_fsm_slave_scan_init(&fsm->fsm_slave_scan, fsm->datagram,
    93             &fsm->fsm_slave_config, &fsm->fsm_coe_map);
    88             &fsm->fsm_slave_config, &fsm->fsm_coe_map);
   210         fsm->slaves_responding = datagram->working_counter;
   205         fsm->slaves_responding = datagram->working_counter;
   211 
   206 
   212         EC_INFO("%u slave%s responding.\n",
   207         EC_INFO("%u slave%s responding.\n",
   213                 fsm->slaves_responding,
   208                 fsm->slaves_responding,
   214                 fsm->slaves_responding == 1 ? "" : "s");
   209                 fsm->slaves_responding == 1 ? "" : "s");
   215 
       
   216         if (master->mode == EC_MASTER_MODE_OPERATION) {
       
   217             if (fsm->slaves_responding == master->slave_count) {
       
   218                 fsm->validate = 1; // start validation later
       
   219             }
       
   220             else {
       
   221                 EC_WARN("Invalid slave count. Bus in tainted state.\n");
       
   222                 fsm->tainted = 1;
       
   223             }
       
   224         }
       
   225     }
   210     }
   226 
   211 
   227     // slave states changed?
   212     // slave states changed?
   228     if (EC_READ_U8(datagram->data) != fsm->slave_states) {
   213     if (EC_READ_U8(datagram->data) != fsm->slave_states) {
   229         char states[EC_STATE_STRING_SIZE];
   214         char states[EC_STATE_STRING_SIZE];
   234 
   219 
   235     if (fsm->topology_change_pending) {
   220     if (fsm->topology_change_pending) {
   236         down(&master->scan_sem);
   221         down(&master->scan_sem);
   237         if (!master->allow_scan) {
   222         if (!master->allow_scan) {
   238             up(&master->scan_sem);
   223             up(&master->scan_sem);
   239         }
   224         } else {
   240         else {
   225             master->scan_busy = 1;
   241             master->scan_state = EC_REQUEST_BUSY;
       
   242             up(&master->scan_sem);
   226             up(&master->scan_sem);
   243             
   227             
   244             // topology change when scan is allowed:
   228             // topology change when scan is allowed:
   245             // clear all slaves and scan the bus
   229             // clear all slaves and scan the bus
   246             fsm->topology_change_pending = 0;
   230             fsm->topology_change_pending = 0;
   247             fsm->tainted = 0;
       
   248             fsm->idle = 0;
   231             fsm->idle = 0;
   249             fsm->scan_jiffies = jiffies;
   232             fsm->scan_jiffies = jiffies;
   250 
   233 
   251 #ifdef EC_EOE
   234 #ifdef EC_EOE
   252             ec_master_eoe_stop(master);
   235             ec_master_eoe_stop(master);
   256 
   239 
   257             master->slave_count = datagram->working_counter;
   240             master->slave_count = datagram->working_counter;
   258 
   241 
   259             if (!master->slave_count) {
   242             if (!master->slave_count) {
   260                 // no slaves present -> finish state machine.
   243                 // no slaves present -> finish state machine.
   261                 master->scan_state = EC_REQUEST_SUCCESS;
   244                 master->scan_busy = 0;
   262                 wake_up_interruptible(&master->scan_queue);
   245                 wake_up_interruptible(&master->scan_queue);
   263                 fsm->state = ec_fsm_master_state_end;
   246                 fsm->state = ec_fsm_master_state_end;
   264                 return;
   247                 return;
   265             }
   248             }
   266 
   249 
   268             for (i = 0; i < master->slave_count; i++) {
   251             for (i = 0; i < master->slave_count; i++) {
   269                 if (!(slave = (ec_slave_t *) kmalloc(sizeof(ec_slave_t),
   252                 if (!(slave = (ec_slave_t *) kmalloc(sizeof(ec_slave_t),
   270                                 GFP_ATOMIC))) {
   253                                 GFP_ATOMIC))) {
   271                     EC_ERR("Failed to allocate slave %i!\n", i);
   254                     EC_ERR("Failed to allocate slave %i!\n", i);
   272                     ec_master_destroy_slaves(master);
   255                     ec_master_destroy_slaves(master);
   273                     master->scan_state = EC_REQUEST_FAILURE;
   256                     master->scan_busy = 0;
   274                     wake_up_interruptible(&master->scan_queue);
   257                     wake_up_interruptible(&master->scan_queue);
   275                     fsm->state = ec_fsm_master_state_error;
   258                     fsm->state = ec_fsm_master_state_error;
   276                     return;
   259                     return;
   277                 }
   260                 }
   278 
   261 
   279                 if (ec_slave_init(slave, master, i, i + 1)) {
   262                 if (ec_slave_init(slave, master, i, i + 1)) {
   280                     // freeing of "slave" already done
   263                     // freeing of "slave" already done
   281                     ec_master_destroy_slaves(master);
   264                     ec_master_destroy_slaves(master);
   282                     master->scan_state = EC_REQUEST_FAILURE;
   265                     master->scan_busy = 0;
   283                     wake_up_interruptible(&master->scan_queue);
   266                     wake_up_interruptible(&master->scan_queue);
   284                     fsm->state = ec_fsm_master_state_error;
   267                     fsm->state = ec_fsm_master_state_error;
   285                     return;
   268                     return;
   286                 }
   269                 }
   287 
   270 
   502         ec_fsm_slave_config_start(&fsm->fsm_slave_config, slave);
   485         ec_fsm_slave_config_start(&fsm->fsm_slave_config, slave);
   503         ec_fsm_slave_config_exec(&fsm->fsm_slave_config); // execute immediately
   486         ec_fsm_slave_config_exec(&fsm->fsm_slave_config); // execute immediately
   504         return 1;
   487         return 1;
   505     }
   488     }
   506 
   489 
   507     if (fsm->config_error)
   490     master->config_busy = 0;
   508         master->config_state = EC_REQUEST_FAILURE;
       
   509     else
       
   510         master->config_state = EC_REQUEST_SUCCESS;
       
   511     wake_up_interruptible(&master->config_queue);
   491     wake_up_interruptible(&master->config_queue);
   512     return 0;
   492     return 0;
   513 }
   493 }
   514 
   494 
   515 /*****************************************************************************/
   495 /*****************************************************************************/
   524                                          )
   504                                          )
   525 {
   505 {
   526     ec_master_t *master = fsm->master;
   506     ec_master_t *master = fsm->master;
   527     ec_slave_t *slave;
   507     ec_slave_t *slave;
   528 
   508 
       
   509     // Start slave configuration, if it is allowed.
   529     down(&master->config_sem);
   510     down(&master->config_sem);
   530     if (!master->allow_config) {
   511     if (!master->allow_config) {
   531         up(&master->config_sem);
   512         up(&master->config_sem);
   532     } else {
   513     } else {
   533         master->config_state = EC_REQUEST_BUSY;
   514         master->config_busy = 1;
   534         fsm->config_error = 0;
       
   535         up(&master->config_sem);
   515         up(&master->config_sem);
   536 
   516 
   537         // check for pending slave configurations
   517         // check for pending slave configurations
   538         if (ec_fsm_master_action_configure(fsm))
   518         if (ec_fsm_master_action_configure(fsm))
   539             return;
   519             return;
   601         fsm->state = ec_fsm_master_state_read_states;
   581         fsm->state = ec_fsm_master_state_read_states;
   602         return;
   582         return;
   603     }
   583     }
   604 
   584 
   605     // all slave states read
   585     // all slave states read
   606 
       
   607     // check, if a bus validation has to be done
       
   608     if (fsm->validate) {
       
   609         fsm->validate = 0;
       
   610         list_for_each_entry(slave, &master->slaves, list) {
       
   611             if (slave->online_state == EC_SLAVE_ONLINE) continue;
       
   612 
       
   613             // At least one slave is offline. validate!
       
   614             EC_INFO("Validating bus.\n");
       
   615             fsm->idle = 0;
       
   616             fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
       
   617             fsm->state = ec_fsm_master_state_validate_vendor;
       
   618             ec_fsm_sii_read(&fsm->fsm_sii, slave, 0x0008,
       
   619                     EC_FSM_SII_USE_INCREMENT_ADDRESS);
       
   620             ec_fsm_sii_exec(&fsm->fsm_sii); // execute immediately
       
   621             return;
       
   622         }
       
   623     }
       
   624 
       
   625     ec_fsm_master_action_process_states(fsm);
   586     ec_fsm_master_action_process_states(fsm);
   626 }
   587 }
   627 
   588 
   628 /*****************************************************************************/
   589 /*****************************************************************************/
   629 
   590 
   697 }
   658 }
   698 
   659 
   699 /*****************************************************************************/
   660 /*****************************************************************************/
   700 
   661 
   701 /**
   662 /**
   702    Master state: VALIDATE_VENDOR.
       
   703    Validates the vendor ID of a slave.
       
   704 */
       
   705 
       
   706 void ec_fsm_master_state_validate_vendor(ec_fsm_master_t *fsm /**< master state machine */)
       
   707 {
       
   708     ec_slave_t *slave = fsm->slave;
       
   709 
       
   710     if (ec_fsm_sii_exec(&fsm->fsm_sii)) return;
       
   711 
       
   712     if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
       
   713         fsm->slave->error_flag = 1;
       
   714         EC_ERR("Failed to validate vendor ID of slave %i.\n",
       
   715                slave->ring_position);
       
   716         fsm->state = ec_fsm_master_state_error;
       
   717         return;
       
   718     }
       
   719 
       
   720     if (EC_READ_U32(fsm->fsm_sii.value) != slave->sii.vendor_id) {
       
   721         EC_ERR("Slave %i has an invalid vendor ID!\n", slave->ring_position);
       
   722         fsm->state = ec_fsm_master_state_error;
       
   723         return;
       
   724     }
       
   725 
       
   726     // vendor ID is ok. check product code.
       
   727     fsm->state = ec_fsm_master_state_validate_product;
       
   728     ec_fsm_sii_read(&fsm->fsm_sii, slave, 0x000A,
       
   729             EC_FSM_SII_USE_INCREMENT_ADDRESS);
       
   730     ec_fsm_sii_exec(&fsm->fsm_sii); // execute immediately
       
   731 }
       
   732 
       
   733 /*****************************************************************************/
       
   734 
       
   735 /**
       
   736    Master action: ADDRESS.
       
   737    Looks for slave, that have lost their configuration and writes
       
   738    their station address, so that they can be reconfigured later.
       
   739 */
       
   740 
       
   741 void ec_fsm_master_action_addresses(ec_fsm_master_t *fsm /**< master state machine */)
       
   742 {
       
   743     ec_datagram_t *datagram = fsm->datagram;
       
   744 
       
   745     while (fsm->slave->online_state == EC_SLAVE_ONLINE) {
       
   746         if (fsm->slave->list.next == &fsm->master->slaves) { // last slave?
       
   747             fsm->state = ec_fsm_master_state_end;
       
   748             return;
       
   749         }
       
   750         // check next slave
       
   751         fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
       
   752     }
       
   753 
       
   754     if (fsm->master->debug_level)
       
   755         EC_DBG("Reinitializing slave %i.\n", fsm->slave->ring_position);
       
   756 
       
   757     // write station address
       
   758     ec_datagram_apwr(datagram, fsm->slave->ring_position, 0x0010, 2);
       
   759     EC_WRITE_U16(datagram->data, fsm->slave->station_address);
       
   760     fsm->retries = EC_FSM_RETRIES;
       
   761     fsm->state = ec_fsm_master_state_rewrite_addresses;
       
   762 }
       
   763 
       
   764 /*****************************************************************************/
       
   765 
       
   766 /**
       
   767    Master state: VALIDATE_PRODUCT.
       
   768    Validates the product ID of a slave.
       
   769 */
       
   770 
       
   771 void ec_fsm_master_state_validate_product(ec_fsm_master_t *fsm /**< master state machine */)
       
   772 {
       
   773     ec_slave_t *slave = fsm->slave;
       
   774 
       
   775     if (ec_fsm_sii_exec(&fsm->fsm_sii)) return;
       
   776 
       
   777     if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
       
   778         fsm->slave->error_flag = 1;
       
   779         EC_ERR("Failed to validate product code of slave %i.\n",
       
   780                slave->ring_position);
       
   781         fsm->state = ec_fsm_master_state_error;
       
   782         return;
       
   783     }
       
   784 
       
   785     if (EC_READ_U32(fsm->fsm_sii.value) != slave->sii.product_code) {
       
   786         EC_ERR("Slave %i: invalid product code!\n", slave->ring_position);
       
   787         EC_ERR("expected 0x%08X, got 0x%08X.\n", slave->sii.product_code,
       
   788                EC_READ_U32(fsm->fsm_sii.value));
       
   789         fsm->state = ec_fsm_master_state_error;
       
   790         return;
       
   791     }
       
   792 
       
   793     // have all states been validated?
       
   794     if (slave->list.next == &fsm->master->slaves) {
       
   795         fsm->topology_change_pending = 0;
       
   796         fsm->tainted = 0;
       
   797         fsm->slave = list_entry(fsm->master->slaves.next, ec_slave_t, list);
       
   798         // start writing addresses to offline slaves
       
   799         ec_fsm_master_action_addresses(fsm);
       
   800         return;
       
   801     }
       
   802 
       
   803     // validate next slave
       
   804     fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
       
   805     fsm->state = ec_fsm_master_state_validate_vendor;
       
   806     ec_fsm_sii_read(&fsm->fsm_sii, slave, 0x0008,
       
   807             EC_FSM_SII_USE_INCREMENT_ADDRESS);
       
   808     ec_fsm_sii_exec(&fsm->fsm_sii); // execute immediately
       
   809 }
       
   810 
       
   811 /*****************************************************************************/
       
   812 
       
   813 /**
       
   814    Master state: REWRITE ADDRESS.
       
   815    Checks, if the new station address has been written to the slave.
       
   816 */
       
   817 
       
   818 void ec_fsm_master_state_rewrite_addresses(ec_fsm_master_t *fsm
       
   819                                      /**< master state machine */
       
   820                                      )
       
   821 {
       
   822     ec_slave_t *slave = fsm->slave;
       
   823     ec_datagram_t *datagram = fsm->datagram;
       
   824 
       
   825     if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
       
   826         return;
       
   827 
       
   828     if (datagram->state != EC_DATAGRAM_RECEIVED) {
       
   829         EC_ERR("Failed to receive address datagram for slave %i"
       
   830                 " (datagram state %i).\n",
       
   831                 slave->ring_position, datagram->state);
       
   832         fsm->state = ec_fsm_master_state_error;
       
   833         return;
       
   834     }
       
   835 
       
   836     if (datagram->working_counter != 1) {
       
   837         EC_ERR("Failed to write station address of slave %i: ",
       
   838                slave->ring_position);
       
   839         ec_datagram_print_wc_error(datagram);
       
   840         fsm->state = ec_fsm_master_state_error;
       
   841         return;
       
   842     }
       
   843 
       
   844     if (fsm->slave->list.next == &fsm->master->slaves) { // last slave?
       
   845         fsm->state = ec_fsm_master_state_end;
       
   846         return;
       
   847     }
       
   848 
       
   849     // check next slave
       
   850     fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
       
   851     // Write new station address to slave
       
   852     ec_fsm_master_action_addresses(fsm);
       
   853 }
       
   854 
       
   855 /*****************************************************************************/
       
   856 
       
   857 /**
       
   858  * Master state: CLEAR ADDRESSES.
   663  * Master state: CLEAR ADDRESSES.
   859  */
   664  */
   860 
   665 
   861 void ec_fsm_master_state_clear_addresses(
   666 void ec_fsm_master_state_clear_addresses(
   862         ec_fsm_master_t *fsm /**< master state machine */
   667         ec_fsm_master_t *fsm /**< master state machine */
   869         return;
   674         return;
   870 
   675 
   871     if (datagram->state != EC_DATAGRAM_RECEIVED) {
   676     if (datagram->state != EC_DATAGRAM_RECEIVED) {
   872         EC_ERR("Failed to receive address clearing datagram (state %i).\n",
   677         EC_ERR("Failed to receive address clearing datagram (state %i).\n",
   873                 datagram->state);
   678                 datagram->state);
   874         master->scan_state = EC_REQUEST_FAILURE;
   679         master->scan_busy = 0;
   875         wake_up_interruptible(&master->scan_queue);
   680         wake_up_interruptible(&master->scan_queue);
   876         fsm->state = ec_fsm_master_state_error;
   681         fsm->state = ec_fsm_master_state_error;
   877         return;
   682         return;
   878     }
   683     }
   879 
   684 
   913         // create EoE handler for this slave
   718         // create EoE handler for this slave
   914         ec_eoe_t *eoe;
   719         ec_eoe_t *eoe;
   915         if (!(eoe = kmalloc(sizeof(ec_eoe_t), GFP_KERNEL))) {
   720         if (!(eoe = kmalloc(sizeof(ec_eoe_t), GFP_KERNEL))) {
   916             EC_ERR("Failed to allocate EoE handler memory for slave %u!\n",
   721             EC_ERR("Failed to allocate EoE handler memory for slave %u!\n",
   917                     slave->ring_position);
   722                     slave->ring_position);
   918         }
   723         } else if (ec_eoe_init(eoe, slave)) {
   919         else if (ec_eoe_init(eoe, slave)) {
       
   920             EC_ERR("Failed to init EoE handler for slave %u!\n",
   724             EC_ERR("Failed to init EoE handler for slave %u!\n",
   921                     slave->ring_position);
   725                     slave->ring_position);
   922             kfree(eoe);
   726             kfree(eoe);
   923         }
   727         } else {
   924         else {
       
   925             list_add_tail(&eoe->list, &master->eoe_handlers);
   728             list_add_tail(&eoe->list, &master->eoe_handlers);
   926         }
   729         }
   927     }
   730     }
   928 #endif
   731 #endif
   929 
   732 
   936     }
   739     }
   937 
   740 
   938     EC_INFO("Bus scanning completed in %u ms.\n",
   741     EC_INFO("Bus scanning completed in %u ms.\n",
   939             (u32) (jiffies - fsm->scan_jiffies) * 1000 / HZ);
   742             (u32) (jiffies - fsm->scan_jiffies) * 1000 / HZ);
   940 
   743 
       
   744     master->scan_busy = 0;
       
   745     wake_up_interruptible(&master->scan_queue);
       
   746 
   941     // Attach slave configurations
   747     // Attach slave configurations
   942     ec_master_attach_slave_configs(master);
   748     ec_master_attach_slave_configs(master);
   943 
   749 
   944 #ifdef EC_EOE
   750 #ifdef EC_EOE
   945     // check if EoE processing has to be started
   751     // check if EoE processing has to be started
   946     ec_master_eoe_start(master);
   752     ec_master_eoe_start(master);
   947 #endif
   753 #endif
   948 
   754 
   949     master->scan_state = EC_REQUEST_SUCCESS;
       
   950     wake_up_interruptible(&master->scan_queue);
       
   951 
       
   952     fsm->state = ec_fsm_master_state_end;
   755     fsm->state = ec_fsm_master_state_end;
   953 }
   756 }
   954 
   757 
   955 /*****************************************************************************/
   758 /*****************************************************************************/
   956 
   759 
   964                                    )
   767                                    )
   965 {
   768 {
   966     if (ec_fsm_slave_config_exec(&fsm->fsm_slave_config)) // execute slave's state machine
   769     if (ec_fsm_slave_config_exec(&fsm->fsm_slave_config)) // execute slave's state machine
   967         return;
   770         return;
   968 
   771 
   969     if (!ec_fsm_slave_config_success(&fsm->fsm_slave_config))
   772     if (!ec_fsm_slave_config_success(&fsm->fsm_slave_config)) {
   970         fsm->config_error = 1;
   773         // TODO: mark slave_config as failed.
       
   774     }
   971 
   775 
   972     // configure next slave, if necessary
   776     // configure next slave, if necessary
   973     if (ec_fsm_master_action_configure(fsm))
   777     if (ec_fsm_master_action_configure(fsm))
   974         return;
   778         return;
   975 
   779