227 return 1; |
227 return 1; |
228 } |
228 } |
229 |
229 |
230 /*****************************************************************************/ |
230 /*****************************************************************************/ |
231 |
231 |
|
232 /** Maximum MAC string size. |
|
233 */ |
|
234 #define EC_MAX_MAC_STRING_SIZE (3 * ETH_ALEN) |
|
235 |
232 /** Print a MAC address to a buffer. |
236 /** Print a MAC address to a buffer. |
|
237 * |
|
238 * The buffer size must be at least EC_MAX_MAC_STRING_SIZE. |
233 * |
239 * |
234 * \return number of bytes written. |
240 * \return number of bytes written. |
235 */ |
241 */ |
236 ssize_t ec_mac_print( |
242 ssize_t ec_mac_print( |
237 const uint8_t *mac, /**< MAC address */ |
243 const uint8_t *mac, /**< MAC address */ |
238 char *buffer /**< target buffer */ |
244 char *buffer /**< Target buffer. */ |
239 ) |
245 ) |
240 { |
246 { |
241 off_t off = 0; |
247 off_t off = 0; |
242 unsigned int i; |
248 unsigned int i; |
243 |
249 |
443 |
449 |
444 /****************************************************************************** |
450 /****************************************************************************** |
445 * Device interface |
451 * Device interface |
446 *****************************************************************************/ |
452 *****************************************************************************/ |
447 |
453 |
|
454 /** Device names. |
|
455 */ |
|
456 static const char *ec_device_names[EC_NUM_DEVICES] = { |
|
457 "main", |
|
458 "backup" |
|
459 }; |
|
460 |
448 /** Offers an EtherCAT device to a certain master. |
461 /** Offers an EtherCAT device to a certain master. |
449 * |
462 * |
450 * The master decides, if it wants to use the device for EtherCAT operation, |
463 * The master decides, if it wants to use the device for EtherCAT operation, |
451 * or not. It is important, that the offered net_device is not used by the |
464 * or not. It is important, that the offered net_device is not used by the |
452 * kernel IP stack. If the master, accepted the offer, the address of the |
465 * kernel IP stack. If the master, accepted the offer, the address of the |
460 ec_pollfunc_t poll, /**< device poll function */ |
473 ec_pollfunc_t poll, /**< device poll function */ |
461 struct module *module /**< pointer to the module */ |
474 struct module *module /**< pointer to the module */ |
462 ) |
475 ) |
463 { |
476 { |
464 ec_master_t *master; |
477 ec_master_t *master; |
465 char str[20]; |
478 char str[EC_MAX_MAC_STRING_SIZE]; |
466 unsigned int i; |
479 unsigned int i, j; |
467 |
480 |
468 for (i = 0; i < master_count; i++) { |
481 for (i = 0; i < master_count; i++) { |
469 master = &masters[i]; |
482 master = &masters[i]; |
470 ec_mac_print(net_dev->dev_addr, str); |
483 ec_mac_print(net_dev->dev_addr, str); |
471 |
484 |
472 down(&master->device_sem); |
485 down(&master->device_sem); |
473 |
486 |
474 if (!master->main_device.dev |
487 for (j = 0; j < EC_NUM_DEVICES; j++) { |
475 && (ec_mac_equal(master->main_mac, net_dev->dev_addr) |
488 if (!master->devices[j].dev |
476 || ec_mac_is_broadcast(master->main_mac))) { |
489 && (ec_mac_equal(master->macs[j], net_dev->dev_addr) |
477 |
490 || ec_mac_is_broadcast(master->macs[j]))) { |
478 EC_INFO("Accepting %s as main device for master %u.\n", |
491 |
479 str, master->index); |
492 EC_INFO("Accepting %s as %s device for master %u.\n", |
480 |
493 str, ec_device_names[j], master->index); |
481 ec_device_attach(&master->main_device, net_dev, poll, module); |
494 |
482 up(&master->device_sem); |
495 ec_device_attach(&master->devices[j], net_dev, poll, module); |
483 |
496 up(&master->device_sem); |
484 snprintf(net_dev->name, IFNAMSIZ, "ecm%u", master->index); |
497 |
485 |
498 snprintf(net_dev->name, IFNAMSIZ, "ec%c%u", |
486 return &master->main_device; // offer accepted |
499 ec_device_names[j][0], master->index); |
487 |
500 |
488 } else if (!master->backup_device.dev |
501 return &master->devices[j]; // offer accepted |
489 && ec_mac_equal(master->backup_mac, net_dev->dev_addr)) { |
502 } |
490 |
503 } |
491 EC_INFO("Accepting %s as backup device for master %u.\n", |
504 |
492 str, master->index); |
505 up(&master->device_sem); |
493 |
506 |
494 ec_device_attach(&master->backup_device, net_dev, poll, module); |
507 EC_MASTER_DBG(master, 1, "Master declined device %s.\n", str); |
495 up(&master->device_sem); |
|
496 |
|
497 snprintf(net_dev->name, IFNAMSIZ, "ecb%u", master->index); |
|
498 |
|
499 return &master->backup_device; // offer accepted |
|
500 |
|
501 } else { |
|
502 |
|
503 up(&master->device_sem); |
|
504 |
|
505 EC_MASTER_DBG(master, 1, "Master declined device %s.\n", str); |
|
506 } |
|
507 } |
508 } |
508 |
509 |
509 return NULL; // offer declined |
510 return NULL; // offer declined |
510 } |
511 } |
511 |
512 |
520 ec_master_t *ecrt_request_master_err( |
521 ec_master_t *ecrt_request_master_err( |
521 unsigned int master_index /**< Master index. */ |
522 unsigned int master_index /**< Master index. */ |
522 ) |
523 ) |
523 { |
524 { |
524 ec_master_t *master, *errptr = NULL; |
525 ec_master_t *master, *errptr = NULL; |
|
526 unsigned int i, got_modules = 0; |
525 |
527 |
526 EC_INFO("Requesting master %u...\n", master_index); |
528 EC_INFO("Requesting master %u...\n", master_index); |
527 |
529 |
528 if (master_index >= master_count) { |
530 if (master_index >= master_count) { |
529 EC_ERR("Invalid master index %u.\n", master_index); |
531 EC_ERR("Invalid master index %u.\n", master_index); |
556 EC_MASTER_ERR(master, "Master still waiting for devices!\n"); |
558 EC_MASTER_ERR(master, "Master still waiting for devices!\n"); |
557 errptr = ERR_PTR(-ENODEV); |
559 errptr = ERR_PTR(-ENODEV); |
558 goto out_release; |
560 goto out_release; |
559 } |
561 } |
560 |
562 |
561 if (!try_module_get(master->main_device.module)) { |
563 for (i = 0; i < EC_NUM_DEVICES; i++) { |
562 up(&master->device_sem); |
564 ec_device_t *device = &master->devices[i]; |
563 EC_ERR("Device module is unloading!\n"); |
565 if (device->dev) { |
564 errptr = ERR_PTR(-ENODEV); |
566 if (!try_module_get(device->module)) { |
565 goto out_release; |
567 up(&master->device_sem); |
|
568 EC_MASTER_ERR(master, "Device module is unloading!\n"); |
|
569 errptr = ERR_PTR(-ENODEV); |
|
570 goto out_module_put; |
|
571 } |
|
572 } |
|
573 got_modules++; |
566 } |
574 } |
567 |
575 |
568 up(&master->device_sem); |
576 up(&master->device_sem); |
569 |
577 |
570 if (ec_master_enter_operation_phase(master)) { |
578 if (ec_master_enter_operation_phase(master)) { |
594 |
607 |
595 /*****************************************************************************/ |
608 /*****************************************************************************/ |
596 |
609 |
597 void ecrt_release_master(ec_master_t *master) |
610 void ecrt_release_master(ec_master_t *master) |
598 { |
611 { |
|
612 unsigned int i; |
|
613 |
599 EC_MASTER_INFO(master, "Releasing master...\n"); |
614 EC_MASTER_INFO(master, "Releasing master...\n"); |
600 |
615 |
601 if (!master->reserved) { |
616 if (!master->reserved) { |
602 EC_MASTER_WARN(master, "%s(): Master was was not requested!\n", |
617 EC_MASTER_WARN(master, "%s(): Master was was not requested!\n", |
603 __func__); |
618 __func__); |
604 return; |
619 return; |
605 } |
620 } |
606 |
621 |
607 ec_master_leave_operation_phase(master); |
622 ec_master_leave_operation_phase(master); |
608 |
623 |
609 module_put(master->main_device.module); |
624 for (i = 0; i < EC_NUM_DEVICES; i++) { |
|
625 if (master->devices[i].dev) { |
|
626 module_put(master->devices[i].module); |
|
627 } |
|
628 } |
|
629 |
610 master->reserved = 0; |
630 master->reserved = 0; |
611 |
631 |
612 EC_MASTER_INFO(master, "Released.\n"); |
632 EC_MASTER_INFO(master, "Released.\n"); |
613 } |
633 } |
614 |
634 |