6 * |
6 * |
7 * This file is part of the IgH EtherCAT Master. |
7 * This file is part of the IgH EtherCAT Master. |
8 * |
8 * |
9 * The IgH EtherCAT Master is free software; you can redistribute it |
9 * The IgH EtherCAT Master is free software; you can redistribute it |
10 * and/or modify it under the terms of the GNU General Public License |
10 * and/or modify it under the terms of the GNU General Public License |
11 * as published by the Free Software Foundation; version 2 of the License. |
11 * as published by the Free Software Foundation; either version 2 of the |
|
12 * License, or (at your option) any later version. |
12 * |
13 * |
13 * The IgH EtherCAT Master is distributed in the hope that it will be |
14 * The IgH EtherCAT Master is distributed in the hope that it will be |
14 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 * GNU General Public License for more details. |
17 * GNU General Public License for more details. |
17 * |
18 * |
18 * You should have received a copy of the GNU General Public License |
19 * You should have received a copy of the GNU General Public License |
19 * along with the IgH EtherCAT Master; if not, write to the Free Software |
20 * along with the IgH EtherCAT Master; if not, write to the Free Software |
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
|
22 * |
|
23 * The right to use EtherCAT Technology is granted and comes free of |
|
24 * charge under condition of compatibility of product made by |
|
25 * Licensee. People intending to distribute/sell products based on the |
|
26 * code, have to sign an agreement to guarantee that products using |
|
27 * software based on IgH EtherCAT master stay compatible with the actual |
|
28 * EtherCAT specification (which are released themselves as an open |
|
29 * standard) as the (only) precondition to have the right to use EtherCAT |
|
30 * Technology, IP and trade marks. |
21 * |
31 * |
22 *****************************************************************************/ |
32 *****************************************************************************/ |
23 |
33 |
24 /** |
34 /** |
25 \file |
35 \file |
55 " at " __DATE__ " " __TIME__ |
65 " at " __DATE__ " " __TIME__ |
56 |
66 |
57 /*****************************************************************************/ |
67 /*****************************************************************************/ |
58 |
68 |
59 static int ec_master_count = 1; |
69 static int ec_master_count = 1; |
|
70 static int ec_eoe_devices = 0; |
60 static struct list_head ec_masters; |
71 static struct list_head ec_masters; |
61 |
72 |
62 /*****************************************************************************/ |
73 /*****************************************************************************/ |
63 |
74 |
64 /** \cond */ |
75 /** \cond */ |
65 |
76 |
66 MODULE_AUTHOR ("Florian Pose <fp@igh-essen.com>"); |
77 module_param(ec_master_count, int, S_IRUGO); |
67 MODULE_DESCRIPTION ("EtherCAT master driver module"); |
78 module_param(ec_eoe_devices, int, S_IRUGO); |
|
79 |
|
80 MODULE_AUTHOR("Florian Pose <fp@igh-essen.com>"); |
|
81 MODULE_DESCRIPTION("EtherCAT master driver module"); |
68 MODULE_LICENSE("GPL"); |
82 MODULE_LICENSE("GPL"); |
69 MODULE_VERSION(COMPILE_INFO); |
83 MODULE_VERSION(COMPILE_INFO); |
70 |
|
71 module_param(ec_master_count, int, 1); |
|
72 MODULE_PARM_DESC(ec_master_count, "number of EtherCAT masters to initialize"); |
84 MODULE_PARM_DESC(ec_master_count, "number of EtherCAT masters to initialize"); |
|
85 MODULE_PARM_DESC(ec_eoe_devices, "number of EoE devices per master"); |
73 |
86 |
74 /** \endcond */ |
87 /** \endcond */ |
75 |
88 |
76 /*****************************************************************************/ |
89 /*****************************************************************************/ |
77 |
90 |
102 (ec_master_t *) kmalloc(sizeof(ec_master_t), GFP_KERNEL))) { |
115 (ec_master_t *) kmalloc(sizeof(ec_master_t), GFP_KERNEL))) { |
103 EC_ERR("Failed to allocate memory for EtherCAT master %i.\n", i); |
116 EC_ERR("Failed to allocate memory for EtherCAT master %i.\n", i); |
104 goto out_free; |
117 goto out_free; |
105 } |
118 } |
106 |
119 |
107 if (ec_master_init(master, i)) // kobject_put is done inside... |
120 if (ec_master_init(master, i, ec_eoe_devices)) |
108 goto out_free; |
121 goto out_free; |
109 |
122 |
110 if (kobject_add(&master->kobj)) { |
123 if (kobject_add(&master->kobj)) { |
111 EC_ERR("Failed to add kobj.\n"); |
124 EC_ERR("Failed to add kobj.\n"); |
112 kobject_put(&master->kobj); // free master |
125 kobject_put(&master->kobj); // free master |
216 } |
229 } |
217 } |
230 } |
218 printk("\n"); |
231 printk("\n"); |
219 } |
232 } |
220 |
233 |
|
234 /*****************************************************************************/ |
|
235 |
|
236 /** |
|
237 Prints slave states in clear text. |
|
238 */ |
|
239 |
|
240 void ec_print_states(const uint8_t states /**< slave states */) |
|
241 { |
|
242 unsigned int first = 1; |
|
243 |
|
244 if (!states) { |
|
245 printk("(unknown)"); |
|
246 return; |
|
247 } |
|
248 |
|
249 if (states & EC_SLAVE_STATE_INIT) { |
|
250 printk("INIT"); |
|
251 first = 0; |
|
252 } |
|
253 if (states & EC_SLAVE_STATE_PREOP) { |
|
254 if (!first) printk(", "); |
|
255 printk("PREOP"); |
|
256 first = 0; |
|
257 } |
|
258 if (states & EC_SLAVE_STATE_SAVEOP) { |
|
259 if (!first) printk(", "); |
|
260 printk("SAVEOP"); |
|
261 first = 0; |
|
262 } |
|
263 if (states & EC_SLAVE_STATE_OP) { |
|
264 if (!first) printk(", "); |
|
265 printk("OP"); |
|
266 } |
|
267 } |
|
268 |
221 /****************************************************************************** |
269 /****************************************************************************** |
222 * Device interface |
270 * Device interface |
223 *****************************************************************************/ |
271 *****************************************************************************/ |
224 |
272 |
225 /** |
273 /** |
238 struct module *module /**< pointer to the module */ |
286 struct module *module /**< pointer to the module */ |
239 ) |
287 ) |
240 { |
288 { |
241 ec_master_t *master; |
289 ec_master_t *master; |
242 |
290 |
243 if (!net_dev) { |
|
244 EC_WARN("Device is NULL!\n"); |
|
245 goto out_return; |
|
246 } |
|
247 |
|
248 if (!(master = ec_find_master(master_index))) return NULL; |
291 if (!(master = ec_find_master(master_index))) return NULL; |
249 |
292 |
250 // critical section start |
|
251 if (master->device) { |
293 if (master->device) { |
252 EC_ERR("Master %i already has a device!\n", master_index); |
294 EC_ERR("Master %i already has a device!\n", master_index); |
253 // critical section leave |
|
254 goto out_return; |
295 goto out_return; |
255 } |
296 } |
256 |
297 |
257 if (!(master->device = |
298 if (!(master->device = |
258 (ec_device_t *) kmalloc(sizeof(ec_device_t), GFP_KERNEL))) { |
299 (ec_device_t *) kmalloc(sizeof(ec_device_t), GFP_KERNEL))) { |
259 EC_ERR("Failed to allocate device!\n"); |
300 EC_ERR("Failed to allocate device!\n"); |
260 // critical section leave |
|
261 goto out_return; |
301 goto out_return; |
262 } |
302 } |
263 // critical section end |
|
264 |
303 |
265 if (ec_device_init(master->device, master, net_dev, isr, module)) { |
304 if (ec_device_init(master->device, master, net_dev, isr, module)) { |
266 EC_ERR("Failed to init device!\n"); |
305 EC_ERR("Failed to init device!\n"); |
267 goto out_free; |
306 goto out_free; |
268 } |
307 } |
367 |
406 |
368 EC_INFO("Requesting master %i...\n", master_index); |
407 EC_INFO("Requesting master %i...\n", master_index); |
369 |
408 |
370 if (!(master = ec_find_master(master_index))) goto out_return; |
409 if (!(master = ec_find_master(master_index))) goto out_return; |
371 |
410 |
372 // begin critical section |
|
373 if (master->reserved) { |
411 if (master->reserved) { |
374 EC_ERR("Master %i is already in use!\n", master_index); |
412 EC_ERR("Master %i is already in use!\n", master_index); |
375 goto out_return; |
413 goto out_return; |
376 } |
414 } |
377 master->reserved = 1; |
415 master->reserved = 1; |
378 // end critical section |
|
379 |
416 |
380 if (!master->device) { |
417 if (!master->device) { |
381 EC_ERR("Master %i has no assigned device!\n", master_index); |
418 EC_ERR("Master %i has no assigned device!\n", master_index); |
382 goto out_release; |
419 goto out_release; |
383 } |
420 } |
402 return master; |
439 return master; |
403 |
440 |
404 out_module_put: |
441 out_module_put: |
405 module_put(master->device->module); |
442 module_put(master->device->module); |
406 ec_master_reset(master); |
443 ec_master_reset(master); |
|
444 ec_master_freerun_start(master); |
407 out_release: |
445 out_release: |
408 master->reserved = 0; |
446 master->reserved = 0; |
409 out_return: |
447 out_return: |
410 EC_ERR("Failed requesting master %i.\n", master_index); |
448 EC_ERR("Failed requesting master %i.\n", master_index); |
411 return NULL; |
449 return NULL; |