00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00034
00035
00036 #include <linux/module.h>
00037 #include <linux/device.h>
00038 #include <linux/err.h>
00039
00040 #include "globals.h"
00041 #include "master.h"
00042 #include "device.h"
00043
00044
00045
00046 #define MAX_MASTERS 32
00048
00049
00050 int __init ec_init_module(void);
00051 void __exit ec_cleanup_module(void);
00052
00053 static int ec_mac_parse(uint8_t *, const char *, int);
00054
00055
00056
00057 static char *main_devices[MAX_MASTERS];
00058 static unsigned int master_count;
00059 static char *backup_devices[MAX_MASTERS];
00060 static unsigned int backup_count;
00061 static unsigned int debug_level;
00063 static ec_master_t *masters;
00064 static struct semaphore master_sem;
00066 dev_t device_number;
00067 struct class *class;
00069 static uint8_t macs[MAX_MASTERS][2][ETH_ALEN];
00071 char *ec_master_version_str = EC_MASTER_VERSION;
00073
00074
00077 MODULE_AUTHOR("Florian Pose <fp@igh-essen.com>");
00078 MODULE_DESCRIPTION("EtherCAT master driver module");
00079 MODULE_LICENSE("GPL");
00080 MODULE_VERSION(EC_MASTER_VERSION);
00081
00082 module_param_array(main_devices, charp, &master_count, S_IRUGO);
00083 MODULE_PARM_DESC(main_devices, "MAC addresses of main devices");
00084 module_param_array(backup_devices, charp, &backup_count, S_IRUGO);
00085 MODULE_PARM_DESC(backup_devices, "MAC addresses of backup devices");
00086 module_param_named(debug_level, debug_level, uint, S_IRUGO);
00087 MODULE_PARM_DESC(debug_level, "Debug level");
00088
00091
00092
00098 int __init ec_init_module(void)
00099 {
00100 int i, ret = 0;
00101
00102 EC_INFO("Master driver %s\n", EC_MASTER_VERSION);
00103
00104 sema_init(&master_sem, 1);
00105
00106 if (master_count) {
00107 if (alloc_chrdev_region(&device_number,
00108 0, master_count, "EtherCAT")) {
00109 EC_ERR("Failed to obtain device number(s)!\n");
00110 ret = -EBUSY;
00111 goto out_return;
00112 }
00113 }
00114
00115 class = class_create(THIS_MODULE, "EtherCAT");
00116 if (IS_ERR(class)) {
00117 EC_ERR("Failed to create device class.\n");
00118 ret = PTR_ERR(class);
00119 goto out_cdev;
00120 }
00121
00122
00123 memset(macs, 0x00, sizeof(uint8_t) * MAX_MASTERS * 2 * ETH_ALEN);
00124
00125
00126 for (i = 0; i < master_count; i++) {
00127 ret = ec_mac_parse(macs[i][0], main_devices[i], 0);
00128 if (ret)
00129 goto out_class;
00130
00131 if (i < backup_count) {
00132 ret = ec_mac_parse(macs[i][1], backup_devices[i], 1);
00133 if (ret)
00134 goto out_class;
00135 }
00136 }
00137
00138
00139 ec_master_init_static();
00140
00141 if (master_count) {
00142 if (!(masters = kmalloc(sizeof(ec_master_t) * master_count,
00143 GFP_KERNEL))) {
00144 EC_ERR("Failed to allocate memory"
00145 " for EtherCAT masters.\n");
00146 ret = -ENOMEM;
00147 goto out_class;
00148 }
00149 }
00150
00151 for (i = 0; i < master_count; i++) {
00152 ret = ec_master_init(&masters[i], i, macs[i][0], macs[i][1],
00153 device_number, class, debug_level);
00154 if (ret)
00155 goto out_free_masters;
00156 }
00157
00158 EC_INFO("%u master%s waiting for devices.\n",
00159 master_count, (master_count == 1 ? "" : "s"));
00160 return ret;
00161
00162 out_free_masters:
00163 for (i--; i >= 0; i--)
00164 ec_master_clear(&masters[i]);
00165 kfree(masters);
00166 out_class:
00167 class_destroy(class);
00168 out_cdev:
00169 if (master_count)
00170 unregister_chrdev_region(device_number, master_count);
00171 out_return:
00172 return ret;
00173 }
00174
00175
00176
00181 void __exit ec_cleanup_module(void)
00182 {
00183 unsigned int i;
00184
00185 for (i = 0; i < master_count; i++) {
00186 ec_master_clear(&masters[i]);
00187 }
00188
00189 if (master_count)
00190 kfree(masters);
00191
00192 class_destroy(class);
00193
00194 if (master_count)
00195 unregister_chrdev_region(device_number, master_count);
00196
00197 EC_INFO("Master module cleaned up.\n");
00198 }
00199
00200
00201
00204 unsigned int ec_master_count(void)
00205 {
00206 return master_count;
00207 }
00208
00209
00210
00211
00212
00216 int ec_mac_equal(
00217 const uint8_t *mac1,
00218 const uint8_t *mac2
00219 )
00220 {
00221 unsigned int i;
00222
00223 for (i = 0; i < ETH_ALEN; i++)
00224 if (mac1[i] != mac2[i])
00225 return 0;
00226
00227 return 1;
00228 }
00229
00230
00231
00234 #define EC_MAX_MAC_STRING_SIZE (3 * ETH_ALEN)
00235
00242 ssize_t ec_mac_print(
00243 const uint8_t *mac,
00244 char *buffer
00245 )
00246 {
00247 off_t off = 0;
00248 unsigned int i;
00249
00250 for (i = 0; i < ETH_ALEN; i++) {
00251 off += sprintf(buffer + off, "%02X", mac[i]);
00252 if (i < ETH_ALEN - 1) off += sprintf(buffer + off, ":");
00253 }
00254
00255 return off;
00256 }
00257
00258
00259
00263 int ec_mac_is_zero(
00264 const uint8_t *mac
00265 )
00266 {
00267 unsigned int i;
00268
00269 for (i = 0; i < ETH_ALEN; i++)
00270 if (mac[i])
00271 return 0;
00272
00273 return 1;
00274 }
00275
00276
00277
00281 int ec_mac_is_broadcast(
00282 const uint8_t *mac
00283 )
00284 {
00285 unsigned int i;
00286
00287 for (i = 0; i < ETH_ALEN; i++)
00288 if (mac[i] != 0xff)
00289 return 0;
00290
00291 return 1;
00292 }
00293
00294
00295
00303 static int ec_mac_parse(uint8_t *mac, const char *src, int allow_empty)
00304 {
00305 unsigned int i, value;
00306 const char *orig = src;
00307 char *rem;
00308
00309 if (!strlen(src)) {
00310 if (allow_empty){
00311 return 0;
00312 } else {
00313 EC_ERR("MAC address may not be empty.\n");
00314 return -EINVAL;
00315 }
00316 }
00317
00318 for (i = 0; i < ETH_ALEN; i++) {
00319 value = simple_strtoul(src, &rem, 16);
00320 if (rem != src + 2
00321 || value > 0xFF
00322 || (i < ETH_ALEN - 1 && *rem != ':')) {
00323 EC_ERR("Invalid MAC address \"%s\".\n", orig);
00324 return -EINVAL;
00325 }
00326 mac[i] = value;
00327 if (i < ETH_ALEN - 1) {
00328 src = rem + 1;
00329 }
00330 }
00331
00332 return 0;
00333 }
00334
00335
00336
00341 void ec_print_data(const uint8_t *data,
00342 size_t size
00343 )
00344 {
00345 unsigned int i;
00346
00347 EC_DBG("");
00348 for (i = 0; i < size; i++) {
00349 printk("%02X ", data[i]);
00350
00351 if ((i + 1) % 16 == 0 && i < size - 1) {
00352 printk("\n");
00353 EC_DBG("");
00354 }
00355
00356 if (i + 1 == 128 && size > 256) {
00357 printk("dropped %zu bytes\n", size - 128 - i);
00358 i = size - 128;
00359 EC_DBG("");
00360 }
00361 }
00362 printk("\n");
00363 }
00364
00365
00366
00369 void ec_print_data_diff(const uint8_t *d1,
00370 const uint8_t *d2,
00371 size_t size
00372 )
00373 {
00374 unsigned int i;
00375
00376 EC_DBG("");
00377 for (i = 0; i < size; i++) {
00378 if (d1[i] == d2[i]) printk(".. ");
00379 else printk("%02X ", d2[i]);
00380 if ((i + 1) % 16 == 0) {
00381 printk("\n");
00382 EC_DBG("");
00383 }
00384 }
00385 printk("\n");
00386 }
00387
00388
00389
00394 size_t ec_state_string(uint8_t states,
00395 char *buffer,
00397 uint8_t multi
00398 )
00399 {
00400 off_t off = 0;
00401 unsigned int first = 1;
00402
00403 if (!states) {
00404 off += sprintf(buffer + off, "(unknown)");
00405 return off;
00406 }
00407
00408 if (multi) {
00409 if (states & EC_SLAVE_STATE_INIT) {
00410 off += sprintf(buffer + off, "INIT");
00411 first = 0;
00412 }
00413 if (states & EC_SLAVE_STATE_PREOP) {
00414 if (!first) off += sprintf(buffer + off, ", ");
00415 off += sprintf(buffer + off, "PREOP");
00416 first = 0;
00417 }
00418 if (states & EC_SLAVE_STATE_SAFEOP) {
00419 if (!first) off += sprintf(buffer + off, ", ");
00420 off += sprintf(buffer + off, "SAFEOP");
00421 first = 0;
00422 }
00423 if (states & EC_SLAVE_STATE_OP) {
00424 if (!first) off += sprintf(buffer + off, ", ");
00425 off += sprintf(buffer + off, "OP");
00426 }
00427 } else {
00428 if ((states & EC_SLAVE_STATE_MASK) == EC_SLAVE_STATE_INIT) {
00429 off += sprintf(buffer + off, "INIT");
00430 } else if ((states & EC_SLAVE_STATE_MASK) == EC_SLAVE_STATE_PREOP) {
00431 off += sprintf(buffer + off, "PREOP");
00432 } else if ((states & EC_SLAVE_STATE_MASK) == EC_SLAVE_STATE_BOOT) {
00433 off += sprintf(buffer + off, "BOOT");
00434 } else if ((states & EC_SLAVE_STATE_MASK) == EC_SLAVE_STATE_SAFEOP) {
00435 off += sprintf(buffer + off, "SAFEOP");
00436 } else if ((states & EC_SLAVE_STATE_MASK) == EC_SLAVE_STATE_OP) {
00437 off += sprintf(buffer + off, "OP");
00438 } else {
00439 off += sprintf(buffer + off, "(invalid)");
00440 }
00441 first = 0;
00442 }
00443
00444 if (states & EC_SLAVE_STATE_ACK_ERR) {
00445 if (!first) off += sprintf(buffer + off, " + ");
00446 off += sprintf(buffer + off, "ERROR");
00447 }
00448
00449 return off;
00450 }
00451
00452
00453
00454
00455
00458 const char *ec_device_names[2] = {
00459 "main",
00460 "backup"
00461 };
00462
00473 ec_device_t *ecdev_offer(
00474 struct net_device *net_dev,
00475 ec_pollfunc_t poll,
00476 struct module *module
00477 )
00478 {
00479 ec_master_t *master;
00480 char str[EC_MAX_MAC_STRING_SIZE];
00481 unsigned int i, dev_idx;
00482
00483 for (i = 0; i < master_count; i++) {
00484 master = &masters[i];
00485 ec_mac_print(net_dev->dev_addr, str);
00486
00487 if (down_interruptible(&master->device_sem)) {
00488 EC_MASTER_WARN(master, "%s() interrupted!\n", __func__);
00489 return NULL;
00490 }
00491
00492 for (dev_idx = EC_DEVICE_MAIN;
00493 dev_idx < ec_master_num_devices(master); dev_idx++) {
00494 if (!master->devices[dev_idx].dev
00495 && (ec_mac_equal(master->macs[dev_idx], net_dev->dev_addr)
00496 || ec_mac_is_broadcast(master->macs[dev_idx]))) {
00497
00498 EC_INFO("Accepting %s as %s device for master %u.\n",
00499 str, ec_device_names[dev_idx != 0], master->index);
00500
00501 ec_device_attach(&master->devices[dev_idx],
00502 net_dev, poll, module);
00503 up(&master->device_sem);
00504
00505 snprintf(net_dev->name, IFNAMSIZ, "ec%c%u",
00506 ec_device_names[dev_idx != 0][0], master->index);
00507
00508 return &master->devices[dev_idx];
00509 }
00510 }
00511
00512 up(&master->device_sem);
00513
00514 EC_MASTER_DBG(master, 1, "Master declined device %s.\n", str);
00515 }
00516
00517 return NULL;
00518 }
00519
00520
00521
00522
00523
00530 ec_master_t *ecrt_request_master_err(
00531 unsigned int master_index
00532 )
00533 {
00534 ec_master_t *master, *errptr = NULL;
00535 unsigned int dev_idx = EC_DEVICE_MAIN;
00536
00537 EC_INFO("Requesting master %u...\n", master_index);
00538
00539 if (master_index >= master_count) {
00540 EC_ERR("Invalid master index %u.\n", master_index);
00541 errptr = ERR_PTR(-EINVAL);
00542 goto out_return;
00543 }
00544 master = &masters[master_index];
00545
00546 if (down_interruptible(&master_sem)) {
00547 errptr = ERR_PTR(-EINTR);
00548 goto out_return;
00549 }
00550
00551 if (master->reserved) {
00552 up(&master_sem);
00553 EC_MASTER_ERR(master, "Master already in use!\n");
00554 errptr = ERR_PTR(-EBUSY);
00555 goto out_return;
00556 }
00557 master->reserved = 1;
00558 up(&master_sem);
00559
00560 if (down_interruptible(&master->device_sem)) {
00561 errptr = ERR_PTR(-EINTR);
00562 goto out_release;
00563 }
00564
00565 if (master->phase != EC_IDLE) {
00566 up(&master->device_sem);
00567 EC_MASTER_ERR(master, "Master still waiting for devices!\n");
00568 errptr = ERR_PTR(-ENODEV);
00569 goto out_release;
00570 }
00571
00572 for (; dev_idx < ec_master_num_devices(master); dev_idx++) {
00573 ec_device_t *device = &master->devices[dev_idx];
00574 if (!try_module_get(device->module)) {
00575 up(&master->device_sem);
00576 EC_MASTER_ERR(master, "Device module is unloading!\n");
00577 errptr = ERR_PTR(-ENODEV);
00578 goto out_module_put;
00579 }
00580 }
00581
00582 up(&master->device_sem);
00583
00584 if (ec_master_enter_operation_phase(master)) {
00585 EC_MASTER_ERR(master, "Failed to enter OPERATION phase!\n");
00586 errptr = ERR_PTR(-EIO);
00587 goto out_module_put;
00588 }
00589
00590 EC_INFO("Successfully requested master %u.\n", master_index);
00591 return master;
00592
00593 out_module_put:
00594 for (; dev_idx > 0; dev_idx--) {
00595 ec_device_t *device = &master->devices[dev_idx - 1];
00596 module_put(device->module);
00597 }
00598 out_release:
00599 master->reserved = 0;
00600 out_return:
00601 return errptr;
00602 }
00603
00604
00605
00606 ec_master_t *ecrt_request_master(unsigned int master_index)
00607 {
00608 ec_master_t *master = ecrt_request_master_err(master_index);
00609 return IS_ERR(master) ? NULL : master;
00610 }
00611
00612
00613
00614 void ecrt_release_master(ec_master_t *master)
00615 {
00616 unsigned int dev_idx;
00617
00618 EC_MASTER_INFO(master, "Releasing master...\n");
00619
00620 if (!master->reserved) {
00621 EC_MASTER_WARN(master, "%s(): Master was was not requested!\n",
00622 __func__);
00623 return;
00624 }
00625
00626 ec_master_leave_operation_phase(master);
00627
00628 for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
00629 dev_idx++) {
00630 module_put(master->devices[dev_idx].module);
00631 }
00632
00633 master->reserved = 0;
00634
00635 EC_MASTER_INFO(master, "Released.\n");
00636 }
00637
00638
00639
00640 unsigned int ecrt_version_magic(void)
00641 {
00642 return ECRT_VERSION_MAGIC;
00643 }
00644
00645
00646
00651 const ec_request_state_t ec_request_state_translation_table[] = {
00652 EC_REQUEST_UNUSED,
00653 EC_REQUEST_BUSY,
00654 EC_REQUEST_BUSY,
00655 EC_REQUEST_SUCCESS,
00656 EC_REQUEST_ERROR
00657 };
00658
00659
00660
00663 module_init(ec_init_module);
00664 module_exit(ec_cleanup_module);
00665
00666 EXPORT_SYMBOL(ecdev_offer);
00667
00668 EXPORT_SYMBOL(ecrt_request_master);
00669 EXPORT_SYMBOL(ecrt_release_master);
00670 EXPORT_SYMBOL(ecrt_version_magic);
00671
00674