master/master.c
changeset 900 f8b5c6d21705
parent 879 9b395c5646ab
child 901 5ecf7e5729f9
equal deleted inserted replaced
899:e82e2e4cdc9b 900:f8b5c6d21705
   124     INIT_LIST_HEAD(&master->slaves);
   124     INIT_LIST_HEAD(&master->slaves);
   125     master->slave_count = 0;
   125     master->slave_count = 0;
   126     
   126     
   127     INIT_LIST_HEAD(&master->configs);
   127     INIT_LIST_HEAD(&master->configs);
   128 
   128 
   129     master->scan_state = EC_REQUEST_SUCCESS;
   129     master->scan_busy = 0;
   130     master->allow_scan = 1;
   130     master->allow_scan = 1;
   131     init_MUTEX(&master->scan_sem);
   131     init_MUTEX(&master->scan_sem);
   132     init_waitqueue_head(&master->scan_queue);
   132     init_waitqueue_head(&master->scan_queue);
   133 
   133 
   134     master->config_state = EC_REQUEST_SUCCESS;
   134     master->config_busy = 0;
   135     master->allow_config = 1;
   135     master->allow_config = 1;
   136     init_MUTEX(&master->config_sem);
   136     init_MUTEX(&master->config_sem);
   137     init_waitqueue_head(&master->config_queue);
   137     init_waitqueue_head(&master->config_queue);
   138     
   138     
   139     INIT_LIST_HEAD(&master->datagram_queue);
   139     INIT_LIST_HEAD(&master->datagram_queue);
   144     master->debug_level = 0;
   144     master->debug_level = 0;
   145     master->stats.timeouts = 0;
   145     master->stats.timeouts = 0;
   146     master->stats.corrupted = 0;
   146     master->stats.corrupted = 0;
   147     master->stats.unmatched = 0;
   147     master->stats.unmatched = 0;
   148     master->stats.output_jiffies = 0;
   148     master->stats.output_jiffies = 0;
   149     master->pdo_slaves_offline = 0; // assume all Pdo slaves online
       
   150     master->frames_timed_out = 0;
   149     master->frames_timed_out = 0;
   151 
   150 
   152     for (i = 0; i < HZ; i++) {
   151     for (i = 0; i < HZ; i++) {
   153         master->idle_cycle_times[i] = 0;
   152         master->idle_cycle_times[i] = 0;
   154 #ifdef EC_EOE
   153 #ifdef EC_EOE
   440     ec_eoe_t *eoe;
   439     ec_eoe_t *eoe;
   441 #endif
   440 #endif
   442 
   441 
   443     down(&master->config_sem);
   442     down(&master->config_sem);
   444     master->allow_config = 0; // temporarily disable slave configuration
   443     master->allow_config = 0; // temporarily disable slave configuration
   445     up(&master->config_sem);
   444     if (master->config_busy) {
   446 
   445         up(&master->config_sem);
   447     // wait for slave configuration to complete
   446 
   448     if (wait_event_interruptible(master->config_queue,
   447         // wait for slave configuration to complete
   449                 master->config_state != EC_REQUEST_BUSY)) {
   448         if (wait_event_interruptible(master->config_queue,
   450         EC_INFO("Finishing slave configuration interrupted by signal.\n");
   449                     !master->config_busy)) {
   451         goto out_allow;
   450             EC_INFO("Finishing slave configuration interrupted by signal.\n");
   452     }
   451             goto out_allow;
   453 
   452         }
   454     if (master->debug_level)
   453 
   455         EC_DBG("Waiting for pending slave configuration returned.\n");
   454         if (master->debug_level)
   456 
   455             EC_DBG("Waiting for pending slave configuration returned.\n");
   457     if (master->debug_level)
   456     } else {
   458         EC_DBG("Disable scanning, current scan state: %u\n",
   457         up(&master->config_sem);
   459                 master->scan_state);
   458     }
       
   459 
   460     down(&master->scan_sem);
   460     down(&master->scan_sem);
   461     master->allow_scan = 0; // 'lock' the slave list
   461     master->allow_scan = 0; // 'lock' the slave list
   462     up(&master->scan_sem);
   462     if (!master->scan_busy) {
   463 
   463         up(&master->scan_sem);
   464     if (master->scan_state == EC_REQUEST_BUSY) {
   464     } else {
       
   465         up(&master->scan_sem);
       
   466 
   465         // wait for slave scan to complete
   467         // wait for slave scan to complete
   466         if (wait_event_interruptible(master->scan_queue,
   468         if (wait_event_interruptible(master->scan_queue, !master->scan_busy)) {
   467                     master->scan_state != EC_REQUEST_BUSY)) {
       
   468             EC_INFO("Waiting for slave scan interrupted by signal.\n");
   469             EC_INFO("Waiting for slave scan interrupted by signal.\n");
   469             goto out_allow;
   470             goto out_allow;
   470         }
   471         }
   471     }
   472         
   472 
   473         if (master->debug_level)
   473     if (master->debug_level)
   474             EC_DBG("Waiting for pending slave scan returned.\n");
   474         EC_DBG("Waiting for pending slave scan returned.\n");
   475     }
   475 
   476 
   476     // set states for all slaves
   477     // set states for all slaves
   477     list_for_each_entry(slave, &master->slaves, list) {
   478     list_for_each_entry(slave, &master->slaves, list) {
   478         ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP);
   479         ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP);
   479     }
   480     }
  1003             break;
  1004             break;
  1004     }
  1005     }
  1005 
  1006 
  1006     off += sprintf(buffer + off, "\nSlaves: %i\n",
  1007     off += sprintf(buffer + off, "\nSlaves: %i\n",
  1007                    master->slave_count);
  1008                    master->slave_count);
  1008     off += sprintf(buffer + off, "Status: %s\n",
       
  1009                    master->fsm.tainted ? "TAINTED" : "sane");
       
  1010     off += sprintf(buffer + off, "Pdo slaves: %s\n",
       
  1011                    master->pdo_slaves_offline ? "INCOMPLETE" : "online");
       
  1012 
       
  1013     off += sprintf(buffer + off, "\nDevices:\n");
  1009     off += sprintf(buffer + off, "\nDevices:\n");
  1014     
  1010     
  1015     down(&master->device_sem);
  1011     down(&master->device_sem);
  1016     off += sprintf(buffer + off, "  Main: ");
  1012     off += sprintf(buffer + off, "  Main: ");
  1017     off += ec_master_device_info(&master->main_device,
  1013     off += ec_master_device_info(&master->main_device,
  1347             return -1;
  1343             return -1;
  1348         }
  1344         }
  1349         domain_offset += domain->data_size;
  1345         domain_offset += domain->data_size;
  1350     }
  1346     }
  1351 
  1347 
  1352     // request slave configuration
       
  1353     down(&master->config_sem);
       
  1354     master->allow_config = 1; // request the current configuration
  1348     master->allow_config = 1; // request the current configuration
  1355     up(&master->config_sem);
  1349     master->allow_scan = 1; // allow re-scanning on topology change
  1356 
  1350 
  1357     if (master->main_device.link_state) {
       
  1358         // wait for configuration to complete
       
  1359         master->config_state = EC_REQUEST_BUSY;
       
  1360         if (wait_event_interruptible(master->config_queue,
       
  1361                     master->config_state != EC_REQUEST_BUSY)) {
       
  1362             EC_INFO("Waiting for configuration interrupted by signal.\n");
       
  1363             return -1;
       
  1364         }
       
  1365 
       
  1366         if (master->config_state != EC_REQUEST_SUCCESS) {
       
  1367             EC_ERR("Failed to configure slaves.\n");
       
  1368             return -1;
       
  1369         }
       
  1370     }
       
  1371     
       
  1372     // restart EoE process and master thread with new locking
  1351     // restart EoE process and master thread with new locking
  1373 #ifdef EC_EOE
  1352 #ifdef EC_EOE
  1374     ec_master_eoe_stop(master);
  1353     ec_master_eoe_stop(master);
  1375 #endif
  1354 #endif
  1376     ec_master_thread_stop(master);
  1355     ec_master_thread_stop(master);
  1388     
  1367     
  1389     if (ec_master_thread_start(master, ec_master_operation_thread)) {
  1368     if (ec_master_thread_start(master, ec_master_operation_thread)) {
  1390         EC_ERR("Failed to start master thread!\n");
  1369         EC_ERR("Failed to start master thread!\n");
  1391         return -1;
  1370         return -1;
  1392     }
  1371     }
       
  1372 
  1393 #ifdef EC_EOE
  1373 #ifdef EC_EOE
  1394     ec_master_eoe_start(master);
  1374     ec_master_eoe_start(master);
  1395 #endif
  1375 #endif
  1396     return 0;
  1376     return 0;
  1397 }
  1377 }
  1530 
  1510 
  1531 /*****************************************************************************/
  1511 /*****************************************************************************/
  1532 
  1512 
  1533 void ecrt_master_state(const ec_master_t *master, ec_master_state_t *state)
  1513 void ecrt_master_state(const ec_master_t *master, ec_master_state_t *state)
  1534 {
  1514 {
  1535     state->bus_state =
       
  1536         (master->pdo_slaves_offline || master->frames_timed_out)
       
  1537         ? EC_BUS_FAILURE : EC_BUS_OK;
       
  1538     state->bus_tainted = master->fsm.tainted; 
       
  1539     state->slaves_responding = master->fsm.slaves_responding;
  1515     state->slaves_responding = master->fsm.slaves_responding;
  1540 }
  1516 }
  1541 
  1517 
  1542 /*****************************************************************************/
  1518 /*****************************************************************************/
  1543 
  1519