master/module.c
changeset 647 dc556a8c8fed
parent 639 aa23c48dca2d
child 648 0a6d38ec463f
equal deleted inserted replaced
646:fbbd4e54e031 647:dc556a8c8fed
    64 
    64 
    65 static char *main[MAX_MASTERS]; /**< main devices parameter */
    65 static char *main[MAX_MASTERS]; /**< main devices parameter */
    66 static char *backup[MAX_MASTERS]; /**< backup devices parameter */
    66 static char *backup[MAX_MASTERS]; /**< backup devices parameter */
    67 
    67 
    68 static ec_master_t *masters; /**< master array */
    68 static ec_master_t *masters; /**< master array */
       
    69 static struct semaphore master_sem; /**< master semaphore */
    69 static unsigned int master_count; /**< number of masters */
    70 static unsigned int master_count; /**< number of masters */
    70 static unsigned int backup_count; /**< number of backup devices */
    71 static unsigned int backup_count; /**< number of backup devices */
    71 
    72 
    72 static uint8_t macs[MAX_MASTERS][2][ETH_ALEN]; /**< MAC addresses */
    73 static uint8_t macs[MAX_MASTERS][2][ETH_ALEN]; /**< MAC addresses */
    73 
    74 
   522                                  /**< master index */
   523                                  /**< master index */
   523                                  )
   524                                  )
   524 {
   525 {
   525     ec_master_t *master;
   526     ec_master_t *master;
   526 
   527 
   527     EC_INFO("Requesting master %i...\n", master_index);
   528     EC_INFO("Requesting master %u...\n", master_index);
   528 
   529 
   529     if (master_index >= master_count) {
   530     if (master_index >= master_count) {
   530         EC_ERR("Invalid master index %u.\n", master_index);
   531         EC_ERR("Invalid master index %u.\n", master_index);
   531         goto out_return;
   532         goto out_return;
   532     }
   533     }
   533     master = &masters[master_index];
   534     master = &masters[master_index];
   534 
   535 
   535     if (!atomic_dec_and_test(&master->available)) {
   536     down(&master_sem);
   536         atomic_inc(&master->available);
   537     if (master->reserved) {
   537         EC_ERR("Master %i is already in use!\n", master_index);
   538         up(&master_sem);
       
   539         EC_ERR("Master %u is already in use!\n", master_index);
   538         goto out_return;
   540         goto out_return;
   539     }
   541     }
       
   542     master->reserved = 1;
       
   543     up(&master_sem);
   540 
   544 
   541     if (down_interruptible(&master->device_sem)) {
   545     if (down_interruptible(&master->device_sem)) {
   542         EC_ERR("Interrupted while waiting for device!\n");
   546         EC_ERR("Interrupted while waiting for device!\n");
   543         goto out_release;
   547         goto out_release;
   544     }
   548     }
   545 
   549 
   546     if (master->mode != EC_MASTER_MODE_IDLE) {
   550     if (master->mode != EC_MASTER_MODE_IDLE) {
   547         up(&master->device_sem);
   551         up(&master->device_sem);
   548         EC_ERR("Master %i still waiting for devices!\n", master_index);
   552         EC_ERR("Master %u still waiting for devices!\n", master_index);
   549         goto out_release;
   553         goto out_release;
   550     }
   554     }
   551 
   555 
   552     if (!try_module_get(master->main_device.module)) {
   556     if (!try_module_get(master->main_device.module)) {
   553         up(&master->device_sem);
   557         up(&master->device_sem);
   565     if (ec_master_enter_operation_mode(master)) {
   569     if (ec_master_enter_operation_mode(master)) {
   566         EC_ERR("Failed to enter OPERATION mode!\n");
   570         EC_ERR("Failed to enter OPERATION mode!\n");
   567         goto out_module_put;
   571         goto out_module_put;
   568     }
   572     }
   569 
   573 
   570     EC_INFO("Successfully requested master %i.\n", master_index);
   574     EC_INFO("Successfully requested master %u.\n", master_index);
   571     return master;
   575     return master;
   572 
   576 
   573  out_module_put:
   577  out_module_put:
   574     module_put(master->main_device.module);
   578     module_put(master->main_device.module);
   575  out_release:
   579  out_release:
   576     atomic_inc(&master->available);
   580     master->reserved = 0;
   577  out_return:
   581  out_return:
   578     return NULL;
   582     return NULL;
   579 }
   583 }
   580 
   584 
   581 /*****************************************************************************/
   585 /*****************************************************************************/
   585    \ingroup RealtimeInterface
   589    \ingroup RealtimeInterface
   586 */
   590 */
   587 
   591 
   588 void ecrt_release_master(ec_master_t *master /**< EtherCAT master */)
   592 void ecrt_release_master(ec_master_t *master /**< EtherCAT master */)
   589 {
   593 {
   590     EC_INFO("Releasing master %i...\n", master->index);
   594     EC_INFO("Releasing master %u...\n", master->index);
   591 
   595 
   592     if (master->mode != EC_MASTER_MODE_OPERATION) {
   596     if (master->mode != EC_MASTER_MODE_OPERATION) {
   593         EC_WARN("Master %i was was not requested!\n", master->index);
   597         EC_WARN("Master %u was was not requested!\n", master->index);
   594         return;
   598         return;
   595     }
   599     }
   596 
   600 
   597     ec_master_leave_operation_mode(master);
   601     ec_master_leave_operation_mode(master);
   598 
   602 
   599     module_put(master->main_device.module);
   603     module_put(master->main_device.module);
   600     atomic_inc(&master->available);
   604     master->reserved = 0;
   601 
   605 
   602     EC_INFO("Released master %i.\n", master->index);
   606     EC_INFO("Released master %u.\n", master->index);
   603 }
   607 }
   604 
   608 
   605 /*****************************************************************************/
   609 /*****************************************************************************/
   606 
   610 
   607 /** \cond */
   611 /** \cond */