44 #include "ethernet.h" |
44 #include "ethernet.h" |
45 |
45 |
46 /*****************************************************************************/ |
46 /*****************************************************************************/ |
47 |
47 |
48 void ec_master_freerun(unsigned long); |
48 void ec_master_freerun(unsigned long); |
|
49 #ifdef EOE_TIMER |
49 void ec_master_run_eoe(unsigned long); |
50 void ec_master_run_eoe(unsigned long); |
|
51 #else |
|
52 void ec_master_run_eoe(void *); |
|
53 #endif |
50 ssize_t ec_show_master_attribute(struct kobject *, struct attribute *, char *); |
54 ssize_t ec_show_master_attribute(struct kobject *, struct attribute *, char *); |
51 void ec_master_process_watch_command(ec_master_t *); |
55 void ec_master_process_watch_command(ec_master_t *); |
52 |
56 |
53 /*****************************************************************************/ |
57 /*****************************************************************************/ |
54 |
58 |
95 |
99 |
96 INIT_LIST_HEAD(&master->slaves); |
100 INIT_LIST_HEAD(&master->slaves); |
97 INIT_LIST_HEAD(&master->command_queue); |
101 INIT_LIST_HEAD(&master->command_queue); |
98 INIT_LIST_HEAD(&master->domains); |
102 INIT_LIST_HEAD(&master->domains); |
99 INIT_LIST_HEAD(&master->eoe_slaves); |
103 INIT_LIST_HEAD(&master->eoe_slaves); |
|
104 |
|
105 ec_command_init(&master->simple_command); |
|
106 ec_command_init(&master->watch_command); |
|
107 |
|
108 // init freerun timer |
|
109 init_timer(&master->freerun_timer); |
|
110 master->freerun_timer.function = ec_master_freerun; |
|
111 master->freerun_timer.data = (unsigned long) master; |
|
112 |
|
113 // init eoe timer |
|
114 #ifdef EOE_TIMER |
|
115 init_timer(&master->eoe_timer); |
|
116 master->eoe_timer.function = ec_master_run_eoe; |
|
117 master->eoe_timer.data = (unsigned long) master; |
|
118 #else |
|
119 if (!(master->eoe_workqueue = create_singlethread_workqueue("EoE"))) { |
|
120 EC_ERR("Failed to create EoE workqueue.\n"); |
|
121 goto out_return; |
|
122 } |
|
123 INIT_WORK(&master->eoe_work, ec_master_run_eoe, (void *) master); |
|
124 #endif |
100 |
125 |
101 // init kobject and add it to the hierarchy |
126 // init kobject and add it to the hierarchy |
102 memset(&master->kobj, 0x00, sizeof(struct kobject)); |
127 memset(&master->kobj, 0x00, sizeof(struct kobject)); |
103 kobject_init(&master->kobj); |
128 kobject_init(&master->kobj); |
104 master->kobj.ktype = &ktype_ec_master; |
129 master->kobj.ktype = &ktype_ec_master; |
105 if (kobject_set_name(&master->kobj, "ethercat%i", index)) { |
130 if (kobject_set_name(&master->kobj, "ethercat%i", index)) { |
106 EC_ERR("Failed to set kobj name.\n"); |
131 EC_ERR("Failed to set kobj name.\n"); |
107 kobject_put(&master->kobj); |
132 goto out_kobj_put; |
108 return -1; |
133 } |
109 } |
|
110 |
|
111 // init freerun timer |
|
112 init_timer(&master->freerun_timer); |
|
113 master->freerun_timer.function = ec_master_freerun; |
|
114 master->freerun_timer.data = (unsigned long) master; |
|
115 |
|
116 // init eoe timer |
|
117 init_timer(&master->eoe_timer); |
|
118 master->eoe_timer.function = ec_master_run_eoe; |
|
119 master->eoe_timer.data = (unsigned long) master; |
|
120 |
|
121 ec_command_init(&master->simple_command); |
|
122 ec_command_init(&master->watch_command); |
|
123 |
134 |
124 ec_master_reset(master); |
135 ec_master_reset(master); |
125 return 0; |
136 return 0; |
|
137 |
|
138 out_kobj_put: |
|
139 kobject_put(&master->kobj); |
|
140 #ifndef EOE_TIMER |
|
141 out_return: |
|
142 #endif |
|
143 return -1; |
126 } |
144 } |
127 |
145 |
128 /*****************************************************************************/ |
146 /*****************************************************************************/ |
129 |
147 |
130 /** |
148 /** |
137 { |
155 { |
138 ec_master_t *master = container_of(kobj, ec_master_t, kobj); |
156 ec_master_t *master = container_of(kobj, ec_master_t, kobj); |
139 |
157 |
140 EC_INFO("Clearing master %i...\n", master->index); |
158 EC_INFO("Clearing master %i...\n", master->index); |
141 |
159 |
142 del_timer_sync(&master->eoe_timer); |
|
143 del_timer_sync(&master->freerun_timer); |
|
144 |
|
145 ec_master_reset(master); |
160 ec_master_reset(master); |
146 |
161 |
147 if (master->device) { |
162 if (master->device) { |
148 ec_device_clear(master->device); |
163 ec_device_clear(master->device); |
149 kfree(master->device); |
164 kfree(master->device); |
150 } |
165 } |
151 |
166 |
152 ec_command_clear(&master->simple_command); |
167 ec_command_clear(&master->simple_command); |
153 ec_command_clear(&master->watch_command); |
168 ec_command_clear(&master->watch_command); |
|
169 |
|
170 #ifndef EOE_TIMER |
|
171 if (master->eoe_workqueue) destroy_workqueue(master->eoe_workqueue); |
|
172 #endif |
154 |
173 |
155 EC_INFO("Master %i cleared.\n", master->index); |
174 EC_INFO("Master %i cleared.\n", master->index); |
156 } |
175 } |
157 |
176 |
158 /*****************************************************************************/ |
177 /*****************************************************************************/ |
169 ec_command_t *command, *next_c; |
188 ec_command_t *command, *next_c; |
170 ec_domain_t *domain, *next_d; |
189 ec_domain_t *domain, *next_d; |
171 ec_eoe_t *eoe, *next_eoe; |
190 ec_eoe_t *eoe, *next_eoe; |
172 |
191 |
173 // stop EoE processing |
192 // stop EoE processing |
|
193 #ifdef EOE_TIMER |
174 del_timer_sync(&master->eoe_timer); |
194 del_timer_sync(&master->eoe_timer); |
|
195 #else |
|
196 if (master->eoe_workqueue) { |
|
197 if (!cancel_delayed_work(&master->eoe_work)) { |
|
198 flush_workqueue(master->eoe_workqueue); |
|
199 } |
|
200 } |
|
201 #endif |
175 |
202 |
176 // stop free-run mode |
203 // stop free-run mode |
177 ec_master_freerun_stop(master); |
204 ec_master_freerun_stop(master); |
178 |
205 |
179 // remove all slaves |
206 // remove all slaves |
837 |
864 |
838 /** |
865 /** |
839 Does the Ethernet-over-EtherCAT processing. |
866 Does the Ethernet-over-EtherCAT processing. |
840 */ |
867 */ |
841 |
868 |
|
869 #ifdef EOE_TIMER |
842 void ec_master_run_eoe(unsigned long data /**< master pointer */) |
870 void ec_master_run_eoe(unsigned long data /**< master pointer */) |
|
871 #else |
|
872 void ec_master_run_eoe(void *data /**< master pointer */) |
|
873 #endif |
843 { |
874 { |
844 ec_master_t *master = (ec_master_t *) data; |
875 ec_master_t *master = (ec_master_t *) data; |
845 ec_eoe_t *eoe; |
876 ec_eoe_t *eoe; |
846 |
877 |
847 if (!master->request_cb(master->cb_data)) goto restart_timer; |
878 // request_cb must return 0, if the lock has been aquired! |
|
879 if (master->request_cb(master->cb_data)) goto queue; |
848 |
880 |
849 ecrt_master_async_receive(master); |
881 ecrt_master_async_receive(master); |
850 list_for_each_entry(eoe, &master->eoe_slaves, list) { |
882 list_for_each_entry(eoe, &master->eoe_slaves, list) { |
851 ec_eoe_run(eoe); |
883 ec_eoe_run(eoe); |
852 } |
884 } |
853 ecrt_master_async_send(master); |
885 ecrt_master_async_send(master); |
854 |
886 |
855 master->release_cb(master->cb_data); |
887 master->release_cb(master->cb_data); |
856 |
888 |
857 restart_timer: |
889 queue: |
|
890 #ifdef EOE_TIMER |
858 master->eoe_timer.expires += HZ / 1000; |
891 master->eoe_timer.expires += HZ / 1000; |
859 add_timer(&master->eoe_timer); |
892 add_timer(&master->eoe_timer); |
|
893 #else |
|
894 queue_delayed_work(master->eoe_workqueue, &master->eoe_work, HZ / 1000); |
|
895 #endif |
860 } |
896 } |
861 |
897 |
862 /****************************************************************************** |
898 /****************************************************************************** |
863 * Realtime interface |
899 * Realtime interface |
864 *****************************************************************************/ |
900 *****************************************************************************/ |
1418 |
1454 |
1419 /*****************************************************************************/ |
1455 /*****************************************************************************/ |
1420 |
1456 |
1421 /** |
1457 /** |
1422 Sets the locking callbacks. |
1458 Sets the locking callbacks. |
|
1459 The request_cb function must return zero, to allow another instance |
|
1460 (the EoE process for example) to access the master. Non-zero means, |
|
1461 that access is forbidden at this time. |
1423 \ingroup RealtimeInterface |
1462 \ingroup RealtimeInterface |
1424 */ |
1463 */ |
1425 |
1464 |
1426 void ecrt_master_callbacks(ec_master_t *master, /**< EtherCAT master */ |
1465 void ecrt_master_callbacks(ec_master_t *master, /**< EtherCAT master */ |
1427 int (*request_cb)(void *), /**< request lock CB */ |
1466 int (*request_cb)(void *), /**< request lock CB */ |
1470 EC_WARN("start_eoe: no EoE-capable slaves present.\n"); |
1509 EC_WARN("start_eoe: no EoE-capable slaves present.\n"); |
1471 return 0; |
1510 return 0; |
1472 } |
1511 } |
1473 |
1512 |
1474 // start EoE processing |
1513 // start EoE processing |
|
1514 #ifdef EOE_TIMER |
1475 master->eoe_timer.expires = jiffies + 10; |
1515 master->eoe_timer.expires = jiffies + 10; |
1476 add_timer(&master->eoe_timer); |
1516 add_timer(&master->eoe_timer); |
|
1517 #else |
|
1518 queue_work(master->eoe_workqueue, &master->eoe_work); |
|
1519 #endif |
1477 return 0; |
1520 return 0; |
1478 } |
1521 } |
1479 |
1522 |
1480 /*****************************************************************************/ |
1523 /*****************************************************************************/ |
1481 |
1524 |