# HG changeset patch # User Florian Pose # Date 1134734699 0 # Node ID f4171b8aadf82839b40542bd5ccc2cf04a198962 # Parent 7d9809fbf7b986afdee0544cebd11b8681f3c88b Master-Reservierung und Use-Count f?r NIC-Treiber. diff -r 7d9809fbf7b9 -r f4171b8aadf8 drivers/8139too.c --- a/drivers/8139too.c Fri Dec 16 09:44:54 2005 +0000 +++ b/drivers/8139too.c Fri Dec 16 12:04:59 2005 +0000 @@ -202,7 +202,7 @@ static int ec_device_master_index = 0; static EtherCAT_device_t rtl_ecat_dev; -static EtherCAT_master_t *rtl_ecat_master = NULL; +int rtl_ecat_dev_registered = 0; /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ @@ -2966,6 +2966,7 @@ EtherCAT_device_init(&rtl_ecat_dev); rtl_ecat_dev.isr = rtl8139_interrupt; + rtl_ecat_dev.module = THIS_MODULE; if (pci_module_init(&rtl8139_pci_driver) < 0) { @@ -2977,20 +2978,15 @@ if (rtl_ecat_dev.dev) { - if ((rtl_ecat_master = EtherCAT_master(ec_device_master_index)) == NULL) - { - printk(KERN_ERR "Could not get EtherCAT master %i.\n", - ec_device_master_index); - goto out_module; - } - printk(KERN_INFO "Registering EtherCAT device...\n"); - if (EtherCAT_register_device(rtl_ecat_master, &rtl_ecat_dev) < 0) + if (EtherCAT_register_device(ec_device_master_index, &rtl_ecat_dev) < 0) { printk(KERN_ERR "Could not register device.\n"); goto out_module; } + rtl_ecat_dev_registered = 1; + printk(KERN_INFO "EtherCAT device registered and opened.\n"); } else @@ -3015,10 +3011,10 @@ printk(KERN_INFO "Cleaning up RTL8139-EtherCAT module...\n"); - if (rtl_ecat_master && rtl_ecat_dev.dev) + if (rtl_ecat_dev_registered && rtl_ecat_dev.dev) { printk(KERN_INFO "Unregistering RTL8139-EtherCAT device...\n"); - EtherCAT_unregister_device(rtl_ecat_master, &rtl_ecat_dev); + EtherCAT_unregister_device(ec_device_master_index, &rtl_ecat_dev); } pci_unregister_driver(&rtl8139_pci_driver); diff -r 7d9809fbf7b9 -r f4171b8aadf8 drivers/ec_device.c --- a/drivers/ec_device.c Fri Dec 16 09:44:54 2005 +0000 +++ b/drivers/ec_device.c Fri Dec 16 12:04:59 2005 +0000 @@ -41,6 +41,7 @@ ecd->state = ECAT_DS_READY; ecd->rx_data_length = 0; ecd->isr = NULL; + ecd->module = NULL; } /***************************************************************/ diff -r 7d9809fbf7b9 -r f4171b8aadf8 drivers/ec_device.h --- a/drivers/ec_device.h Fri Dec 16 09:44:54 2005 +0000 +++ b/drivers/ec_device.h Fri Dec 16 12:04:59 2005 +0000 @@ -63,6 +63,8 @@ volatile unsigned int rx_data_length; /**< Länge des zuletzt empfangenen Rahmens */ irqreturn_t (*isr)(int, void *, struct pt_regs *); /**< Adresse der ISR */ + struct module *module; /**< Zeiger auf das Modul, das das Gerät zur + Verfügung stellt. */ } EtherCAT_device_t; diff -r 7d9809fbf7b9 -r f4171b8aadf8 drivers/ec_master.c --- a/drivers/ec_master.c Fri Dec 16 09:44:54 2005 +0000 +++ b/drivers/ec_master.c Fri Dec 16 12:04:59 2005 +0000 @@ -69,9 +69,9 @@ /***************************************************************/ /** - Setzt das EtherCAT-Geraet, auf dem der Master arbeitet. - - Registriert das Geraet beim master, der es daraufhin oeffnet. + Öffnet ein EtherCAT-Geraet für den Master. + + Registriert das Geraet beim Master, der es daraufhin oeffnet. @param master Der EtherCAT-Master @param device Das EtherCAT-Geraet @@ -80,12 +80,12 @@ oder das Geraet nicht geoeffnet werden konnte. */ -int EtherCAT_register_device(EtherCAT_master_t *master, - EtherCAT_device_t *device) +int EtherCAT_master_open(EtherCAT_master_t *master, + EtherCAT_device_t *device) { if (!master || !device) { - printk(KERN_ERR "EtherCAT: Illegal parameters for register_device()!\n"); + printk(KERN_ERR "EtherCAT: Illegal parameters for master_open()!\n"); return -1; } @@ -110,18 +110,18 @@ /***************************************************************/ /** - Loescht das EtherCAT-Geraet, auf dem der Master arbeitet. + Schliesst das EtherCAT-Geraet, auf dem der Master arbeitet. @param master Der EtherCAT-Master @param device Das EtherCAT-Geraet */ -void EtherCAT_unregister_device(EtherCAT_master_t *master, - EtherCAT_device_t *device) +void EtherCAT_master_close(EtherCAT_master_t *master, + EtherCAT_device_t *device) { if (master->dev != device) { - printk(KERN_WARNING "EtherCAT: Trying to unregister unknown device.\n"); + printk(KERN_WARNING "EtherCAT: Trying to close an unknown device!\n"); return; } @@ -1138,8 +1138,8 @@ EXPORT_SYMBOL(EtherCAT_master_init); EXPORT_SYMBOL(EtherCAT_master_clear); -EXPORT_SYMBOL(EtherCAT_register_device); -EXPORT_SYMBOL(EtherCAT_unregister_device); +EXPORT_SYMBOL(EtherCAT_master_open); +EXPORT_SYMBOL(EtherCAT_master_close); EXPORT_SYMBOL(EtherCAT_read_process_data); EXPORT_SYMBOL(EtherCAT_write_process_data); EXPORT_SYMBOL(EtherCAT_check_slaves); diff -r 7d9809fbf7b9 -r f4171b8aadf8 drivers/ec_master.h --- a/drivers/ec_master.h Fri Dec 16 09:44:54 2005 +0000 +++ b/drivers/ec_master.h Fri Dec 16 12:04:59 2005 +0000 @@ -60,8 +60,8 @@ void EtherCAT_master_clear(EtherCAT_master_t *); // Registration of devices -int EtherCAT_register_device(EtherCAT_master_t *, EtherCAT_device_t *); -void EtherCAT_unregister_device(EtherCAT_master_t *, EtherCAT_device_t *); +int EtherCAT_master_open(EtherCAT_master_t *, EtherCAT_device_t *); +void EtherCAT_master_close(EtherCAT_master_t *, EtherCAT_device_t *); // Sending and receiving int EtherCAT_simple_send_receive(EtherCAT_master_t *, EtherCAT_command_t *); 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); +} + +/******************************************************************************/ diff -r 7d9809fbf7b9 -r f4171b8aadf8 drivers/ec_module.h --- a/drivers/ec_module.h Fri Dec 16 09:44:54 2005 +0000 +++ b/drivers/ec_module.h Fri Dec 16 12:04:59 2005 +0000 @@ -29,6 +29,11 @@ int __init ecat_init_module(void); void __exit ecat_cleanup_module(void); -EtherCAT_master_t *EtherCAT_master(int); +// Registration of devices +int EtherCAT_register_device(int, EtherCAT_device_t *); +void EtherCAT_unregister_device(int, EtherCAT_device_t *); + +EtherCAT_master_t *EtherCAT_request(int); +void EtherCAT_release(EtherCAT_master_t *); /******************************************************************************/ diff -r 7d9809fbf7b9 -r f4171b8aadf8 mini/ec_mini.c --- a/mini/ec_mini.c Fri Dec 16 09:44:54 2005 +0000 +++ b/mini/ec_mini.c Fri Dec 16 12:04:59 2005 +0000 @@ -230,9 +230,9 @@ { printk(KERN_INFO "=== Starting Minimal EtherCAT environment... ===\n"); - if ((ecat_master = EtherCAT_master(0)) == NULL) + if ((ecat_master = EtherCAT_request(0)) == NULL) { - printk(KERN_ERR "No EtherCAT master available!\n"); + printk(KERN_ERR "EtherCAT master 0 not available!\n"); return -1; } @@ -290,6 +290,8 @@ printk(KERN_INFO "Deactivating slaves.\n"); EtherCAT_deactivate_all_slaves(ecat_master); + + EtherCAT_release(ecat_master); } printk(KERN_INFO "=== Minimal EtherCAT environment stopped. ===\n"); diff -r 7d9809fbf7b9 -r f4171b8aadf8 rt/msr_module.c --- a/rt/msr_module.c Fri Dec 16 09:44:54 2005 +0000 +++ b/rt/msr_module.c Fri Dec 16 12:04:59 2005 +0000 @@ -399,9 +399,9 @@ msr_jitter_init(); printk(KERN_INFO "=== Starting EtherCAT environment... ===\n"); - if ((ecat_master = EtherCAT_master(0)) == NULL) + if ((ecat_master = EtherCAT_request(0)) == NULL) { - printk(KERN_ERR "No EtherCAT master available!\n"); + printk(KERN_ERR "EtherCAT master 0 not available!\n"); msr_rtlib_cleanup(); return -1; } @@ -469,6 +469,8 @@ EtherCAT_clear_process_data(ecat_master); printk(KERN_INFO "Deactivating slaves.\n"); EtherCAT_deactivate_all_slaves(ecat_master); + + EtherCAT_release(ecat_master); } printk(KERN_INFO "=== EtherCAT environment stopped. ===\n");