59 static char *backup_devices[MAX_MASTERS]; /**< Backup devices parameter. */ |
59 static char *backup_devices[MAX_MASTERS]; /**< Backup devices parameter. */ |
60 static unsigned int backup_count; /**< Number of backup devices. */ |
60 static unsigned int backup_count; /**< Number of backup devices. */ |
61 static unsigned int debug_level; /**< Debug level parameter. */ |
61 static unsigned int debug_level; /**< Debug level parameter. */ |
62 |
62 |
63 static ec_master_t *masters; /**< Array of masters. */ |
63 static ec_master_t *masters; /**< Array of masters. */ |
64 static struct semaphore master_sem; /**< Master semaphore. */ |
64 static struct ec_mutex_t master_mutex; /**< Master mutex. */ |
65 |
65 |
66 dev_t device_number; /**< Device number for master cdevs. */ |
66 dev_t device_number; /**< Device number for master cdevs. */ |
67 struct class *class; /**< Device class. */ |
67 struct class *class; /**< Device class. */ |
68 |
68 |
69 static uint8_t macs[MAX_MASTERS][2][ETH_ALEN]; /**< MAC addresses. */ |
69 static uint8_t macs[MAX_MASTERS][2][ETH_ALEN]; /**< MAC addresses. */ |
99 { |
99 { |
100 int i, ret = 0; |
100 int i, ret = 0; |
101 |
101 |
102 EC_INFO("Master driver %s\n", EC_MASTER_VERSION); |
102 EC_INFO("Master driver %s\n", EC_MASTER_VERSION); |
103 |
103 |
104 sema_init(&master_sem, 1); |
104 ec_mutex_init(&master_mutex); |
105 |
105 |
106 if (master_count) { |
106 if (master_count) { |
107 if (alloc_chrdev_region(&device_number, |
107 if (alloc_chrdev_region(&device_number, |
108 0, master_count, "EtherCAT")) { |
108 0, master_count, "EtherCAT")) { |
109 EC_ERR("Failed to obtain device number(s)!\n"); |
109 EC_ERR("Failed to obtain device number(s)!\n"); |
466 unsigned int i; |
466 unsigned int i; |
467 |
467 |
468 for (i = 0; i < master_count; i++) { |
468 for (i = 0; i < master_count; i++) { |
469 master = &masters[i]; |
469 master = &masters[i]; |
470 |
470 |
471 down(&master->device_sem); |
471 ec_mutex_lock(&master->device_mutex); |
472 if (master->main_device.dev) { // master already has a device |
472 if (master->main_device.dev) { // master already has a device |
473 up(&master->device_sem); |
473 ec_mutex_unlock(&master->device_mutex); |
474 continue; |
474 continue; |
475 } |
475 } |
476 |
476 |
477 if (ec_mac_equal(master->main_mac, net_dev->dev_addr) |
477 if (ec_mac_equal(master->main_mac, net_dev->dev_addr) |
478 || ec_mac_is_broadcast(master->main_mac)) { |
478 || ec_mac_is_broadcast(master->main_mac)) { |
479 ec_mac_print(net_dev->dev_addr, str); |
479 ec_mac_print(net_dev->dev_addr, str); |
480 EC_INFO("Accepting device %s for master %u.\n", |
480 EC_INFO("Accepting device %s for master %u.\n", |
481 str, master->index); |
481 str, master->index); |
482 |
482 |
483 ec_device_attach(&master->main_device, net_dev, poll, module); |
483 ec_device_attach(&master->main_device, net_dev, poll, module); |
484 up(&master->device_sem); |
484 ec_mutex_unlock(&master->device_mutex); |
485 |
485 |
486 snprintf(net_dev->name, IFNAMSIZ, "ec%u", master->index); |
486 snprintf(net_dev->name, IFNAMSIZ, "ec%u", master->index); |
487 |
487 |
488 return &master->main_device; // offer accepted |
488 return &master->main_device; // offer accepted |
489 } |
489 } |
490 else { |
490 else { |
491 up(&master->device_sem); |
491 ec_mutex_unlock(&master->device_mutex); |
492 |
492 |
493 if (master->debug_level) { |
493 if (master->debug_level) { |
494 ec_mac_print(net_dev->dev_addr, str); |
494 ec_mac_print(net_dev->dev_addr, str); |
495 EC_MASTER_DBG(master, 0, "Master declined device %s.\n", |
495 EC_MASTER_DBG(master, 0, "Master declined device %s.\n", |
496 str); |
496 str); |
522 errptr = ERR_PTR(-EINVAL); |
522 errptr = ERR_PTR(-EINVAL); |
523 goto out_return; |
523 goto out_return; |
524 } |
524 } |
525 master = &masters[master_index]; |
525 master = &masters[master_index]; |
526 |
526 |
527 if (down_interruptible(&master_sem)) { |
527 if (ec_mutex_lock_interruptible(&master_mutex)) { |
528 errptr = ERR_PTR(-EINTR); |
528 errptr = ERR_PTR(-EINTR); |
529 goto out_return; |
529 goto out_return; |
530 } |
530 } |
531 |
531 |
532 if (master->reserved) { |
532 if (master->reserved) { |
533 up(&master_sem); |
533 ec_mutex_unlock(&master_mutex); |
534 EC_MASTER_ERR(master, "Master already in use!\n"); |
534 EC_MASTER_ERR(master, "Master already in use!\n"); |
535 errptr = ERR_PTR(-EBUSY); |
535 errptr = ERR_PTR(-EBUSY); |
536 goto out_return; |
536 goto out_return; |
537 } |
537 } |
538 master->reserved = 1; |
538 master->reserved = 1; |
539 up(&master_sem); |
539 ec_mutex_unlock(&master_mutex); |
540 |
540 |
541 if (down_interruptible(&master->device_sem)) { |
541 if (ec_mutex_lock_interruptible(&master->device_mutex)) { |
542 errptr = ERR_PTR(-EINTR); |
542 errptr = ERR_PTR(-EINTR); |
543 goto out_release; |
543 goto out_release; |
544 } |
544 } |
545 |
545 |
546 if (master->phase != EC_IDLE) { |
546 if (master->phase != EC_IDLE) { |
547 up(&master->device_sem); |
547 ec_mutex_unlock(&master->device_mutex); |
548 EC_MASTER_ERR(master, "Master still waiting for devices!\n"); |
548 EC_MASTER_ERR(master, "Master still waiting for devices!\n"); |
549 errptr = ERR_PTR(-ENODEV); |
549 errptr = ERR_PTR(-ENODEV); |
550 goto out_release; |
550 goto out_release; |
551 } |
551 } |
552 |
552 |
553 if (!try_module_get(master->main_device.module)) { |
553 if (!try_module_get(master->main_device.module)) { |
554 up(&master->device_sem); |
554 ec_mutex_unlock(&master->device_mutex); |
555 EC_ERR("Device module is unloading!\n"); |
555 EC_ERR("Device module is unloading!\n"); |
556 errptr = ERR_PTR(-ENODEV); |
556 errptr = ERR_PTR(-ENODEV); |
557 goto out_release; |
557 goto out_release; |
558 } |
558 } |
559 |
559 |
560 up(&master->device_sem); |
560 ec_mutex_unlock(&master->device_mutex); |
561 |
561 |
562 if (ec_master_enter_operation_phase(master)) { |
562 if (ec_master_enter_operation_phase(master)) { |
563 EC_MASTER_ERR(master, "Failed to enter OPERATION phase!\n"); |
563 EC_MASTER_ERR(master, "Failed to enter OPERATION phase!\n"); |
564 errptr = ERR_PTR(-EIO); |
564 errptr = ERR_PTR(-EIO); |
565 goto out_module_put; |
565 goto out_module_put; |
608 |
608 |
609 unsigned int ecrt_version_magic(void) |
609 unsigned int ecrt_version_magic(void) |
610 { |
610 { |
611 return ECRT_VERSION_MAGIC; |
611 return ECRT_VERSION_MAGIC; |
612 } |
612 } |
|
613 |
|
614 |
|
615 |
|
616 /** Return pointer to running master |
|
617 /*****************************************************************************/ |
|
618 ec_master_t *ecrt_attach_master(unsigned int master_index) |
|
619 { |
|
620 ec_master_t *master = NULL; |
|
621 |
|
622 EC_INFO("Requesting master %u...\n", master_index); |
|
623 |
|
624 if (master_index >= master_count) { |
|
625 EC_ERR("Invalid master index %u.\n", master_index); |
|
626 return master; |
|
627 } |
|
628 |
|
629 master = &masters[master_index]; |
|
630 if (master->reserved) |
|
631 { |
|
632 // ok master is attached |
|
633 EC_INFO("attaching Master %u!\n", master_index); |
|
634 } |
|
635 else |
|
636 { |
|
637 EC_ERR("No Master %u in use!\n", master_index); |
|
638 master = NULL; |
|
639 } |
|
640 return master; |
|
641 } |
|
642 |
|
643 |
613 |
644 |
614 /*****************************************************************************/ |
645 /*****************************************************************************/ |
615 |
646 |
616 /** Global request state type translation table. |
647 /** Global request state type translation table. |
617 * |
648 * |
635 EXPORT_SYMBOL(ecdev_offer); |
666 EXPORT_SYMBOL(ecdev_offer); |
636 |
667 |
637 EXPORT_SYMBOL(ecrt_request_master); |
668 EXPORT_SYMBOL(ecrt_request_master); |
638 EXPORT_SYMBOL(ecrt_release_master); |
669 EXPORT_SYMBOL(ecrt_release_master); |
639 EXPORT_SYMBOL(ecrt_version_magic); |
670 EXPORT_SYMBOL(ecrt_version_magic); |
|
671 EXPORT_SYMBOL(ecrt_attach_master); |
640 |
672 |
641 /** \endcond */ |
673 /** \endcond */ |
642 |
674 |
643 /*****************************************************************************/ |
675 /*****************************************************************************/ |