diff -r 7d9809fbf7b9 -r f4171b8aadf8 drivers/ec_module.c --- a/drivers/ec_module.c Fri Dec 16 09:44:54 2005 +0000 +++ b/drivers/ec_module.c Fri Dec 16 12:04:59 2005 +0000 @@ -30,6 +30,7 @@ int ecat_master_count = 1; EtherCAT_master_t *ecat_masters = NULL; +int *ecat_masters_reserved = NULL; /******************************************************************************/ @@ -44,7 +45,10 @@ module_init(ecat_init_module); module_exit(ecat_cleanup_module); -EXPORT_SYMBOL(EtherCAT_master); +EXPORT_SYMBOL(EtherCAT_register_device); +EXPORT_SYMBOL(EtherCAT_unregister_device); +EXPORT_SYMBOL(EtherCAT_request); +EXPORT_SYMBOL(EtherCAT_release); /******************************************************************************/ @@ -82,9 +86,18 @@ return -1; } + if ((ecat_masters_reserved = (int *) kmalloc(sizeof(int) * ecat_master_count, + GFP_KERNEL)) == NULL) + { + printk(KERN_ERR "EtherCAT: Could not allocate memory for reservation flags!\n"); + kfree(ecat_masters); + return -1; + } + for (i = 0; i < ecat_master_count; i++) { EtherCAT_master_init(&ecat_masters[i]); + ecat_masters_reserved[i] = 0; } printk(KERN_ERR "EtherCAT: Master driver initialized.\n"); @@ -110,6 +123,10 @@ { for (i = 0; i < ecat_master_count; i++) { + if (ecat_masters_reserved[i]) { + printk(KERN_WARNING "EtherCAT: Warning - Master %i is still in use!\n", i); + } + EtherCAT_master_clear(&ecat_masters[i]); } @@ -119,24 +136,129 @@ printk(KERN_ERR "EtherCAT: Master driver cleaned up.\n"); } -/******************************************************************************/ - -/** - Gibt einen Zeiger auf einen bestimmten EtherCAT-Master zurueck. +/***************************************************************/ + +/** + Setzt das EtherCAT-Geraet, auf dem der Master arbeitet. + + Registriert das Geraet beim Master, der es daraufhin oeffnet. + + @param master Der EtherCAT-Master + @param device Das EtherCAT-Geraet + @return 0, wenn alles o.k., + < 0, wenn bereits ein Geraet registriert + oder das Geraet nicht geoeffnet werden konnte. +*/ + +int EtherCAT_register_device(int index, EtherCAT_device_t *device) +{ + if (index < 0 || index >= ecat_master_count) + { + printk(KERN_ERR "EtherCAT: Master %i does not exist!\n", index); + return -1; + } + + return EtherCAT_master_open(&ecat_masters[index], device); +} + +/***************************************************************/ + +/** + Loescht das EtherCAT-Geraet, auf dem der Master arbeitet. + + @param master Der EtherCAT-Master + @param device Das EtherCAT-Geraet +*/ + +void EtherCAT_unregister_device(int index, EtherCAT_device_t *device) +{ + if (index < 0 || index >= ecat_master_count) + { + printk(KERN_WARNING "EtherCAT: Master %i does not exist!\n", index); + return; + } + + EtherCAT_master_close(&ecat_masters[index], device); +} + +/******************************************************************************/ + +/** + Reserviert einen bestimmten EtherCAT-Master und das zugehörige Gerät. + + Gibt einen Zeiger auf den reservierten EtherCAT-Master zurueck. @param index Index des gewuenschten Masters @returns Zeiger auf EtherCAT-Master oder NULL, wenn Parameter ungueltig. */ -EtherCAT_master_t *EtherCAT_master(int index) -{ - if (index < 0 || index >= ecat_master_count) - { +EtherCAT_master_t *EtherCAT_request(int index) +{ + if (index < 0 || index >= ecat_master_count) { printk(KERN_ERR "EtherCAT: Master %i does not exist!\n", index); return NULL; } + if (ecat_masters_reserved[index]) { + printk(KERN_ERR "EtherCAT: Master %i already in use!\n", index); + return NULL; + } + + if (!ecat_masters[index].dev) { + printk(KERN_ERR "EtherCAT: Master %i has no device assigned yet!\n", index); + return NULL; + } + + if (!ecat_masters[index].dev->module) { + printk(KERN_ERR "EtherCAT: Master %i device module is not set!\n", index); + return NULL; + } + + if (!try_module_get(ecat_masters[index].dev->module)) { + printk(KERN_ERR "EtherCAT: Could not reserve device module!\n"); + return NULL; + } + + ecat_masters_reserved[index] = 1; + + printk(KERN_INFO "EtherCAT: Reserved master %i.\n", index); + return &ecat_masters[index]; } /******************************************************************************/ + +/** + Gibt einen zuvor reservierten EtherCAT-Master wieder frei. + + @param master Zeiger auf den freizugebenden EtherCAT-Master. +*/ + +void EtherCAT_release(EtherCAT_master_t *master) +{ + unsigned int i; + + for (i = 0; i < ecat_master_count; i++) + { + if (&ecat_masters[i] == master) + { + if (!ecat_masters[i].dev) { + printk(KERN_WARNING "EtherCAT: Could not release device" + "module because of no device!\n"); + return; + } + + module_put(ecat_masters[i].dev->module); + ecat_masters_reserved[i] = 0; + + printk(KERN_INFO "EtherCAT: Released master %i.\n", i); + + return; + } + } + + printk(KERN_WARNING "EtherCAT: Master %X was never reserved!\n", + (unsigned int) master); +} + +/******************************************************************************/