module.c

Go to the documentation of this file.
00001 /******************************************************************************
00002  *
00003  *  $Id: module.c 490 2006-08-02 12:25:25Z fp $
00004  *
00005  *  Copyright (C) 2006  Florian Pose, Ingenieurgemeinschaft IgH
00006  *
00007  *  This file is part of the IgH EtherCAT Master.
00008  *
00009  *  The IgH EtherCAT Master is free software; you can redistribute it
00010  *  and/or modify it under the terms of the GNU General Public License
00011  *  as published by the Free Software Foundation; either version 2 of the
00012  *  License, or (at your option) any later version.
00013  *
00014  *  The IgH EtherCAT Master is distributed in the hope that it will be
00015  *  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  *  GNU General Public License for more details.
00018  *
00019  *  You should have received a copy of the GNU General Public License
00020  *  along with the IgH EtherCAT Master; if not, write to the Free Software
00021  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00022  *
00023  *  The right to use EtherCAT Technology is granted and comes free of
00024  *  charge under condition of compatibility of product made by
00025  *  Licensee. People intending to distribute/sell products based on the
00026  *  code, have to sign an agreement to guarantee that products using
00027  *  software based on IgH EtherCAT master stay compatible with the actual
00028  *  EtherCAT specification (which are released themselves as an open
00029  *  standard) as the (only) precondition to have the right to use EtherCAT
00030  *  Technology, IP and trade marks.
00031  *
00032  *****************************************************************************/
00033 
00039 /*****************************************************************************/
00040 
00041 #include <linux/module.h>
00042 #include <linux/kernel.h>
00043 #include <linux/init.h>
00044 
00045 #include "globals.h"
00046 #include "master.h"
00047 #include "device.h"
00048 
00049 /*****************************************************************************/
00050 
00051 int __init ec_init_module(void);
00052 void __exit ec_cleanup_module(void);
00053 
00054 /*****************************************************************************/
00055 
00060 #define COMPILE_INFO EC_STR(EC_MASTER_VERSION_MAIN) \
00061                      "." EC_STR(EC_MASTER_VERSION_SUB) \
00062                      " (" EC_MASTER_VERSION_EXTRA ")" \
00063                      " - rev. " EC_STR(SVNREV) \
00064                      ", compiled by " EC_STR(USER) \
00065                      " at " __DATE__ " " __TIME__
00066 
00067 /*****************************************************************************/
00068 
00069 static int ec_master_count = 1; 
00070 static int ec_eoeif_count = 0; 
00071 static struct list_head ec_masters; 
00073 /*****************************************************************************/
00074 
00077 module_param(ec_master_count, int, S_IRUGO);
00078 module_param(ec_eoeif_count, int, S_IRUGO);
00079 
00080 MODULE_AUTHOR("Florian Pose <fp@igh-essen.com>");
00081 MODULE_DESCRIPTION("EtherCAT master driver module");
00082 MODULE_LICENSE("GPL");
00083 MODULE_VERSION(COMPILE_INFO);
00084 MODULE_PARM_DESC(ec_master_count, "number of EtherCAT masters to initialize");
00085 MODULE_PARM_DESC(ec_eoeif_count, "number of EoE interfaces per master");
00086 
00089 /*****************************************************************************/
00090 
00097 int __init ec_init_module(void)
00098 {
00099     unsigned int i;
00100     ec_master_t *master, *next;
00101 
00102     EC_INFO("Master driver, %s\n", COMPILE_INFO);
00103 
00104     if (ec_master_count < 1) {
00105         EC_ERR("Error - Invalid ec_master_count: %i\n", ec_master_count);
00106         goto out_return;
00107     }
00108 
00109     EC_INFO("Initializing %i EtherCAT master(s)...\n", ec_master_count);
00110 
00111     INIT_LIST_HEAD(&ec_masters);
00112 
00113     for (i = 0; i < ec_master_count; i++) {
00114         if (!(master =
00115               (ec_master_t *) kmalloc(sizeof(ec_master_t), GFP_KERNEL))) {
00116             EC_ERR("Failed to allocate memory for EtherCAT master %i.\n", i);
00117             goto out_free;
00118         }
00119 
00120         if (ec_master_init(master, i, ec_eoeif_count))
00121             goto out_free;
00122 
00123         if (kobject_add(&master->kobj)) {
00124             EC_ERR("Failed to add kobj.\n");
00125             kobject_put(&master->kobj); // free master
00126             goto out_free;
00127         }
00128 
00129         list_add_tail(&master->list, &ec_masters);
00130     }
00131 
00132     EC_INFO("Master driver initialized.\n");
00133     return 0;
00134 
00135  out_free:
00136     list_for_each_entry_safe(master, next, &ec_masters, list) {
00137         list_del(&master->list);
00138         kobject_del(&master->kobj);
00139         kobject_put(&master->kobj);
00140     }
00141  out_return:
00142     return -1;
00143 }
00144 
00145 /*****************************************************************************/
00146 
00152 void __exit ec_cleanup_module(void)
00153 {
00154     ec_master_t *master, *next;
00155 
00156     EC_INFO("Cleaning up master driver...\n");
00157 
00158     list_for_each_entry_safe(master, next, &ec_masters, list) {
00159         list_del(&master->list);
00160         kobject_del(&master->kobj);
00161         kobject_put(&master->kobj); // free master
00162     }
00163 
00164     EC_INFO("Master driver cleaned up.\n");
00165 }
00166 
00167 /*****************************************************************************/
00168 
00174 ec_master_t *ec_find_master(unsigned int master_index )
00175 {
00176     ec_master_t *master;
00177 
00178     list_for_each_entry(master, &ec_masters, list) {
00179         if (master->index == master_index) return master;
00180     }
00181 
00182     EC_ERR("Master %i does not exist!\n", master_index);
00183     return NULL;
00184 }
00185 
00186 /*****************************************************************************/
00187 
00192 void ec_print_data(const uint8_t *data, 
00193                    size_t size 
00194                    )
00195 {
00196     unsigned int i;
00197 
00198     EC_DBG("");
00199     for (i = 0; i < size; i++) {
00200         printk("%02X ", data[i]);
00201         if ((i + 1) % 16 == 0) {
00202             printk("\n");
00203             EC_DBG("");
00204         }
00205     }
00206     printk("\n");
00207 }
00208 
00209 /*****************************************************************************/
00210 
00215 void ec_print_data_diff(const uint8_t *d1, 
00216                         const uint8_t *d2, 
00217                         size_t size 
00218                         )
00219 {
00220     unsigned int i;
00221 
00222     EC_DBG("");
00223     for (i = 0; i < size; i++) {
00224         if (d1[i] == d2[i]) printk(".. ");
00225         else printk("%02X ", d2[i]);
00226         if ((i + 1) % 16 == 0) {
00227             printk("\n");
00228             EC_DBG("");
00229         }
00230     }
00231     printk("\n");
00232 }
00233 
00234 /*****************************************************************************/
00235 
00240 void ec_print_states(const uint8_t states )
00241 {
00242     unsigned int first = 1;
00243 
00244     if (!states) {
00245         printk("(unknown)");
00246         return;
00247     }
00248 
00249     if (states & EC_SLAVE_STATE_INIT) {
00250         printk("INIT");
00251         first = 0;
00252     }
00253     if (states & EC_SLAVE_STATE_PREOP) {
00254         if (!first) printk(", ");
00255         printk("PREOP");
00256         first = 0;
00257     }
00258     if (states & EC_SLAVE_STATE_SAVEOP) {
00259         if (!first) printk(", ");
00260         printk("SAVEOP");
00261         first = 0;
00262     }
00263     if (states & EC_SLAVE_STATE_OP) {
00264         if (!first) printk(", ");
00265         printk("OP");
00266     }
00267 }
00268 
00269 /******************************************************************************
00270  *  Device interface
00271  *****************************************************************************/
00272 
00282 ec_device_t *ecdev_register(unsigned int master_index, 
00283                             struct net_device *net_dev, 
00285                             ec_isr_t isr, 
00286                             struct module *module 
00287                             )
00288 {
00289     ec_master_t *master;
00290 
00291     if (!(master = ec_find_master(master_index))) return NULL;
00292 
00293     if (master->device) {
00294         EC_ERR("Master %i already has a device!\n", master_index);
00295         goto out_return;
00296     }
00297 
00298     if (!(master->device =
00299           (ec_device_t *) kmalloc(sizeof(ec_device_t), GFP_KERNEL))) {
00300         EC_ERR("Failed to allocate device!\n");
00301         goto out_return;
00302     }
00303 
00304     if (ec_device_init(master->device, master, net_dev, isr, module)) {
00305         EC_ERR("Failed to init device!\n");
00306         goto out_free;
00307     }
00308 
00309     return master->device;
00310 
00311  out_free:
00312     kfree(master->device);
00313     master->device = NULL;
00314  out_return:
00315     return NULL;
00316 }
00317 
00318 /*****************************************************************************/
00319 
00329 void ecdev_unregister(unsigned int master_index, 
00330                       ec_device_t *device 
00331                       )
00332 {
00333     ec_master_t *master;
00334 
00335     if (!(master = ec_find_master(master_index))) return;
00336 
00337     if (!master->device || master->device != device) {
00338         EC_WARN("Unable to unregister device!\n");
00339         return;
00340     }
00341 
00342     ec_device_clear(master->device);
00343     kfree(master->device);
00344     master->device = NULL;
00345 }
00346 
00347 /*****************************************************************************/
00348 
00357 int ecdev_start(unsigned int master_index )
00358 {
00359     ec_master_t *master;
00360     if (!(master = ec_find_master(master_index))) return -1;
00361 
00362     if (ec_device_open(master->device)) {
00363         EC_ERR("Failed to open device!\n");
00364         return -1;
00365     }
00366 
00367     ec_master_idle_start(master);
00368     return 0;
00369 }
00370 
00371 /*****************************************************************************/
00372 
00380 void ecdev_stop(unsigned int master_index )
00381 {
00382     ec_master_t *master;
00383     if (!(master = ec_find_master(master_index))) return;
00384 
00385     ec_master_idle_stop(master);
00386 
00387     if (ec_device_close(master->device))
00388         EC_WARN("Failed to close device!\n");
00389 }
00390 
00391 /******************************************************************************
00392  *  Realtime interface
00393  *****************************************************************************/
00394 
00401 ec_master_t *ecrt_request_master(unsigned int master_index
00403                                  )
00404 {
00405     ec_master_t *master;
00406 
00407     EC_INFO("Requesting master %i...\n", master_index);
00408 
00409     if (!(master = ec_find_master(master_index))) goto out_return;
00410 
00411     if (master->reserved) {
00412         EC_ERR("Master %i is already in use!\n", master_index);
00413         goto out_return;
00414     }
00415     master->reserved = 1;
00416 
00417     if (!master->device) {
00418         EC_ERR("Master %i has no assigned device!\n", master_index);
00419         goto out_release;
00420     }
00421 
00422     if (!try_module_get(master->device->module)) {
00423         EC_ERR("Failed to reserve device module!\n");
00424         goto out_release;
00425     }
00426 
00427     ec_master_idle_stop(master);
00428     ec_master_reset(master);
00429     master->mode = EC_MASTER_MODE_RUNNING;
00430 
00431     if (!master->device->link_state) EC_WARN("Link is DOWN.\n");
00432 
00433     if (ec_master_bus_scan(master)) {
00434         EC_ERR("Bus scan failed!\n");
00435         goto out_module_put;
00436     }
00437 
00438     EC_INFO("Master %i is ready.\n", master_index);
00439     return master;
00440 
00441  out_module_put:
00442     module_put(master->device->module);
00443     ec_master_reset(master);
00444     ec_master_idle_start(master);
00445  out_release:
00446     master->reserved = 0;
00447  out_return:
00448     EC_ERR("Failed requesting master %i.\n", master_index);
00449     return NULL;
00450 }
00451 
00452 /*****************************************************************************/
00453 
00459 void ecrt_release_master(ec_master_t *master )
00460 {
00461     EC_INFO("Releasing master %i...\n", master->index);
00462 
00463     if (!master->reserved) {
00464         EC_ERR("Master %i was never requested!\n", master->index);
00465         return;
00466     }
00467 
00468     ec_master_reset(master);
00469     ec_master_idle_start(master);
00470 
00471     module_put(master->device->module);
00472     master->reserved = 0;
00473 
00474     EC_INFO("Released master %i.\n", master->index);
00475     return;
00476 }
00477 
00478 /*****************************************************************************/
00479 
00482 module_init(ec_init_module);
00483 module_exit(ec_cleanup_module);
00484 
00485 EXPORT_SYMBOL(ecdev_register);
00486 EXPORT_SYMBOL(ecdev_unregister);
00487 EXPORT_SYMBOL(ecdev_start);
00488 EXPORT_SYMBOL(ecdev_stop);
00489 EXPORT_SYMBOL(ecrt_request_master);
00490 EXPORT_SYMBOL(ecrt_release_master);
00491 
00494 /*****************************************************************************/

Generated on Wed Aug 2 18:41:43 2006 for IgH EtherCAT master by  doxygen 1.4.6