master/module.c
changeset 573 cdee4ea90ce9
parent 572 aef7ea866a41
child 575 9a2121b500b1
equal deleted inserted replaced
572:aef7ea866a41 573:cdee4ea90ce9
    52 int __init ec_init_module(void);
    52 int __init ec_init_module(void);
    53 void __exit ec_cleanup_module(void);
    53 void __exit ec_cleanup_module(void);
    54 
    54 
    55 /*****************************************************************************/
    55 /*****************************************************************************/
    56 
    56 
    57 static int ec_master_count = 1; /**< parameter value, number of masters */
    57 static char *main; /**< main devices parameter */
    58 static struct list_head ec_masters; /**< list of masters */
    58 static char *backup; /**< backup devices parameter */
       
    59 
       
    60 static LIST_HEAD(main_device_ids); /**< list of main device IDs */
       
    61 static LIST_HEAD(backup_device_ids); /**< list of main device IDs */
       
    62 static LIST_HEAD(masters); /**< list of masters */
    59 static dev_t device_number; /**< XML character device number */
    63 static dev_t device_number; /**< XML character device number */
    60 ec_xmldev_t xmldev; /**< XML character device */
    64 ec_xmldev_t xmldev; /**< XML character device */
    61 
    65 
    62 char *ec_master_version_str = EC_MASTER_VERSION;
    66 char *ec_master_version_str = EC_MASTER_VERSION;
    63 
    67 
    64 /*****************************************************************************/
    68 /*****************************************************************************/
    65 
    69 
    66 /** \cond */
    70 /** \cond */
    67 
       
    68 module_param(ec_master_count, int, S_IRUGO);
       
    69 
    71 
    70 MODULE_AUTHOR("Florian Pose <fp@igh-essen.com>");
    72 MODULE_AUTHOR("Florian Pose <fp@igh-essen.com>");
    71 MODULE_DESCRIPTION("EtherCAT master driver module");
    73 MODULE_DESCRIPTION("EtherCAT master driver module");
    72 MODULE_LICENSE("GPL");
    74 MODULE_LICENSE("GPL");
    73 MODULE_VERSION(EC_MASTER_VERSION);
    75 MODULE_VERSION(EC_MASTER_VERSION);
    74 MODULE_PARM_DESC(ec_master_count, "number of EtherCAT masters to initialize");
    76 
       
    77 module_param(main, charp, S_IRUGO);
       
    78 MODULE_PARM_DESC(main, "main device IDs");
       
    79 module_param(backup, charp, S_IRUGO);
       
    80 MODULE_PARM_DESC(backup, "backup device IDs");
    75 
    81 
    76 /** \endcond */
    82 /** \endcond */
       
    83 
       
    84 /*****************************************************************************/
       
    85 
       
    86 void clear_device_ids(struct list_head *device_ids)
       
    87 {
       
    88     ec_device_id_t *dev_id, *next_dev_id;
       
    89     
       
    90     list_for_each_entry_safe(dev_id, next_dev_id, device_ids, list) {
       
    91         list_del(&dev_id->list);
       
    92         kfree(dev_id);
       
    93     }
       
    94 }
       
    95 
       
    96 /*****************************************************************************/
       
    97 
       
    98 static int parse_device_id_mac(ec_device_id_t *dev_id,
       
    99         const char *src, const char **remainder)
       
   100 {
       
   101     unsigned int i, value;
       
   102     char *rem;
       
   103 
       
   104     for (i = 0; i < ETH_ALEN; i++) {
       
   105         value = simple_strtoul(src, &rem, 16);
       
   106         if (rem != src + 2
       
   107                 || value > 0xFF
       
   108                 || (i < ETH_ALEN - 1 && *rem != ':')) {
       
   109             return -1;
       
   110         }
       
   111         dev_id->octets[i] = value;
       
   112         if (i < ETH_ALEN - 1)
       
   113             src = rem + 1;
       
   114     }
       
   115 
       
   116     dev_id->type = ec_device_id_mac;
       
   117     *remainder = rem;
       
   118     return 0;
       
   119 }
       
   120 
       
   121 /*****************************************************************************/
       
   122 
       
   123 static int parse_device_ids(struct list_head *device_ids, const char *src)
       
   124 {
       
   125     const char *rem;
       
   126     ec_device_id_t *dev_id;
       
   127     unsigned int index = 0;
       
   128 
       
   129     while (*src) {
       
   130         // allocate new device ID
       
   131         if (!(dev_id = kmalloc(sizeof(ec_device_id_t), GFP_KERNEL))) {
       
   132             EC_ERR("Out of memory!\n");
       
   133             goto out_free;
       
   134         }
       
   135         
       
   136         if (*src == ';') { // empty device ID
       
   137             dev_id->type = ec_device_id_empty;
       
   138         }
       
   139         else if (*src == 'M') {
       
   140             src++;
       
   141             if (parse_device_id_mac(dev_id, src, &rem)) {
       
   142                 EC_ERR("Device ID %u: Invalid MAC syntax!\n", index);
       
   143                 kfree(dev_id);
       
   144                 goto out_free;
       
   145             }
       
   146             src = rem;
       
   147         }
       
   148         else {
       
   149             EC_ERR("Device ID %u: Unknown format \'%c\'!\n", index, *src);
       
   150             kfree(dev_id);
       
   151             goto out_free;
       
   152         }
       
   153         
       
   154         list_add_tail(&dev_id->list, device_ids); 
       
   155         if (*src) {
       
   156             if (*src != ';') {
       
   157                 EC_ERR("Invalid delimiter '%c' after device ID %i!\n",
       
   158                         *src, index);
       
   159                 goto out_free;
       
   160             }
       
   161             src++; // skip delimiter
       
   162         }
       
   163         index++;
       
   164     }
       
   165 
       
   166     return 0;
       
   167 
       
   168 out_free:
       
   169     clear_device_ids(device_ids);
       
   170     return -1;
       
   171 }
       
   172 
       
   173 /*****************************************************************************/
       
   174 
       
   175 static int create_device_ids(void)
       
   176 {
       
   177     ec_device_id_t *id;
       
   178     unsigned int main_count = 0, backup_count = 0;
       
   179     
       
   180     if (parse_device_ids(&main_device_ids, main))
       
   181         return -1;
       
   182 
       
   183     if (parse_device_ids(&backup_device_ids, main))
       
   184         return -1;
       
   185 
       
   186     // count main device IDs and check for empty ones
       
   187     list_for_each_entry(id, &main_device_ids, list) {
       
   188         if (id->type == ec_device_id_empty) {
       
   189             EC_ERR("Main device IDs may not be empty!\n");
       
   190             return -1;
       
   191         }
       
   192         main_count++;
       
   193     }
       
   194 
       
   195     // count backup device IDs
       
   196     list_for_each_entry(id, &backup_device_ids, list) {
       
   197         backup_count++;
       
   198     }
       
   199 
       
   200     // fill up backup device IDs
       
   201     while (backup_count < main_count) {
       
   202         if (!(id = kmalloc(sizeof(ec_device_id_t), GFP_KERNEL))) {
       
   203             EC_ERR("Out of memory!\n");
       
   204             return -1;
       
   205         }
       
   206         
       
   207         id->type = ec_device_id_empty;
       
   208         list_add_tail(&id->list, &backup_device_ids);
       
   209         backup_count++;
       
   210     }
       
   211 
       
   212     return 0;
       
   213 }
       
   214 
       
   215 /*****************************************************************************/
       
   216 
       
   217 static int device_id_check(const ec_device_id_t *dev_id,
       
   218         const struct net_device *dev, const char *driver_name,
       
   219         unsigned int device_index)
       
   220 {
       
   221     unsigned int i;
       
   222     
       
   223     switch (dev_id->type) {
       
   224         case ec_device_id_mac:
       
   225             for (i = 0; i < ETH_ALEN; i++)
       
   226                 if (dev->dev_addr[i] != dev_id->octets[i])
       
   227                     return 0;
       
   228             return 1;
       
   229         default:
       
   230             return 0;
       
   231     }
       
   232 }
       
   233                 
    77 
   234 
    78 /*****************************************************************************/
   235 /*****************************************************************************/
    79 
   236 
    80 /**
   237 /**
    81    Module initialization.
   238    Module initialization.
    83    \return 0 on success, else < 0
   240    \return 0 on success, else < 0
    84 */
   241 */
    85 
   242 
    86 int __init ec_init_module(void)
   243 int __init ec_init_module(void)
    87 {
   244 {
    88     unsigned int i;
       
    89     ec_master_t *master, *next;
   245     ec_master_t *master, *next;
       
   246     ec_device_id_t *main_dev_id, *backup_dev_id;
       
   247     unsigned int master_index = 0;
    90 
   248 
    91     EC_INFO("Master driver %s\n", EC_MASTER_VERSION);
   249     EC_INFO("Master driver %s\n", EC_MASTER_VERSION);
    92 
   250 
    93     if (ec_master_count < 1) {
   251     if (alloc_chrdev_region(&device_number, 0, 1, "EtherCAT")) {
    94         EC_ERR("Invalid ec_master_count: %i\n", ec_master_count);
   252         EC_ERR("Failed to obtain device number!\n");
    95         goto out_return;
   253         goto out_return;
    96     }
   254     }
    97 
   255 
    98     if (alloc_chrdev_region(&device_number, 0, ec_master_count, "EtherCAT")) {
   256     if (create_device_ids())
    99         EC_ERR("Failed to allocate device number!\n");
   257         goto out_free_ids;
   100         goto out_return;
   258     
   101     }
   259     if (!list_empty(&main_device_ids)) {
   102 
   260         main_dev_id =
   103     EC_INFO("Initializing %i EtherCAT master(s)...\n", ec_master_count);
   261             list_entry(main_device_ids.next, ec_device_id_t, list);
   104 
   262         backup_dev_id =
   105     INIT_LIST_HEAD(&ec_masters);
   263             list_entry(backup_device_ids.next, ec_device_id_t, list);
   106 
   264         
   107     for (i = 0; i < ec_master_count; i++) {
   265         while (1) {
   108         if (!(master =
   266             if (!(master = (ec_master_t *)
   109               (ec_master_t *) kmalloc(sizeof(ec_master_t), GFP_KERNEL))) {
   267                         kmalloc(sizeof(ec_master_t), GFP_KERNEL))) {
   110             EC_ERR("Failed to allocate memory for EtherCAT master %i.\n", i);
   268                 EC_ERR("Failed to allocate memory for EtherCAT master %i.\n",
   111             goto out_free;
   269                         master_index);
   112         }
   270                 goto out_free_masters;
   113 
   271             }
   114         if (ec_master_init(master, i, 0))
   272 
   115             goto out_free;
   273             if (ec_master_init(master, master_index,
   116 
   274                         main_dev_id, backup_dev_id, 0))
   117         list_add_tail(&master->list, &ec_masters);
   275                 goto out_free_masters;
   118     }
   276 
   119 
   277             list_add_tail(&master->list, &masters);
   120     EC_INFO("Master driver initialized.\n");
   278             master_index++;
       
   279 
       
   280             // last device IDs?
       
   281             if (main_dev_id->list.next == &main_device_ids)
       
   282                 break;
       
   283             
       
   284             // next device IDs
       
   285             main_dev_id =
       
   286                 list_entry(main_dev_id->list.next, ec_device_id_t, list);
       
   287             backup_dev_id =
       
   288                 list_entry(backup_dev_id->list.next, ec_device_id_t, list);
       
   289         }
       
   290     }
       
   291     
       
   292     EC_INFO("%u master%s waiting for devices.\n",
       
   293             master_index, (master_index == 1 ? "" : "s"));
   121     return 0;
   294     return 0;
   122 
   295 
   123  out_free:
   296 out_free_masters:
   124     list_for_each_entry_safe(master, next, &ec_masters, list) {
   297     list_for_each_entry_safe(master, next, &masters, list) {
   125         list_del(&master->list);
   298         list_del(&master->list);
   126         kobject_del(&master->kobj);
   299         kobject_del(&master->kobj);
   127         kobject_put(&master->kobj);
   300         kobject_put(&master->kobj);
   128     }
   301     }
   129  out_return:
   302 out_free_ids:
       
   303     clear_device_ids(&main_device_ids);
       
   304     clear_device_ids(&backup_device_ids);
       
   305     unregister_chrdev_region(device_number, 1);
       
   306 out_return:
   130     return -1;
   307     return -1;
   131 }
   308 }
   132 
   309 
   133 /*****************************************************************************/
   310 /*****************************************************************************/
   134 
   311 
   141 {
   318 {
   142     ec_master_t *master, *next;
   319     ec_master_t *master, *next;
   143 
   320 
   144     EC_INFO("Cleaning up master driver...\n");
   321     EC_INFO("Cleaning up master driver...\n");
   145 
   322 
   146     list_for_each_entry_safe(master, next, &ec_masters, list) {
   323     list_for_each_entry_safe(master, next, &masters, list) {
   147         list_del(&master->list);
   324         list_del(&master->list);
   148         ec_master_destroy(master);
   325         ec_master_destroy(master);
   149     }
   326     }
   150 
   327 
   151     unregister_chrdev_region(device_number, ec_master_count);
   328     unregister_chrdev_region(device_number, 1);
   152 
   329 
   153     EC_INFO("Master driver cleaned up.\n");
   330     EC_INFO("Master driver cleaned up.\n");
   154 }
   331 }
   155 
   332 
   156 /*****************************************************************************/
   333 /*****************************************************************************/
   162 
   339 
   163 ec_master_t *ec_find_master(unsigned int master_index /**< master index */)
   340 ec_master_t *ec_find_master(unsigned int master_index /**< master index */)
   164 {
   341 {
   165     ec_master_t *master;
   342     ec_master_t *master;
   166 
   343 
   167     list_for_each_entry(master, &ec_masters, list) {
   344     list_for_each_entry(master, &masters, list) {
   168         if (master->index == master_index) return master;
   345         if (master->index == master_index) return master;
   169     }
   346     }
   170 
   347 
   171     EC_ERR("Master %i does not exist!\n", master_index);
   348     EC_ERR("Master %i does not exist!\n", master_index);
   172     return NULL;
   349     return NULL;
   268 /******************************************************************************
   445 /******************************************************************************
   269  *  Device interface
   446  *  Device interface
   270  *****************************************************************************/
   447  *****************************************************************************/
   271 
   448 
   272 /**
   449 /**
   273    Connects an EtherCAT device to a certain master.
   450    Offers an EtherCAT device to a certain master.
   274    The master will use the device for sending and receiving frames. It is
   451    The master decides, if it wants to use the device for EtherCAT operation,
   275    required that no other instance (for example the kernel IP stack) uses
   452    or not. It is important, that the offered net_device is not used by
   276    the device.
   453    the kernel IP stack. If the master, accepted the offer, the address of
       
   454    the newly created EtherCAT device is written to the ecdev pointer, else
       
   455    the pointer is written to zero.
   277    \return 0 on success, else < 0
   456    \return 0 on success, else < 0
   278    \ingroup DeviceInterface
   457    \ingroup DeviceInterface
   279 */
   458 */
   280 
   459 
   281 ec_device_t *ecdev_register(unsigned int master_index, /**< master index */
   460 int ecdev_offer(struct net_device *net_dev, /**< net_device to offer */
   282                             struct net_device *net_dev, /**< net_device of
   461         ec_device_t **ecdev, /**< pointer to store a device on success */
   283                                                            the device */
   462         const char *driver_name, /**< name of the network driver */
   284                             ec_pollfunc_t poll, /**< device poll function */
   463         unsigned int device_index, /**< index of the supported device */
   285                             struct module *module /**< pointer to the module */
   464         ec_pollfunc_t poll, /**< device poll function */
   286                             )
   465         struct module *module /**< pointer to the module */
       
   466         )
   287 {
   467 {
   288     ec_master_t *master;
   468     ec_master_t *master;
   289 
   469     unsigned int i;
   290     if (!(master = ec_find_master(master_index))) return NULL;
   470 
   291 
   471     list_for_each_entry(master, &masters, list) {
   292     if (down_interruptible(&master->device_sem)) {
   472         if (down_interruptible(&master->device_sem)) {
   293         EC_ERR("Interrupted while waiting for device!\n");
   473             EC_ERR("Interrupted while waiting for device semaphore!\n");
   294         goto out_return;
   474             goto out_return;
   295     }
   475         }
   296 
   476 
   297     if (master->device) {
   477         if (device_id_check(master->main_device_id, net_dev,
   298         EC_ERR("Master %i already has a device!\n", master_index);
   478                     driver_name, device_index)) {
   299         goto out_up;
   479 
   300     }
   480             EC_INFO("Accepting device %s:%u (", driver_name, device_index);
   301 
   481             for (i = 0; i < ETH_ALEN; i++) {
   302     if (!(master->device =
   482                 printk("%02X", net_dev->dev_addr[i]);
   303           (ec_device_t *) kmalloc(sizeof(ec_device_t), GFP_KERNEL))) {
   483                 if (i < ETH_ALEN - 1) printk(":");
   304         EC_ERR("Failed to allocate device!\n");
   484             }
   305         goto out_up;
   485             printk(") for master %u.\n", master->index);
   306     }
   486 
   307 
   487             if (master->device) {
   308     if (ec_device_init(master->device, master, net_dev, poll, module)) {
   488                 EC_ERR("Master already has a device.\n");
   309         EC_ERR("Failed to init device!\n");
   489                 goto out_up;
   310         goto out_free;
   490             }
   311     }
   491             
   312 
   492             if (!(master->device = (ec_device_t *)
   313     up(&master->device_sem);
   493                         kmalloc(sizeof(ec_device_t), GFP_KERNEL))) {
   314     return master->device;
   494                 EC_ERR("Failed to allocate device!\n");
       
   495                 goto out_up;
       
   496             }
       
   497 
       
   498             if (ec_device_init(master->device, master,
       
   499                         net_dev, poll, module)) {
       
   500                 EC_ERR("Failed to init device!\n");
       
   501                 goto out_free;
       
   502             }
       
   503 
       
   504             up(&master->device_sem);
       
   505             sprintf(net_dev->name, "ec%u", master->index);
       
   506             *ecdev = master->device; // offer accepted
       
   507             return 0; // no error
       
   508         }
       
   509 
       
   510         up(&master->device_sem);
       
   511     }
       
   512 
       
   513     *ecdev = NULL; // offer declined
       
   514     return 0; // no error
   315 
   515 
   316  out_free:
   516  out_free:
   317     kfree(master->device);
   517     kfree(master->device);
   318     master->device = NULL;
   518     master->device = NULL;
   319  out_up:
   519  out_up:
   320     up(&master->device_sem);
   520     up(&master->device_sem);
   321  out_return:
   521  out_return:
   322     return NULL;
   522     return 1;
   323 }
   523 }
   324 
   524 
   325 /*****************************************************************************/
   525 /*****************************************************************************/
   326 
   526 
   327 /**
   527 /**
   328    Disconnect an EtherCAT device from the master.
   528    Withdraws an EtherCAT device from the master.
   329    The device is disconnected from the master and all device ressources
   529    The device is disconnected from the master and all device ressources
   330    are freed.
   530    are freed.
   331    \attention Before calling this function, the ecdev_stop() function has
   531    \attention Before calling this function, the ecdev_stop() function has
   332    to be called, to be sure that the master does not use the device any more.
   532    to be called, to be sure that the master does not use the device any more.
   333    \ingroup DeviceInterface
   533    \ingroup DeviceInterface
   334 */
   534 */
   335 
   535 
   336 void ecdev_unregister(unsigned int master_index, /**< master index */
   536 void ecdev_withdraw(ec_device_t *device /**< EtherCAT device */)
   337                       ec_device_t *device /**< EtherCAT device */
   537 {
   338                       )
   538     ec_master_t *master = device->master;
   339 {
   539     unsigned int i;
   340     ec_master_t *master;
       
   341 
       
   342     if (!(master = ec_find_master(master_index))) return;
       
   343 
   540 
   344     down(&master->device_sem);
   541     down(&master->device_sem);
   345 
   542     
   346     if (!master->device || master->device != device) {
   543     EC_INFO("Master %u releasing device ", master->index);
   347         up(&master->device_sem);
   544     for (i = 0; i < ETH_ALEN; i++) {
   348         EC_WARN("Unable to unregister device!\n");
   545         printk("%02X", device->dev->dev_addr[i]);
   349         return;
   546         if (i < ETH_ALEN - 1) printk(":");
   350     }
   547     }
   351 
   548     printk(".\n");
       
   549     
   352     ec_device_clear(master->device);
   550     ec_device_clear(master->device);
   353     kfree(master->device);
   551     kfree(master->device);
   354     master->device = NULL;
   552     master->device = NULL;
   355 
   553     
   356     up(&master->device_sem);
   554     up(&master->device_sem);
   357 }
   555 }
   358 
   556 
   359 /*****************************************************************************/
   557 /*****************************************************************************/
   360 
   558 
   503 /** \cond */
   701 /** \cond */
   504 
   702 
   505 module_init(ec_init_module);
   703 module_init(ec_init_module);
   506 module_exit(ec_cleanup_module);
   704 module_exit(ec_cleanup_module);
   507 
   705 
   508 EXPORT_SYMBOL(ecdev_register);
   706 EXPORT_SYMBOL(ecdev_offer);
   509 EXPORT_SYMBOL(ecdev_unregister);
   707 EXPORT_SYMBOL(ecdev_withdraw);
   510 EXPORT_SYMBOL(ecdev_open);
   708 EXPORT_SYMBOL(ecdev_open);
   511 EXPORT_SYMBOL(ecdev_close);
   709 EXPORT_SYMBOL(ecdev_close);
   512 EXPORT_SYMBOL(ecrt_request_master);
   710 EXPORT_SYMBOL(ecrt_request_master);
   513 EXPORT_SYMBOL(ecrt_release_master);
   711 EXPORT_SYMBOL(ecrt_release_master);
   514 EXPORT_SYMBOL(ecrt_version_magic);
   712 EXPORT_SYMBOL(ecrt_version_magic);