master/module.c
branchstable-1.5
changeset 2419 fdb85a806585
parent 2382 2565cb4d9e31
parent 2374 e898451c054a
child 2453 d461b1f07296
equal deleted inserted replaced
2417:63bef67e812b 2419:fdb85a806585
   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 
   287 
   293 
   288 /*****************************************************************************/
   294 /*****************************************************************************/
   289 
   295 
   290 /** Parse a MAC address from a string.
   296 /** Parse a MAC address from a string.
   291  *
   297  *
   292  * The MAC address must follow the regexp
   298  * The MAC address must match the regular expression
   293  * "([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}".
   299  * "([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}".
   294  *
   300  *
   295  * \return 0 on success, else < 0
   301  * \return 0 on success, else < 0
   296  */
   302  */
   297 static int ec_mac_parse(uint8_t *mac, const char *src, int allow_empty)
   303 static int ec_mac_parse(uint8_t *mac, const char *src, int allow_empty)
   301     char *rem;
   307     char *rem;
   302 
   308 
   303     if (!strlen(src)) {
   309     if (!strlen(src)) {
   304         if (allow_empty){
   310         if (allow_empty){
   305             return 0;
   311             return 0;
   306         }
   312         } else {
   307         else {
       
   308             EC_ERR("MAC address may not be empty.\n");
   313             EC_ERR("MAC address may not be empty.\n");
   309             return -EINVAL;
   314             return -EINVAL;
   310         }
   315         }
   311     }
   316     }
   312 
   317 
   317                 || (i < ETH_ALEN - 1 && *rem != ':')) {
   322                 || (i < ETH_ALEN - 1 && *rem != ':')) {
   318             EC_ERR("Invalid MAC address \"%s\".\n", orig);
   323             EC_ERR("Invalid MAC address \"%s\".\n", orig);
   319             return -EINVAL;
   324             return -EINVAL;
   320         }
   325         }
   321         mac[i] = value;
   326         mac[i] = value;
   322         if (i < ETH_ALEN - 1)
   327         if (i < ETH_ALEN - 1) {
   323             src = rem + 1; // skip colon
   328             src = rem + 1; // skip colon
       
   329         }
   324     }
   330     }
   325 
   331 
   326     return 0;
   332     return 0;
   327 }
   333 }
   328 
   334 
   443 
   449 
   444 /******************************************************************************
   450 /******************************************************************************
   445  *  Device interface
   451  *  Device interface
   446  *****************************************************************************/
   452  *****************************************************************************/
   447 
   453 
       
   454 /** Device names.
       
   455  */
       
   456 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];
       
   483         ec_mac_print(net_dev->dev_addr, str);
   470 
   484 
   471         down(&master->device_sem);
   485         down(&master->device_sem);
   472         if (master->main_device.dev) { // master already has a device
   486 
   473             up(&master->device_sem);
   487         for (j = 0; j < EC_NUM_DEVICES; j++) {
   474             continue;
   488             if (!master->devices[j].dev
   475         }
   489                 && (ec_mac_equal(master->macs[j], net_dev->dev_addr)
   476 
   490                     || ec_mac_is_broadcast(master->macs[j]))) {
   477         if (ec_mac_equal(master->main_mac, net_dev->dev_addr)
   491 
   478                 || ec_mac_is_broadcast(master->main_mac)) {
   492                 EC_INFO("Accepting %s as %s device for master %u.\n",
   479             ec_mac_print(net_dev->dev_addr, str);
   493                         str, ec_device_names[j], master->index);
   480             EC_INFO("Accepting device %s for master %u.\n",
   494 
   481                     str, master->index);
   495                 ec_device_attach(&master->devices[j], net_dev, poll, module);
   482 
   496                 up(&master->device_sem);
   483             ec_device_attach(&master->main_device, net_dev, poll, module);
   497 
   484             up(&master->device_sem);
   498                 snprintf(net_dev->name, IFNAMSIZ, "ec%c%u",
   485 
   499                         ec_device_names[j][0], master->index);
   486             snprintf(net_dev->name, IFNAMSIZ, "ec%u", master->index);
   500 
   487 
   501                 return &master->devices[j]; // offer accepted
   488             return &master->main_device; // offer accepted
       
   489         }
       
   490         else {
       
   491             up(&master->device_sem);
       
   492 
       
   493             if (master->debug_level) {
       
   494                 ec_mac_print(net_dev->dev_addr, str);
       
   495                 EC_MASTER_DBG(master, 0, "Master declined device %s.\n",
       
   496                         str);
       
   497             }
   502             }
   498         }
   503         }
       
   504 
       
   505         up(&master->device_sem);
       
   506 
       
   507         EC_MASTER_DBG(master, 1, "Master declined device %s.\n", str);
   499     }
   508     }
   500 
   509 
   501     return NULL; // offer declined
   510     return NULL; // offer declined
   502 }
   511 }
   503 
   512 
   504 /******************************************************************************
   513 /******************************************************************************
   505  *  Realtime interface
   514  * Application interface
   506  *****************************************************************************/
   515  *****************************************************************************/
   507 
   516 
   508 /** Request a master.
   517 /** Request a master.
   509  *
   518  *
   510  * Same as ecrt_request_master(), but with ERR_PTR() return value.
   519  * Same as ecrt_request_master(), but with ERR_PTR() return value.
   512 ec_master_t *ecrt_request_master_err(
   521 ec_master_t *ecrt_request_master_err(
   513         unsigned int master_index /**< Master index. */
   522         unsigned int master_index /**< Master index. */
   514         )
   523         )
   515 {
   524 {
   516     ec_master_t *master, *errptr = NULL;
   525     ec_master_t *master, *errptr = NULL;
       
   526     unsigned int i, got_modules = 0;
   517 
   527 
   518     EC_INFO("Requesting master %u...\n", master_index);
   528     EC_INFO("Requesting master %u...\n", master_index);
   519 
   529 
   520     if (master_index >= master_count) {
   530     if (master_index >= master_count) {
   521         EC_ERR("Invalid master index %u.\n", master_index);
   531         EC_ERR("Invalid master index %u.\n", master_index);
   548         EC_MASTER_ERR(master, "Master still waiting for devices!\n");
   558         EC_MASTER_ERR(master, "Master still waiting for devices!\n");
   549         errptr = ERR_PTR(-ENODEV);
   559         errptr = ERR_PTR(-ENODEV);
   550         goto out_release;
   560         goto out_release;
   551     }
   561     }
   552 
   562 
   553     if (!try_module_get(master->main_device.module)) {
   563     for (i = 0; i < EC_NUM_DEVICES; i++) {
   554         up(&master->device_sem);
   564         ec_device_t *device = &master->devices[i];
   555         EC_ERR("Device module is unloading!\n");
   565         if (device->dev) {
   556         errptr = ERR_PTR(-ENODEV);
   566             if (!try_module_get(device->module)) {
   557         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++;
   558     }
   574     }
   559 
   575 
   560     up(&master->device_sem);
   576     up(&master->device_sem);
   561 
   577 
   562     if (ec_master_enter_operation_phase(master)) {
   578     if (ec_master_enter_operation_phase(master)) {
   567 
   583 
   568     EC_INFO("Successfully requested master %u.\n", master_index);
   584     EC_INFO("Successfully requested master %u.\n", master_index);
   569     return master;
   585     return master;
   570 
   586 
   571  out_module_put:
   587  out_module_put:
   572     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     }
   573  out_release:
   594  out_release:
   574     master->reserved = 0;
   595     master->reserved = 0;
   575  out_return:
   596  out_return:
   576     return errptr;
   597     return errptr;
   577 }
   598 }
   586 
   607 
   587 /*****************************************************************************/
   608 /*****************************************************************************/
   588 
   609 
   589 void ecrt_release_master(ec_master_t *master)
   610 void ecrt_release_master(ec_master_t *master)
   590 {
   611 {
       
   612     unsigned int i;
       
   613 
   591     EC_MASTER_INFO(master, "Releasing master...\n");
   614     EC_MASTER_INFO(master, "Releasing master...\n");
   592 
   615 
   593     if (!master->reserved) {
   616     if (!master->reserved) {
   594         EC_MASTER_WARN(master, "%s(): Master was was not requested!\n",
   617         EC_MASTER_WARN(master, "%s(): Master was was not requested!\n",
   595                 __func__);
   618                 __func__);
   596         return;
   619         return;
   597     }
   620     }
   598 
   621 
   599     ec_master_leave_operation_phase(master);
   622     ec_master_leave_operation_phase(master);
   600 
   623 
   601     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 
   602     master->reserved = 0;
   630     master->reserved = 0;
   603 
   631 
   604     EC_MASTER_INFO(master, "Released.\n");
   632     EC_MASTER_INFO(master, "Released.\n");
   605 }
   633 }
   606 
   634