master/module.c
branchredundancy
changeset 2267 2d36f36a433c
parent 2159 72ac85ee3729
child 2374 e898451c054a
equal deleted inserted replaced
2160:e3bf5adad75f 2267:2d36f36a433c
   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)) {
   575 
   583 
   576     EC_INFO("Successfully requested master %u.\n", master_index);
   584     EC_INFO("Successfully requested master %u.\n", master_index);
   577     return master;
   585     return master;
   578 
   586 
   579  out_module_put:
   587  out_module_put:
   580     module_put(master->main_device.module);
   588     for (; got_modules > 0; got_modules--) {
       
   589         ec_device_t *device = &master->devices[i - 1];
       
   590         if (device->dev) {
       
   591             module_put(device->module);
       
   592         }
       
   593     }
   581  out_release:
   594  out_release:
   582     master->reserved = 0;
   595     master->reserved = 0;
   583  out_return:
   596  out_return:
   584     return errptr;
   597     return errptr;
   585 }
   598 }
   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