53 #include "ethernet.h" |
53 #include "ethernet.h" |
54 |
54 |
55 /*****************************************************************************/ |
55 /*****************************************************************************/ |
56 |
56 |
57 void ec_master_clear(struct kobject *); |
57 void ec_master_clear(struct kobject *); |
|
58 void ec_master_destroy_domains(ec_master_t *); |
58 void ec_master_sync_io(ec_master_t *); |
59 void ec_master_sync_io(ec_master_t *); |
59 void ec_master_idle_run(void *); |
60 void ec_master_idle_run(void *); |
60 void ec_master_eoe_run(unsigned long); |
61 void ec_master_eoe_run(unsigned long); |
61 void ec_master_check_sdo(unsigned long); |
62 void ec_master_check_sdo(unsigned long); |
62 int ec_master_measure_bus_time(ec_master_t *); |
63 int ec_master_measure_bus_time(ec_master_t *); |
220 |
221 |
221 /*****************************************************************************/ |
222 /*****************************************************************************/ |
222 |
223 |
223 /** |
224 /** |
224 Master destructor. |
225 Master destructor. |
225 Removes all pending datagrams, clears the slave list, clears all domains |
226 Clears the kobj-hierarchy bottom up and frees the master. |
226 and frees the device. |
227 */ |
|
228 |
|
229 void ec_master_destroy(ec_master_t *master /**< EtherCAT master */) |
|
230 { |
|
231 ec_master_destroy_slaves(master); |
|
232 ec_master_destroy_domains(master); |
|
233 |
|
234 // destroy self |
|
235 kobject_del(&master->kobj); |
|
236 kobject_put(&master->kobj); // free master |
|
237 } |
|
238 |
|
239 /*****************************************************************************/ |
|
240 |
|
241 /** |
|
242 Clear and free master. |
|
243 This method is called by the kobject, |
|
244 once there are no more references to it. |
227 */ |
245 */ |
228 |
246 |
229 void ec_master_clear(struct kobject *kobj /**< kobject of the master */) |
247 void ec_master_clear(struct kobject *kobj /**< kobject of the master */) |
230 { |
248 { |
231 ec_master_t *master = container_of(kobj, ec_master_t, kobj); |
249 ec_master_t *master = container_of(kobj, ec_master_t, kobj); |
232 ec_eoe_t *eoe, *next_eoe; |
250 ec_eoe_t *eoe, *next_eoe; |
233 ec_datagram_t *datagram, *next_c; |
251 ec_datagram_t *datagram, *next_c; |
234 |
|
235 ec_master_clear_slaves(master); |
|
236 |
252 |
237 // empty datagram queue |
253 // empty datagram queue |
238 list_for_each_entry_safe(datagram, next_c, |
254 list_for_each_entry_safe(datagram, next_c, |
239 &master->datagram_queue, queue) { |
255 &master->datagram_queue, queue) { |
240 datagram->state = EC_DATAGRAM_ERROR; |
256 datagram->state = EC_DATAGRAM_ERROR; |
250 list_del(&eoe->list); |
266 list_del(&eoe->list); |
251 ec_eoe_clear(eoe); |
267 ec_eoe_clear(eoe); |
252 kfree(eoe); |
268 kfree(eoe); |
253 } |
269 } |
254 |
270 |
255 EC_INFO("Master %i cleared.\n", master->index); |
271 EC_INFO("Master %i freed.\n", master->index); |
256 |
272 |
257 kfree(master); |
273 kfree(master); |
258 } |
274 } |
259 |
275 |
260 /*****************************************************************************/ |
276 /*****************************************************************************/ |
261 |
277 |
262 /** |
278 /** |
263 Clears all slaves. |
279 Destroy all slaves. |
264 */ |
280 */ |
265 |
281 |
266 void ec_master_clear_slaves(ec_master_t *master) |
282 void ec_master_destroy_slaves(ec_master_t *master) |
267 { |
283 { |
268 ec_slave_t *slave, *next_slave; |
284 ec_slave_t *slave, *next_slave; |
269 |
285 |
270 list_for_each_entry_safe(slave, next_slave, &master->slaves, list) { |
286 list_for_each_entry_safe(slave, next_slave, &master->slaves, list) { |
271 list_del(&slave->list); |
287 list_del(&slave->list); |
272 kobject_del(&slave->kobj); |
288 ec_slave_destroy(slave); |
273 kobject_put(&slave->kobj); |
|
274 } |
289 } |
275 |
290 |
276 master->slave_count = 0; |
291 master->slave_count = 0; |
|
292 } |
|
293 |
|
294 /*****************************************************************************/ |
|
295 |
|
296 /** |
|
297 Destroy all domains. |
|
298 */ |
|
299 |
|
300 void ec_master_destroy_domains(ec_master_t *master) |
|
301 { |
|
302 ec_domain_t *domain, *next_d; |
|
303 |
|
304 list_for_each_entry_safe(domain, next_d, &master->domains, list) { |
|
305 list_del(&domain->list); |
|
306 ec_domain_destroy(domain); |
|
307 } |
277 } |
308 } |
278 |
309 |
279 /*****************************************************************************/ |
310 /*****************************************************************************/ |
280 |
311 |
281 /** |
312 /** |
384 |
415 |
385 void ec_master_leave_operation_mode(ec_master_t *master |
416 void ec_master_leave_operation_mode(ec_master_t *master |
386 /**< EtherCAT master */) |
417 /**< EtherCAT master */) |
387 { |
418 { |
388 ec_slave_t *slave; |
419 ec_slave_t *slave; |
389 ec_domain_t *domain, *next_d; |
420 |
390 |
421 ec_master_destroy_domains(master); |
391 // clear domains |
|
392 list_for_each_entry_safe(domain, next_d, &master->domains, list) { |
|
393 ec_domain_dequeue_datagrams(domain); |
|
394 list_del(&domain->list); |
|
395 kobject_del(&domain->kobj); |
|
396 kobject_put(&domain->kobj); |
|
397 } |
|
398 |
422 |
399 master->request_cb = NULL; |
423 master->request_cb = NULL; |
400 master->release_cb = NULL; |
424 master->release_cb = NULL; |
401 master->cb_data = NULL; |
425 master->cb_data = NULL; |
402 |
426 |