IgH EtherCAT Master  1.5.2
module.c
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * $Id$
4  *
5  * Copyright (C) 2006-2008 Florian Pose, Ingenieurgemeinschaft IgH
6  *
7  * This file is part of the IgH EtherCAT Master.
8  *
9  * The IgH EtherCAT Master is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License version 2, as
11  * published by the Free Software Foundation.
12  *
13  * The IgH EtherCAT Master is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16  * Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * 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  *
22  * ---
23  *
24  * The license mentioned above concerns the source code only. Using the
25  * EtherCAT technology and brand is only permitted in compliance with the
26  * industrial property and similar rights of Beckhoff Automation GmbH.
27  *
28  *****************************************************************************/
29 
34 /*****************************************************************************/
35 
36 #include <linux/module.h>
37 #include <linux/device.h>
38 #include <linux/err.h>
39 
40 #include "globals.h"
41 #include "master.h"
42 #include "device.h"
43 
44 /*****************************************************************************/
45 
46 #define MAX_MASTERS 32
48 /*****************************************************************************/
49 
50 int __init ec_init_module(void);
51 void __exit ec_cleanup_module(void);
52 
53 static int ec_mac_parse(uint8_t *, const char *, int);
54 
55 /*****************************************************************************/
56 
57 static char *main_devices[MAX_MASTERS];
58 static unsigned int master_count;
59 static char *backup_devices[MAX_MASTERS];
60 static unsigned int backup_count;
61 static unsigned int debug_level;
64 static struct semaphore master_sem;
67 struct class *class;
69 static uint8_t macs[MAX_MASTERS][2][ETH_ALEN];
71 char *ec_master_version_str = EC_MASTER_VERSION;
73 /*****************************************************************************/
74 
77 MODULE_AUTHOR("Florian Pose <fp@igh-essen.com>");
78 MODULE_DESCRIPTION("EtherCAT master driver module");
79 MODULE_LICENSE("GPL");
80 MODULE_VERSION(EC_MASTER_VERSION);
81 
82 module_param_array(main_devices, charp, &master_count, S_IRUGO);
83 MODULE_PARM_DESC(main_devices, "MAC addresses of main devices");
84 module_param_array(backup_devices, charp, &backup_count, S_IRUGO);
85 MODULE_PARM_DESC(backup_devices, "MAC addresses of backup devices");
86 module_param_named(debug_level, debug_level, uint, S_IRUGO);
87 MODULE_PARM_DESC(debug_level, "Debug level");
88 
91 /*****************************************************************************/
92 
98 int __init ec_init_module(void)
99 {
100  int i, ret = 0;
101 
102  EC_INFO("Master driver %s\n", EC_MASTER_VERSION);
103 
104  sema_init(&master_sem, 1);
105 
106  if (master_count) {
107  if (alloc_chrdev_region(&device_number,
108  0, master_count, "EtherCAT")) {
109  EC_ERR("Failed to obtain device number(s)!\n");
110  ret = -EBUSY;
111  goto out_return;
112  }
113  }
114 
115  class = class_create(THIS_MODULE, "EtherCAT");
116  if (IS_ERR(class)) {
117  EC_ERR("Failed to create device class.\n");
118  ret = PTR_ERR(class);
119  goto out_cdev;
120  }
121 
122  // zero MAC addresses
123  memset(macs, 0x00, sizeof(uint8_t) * MAX_MASTERS * 2 * ETH_ALEN);
124 
125  // process MAC parameters
126  for (i = 0; i < master_count; i++) {
127  ret = ec_mac_parse(macs[i][0], main_devices[i], 0);
128  if (ret)
129  goto out_class;
130 
131  if (i < backup_count) {
132  ret = ec_mac_parse(macs[i][1], backup_devices[i], 1);
133  if (ret)
134  goto out_class;
135  }
136  }
137 
138  // initialize static master variables
140 
141  if (master_count) {
142  if (!(masters = kmalloc(sizeof(ec_master_t) * master_count,
143  GFP_KERNEL))) {
144  EC_ERR("Failed to allocate memory"
145  " for EtherCAT masters.\n");
146  ret = -ENOMEM;
147  goto out_class;
148  }
149  }
150 
151  for (i = 0; i < master_count; i++) {
152  ret = ec_master_init(&masters[i], i, macs[i][0], macs[i][1],
153  device_number, class, debug_level);
154  if (ret)
155  goto out_free_masters;
156  }
157 
158  EC_INFO("%u master%s waiting for devices.\n",
159  master_count, (master_count == 1 ? "" : "s"));
160  return ret;
161 
162 out_free_masters:
163  for (i--; i >= 0; i--)
164  ec_master_clear(&masters[i]);
165  kfree(masters);
166 out_class:
167  class_destroy(class);
168 out_cdev:
169  if (master_count)
170  unregister_chrdev_region(device_number, master_count);
171 out_return:
172  return ret;
173 }
174 
175 /*****************************************************************************/
176 
181 void __exit ec_cleanup_module(void)
182 {
183  unsigned int i;
184 
185  for (i = 0; i < master_count; i++) {
186  ec_master_clear(&masters[i]);
187  }
188 
189  if (master_count)
190  kfree(masters);
191 
192  class_destroy(class);
193 
194  if (master_count)
195  unregister_chrdev_region(device_number, master_count);
196 
197  EC_INFO("Master module cleaned up.\n");
198 }
199 
200 /*****************************************************************************/
201 
204 unsigned int ec_master_count(void)
205 {
206  return master_count;
207 }
208 
209 /*****************************************************************************
210  * MAC address functions
211  ****************************************************************************/
212 
217  const uint8_t *mac1,
218  const uint8_t *mac2
219  )
220 {
221  unsigned int i;
222 
223  for (i = 0; i < ETH_ALEN; i++)
224  if (mac1[i] != mac2[i])
225  return 0;
226 
227  return 1;
228 }
229 
230 /*****************************************************************************/
231 
234 #define EC_MAX_MAC_STRING_SIZE (3 * ETH_ALEN)
235 
242 ssize_t ec_mac_print(
243  const uint8_t *mac,
244  char *buffer
245  )
246 {
247  off_t off = 0;
248  unsigned int i;
249 
250  for (i = 0; i < ETH_ALEN; i++) {
251  off += sprintf(buffer + off, "%02X", mac[i]);
252  if (i < ETH_ALEN - 1) off += sprintf(buffer + off, ":");
253  }
254 
255  return off;
256 }
257 
258 /*****************************************************************************/
259 
264  const uint8_t *mac
265  )
266 {
267  unsigned int i;
268 
269  for (i = 0; i < ETH_ALEN; i++)
270  if (mac[i])
271  return 0;
272 
273  return 1;
274 }
275 
276 /*****************************************************************************/
277 
282  const uint8_t *mac
283  )
284 {
285  unsigned int i;
286 
287  for (i = 0; i < ETH_ALEN; i++)
288  if (mac[i] != 0xff)
289  return 0;
290 
291  return 1;
292 }
293 
294 /*****************************************************************************/
295 
303 static int ec_mac_parse(uint8_t *mac, const char *src, int allow_empty)
304 {
305  unsigned int i, value;
306  const char *orig = src;
307  char *rem;
308 
309  if (!strlen(src)) {
310  if (allow_empty){
311  return 0;
312  } else {
313  EC_ERR("MAC address may not be empty.\n");
314  return -EINVAL;
315  }
316  }
317 
318  for (i = 0; i < ETH_ALEN; i++) {
319  value = simple_strtoul(src, &rem, 16);
320  if (rem != src + 2
321  || value > 0xFF
322  || (i < ETH_ALEN - 1 && *rem != ':')) {
323  EC_ERR("Invalid MAC address \"%s\".\n", orig);
324  return -EINVAL;
325  }
326  mac[i] = value;
327  if (i < ETH_ALEN - 1) {
328  src = rem + 1; // skip colon
329  }
330  }
331 
332  return 0;
333 }
334 
335 /*****************************************************************************/
336 
341 void ec_print_data(const uint8_t *data,
342  size_t size
343  )
344 {
345  unsigned int i;
346 
347  EC_DBG("");
348  for (i = 0; i < size; i++) {
349  printk("%02X ", data[i]);
350 
351  if ((i + 1) % 16 == 0 && i < size - 1) {
352  printk("\n");
353  EC_DBG("");
354  }
355 
356  if (i + 1 == 128 && size > 256) {
357  printk("dropped %zu bytes\n", size - 128 - i);
358  i = size - 128;
359  EC_DBG("");
360  }
361  }
362  printk("\n");
363 }
364 
365 /*****************************************************************************/
366 
369 void ec_print_data_diff(const uint8_t *d1,
370  const uint8_t *d2,
371  size_t size
372  )
373 {
374  unsigned int i;
375 
376  EC_DBG("");
377  for (i = 0; i < size; i++) {
378  if (d1[i] == d2[i]) printk(".. ");
379  else printk("%02X ", d2[i]);
380  if ((i + 1) % 16 == 0) {
381  printk("\n");
382  EC_DBG("");
383  }
384  }
385  printk("\n");
386 }
387 
388 /*****************************************************************************/
389 
394 size_t ec_state_string(uint8_t states,
395  char *buffer,
397  uint8_t multi
398  )
399 {
400  off_t off = 0;
401  unsigned int first = 1;
402 
403  if (!states) {
404  off += sprintf(buffer + off, "(unknown)");
405  return off;
406  }
407 
408  if (multi) { // multiple slaves
409  if (states & EC_SLAVE_STATE_INIT) {
410  off += sprintf(buffer + off, "INIT");
411  first = 0;
412  }
413  if (states & EC_SLAVE_STATE_PREOP) {
414  if (!first) off += sprintf(buffer + off, ", ");
415  off += sprintf(buffer + off, "PREOP");
416  first = 0;
417  }
418  if (states & EC_SLAVE_STATE_SAFEOP) {
419  if (!first) off += sprintf(buffer + off, ", ");
420  off += sprintf(buffer + off, "SAFEOP");
421  first = 0;
422  }
423  if (states & EC_SLAVE_STATE_OP) {
424  if (!first) off += sprintf(buffer + off, ", ");
425  off += sprintf(buffer + off, "OP");
426  }
427  } else { // single slave
428  if ((states & EC_SLAVE_STATE_MASK) == EC_SLAVE_STATE_INIT) {
429  off += sprintf(buffer + off, "INIT");
430  } else if ((states & EC_SLAVE_STATE_MASK) == EC_SLAVE_STATE_PREOP) {
431  off += sprintf(buffer + off, "PREOP");
432  } else if ((states & EC_SLAVE_STATE_MASK) == EC_SLAVE_STATE_BOOT) {
433  off += sprintf(buffer + off, "BOOT");
434  } else if ((states & EC_SLAVE_STATE_MASK) == EC_SLAVE_STATE_SAFEOP) {
435  off += sprintf(buffer + off, "SAFEOP");
436  } else if ((states & EC_SLAVE_STATE_MASK) == EC_SLAVE_STATE_OP) {
437  off += sprintf(buffer + off, "OP");
438  } else {
439  off += sprintf(buffer + off, "(invalid)");
440  }
441  first = 0;
442  }
443 
444  if (states & EC_SLAVE_STATE_ACK_ERR) {
445  if (!first) off += sprintf(buffer + off, " + ");
446  off += sprintf(buffer + off, "ERROR");
447  }
448 
449  return off;
450 }
451 
452 /******************************************************************************
453  * Device interface
454  *****************************************************************************/
455 
458 const char *ec_device_names[2] = {
459  "main",
460  "backup"
461 };
462 
474  struct net_device *net_dev,
475  ec_pollfunc_t poll,
476  struct module *module
477  )
478 {
479  ec_master_t *master;
480  char str[EC_MAX_MAC_STRING_SIZE];
481  unsigned int i, dev_idx;
482 
483  for (i = 0; i < master_count; i++) {
484  master = &masters[i];
485  ec_mac_print(net_dev->dev_addr, str);
486 
487  if (down_interruptible(&master->device_sem)) {
488  EC_MASTER_WARN(master, "%s() interrupted!\n", __func__);
489  return NULL;
490  }
491 
492  for (dev_idx = EC_DEVICE_MAIN;
493  dev_idx < ec_master_num_devices(master); dev_idx++) {
494  if (!master->devices[dev_idx].dev
495  && (ec_mac_equal(master->macs[dev_idx], net_dev->dev_addr)
496  || ec_mac_is_broadcast(master->macs[dev_idx]))) {
497 
498  EC_INFO("Accepting %s as %s device for master %u.\n",
499  str, ec_device_names[dev_idx != 0], master->index);
500 
501  ec_device_attach(&master->devices[dev_idx],
502  net_dev, poll, module);
503  up(&master->device_sem);
504 
505  snprintf(net_dev->name, IFNAMSIZ, "ec%c%u",
506  ec_device_names[dev_idx != 0][0], master->index);
507 
508  return &master->devices[dev_idx]; // offer accepted
509  }
510  }
511 
512  up(&master->device_sem);
513 
514  EC_MASTER_DBG(master, 1, "Master declined device %s.\n", str);
515  }
516 
517  return NULL; // offer declined
518 }
519 
520 /******************************************************************************
521  * Application interface
522  *****************************************************************************/
523 
531  unsigned int master_index
532  )
533 {
534  ec_master_t *master, *errptr = NULL;
535  unsigned int dev_idx = EC_DEVICE_MAIN;
536 
537  EC_INFO("Requesting master %u...\n", master_index);
538 
539  if (master_index >= master_count) {
540  EC_ERR("Invalid master index %u.\n", master_index);
541  errptr = ERR_PTR(-EINVAL);
542  goto out_return;
543  }
544  master = &masters[master_index];
545 
546  if (down_interruptible(&master_sem)) {
547  errptr = ERR_PTR(-EINTR);
548  goto out_return;
549  }
550 
551  if (master->reserved) {
552  up(&master_sem);
553  EC_MASTER_ERR(master, "Master already in use!\n");
554  errptr = ERR_PTR(-EBUSY);
555  goto out_return;
556  }
557  master->reserved = 1;
558  up(&master_sem);
559 
560  if (down_interruptible(&master->device_sem)) {
561  errptr = ERR_PTR(-EINTR);
562  goto out_release;
563  }
564 
565  if (master->phase != EC_IDLE) {
566  up(&master->device_sem);
567  EC_MASTER_ERR(master, "Master still waiting for devices!\n");
568  errptr = ERR_PTR(-ENODEV);
569  goto out_release;
570  }
571 
572  for (; dev_idx < ec_master_num_devices(master); dev_idx++) {
573  ec_device_t *device = &master->devices[dev_idx];
574  if (!try_module_get(device->module)) {
575  up(&master->device_sem);
576  EC_MASTER_ERR(master, "Device module is unloading!\n");
577  errptr = ERR_PTR(-ENODEV);
578  goto out_module_put;
579  }
580  }
581 
582  up(&master->device_sem);
583 
584  if (ec_master_enter_operation_phase(master)) {
585  EC_MASTER_ERR(master, "Failed to enter OPERATION phase!\n");
586  errptr = ERR_PTR(-EIO);
587  goto out_module_put;
588  }
589 
590  EC_INFO("Successfully requested master %u.\n", master_index);
591  return master;
592 
593  out_module_put:
594  for (; dev_idx > 0; dev_idx--) {
595  ec_device_t *device = &master->devices[dev_idx - 1];
596  module_put(device->module);
597  }
598  out_release:
599  master->reserved = 0;
600  out_return:
601  return errptr;
602 }
603 
604 /*****************************************************************************/
605 
606 ec_master_t *ecrt_request_master(unsigned int master_index)
607 {
608  ec_master_t *master = ecrt_request_master_err(master_index);
609  return IS_ERR(master) ? NULL : master;
610 }
611 
612 /*****************************************************************************/
613 
615 {
616  unsigned int dev_idx;
617 
618  EC_MASTER_INFO(master, "Releasing master...\n");
619 
620  if (!master->reserved) {
621  EC_MASTER_WARN(master, "%s(): Master was was not requested!\n",
622  __func__);
623  return;
624  }
625 
627 
628  for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
629  dev_idx++) {
630  module_put(master->devices[dev_idx].module);
631  }
632 
633  master->reserved = 0;
634 
635  EC_MASTER_INFO(master, "Released.\n");
636 }
637 
638 /*****************************************************************************/
639 
640 unsigned int ecrt_version_magic(void)
641 {
642  return ECRT_VERSION_MAGIC;
643 }
644 
645 /*****************************************************************************/
646 
652  EC_REQUEST_UNUSED, // EC_INT_REQUEST_INIT,
653  EC_REQUEST_BUSY, // EC_INT_REQUEST_QUEUED,
654  EC_REQUEST_BUSY, // EC_INT_REQUEST_BUSY,
655  EC_REQUEST_SUCCESS, // EC_INT_REQUEST_SUCCESS,
656  EC_REQUEST_ERROR // EC_INT_REQUEST_FAILURE
657 };
658 
659 /*****************************************************************************/
660 
663 module_init(ec_init_module);
664 module_exit(ec_cleanup_module);
665 
666 EXPORT_SYMBOL(ecdev_offer);
667 
668 EXPORT_SYMBOL(ecrt_request_master);
669 EXPORT_SYMBOL(ecrt_release_master);
670 EXPORT_SYMBOL(ecrt_version_magic);
671 
674 /*****************************************************************************/
unsigned int reserved
True, if the master is in use.
Definition: master.h:196
void ec_print_data(const uint8_t *data, size_t size)
Outputs frame contents for debugging purposes.
Definition: module.c:341
#define EC_SLAVE_STATE_MASK
Slave state mask.
Definition: globals.h:123
static char * backup_devices[MAX_MASTERS]
Backup devices parameter.
Definition: module.c:59
size_t ec_state_string(uint8_t states, char *buffer, uint8_t multi)
Prints slave states in clear text.
Definition: module.c:394
int ec_mac_is_broadcast(const uint8_t *mac)
Definition: module.c:281
void ecrt_release_master(ec_master_t *master)
Releases a requested EtherCAT master.
Definition: module.c:614
void ec_master_clear(ec_master_t *master)
Destructor.
Definition: master.c:385
OP (mailbox communication and input/output update)
Definition: globals.h:138
ssize_t ec_mac_print(const uint8_t *mac, char *buffer)
Print a MAC address to a buffer.
Definition: module.c:242
void ec_master_leave_operation_phase(ec_master_t *master)
Transition function from OPERATION to IDLE phase.
Definition: master.c:764
#define ec_master_num_devices(MASTER)
Number of Ethernet devices.
Definition: master.h:330
#define EC_MAX_MAC_STRING_SIZE
Maximum MAC string size.
Definition: module.c:234
struct module * module
pointer to the device's owning module
Definition: device.h:86
dev_t device_number
Device number for master cdevs.
Definition: module.c:66
Bootstrap state (mailbox communication, firmware update)
Definition: globals.h:134
int ec_mac_is_zero(const uint8_t *mac)
Definition: module.c:263
#define MAX_MASTERS
Maximum number of masters.
Definition: module.c:46
static ec_master_t * masters
Array of masters.
Definition: module.c:63
char * ec_master_version_str
Version string.
Definition: module.c:71
Acknowledge/Error bit (no actual state)
Definition: globals.h:140
static unsigned int debug_level
Debug level parameter.
Definition: module.c:61
const uint8_t * macs[EC_MAX_NUM_DEVICES]
Device MAC addresses.
Definition: master.h:212
void ec_print_data_diff(const uint8_t *d1, const uint8_t *d2, size_t size)
Outputs frame contents and differences for debugging purposes.
Definition: module.c:369
ec_master_t * ecrt_request_master_err(unsigned int master_index)
Request a master.
Definition: module.c:530
Global definitions and macros.
EtherCAT master structure.
void __exit ec_cleanup_module(void)
Module cleanup.
Definition: module.c:181
SAFEOP (mailbox communication and input update)
Definition: globals.h:136
Not requested.
Definition: ecrt.h:518
#define EC_MASTER_DBG(master, level, fmt, args...)
Convenience macro for printing master-specific debug messages to syslog.
Definition: master.h:111
ec_master_t * ecrt_request_master(unsigned int master_index)
Requests an EtherCAT master for realtime operation.
Definition: module.c:606
Request is being processed.
Definition: ecrt.h:519
static uint8_t macs[MAX_MASTERS][2][ETH_ALEN]
MAC addresses.
Definition: module.c:69
ec_master_phase_t phase
Master phase.
Definition: master.h:223
static unsigned int master_count
Number of masters.
Definition: module.c:58
struct semaphore device_sem
Device semaphore.
Definition: master.h:218
EtherCAT device.
Definition: device.h:81
int __init ec_init_module(void)
Module initialization.
Definition: module.c:98
Main device.
Definition: globals.h:202
unsigned int ecrt_version_magic(void)
Returns the version magic of the realtime interface.
Definition: module.c:640
int ec_master_init(ec_master_t *master, unsigned int index, const uint8_t *main_mac, const uint8_t *backup_mac, dev_t device_number, struct class *class, unsigned int debug_level)
Master constructor.
Definition: master.c:133
#define EC_MASTER_WARN(master, fmt, args...)
Convenience macro for printing master-specific warnings to syslog.
Definition: master.h:97
int ec_master_enter_operation_phase(ec_master_t *master)
Transition function from IDLE to OPERATION phase.
Definition: master.c:682
struct class * class
Device class.
Definition: module.c:67
#define EC_MASTER_ERR(master, fmt, args...)
Convenience macro for printing master-specific errors to syslog.
Definition: master.h:85
int ec_mac_equal(const uint8_t *mac1, const uint8_t *mac2)
Definition: module.c:216
INIT state (no mailbox communication, no IO)
Definition: globals.h:130
Idle phase.
Definition: master.h:133
#define EC_DBG(fmt, args...)
Convenience macro for printing EtherCAT debug messages to syslog.
Definition: globals.h:247
#define EC_INFO(fmt, args...)
Convenience macro for printing EtherCAT-specific information to syslog.
Definition: globals.h:217
#define EC_ERR(fmt, args...)
Convenience macro for printing EtherCAT-specific errors to syslog.
Definition: globals.h:227
ec_device_t * ecdev_offer(struct net_device *net_dev, ec_pollfunc_t poll, struct module *module)
Offers an EtherCAT device to a certain master.
Definition: module.c:473
void(* ec_pollfunc_t)(struct net_device *)
Device poll function type.
Definition: ecdev.h:57
unsigned int ec_master_count(void)
Get the number of masters.
Definition: module.c:204
static struct semaphore master_sem
Master semaphore.
Definition: module.c:64
const ec_request_state_t ec_request_state_translation_table[]
Global request state type translation table.
Definition: module.c:651
void ec_device_attach(ec_device_t *device, struct net_device *net_dev, ec_pollfunc_t poll, struct module *module)
Associate with net_device.
Definition: device.c:182
EtherCAT device structure.
static int ec_mac_parse(uint8_t *, const char *, int)
Parse a MAC address from a string.
Definition: module.c:303
struct net_device * dev
pointer to the assigned net_device
Definition: device.h:84
Request was processed successfully.
Definition: ecrt.h:520
static unsigned int backup_count
Number of backup devices.
Definition: module.c:60
ec_request_state_t
Request state.
Definition: ecrt.h:517
unsigned int index
Index.
Definition: master.h:195
PREOP state (mailbox communication, no IO)
Definition: globals.h:132
#define EC_MASTER_INFO(master, fmt, args...)
Convenience macro for printing master-specific information to syslog.
Definition: master.h:73
static char * main_devices[MAX_MASTERS]
Main devices parameter.
Definition: module.c:57
EtherCAT master.
Definition: master.h:194
Request processing failed.
Definition: ecrt.h:521
ec_device_t devices[EC_MAX_NUM_DEVICES]
EtherCAT devices.
Definition: master.h:211
void ec_master_init_static(void)
Static variables initializer.
Definition: master.c:112
#define ECRT_VERSION_MAGIC
EtherCAT realtime interface version word.
Definition: ecrt.h:151
const char * ec_device_names[2]
Device names.
Definition: module.c:458