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 */ |