23 #include "command.h" |
23 #include "command.h" |
24 #include "ethernet.h" |
24 #include "ethernet.h" |
25 |
25 |
26 /*****************************************************************************/ |
26 /*****************************************************************************/ |
27 |
27 |
|
28 static struct attribute attr_slave_count = { |
|
29 .name = "slave_count", |
|
30 .owner = THIS_MODULE, |
|
31 .mode = S_IRUGO |
|
32 }; |
|
33 |
|
34 static struct attribute *ec_def_attrs[] = { |
|
35 &attr_slave_count, |
|
36 NULL, |
|
37 }; |
|
38 |
|
39 static struct sysfs_ops ec_sysfs_ops = { |
|
40 .show = &ec_show_master_attribute, |
|
41 .store = NULL |
|
42 }; |
|
43 |
|
44 static struct kobj_type ktype_ec_master = { |
|
45 .release = ec_master_clear, |
|
46 .sysfs_ops = &ec_sysfs_ops, |
|
47 .default_attrs = ec_def_attrs |
|
48 }; |
|
49 |
|
50 /*****************************************************************************/ |
|
51 |
28 /** |
52 /** |
29 Konstruktor des EtherCAT-Masters. |
53 Konstruktor des EtherCAT-Masters. |
30 */ |
54 */ |
31 |
55 |
32 void ec_master_init(ec_master_t *master /**< EtherCAT-Master */) |
56 int ec_master_init(ec_master_t *master, /**< EtherCAT-Master */ |
33 { |
57 unsigned int index /**< Master-Index */ |
|
58 ) |
|
59 { |
|
60 EC_INFO("Initializing master %i.\n", index); |
|
61 |
|
62 master->index = index; |
34 master->slaves = NULL; |
63 master->slaves = NULL; |
35 master->device = NULL; |
64 master->device = NULL; |
|
65 master->reserved = 0; |
36 |
66 |
37 INIT_LIST_HEAD(&master->command_queue); |
67 INIT_LIST_HEAD(&master->command_queue); |
38 INIT_LIST_HEAD(&master->domains); |
68 INIT_LIST_HEAD(&master->domains); |
39 INIT_LIST_HEAD(&master->eoe_slaves); |
69 INIT_LIST_HEAD(&master->eoe_slaves); |
40 |
70 |
|
71 // Init kobject and add it to the hierarchy |
|
72 memset(&master->kobj, 0x00, sizeof(struct kobject)); |
|
73 kobject_init(&master->kobj); |
|
74 master->kobj.ktype = &ktype_ec_master; |
|
75 if (kobject_set_name(&master->kobj, "ethercat%i", index)) { |
|
76 EC_ERR("Failed to set kobj name.\n"); |
|
77 kobject_put(&master->kobj); |
|
78 return -1; |
|
79 } |
|
80 |
41 ec_command_init(&master->simple_command); |
81 ec_command_init(&master->simple_command); |
42 ec_command_init(&master->watch_command); |
82 ec_command_init(&master->watch_command); |
43 |
83 |
44 ec_master_reset(master); |
84 ec_master_reset(master); |
|
85 return 0; |
45 } |
86 } |
46 |
87 |
47 /*****************************************************************************/ |
88 /*****************************************************************************/ |
48 |
89 |
49 /** |
90 /** |
51 |
92 |
52 Entfernt alle Kommandos aus der Liste, löscht den Zeiger |
93 Entfernt alle Kommandos aus der Liste, löscht den Zeiger |
53 auf das Slave-Array und gibt die Prozessdaten frei. |
94 auf das Slave-Array und gibt die Prozessdaten frei. |
54 */ |
95 */ |
55 |
96 |
56 void ec_master_clear(ec_master_t *master /**< EtherCAT-Master */) |
97 void ec_master_clear(struct kobject *kobj /**< KObject des Masters */) |
57 { |
98 { |
|
99 ec_master_t *master = container_of(kobj, ec_master_t, kobj); |
|
100 |
|
101 EC_INFO("Clearing master %i...\n", master->index); |
|
102 |
58 ec_master_reset(master); |
103 ec_master_reset(master); |
59 |
104 |
60 if (master->device) { |
105 if (master->device) { |
61 ec_device_clear(master->device); |
106 ec_device_clear(master->device); |
62 kfree(master->device); |
107 kfree(master->device); |
63 } |
108 } |
64 |
109 |
65 ec_command_clear(&master->simple_command); |
110 ec_command_clear(&master->simple_command); |
66 ec_command_clear(&master->watch_command); |
111 ec_command_clear(&master->watch_command); |
|
112 |
|
113 EC_INFO("Master %i cleared.\n", master->index); |
67 } |
114 } |
68 |
115 |
69 /*****************************************************************************/ |
116 /*****************************************************************************/ |
70 |
117 |
71 /** |
118 /** |
100 } |
147 } |
101 |
148 |
102 // Domain-Liste leeren |
149 // Domain-Liste leeren |
103 list_for_each_entry_safe(domain, next_d, &master->domains, list) { |
150 list_for_each_entry_safe(domain, next_d, &master->domains, list) { |
104 list_del(&domain->list); |
151 list_del(&domain->list); |
105 ec_domain_clear(domain); |
152 kobject_del(&domain->kobj); |
106 kfree(domain); |
153 kobject_put(&domain->kobj); |
107 } |
154 } |
108 |
155 |
109 // EOE-Liste leeren |
156 // EOE-Liste leeren |
110 list_for_each_entry_safe(eoe, next_eoe, &master->eoe_slaves, list) { |
157 list_for_each_entry_safe(eoe, next_eoe, &master->eoe_slaves, list) { |
111 list_del(&eoe->list); |
158 list_del(&eoe->list); |
707 } |
754 } |
708 |
755 |
709 /*****************************************************************************/ |
756 /*****************************************************************************/ |
710 |
757 |
711 /** |
758 /** |
|
759 Formatiert Attribut-Daten für lesenden Zugriff im SysFS |
|
760 |
|
761 \return Anzahl Bytes im Speicher |
|
762 */ |
|
763 |
|
764 ssize_t ec_show_master_attribute(struct kobject *kobj, /**< KObject */ |
|
765 struct attribute *attr, /**< Attribut */ |
|
766 char *buffer /**< Speicher für die Daten */ |
|
767 ) |
|
768 { |
|
769 ec_master_t *master = container_of(kobj, ec_master_t, kobj); |
|
770 |
|
771 if (attr == &attr_slave_count) { |
|
772 return sprintf(buffer, "%i\n", master->slave_count); |
|
773 } |
|
774 |
|
775 return 0; |
|
776 } |
|
777 |
|
778 /*****************************************************************************/ |
|
779 |
|
780 /** |
712 Gibt Überwachungsinformationen aus. |
781 Gibt Überwachungsinformationen aus. |
713 */ |
782 */ |
714 |
783 |
715 void ec_master_process_watch_command(ec_master_t *master |
784 void ec_master_process_watch_command(ec_master_t *master |
716 /**< EtherCAT-Master */ |
785 /**< EtherCAT-Master */ |
765 \return Zeiger auf die Domäne bei Erfolg, sonst NULL. |
834 \return Zeiger auf die Domäne bei Erfolg, sonst NULL. |
766 */ |
835 */ |
767 |
836 |
768 ec_domain_t *ecrt_master_create_domain(ec_master_t *master /**< Master */) |
837 ec_domain_t *ecrt_master_create_domain(ec_master_t *master /**< Master */) |
769 { |
838 { |
770 ec_domain_t *domain; |
839 ec_domain_t *domain, *last_domain; |
|
840 unsigned int index; |
771 |
841 |
772 if (!(domain = (ec_domain_t *) kmalloc(sizeof(ec_domain_t), GFP_KERNEL))) { |
842 if (!(domain = (ec_domain_t *) kmalloc(sizeof(ec_domain_t), GFP_KERNEL))) { |
773 EC_ERR("Error allocating domain memory!\n"); |
843 EC_ERR("Error allocating domain memory!\n"); |
774 return NULL; |
844 goto out_return; |
775 } |
845 } |
776 |
846 |
777 ec_domain_init(domain, master); |
847 if (list_empty(&master->domains)) index = 0; |
|
848 else { |
|
849 last_domain = list_entry(master->domains.prev, ec_domain_t, list); |
|
850 index = last_domain->index + 1; |
|
851 } |
|
852 |
|
853 if (ec_domain_init(domain, master, index)) { |
|
854 EC_ERR("Failed to init domain.\n"); |
|
855 goto out_return; |
|
856 } |
|
857 |
|
858 if (kobject_add(&domain->kobj)) { |
|
859 EC_ERR("Failed to add domain kobject.\n"); |
|
860 goto out_put; |
|
861 } |
|
862 |
778 list_add_tail(&domain->list, &master->domains); |
863 list_add_tail(&domain->list, &master->domains); |
779 |
|
780 return domain; |
864 return domain; |
|
865 |
|
866 out_put: |
|
867 kobject_put(&domain->kobj); |
|
868 out_return: |
|
869 return NULL; |
781 } |
870 } |
782 |
871 |
783 /*****************************************************************************/ |
872 /*****************************************************************************/ |
784 |
873 |
785 /** |
874 /** |