Main Page | Modules | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

module.c

Go to the documentation of this file.
00001 /******************************************************************************
00002  *
00003  *  $Id: module.c 682 2006-11-07 12:13:30Z 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 
00056 static int ec_master_count = 1; 
00057 static int ec_eoeif_count = 0; 
00058 static struct list_head ec_masters; 
00060 char *ec_master_version_str = EC_MASTER_VERSION;
00061 
00062 /*****************************************************************************/
00063 
00066 module_param(ec_master_count, int, S_IRUGO);
00067 module_param(ec_eoeif_count, int, S_IRUGO);
00068 
00069 MODULE_AUTHOR("Florian Pose <fp@igh-essen.com>");
00070 MODULE_DESCRIPTION("EtherCAT master driver module");
00071 MODULE_LICENSE("GPL");
00072 MODULE_VERSION(EC_MASTER_VERSION);
00073 MODULE_PARM_DESC(ec_master_count, "number of EtherCAT masters to initialize");
00074 MODULE_PARM_DESC(ec_eoeif_count, "number of EoE interfaces per master");
00075 
00078 /*****************************************************************************/
00079 
00086 int __init ec_init_module(void)
00087 {
00088     unsigned int i;
00089     ec_master_t *master, *next;
00090 
00091     EC_INFO("Master driver %s\n", EC_MASTER_VERSION);
00092 
00093     if (ec_master_count < 1) {
00094         EC_ERR("Error - Invalid ec_master_count: %i\n", ec_master_count);
00095         goto out_return;
00096     }
00097 
00098     EC_INFO("Initializing %i EtherCAT master(s)...\n", ec_master_count);
00099 
00100     INIT_LIST_HEAD(&ec_masters);
00101 
00102     for (i = 0; i < ec_master_count; i++) {
00103         if (!(master =
00104               (ec_master_t *) kmalloc(sizeof(ec_master_t), GFP_KERNEL))) {
00105             EC_ERR("Failed to allocate memory for EtherCAT master %i.\n", i);
00106             goto out_free;
00107         }
00108 
00109         if (ec_master_init(master, i, ec_eoeif_count))
00110             goto out_free;
00111 
00112         list_add_tail(&master->list, &ec_masters);
00113     }
00114 
00115     EC_INFO("Master driver initialized.\n");
00116     return 0;
00117 
00118  out_free:
00119     list_for_each_entry_safe(master, next, &ec_masters, list) {
00120         list_del(&master->list);
00121         kobject_del(&master->kobj);
00122         kobject_put(&master->kobj);
00123     }
00124  out_return:
00125     return -1;
00126 }
00127 
00128 /*****************************************************************************/
00129 
00135 void __exit ec_cleanup_module(void)
00136 {
00137     ec_master_t *master, *next;
00138 
00139     EC_INFO("Cleaning up master driver...\n");
00140 
00141     list_for_each_entry_safe(master, next, &ec_masters, list) {
00142         list_del(&master->list);
00143         ec_master_destroy(master);
00144     }
00145 
00146     EC_INFO("Master driver cleaned up.\n");
00147 }
00148 
00149 /*****************************************************************************/
00150 
00156 ec_master_t *ec_find_master(unsigned int master_index )
00157 {
00158     ec_master_t *master;
00159 
00160     list_for_each_entry(master, &ec_masters, list) {
00161         if (master->index == master_index) return master;
00162     }
00163 
00164     EC_ERR("Master %i does not exist!\n", master_index);
00165     return NULL;
00166 }
00167 
00168 /*****************************************************************************/
00169 
00174 void ec_print_data(const uint8_t *data, 
00175                    size_t size 
00176                    )
00177 {
00178     unsigned int i;
00179 
00180     EC_DBG("");
00181     for (i = 0; i < size; i++) {
00182         printk("%02X ", data[i]);
00183         if ((i + 1) % 16 == 0) {
00184             printk("\n");
00185             EC_DBG("");
00186         }
00187     }
00188     printk("\n");
00189 }
00190 
00191 /*****************************************************************************/
00192 
00197 void ec_print_data_diff(const uint8_t *d1, 
00198                         const uint8_t *d2, 
00199                         size_t size 
00200                         )
00201 {
00202     unsigned int i;
00203 
00204     EC_DBG("");
00205     for (i = 0; i < size; i++) {
00206         if (d1[i] == d2[i]) printk(".. ");
00207         else printk("%02X ", d2[i]);
00208         if ((i + 1) % 16 == 0) {
00209             printk("\n");
00210             EC_DBG("");
00211         }
00212     }
00213     printk("\n");
00214 }
00215 
00216 /*****************************************************************************/
00217 
00222 size_t ec_state_string(uint8_t states, 
00223                        char *buffer 
00225                        )
00226 {
00227     off_t off = 0;
00228     unsigned int first = 1;
00229 
00230     if (!states) {
00231         off += sprintf(buffer + off, "(unknown)");
00232         return off;
00233     }
00234 
00235     if (states & EC_SLAVE_STATE_INIT) {
00236         off += sprintf(buffer + off, "INIT");
00237         first = 0;
00238     }
00239     if (states & EC_SLAVE_STATE_PREOP) {
00240         if (!first) off += sprintf(buffer + off, ", ");
00241         off += sprintf(buffer + off, "PREOP");
00242         first = 0;
00243     }
00244     if (states & EC_SLAVE_STATE_SAVEOP) {
00245         if (!first) off += sprintf(buffer + off, ", ");
00246         off += sprintf(buffer + off, "SAVEOP");
00247         first = 0;
00248     }
00249     if (states & EC_SLAVE_STATE_OP) {
00250         if (!first) off += sprintf(buffer + off, ", ");
00251         off += sprintf(buffer + off, "OP");
00252     }
00253     if (states & EC_SLAVE_STATE_ACK_ERR) {
00254         if (!first) off += sprintf(buffer + off, " + ");
00255         off += sprintf(buffer + off, "ERROR");
00256     }
00257 
00258     return off;
00259 }
00260 
00261 /******************************************************************************
00262  *  Device interface
00263  *****************************************************************************/
00264 
00274 ec_device_t *ecdev_register(unsigned int master_index, 
00275                             struct net_device *net_dev, 
00277                             ec_isr_t isr, 
00278                             struct module *module 
00279                             )
00280 {
00281     ec_master_t *master;
00282 
00283     if (!(master = ec_find_master(master_index))) return NULL;
00284 
00285     if (down_interruptible(&master->device_sem)) {
00286         EC_ERR("Interrupted while waiting for device!\n");
00287         goto out_return;
00288     }
00289 
00290     if (master->device) {
00291         EC_ERR("Master %i already has a device!\n", master_index);
00292         goto out_up;
00293     }
00294 
00295     if (!(master->device =
00296           (ec_device_t *) kmalloc(sizeof(ec_device_t), GFP_KERNEL))) {
00297         EC_ERR("Failed to allocate device!\n");
00298         goto out_up;
00299     }
00300 
00301     if (ec_device_init(master->device, master, net_dev, isr, module)) {
00302         EC_ERR("Failed to init device!\n");
00303         goto out_free;
00304     }
00305 
00306     up(&master->device_sem);
00307     return master->device;
00308 
00309  out_free:
00310     kfree(master->device);
00311     master->device = NULL;
00312  out_up:
00313     up(&master->device_sem);
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     down(&master->device_sem);
00338 
00339     if (!master->device || master->device != device) {
00340         up(&master->device_sem);
00341         EC_WARN("Unable to unregister device!\n");
00342         return;
00343     }
00344 
00345     ec_device_clear(master->device);
00346     kfree(master->device);
00347     master->device = NULL;
00348 
00349     up(&master->device_sem);
00350 }
00351 
00352 /*****************************************************************************/
00353 
00362 int ecdev_start(unsigned int master_index )
00363 {
00364     ec_master_t *master;
00365     if (!(master = ec_find_master(master_index))) return -1;
00366 
00367     if (ec_device_open(master->device)) {
00368         EC_ERR("Failed to open device!\n");
00369         return -1;
00370     }
00371 
00372     ec_master_enter_idle_mode(master);
00373 
00374     return 0;
00375 }
00376 
00377 /*****************************************************************************/
00378 
00386 void ecdev_stop(unsigned int master_index )
00387 {
00388     ec_master_t *master;
00389     if (!(master = ec_find_master(master_index))) return;
00390 
00391     ec_master_leave_idle_mode(master);
00392 
00393     if (ec_device_close(master->device))
00394         EC_WARN("Failed to close device!\n");
00395 }
00396 
00397 /******************************************************************************
00398  *  Realtime interface
00399  *****************************************************************************/
00400 
00407 ec_master_t *ecrt_request_master(unsigned int master_index
00409                                  )
00410 {
00411     ec_master_t *master;
00412 
00413     EC_INFO("Requesting master %i...\n", master_index);
00414 
00415     if (!(master = ec_find_master(master_index))) goto out_return;
00416 
00417     if (!atomic_dec_and_test(&master->available)) {
00418         atomic_inc(&master->available);
00419         EC_ERR("Master %i is already in use!\n", master_index);
00420         goto out_return;
00421     }
00422 
00423     if (down_interruptible(&master->device_sem)) {
00424         EC_ERR("Interrupted while waiting for device!\n");
00425         goto out_release;
00426     }
00427 
00428     if (!master->device) {
00429         up(&master->device_sem);
00430         EC_ERR("Master %i has no assigned device!\n", master_index);
00431         goto out_release;
00432     }
00433 
00434     if (!try_module_get(master->device->module)) {
00435         up(&master->device_sem);
00436         EC_ERR("Device module is unloading!\n");
00437         goto out_release;
00438     }
00439 
00440     up(&master->device_sem);
00441 
00442     if (!master->device->link_state) {
00443         EC_ERR("Link is DOWN.\n");
00444         goto out_module_put;
00445     }
00446 
00447     if (ec_master_enter_operation_mode(master)) {
00448         EC_ERR("Failed to enter OPERATION mode!\n");
00449         goto out_module_put;
00450     }
00451 
00452     EC_INFO("Successfully requested master %i.\n", master_index);
00453     return master;
00454 
00455  out_module_put:
00456     module_put(master->device->module);
00457  out_release:
00458     atomic_inc(&master->available);
00459  out_return:
00460     return NULL;
00461 }
00462 
00463 /*****************************************************************************/
00464 
00470 void ecrt_release_master(ec_master_t *master )
00471 {
00472     ec_master_leave_operation_mode(master);
00473 
00474     module_put(master->device->module);
00475     atomic_inc(&master->available);
00476 
00477     EC_INFO("Released master %i.\n", master->index);
00478     return;
00479 }
00480 
00481 /*****************************************************************************/
00482 
00485 module_init(ec_init_module);
00486 module_exit(ec_cleanup_module);
00487 
00488 EXPORT_SYMBOL(ecdev_register);
00489 EXPORT_SYMBOL(ecdev_unregister);
00490 EXPORT_SYMBOL(ecdev_start);
00491 EXPORT_SYMBOL(ecdev_stop);
00492 EXPORT_SYMBOL(ecrt_request_master);
00493 EXPORT_SYMBOL(ecrt_release_master);
00494 
00497 /*****************************************************************************/

Generated on Tue Nov 7 15:03:36 2006 for IgH EtherCAT master by  doxygen 1.4.4